@seniorsistemas/data-seniorx-core 3.0.0 → 3.1.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 (180) hide show
  1. package/core/constants/editable-overlay.const.d.ts +4 -0
  2. package/core/constants/help-popover.const.d.ts +7 -0
  3. package/core/constants/input-mask.const.d.ts +5 -0
  4. package/core/constants/navigation-button.const.d.ts +3 -0
  5. package/core/constants/object-card.const.d.ts +21 -0
  6. package/core/constants/thumbnail.const.d.ts +6 -0
  7. package/core/constants/thumbnails.const.d.ts +4 -0
  8. package/core/constants/token-list.const.d.ts +3 -0
  9. package/core/types/button.type.d.ts +1 -1
  10. package/core/types/datepicker.type.d.ts +28 -0
  11. package/core/types/dynamic-form.type.d.ts +29 -0
  12. package/core/types/editable-overlay.type.d.ts +15 -0
  13. package/core/types/help-popover.type.d.ts +2 -0
  14. package/core/types/input-mask.type.d.ts +6 -0
  15. package/core/types/lookup.type.d.ts +45 -0
  16. package/core/types/navigation-button.type.d.ts +9 -0
  17. package/core/types/row-card.type.d.ts +5 -0
  18. package/core/types/semantics.type.d.ts +1 -1
  19. package/core/types/table-options.type.d.ts +1 -0
  20. package/core/types/thumbnail.type.d.ts +1 -0
  21. package/core/types/thumbnails.type.d.ts +20 -0
  22. package/core/types/token-list.type.d.ts +6 -0
  23. package/core/utils/emoji-support.util.d.ts +12 -0
  24. package/core/utils/overlay-dismiss.util.d.ts +25 -0
  25. package/esm2022/core/config/row-card.type.config.mjs +3 -1
  26. package/esm2022/core/constants/country-phone-picker.const.mjs +6 -6
  27. package/esm2022/core/constants/editable-overlay.const.mjs +5 -0
  28. package/esm2022/core/constants/help-popover.const.mjs +7 -0
  29. package/esm2022/core/constants/input-mask.const.mjs +6 -0
  30. package/esm2022/core/constants/navigation-button.const.mjs +4 -0
  31. package/esm2022/core/constants/object-card.const.mjs +23 -0
  32. package/esm2022/core/constants/thumbnail.const.mjs +14 -0
  33. package/esm2022/core/constants/thumbnails.const.mjs +5 -0
  34. package/esm2022/core/constants/token-list.const.mjs +4 -0
  35. package/esm2022/core/types/button.type.mjs +1 -1
  36. package/esm2022/core/types/datepicker.type.mjs +2 -0
  37. package/esm2022/core/types/dynamic-form.type.mjs +2 -0
  38. package/esm2022/core/types/editable-overlay.type.mjs +2 -0
  39. package/esm2022/core/types/help-popover.type.mjs +2 -0
  40. package/esm2022/core/types/input-mask.type.mjs +2 -0
  41. package/esm2022/core/types/lookup.type.mjs +2 -0
  42. package/esm2022/core/types/navigation-button.type.mjs +2 -0
  43. package/esm2022/core/types/row-card.type.mjs +1 -1
  44. package/esm2022/core/types/semantics.type.mjs +1 -1
  45. package/esm2022/core/types/table-options.type.mjs +1 -1
  46. package/esm2022/core/types/thumbnail.type.mjs +2 -0
  47. package/esm2022/core/types/thumbnails.type.mjs +2 -0
  48. package/esm2022/core/types/token-list.type.mjs +2 -0
  49. package/esm2022/core/utils/emoji-support.util.mjs +48 -0
  50. package/esm2022/core/utils/mask.util.mjs +2 -2
  51. package/esm2022/core/utils/overlay-dismiss.util.mjs +38 -0
  52. package/esm2022/features/alert/alert.component.mjs +5 -2
  53. package/esm2022/features/autocomplete/autocomplete.component.mjs +30 -8
  54. package/esm2022/features/bignumber-input/bignumber-input.component.mjs +1 -1
  55. package/esm2022/features/button/button.component.mjs +13 -5
  56. package/esm2022/features/card-list/card/card.component.mjs +2 -2
  57. package/esm2022/features/card-list/card-list.component.mjs +2 -2
  58. package/esm2022/features/checkbox-list/checkbox-list.component.mjs +25 -5
  59. package/esm2022/features/chips/chips.component.mjs +3 -3
  60. package/esm2022/features/code-editor/code-editor.component.mjs +12 -3
  61. package/esm2022/features/combobox/combobox.component.mjs +3 -3
  62. package/esm2022/features/confirm/confirm.component.mjs +2 -2
  63. package/esm2022/features/context-selector/context-selector.component.mjs +1 -1
  64. package/esm2022/features/country-phone-picker/country-phone-picker.component.mjs +22 -18
  65. package/esm2022/features/currency/currency.component.mjs +3 -3
  66. package/esm2022/features/datepicker/datepicker.component.mjs +814 -0
  67. package/esm2022/features/dynamic-form/dynamic-form-field.directive.mjs +178 -0
  68. package/esm2022/features/dynamic-form/dynamic-form.component.mjs +60 -0
  69. package/esm2022/features/dynamic-form/dynamic-form.registry.mjs +13 -0
  70. package/esm2022/features/editable-overlay/editable-overlay-editor.directive.mjs +31 -0
  71. package/esm2022/features/editable-overlay/editable-overlay.component.mjs +217 -0
  72. package/esm2022/features/editor/editor.component.mjs +173 -0
  73. package/esm2022/features/empty-state/empty-state.component.mjs +3 -3
  74. package/esm2022/features/fileupload/fileupload.component.mjs +3 -3
  75. package/esm2022/features/help-popover/help-popover.component.mjs +204 -0
  76. package/esm2022/features/hyperlink/hyperlink.component.mjs +3 -3
  77. package/esm2022/features/icon-picker/icon-picker.component.mjs +4 -4
  78. package/esm2022/features/image-cropper/image-cropper.component.mjs +2 -2
  79. package/esm2022/features/info-sign/info-sign.component.mjs +6 -3
  80. package/esm2022/features/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.mjs +1 -1
  81. package/esm2022/features/inline-edit/components/inline-edit-item/inline-edit-item.component.mjs +2 -2
  82. package/esm2022/features/input-mask/input-mask.directive.mjs +510 -0
  83. package/esm2022/features/list/list.component.mjs +2 -2
  84. package/esm2022/features/localized-number-input/localized-number-input.component.mjs +3 -3
  85. package/esm2022/features/lookup/lookup.component.mjs +351 -0
  86. package/esm2022/features/modal/modal.component.mjs +6 -3
  87. package/esm2022/features/modalc/modalc.component.mjs +6 -3
  88. package/esm2022/features/navigation-button/navigation-button.component.mjs +172 -0
  89. package/esm2022/features/number-input/number-input.component.mjs +10 -4
  90. package/esm2022/features/object-card/components/object-card-field/object-card-field.component.mjs +89 -0
  91. package/esm2022/features/object-card/components/object-card-main/object-card-main.component.mjs +114 -0
  92. package/esm2022/features/object-card/object-card.component.mjs +199 -0
  93. package/esm2022/features/password-strength/password-strength.component.mjs +3 -3
  94. package/esm2022/features/pin-code-field/pin-code-field.component.mjs +14 -4
  95. package/esm2022/features/popover/popover.component.mjs +29 -3
  96. package/esm2022/features/profile-picture-picker/profile-picture-picker.component.mjs +13 -4
  97. package/esm2022/features/rating-scale/rating-scale.component.mjs +24 -4
  98. package/esm2022/features/row-card-list/row-card/row-card.component.mjs +19 -4
  99. package/esm2022/features/row-card-list/row-card-list.component.mjs +12 -3
  100. package/esm2022/features/scaffold/scaffold.component.mjs +3 -3
  101. package/esm2022/features/searchbox/searchbox.component.mjs +2 -2
  102. package/esm2022/features/select-button/select-button.component.mjs +26 -4
  103. package/esm2022/features/slider/slider.component.mjs +3 -3
  104. package/esm2022/features/split-button/split-button.component.mjs +1 -1
  105. package/esm2022/features/spotlight/components/spotlight-overlay/spotlight-overlay.component.mjs +15 -18
  106. package/esm2022/features/spotlight/spotlight.component.mjs +2 -2
  107. package/esm2022/features/star-rating/star-rating.component.mjs +25 -4
  108. package/esm2022/features/table/components/table-cell-content.component.mjs +2 -2
  109. package/esm2022/features/table/table.component.mjs +30 -9
  110. package/esm2022/features/textarea/textarea.component.mjs +3 -3
  111. package/esm2022/features/thumbnail/thumbnail.component.mjs +86 -0
  112. package/esm2022/features/thumbnails/components/thumbnail-item/thumbnail-item.component.mjs +59 -0
  113. package/esm2022/features/thumbnails/components/thumbnail-item-image/thumbnail-item-image.component.mjs +25 -0
  114. package/esm2022/features/thumbnails/components/thumbnail-item-video/thumbnail-item-video.component.mjs +50 -0
  115. package/esm2022/features/thumbnails/thumbnails.component.mjs +76 -0
  116. package/esm2022/features/tiered-menu/directives/tiered-menu.directive.mjs +13 -1
  117. package/esm2022/features/token-list/token-list.component.mjs +64 -0
  118. package/esm2022/features/visual-sql-editor/visual-sql-editor.component.mjs +2 -2
  119. package/esm2022/locales/en.json +409 -1
  120. package/esm2022/locales/es-CO.json +423 -2
  121. package/esm2022/locales/pt.json +1037 -630
  122. package/esm2022/providers/features.provider.mjs +20 -2
  123. package/esm2022/providers/primeng-config.provider.mjs +14 -128
  124. package/esm2022/providers/translate.provider.mjs +2 -2
  125. package/esm2022/public-api.mjs +31 -1
  126. package/features/alert/alert.component.d.ts +1 -0
  127. package/features/autocomplete/autocomplete.component.d.ts +9 -3
  128. package/features/button/button.component.d.ts +3 -1
  129. package/features/checkbox-list/checkbox-list.component.d.ts +8 -1
  130. package/features/code-editor/code-editor.component.d.ts +5 -1
  131. package/features/country-phone-picker/country-phone-picker.component.d.ts +3 -0
  132. package/features/datepicker/datepicker.component.d.ts +118 -0
  133. package/features/dynamic-form/dynamic-form-field.directive.d.ts +26 -0
  134. package/features/dynamic-form/dynamic-form.component.d.ts +15 -0
  135. package/features/dynamic-form/dynamic-form.registry.d.ts +11 -0
  136. package/features/editable-overlay/editable-overlay-editor.directive.d.ts +22 -0
  137. package/features/editable-overlay/editable-overlay.component.d.ts +60 -0
  138. package/features/editor/editor.component.d.ts +47 -0
  139. package/features/help-popover/help-popover.component.d.ts +81 -0
  140. package/features/info-sign/info-sign.component.d.ts +2 -1
  141. package/features/input-mask/input-mask.directive.d.ts +117 -0
  142. package/features/lookup/lookup.component.d.ts +104 -0
  143. package/features/modal/modal.component.d.ts +2 -1
  144. package/features/modalc/modalc.component.d.ts +2 -1
  145. package/features/navigation-button/navigation-button.component.d.ts +58 -0
  146. package/features/number-input/number-input.component.d.ts +3 -1
  147. package/features/object-card/components/object-card-field/object-card-field.component.d.ts +48 -0
  148. package/features/object-card/components/object-card-main/object-card-main.component.d.ts +57 -0
  149. package/features/object-card/object-card.component.d.ts +70 -0
  150. package/features/pin-code-field/pin-code-field.component.d.ts +6 -1
  151. package/features/popover/popover.component.d.ts +4 -1
  152. package/features/profile-picture-picker/profile-picture-picker.component.d.ts +5 -1
  153. package/features/rating-scale/rating-scale.component.d.ts +9 -1
  154. package/features/row-card-list/row-card/row-card.component.d.ts +6 -1
  155. package/features/row-card-list/row-card-list.component.d.ts +4 -1
  156. package/features/select-button/select-button.component.d.ts +9 -1
  157. package/features/star-rating/star-rating.component.d.ts +9 -1
  158. package/features/table/table.component.d.ts +2 -1
  159. package/features/thumbnail/thumbnail.component.d.ts +48 -0
  160. package/features/thumbnails/components/thumbnail-item/thumbnail-item.component.d.ts +29 -0
  161. package/features/thumbnails/components/thumbnail-item-image/thumbnail-item-image.component.d.ts +13 -0
  162. package/features/thumbnails/components/thumbnail-item-video/thumbnail-item-video.component.d.ts +19 -0
  163. package/features/thumbnails/thumbnails.component.d.ts +46 -0
  164. package/features/tiered-menu/directives/tiered-menu.directive.d.ts +2 -0
  165. package/features/token-list/token-list.component.d.ts +31 -0
  166. package/fesm2022/seniorsistemas-data-seniorx-core.mjs +11288 -6613
  167. package/fesm2022/seniorsistemas-data-seniorx-core.mjs.map +1 -1
  168. package/package.json +12 -3
  169. package/providers/primeng-config.provider.d.ts +12 -0
  170. package/public-api.d.ts +38 -0
  171. package/src/locales/en.json +409 -1
  172. package/src/locales/es-CO.json +423 -2
  173. package/src/locales/pt.json +1037 -630
  174. package/styles/sdc-global-variables.scss +38 -0
  175. package/styles.css +132 -0
  176. package/styles.scss +2 -0
  177. package/esm2022/providers/custom/button.mjs +0 -93
  178. package/esm2022/providers/custom/toast.mjs +0 -75
  179. package/providers/custom/button.d.ts +0 -16
  180. package/providers/custom/toast.d.ts +0 -14
@@ -0,0 +1,814 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, computed, ElementRef, EventEmitter, Input, Output, signal, ViewChild, ViewChildren, ViewEncapsulation, forwardRef, inject } from '@angular/core';
3
+ import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
4
+ import { TranslateModule, TranslateService } from '@ngx-translate/core';
5
+ import { Subscription } from 'rxjs';
6
+ import { InputsComponent } from '../../core/directives/inputs.directive';
7
+ import { focusFirstDescendant } from '../../core/utils/focus.util';
8
+ import { nextSequentialId } from '../../core/utils/id.util';
9
+ import { PopoverComponent } from '../popover/popover.component';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/common";
12
+ import * as i2 from "@ngx-translate/core";
13
+ const DAYS_IN_WEEK = 7;
14
+ const YEARS_PER_PAGE = 12;
15
+ const HOUR_FORMAT_12_MAX = 12;
16
+ const HOUR_FORMAT_24_MAX = 23;
17
+ const YEAR_SHORT_LENGTH = 2;
18
+ export class DatepickerComponent extends InputsComponent {
19
+ translate = inject(TranslateService);
20
+ cdr = inject(ChangeDetectorRef);
21
+ elementRef = inject(ElementRef);
22
+ subscriptions = new Subscription();
23
+ // --- Inputs ---
24
+ mode = 'date';
25
+ selectionMode = 'single';
26
+ showIcon = true;
27
+ icon = 'fas fa-calendar';
28
+ min = null;
29
+ max = null;
30
+ defaultDate = null;
31
+ dateFormat = 'dd/MM/yyyy';
32
+ hourFormat = '24';
33
+ minuteStep = 5;
34
+ showSeconds = false;
35
+ rangeSeparator = ' — ';
36
+ showOnFocus = true;
37
+ readonlyInput = false;
38
+ firstDayOfWeek = 0;
39
+ showButtonBar = true;
40
+ showClear = false;
41
+ disabledDates = [];
42
+ disabledDays = [];
43
+ // --- Outputs ---
44
+ selected = new EventEmitter();
45
+ closed = new EventEmitter();
46
+ monthChange = new EventEmitter();
47
+ yearChange = new EventEmitter();
48
+ // --- View Children ---
49
+ inputRef;
50
+ triggerRef;
51
+ panelContentRef;
52
+ dayButtonRefs;
53
+ inputId = nextSequentialId('sdc-datepicker-input');
54
+ // --- Signals ---
55
+ panelOpen = false;
56
+ suppressNextFocusOpen = false;
57
+ currentView = signal('days');
58
+ viewDate = signal(new Date());
59
+ focusedDate = signal(null);
60
+ // Time signals
61
+ hours = signal(0);
62
+ minutes = signal(0);
63
+ seconds = signal(0);
64
+ // Range selection state
65
+ rangeStart = signal(null);
66
+ rangeEnd = signal(null);
67
+ rangeSelecting = signal(false);
68
+ // --- Computed ---
69
+ weekDayNames = computed(() => {
70
+ const days = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
71
+ const shifted = [];
72
+ for (let i = 0; i < DAYS_IN_WEEK; i++) {
73
+ shifted.push(days[(i + this.firstDayOfWeek) % DAYS_IN_WEEK]);
74
+ }
75
+ return shifted;
76
+ });
77
+ // NOTE: intentionally a plain method (not `computed()`). `this.value` is a plain
78
+ // @Input inherited from InputsComponent, not a Signal, so wrapping this in `computed()`
79
+ // would freeze it after the first read (Angular computed() only reacts to Signal reads).
80
+ // OnPush + the existing `markForCheck()` calls after every value mutation keep this correct.
81
+ calendarDays() {
82
+ const viewD = this.viewDate();
83
+ const year = viewD.getFullYear();
84
+ const month = viewD.getMonth();
85
+ const firstOfMonth = new Date(year, month, 1);
86
+ const startDay = firstOfMonth.getDay();
87
+ const daysBeforeStart = (startDay - this.firstDayOfWeek + DAYS_IN_WEEK) % DAYS_IN_WEEK;
88
+ const startDate = new Date(year, month, 1 - daysBeforeStart);
89
+ const today = new Date();
90
+ today.setHours(0, 0, 0, 0);
91
+ const days = [];
92
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
93
+ // Dynamic row count (5, 6, or rarely 4 weeks) instead of a fixed 42-cell (6 row) grid,
94
+ // matching Angular Components behavior. Avoids a trailing all-disabled/blank week
95
+ // for months that only need 5 rows.
96
+ const totalCells = Math.ceil((daysBeforeStart + daysInMonth) / DAYS_IN_WEEK) * DAYS_IN_WEEK;
97
+ for (let i = 0; i < totalCells; i++) {
98
+ const date = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() + i);
99
+ date.setHours(0, 0, 0, 0);
100
+ days.push({
101
+ date,
102
+ day: date.getDate(),
103
+ currentMonth: date.getMonth() === month,
104
+ today: date.getTime() === today.getTime(),
105
+ selected: this.isDateSelected(date),
106
+ disabled: this.isDateDisabled(date),
107
+ inRange: this.isInRange(date),
108
+ rangeStart: this.isRangeStart(date),
109
+ rangeEnd: this.isRangeEnd(date)
110
+ });
111
+ }
112
+ return days;
113
+ }
114
+ // Groups `calendarDays()` into 7-day weeks so the template can render a real
115
+ // <table>/<tr>/<td> grid (native row/gridcell semantics) instead of ARIA roles on <div>s.
116
+ calendarWeeks() {
117
+ const days = this.calendarDays();
118
+ const weeks = [];
119
+ for (let i = 0; i < days.length; i += DAYS_IN_WEEK) {
120
+ weeks.push(days.slice(i, i + DAYS_IN_WEEK));
121
+ }
122
+ return weeks;
123
+ }
124
+ // NOTE: plain method for the same reason as `calendarDays` above (depends on `this.value`,
125
+ // a non-Signal @Input).
126
+ calendarMonths() {
127
+ const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
128
+ const viewD = this.viewDate();
129
+ return monthNames.map((name, index) => ({
130
+ month: index,
131
+ selected: this.isMonthSelected(index, viewD.getFullYear()),
132
+ name
133
+ }));
134
+ }
135
+ yearRange = computed(() => {
136
+ const viewD = this.viewDate();
137
+ const currentYear = viewD.getFullYear();
138
+ const startYear = currentYear - (currentYear % YEARS_PER_PAGE);
139
+ const years = [];
140
+ for (let i = 0; i < YEARS_PER_PAGE; i++) {
141
+ years.push(startYear + i);
142
+ }
143
+ return years;
144
+ });
145
+ // NOTE: plain method for the same reason as `calendarDays` above (depends on `this.value`,
146
+ // a non-Signal @Input).
147
+ displayValue() {
148
+ const val = this.value;
149
+ if (!val) {
150
+ return '';
151
+ }
152
+ if (this.mode === 'range') {
153
+ const range = val;
154
+ const startStr = range.start ? this.formatDate(range.start) : '';
155
+ const endStr = range.end ? this.formatDate(range.end) : '';
156
+ return startStr && endStr ? `${startStr}${this.rangeSeparator}${endStr}` : startStr;
157
+ }
158
+ if (this.selectionMode === 'multiple' && Array.isArray(val)) {
159
+ return val.map(d => this.formatDate(d)).join(', ');
160
+ }
161
+ if (val instanceof Date) {
162
+ return this.formatDate(val);
163
+ }
164
+ return '';
165
+ }
166
+ viewMonthYearLabel = computed(() => {
167
+ const monthNames = ['January', 'February', 'March', 'April', 'May', 'June',
168
+ 'July', 'August', 'September', 'October', 'November', 'December'];
169
+ const viewD = this.viewDate();
170
+ if (this.currentView() === 'years') {
171
+ const years = this.yearRange();
172
+ return `${years[0]} - ${years[years.length - 1]}`;
173
+ }
174
+ return `${monthNames[viewD.getMonth()]} ${viewD.getFullYear()}`;
175
+ });
176
+ showTimePicker = computed(() => {
177
+ return this.mode === 'datetime' || this.mode === 'time';
178
+ });
179
+ // --- Lifecycle ---
180
+ ngOnInit() {
181
+ this.initializeViewDate();
182
+ this.subscriptions.add(this.translate.onLangChange.subscribe(() => {
183
+ this.cdr.markForCheck();
184
+ }));
185
+ }
186
+ ngOnDestroy() {
187
+ this.subscriptions.unsubscribe();
188
+ }
189
+ // --- ControlValueAccessor override ---
190
+ writeValue(value) {
191
+ this.value = value;
192
+ if (value instanceof Date) {
193
+ this.viewDate.set(new Date(value.getFullYear(), value.getMonth(), 1));
194
+ this.hours.set(value.getHours());
195
+ this.minutes.set(value.getMinutes());
196
+ this.seconds.set(value.getSeconds());
197
+ }
198
+ this.cdr.markForCheck();
199
+ }
200
+ // --- Validator ---
201
+ validate(control) {
202
+ const val = control.value;
203
+ if (!val) {
204
+ return null;
205
+ }
206
+ if (this.min && val instanceof Date && val < this.min) {
207
+ return { sdcDatepickerMin: { min: this.min, actual: val } };
208
+ }
209
+ if (this.max && val instanceof Date && val > this.max) {
210
+ return { sdcDatepickerMax: { max: this.max, actual: val } };
211
+ }
212
+ return null;
213
+ }
214
+ // --- Panel actions ---
215
+ openPanel() {
216
+ if (this.disabled || this.panelOpen) {
217
+ return;
218
+ }
219
+ this.panelOpen = true;
220
+ this.initializeViewDate();
221
+ this.cdr.detectChanges(); // Force immediate CD for CDK overlay
222
+ }
223
+ closePanel() {
224
+ if (!this.panelOpen) {
225
+ return;
226
+ }
227
+ this.panelOpen = false;
228
+ this.closed.emit();
229
+ this.onTouched();
230
+ this.cdr.detectChanges(); // Force immediate CD for CDK overlay
231
+ }
232
+ // Closes the panel and returns focus to the trigger input. Only used for closes driven
233
+ // directly by an in-widget action (Escape, a day/footer-button selection) — the day button
234
+ // or footer button that had focus is about to be destroyed, so restoring focus to the input
235
+ // is always correct there. NOT used for `onPopoverOpenChange` (outside-click), where forcing
236
+ // focus back would fight the click the user just made on something else.
237
+ closePanelAndFocusInput() {
238
+ this.closePanel();
239
+ // `showOnFocus` reopens the panel on (focus) — without this guard, focusing the input
240
+ // back here would immediately reopen the panel we just closed.
241
+ this.suppressNextFocusOpen = true;
242
+ this.inputRef?.nativeElement?.focus();
243
+ }
244
+ togglePanel() {
245
+ if (this.panelOpen) {
246
+ this.closePanel();
247
+ }
248
+ else {
249
+ this.openPanel();
250
+ }
251
+ }
252
+ onInputClick() {
253
+ if (this.showOnFocus && !this.disabled) {
254
+ this.openPanel();
255
+ }
256
+ }
257
+ onInputFocus() {
258
+ if (this.suppressNextFocusOpen) {
259
+ this.suppressNextFocusOpen = false;
260
+ return;
261
+ }
262
+ this.onInputClick();
263
+ }
264
+ onOverlayKeydown(event) {
265
+ if (event.key === 'Escape') {
266
+ this.closePanelAndFocusInput();
267
+ event.preventDefault();
268
+ }
269
+ }
270
+ onKeydown(event) {
271
+ if (event.key === 'Tab' && !event.shiftKey && this.panelOpen) {
272
+ this.focusIntoPanel(event);
273
+ return;
274
+ }
275
+ const view = this.currentView();
276
+ if (view === 'days') {
277
+ this.handleDaysKeydown(event);
278
+ }
279
+ }
280
+ // Tab from the input would otherwise escape straight past the calendar: the popover's panel
281
+ // is portaled to <body> (far from the input in DOM order), so without this it jumps to
282
+ // whatever page element happens to come next, never reaching the calendar at all. This
283
+ // redirects Tab into the panel instead — deliberately NOT done on open/focus (e.g. via
284
+ // `focusOnOpen`), which would steal focus from the input and break typing a date manually.
285
+ focusIntoPanel(event) {
286
+ if (this.currentView() === 'days') {
287
+ const days = this.calendarDays();
288
+ const activeDate = this.focusedDate()
289
+ ?? days.find(d => d.today)?.date
290
+ ?? days.find(d => d.currentMonth)?.date;
291
+ if (activeDate) {
292
+ event.preventDefault();
293
+ this.focusDayButton(activeDate);
294
+ return;
295
+ }
296
+ }
297
+ const panel = this.panelContentRef?.nativeElement;
298
+ if (panel) {
299
+ event.preventDefault();
300
+ focusFirstDescendant(panel, panel);
301
+ }
302
+ }
303
+ // Bound on the calendar grid itself (`.sdc-datepicker__days`), which lives in the popover's
304
+ // portal — a separate DOM subtree from the input, so `onKeydown` above (bound on the input)
305
+ // never sees keydowns that originate from a day button that already has real focus. Only
306
+ // arrow keys are forwarded here: Enter/Space are left to the button's native activation
307
+ // (which already fires `selectDay` via `(click)`), otherwise they'd double-fire.
308
+ onDaysGridKeydown(event) {
309
+ if (this.currentView() !== 'days') {
310
+ return;
311
+ }
312
+ if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight' && event.key !== 'ArrowUp' && event.key !== 'ArrowDown') {
313
+ return;
314
+ }
315
+ this.handleDaysKeydown(event);
316
+ }
317
+ // --- Navigation ---
318
+ prevMonth() {
319
+ const d = this.viewDate();
320
+ const newDate = new Date(d.getFullYear(), d.getMonth() - 1, 1);
321
+ this.viewDate.set(newDate);
322
+ this.monthChange.emit({ month: newDate.getMonth() + 1, year: newDate.getFullYear() });
323
+ }
324
+ nextMonth() {
325
+ const d = this.viewDate();
326
+ const newDate = new Date(d.getFullYear(), d.getMonth() + 1, 1);
327
+ this.viewDate.set(newDate);
328
+ this.monthChange.emit({ month: newDate.getMonth() + 1, year: newDate.getFullYear() });
329
+ }
330
+ prevYear() {
331
+ const d = this.viewDate();
332
+ this.viewDate.set(new Date(d.getFullYear() - 1, d.getMonth(), 1));
333
+ this.yearChange.emit({ month: d.getMonth() + 1, year: d.getFullYear() - 1 });
334
+ }
335
+ nextYear() {
336
+ const d = this.viewDate();
337
+ this.viewDate.set(new Date(d.getFullYear() + 1, d.getMonth(), 1));
338
+ this.yearChange.emit({ month: d.getMonth() + 1, year: d.getFullYear() + 1 });
339
+ }
340
+ prevYearRange() {
341
+ const d = this.viewDate();
342
+ this.viewDate.set(new Date(d.getFullYear() - YEARS_PER_PAGE, d.getMonth(), 1));
343
+ }
344
+ nextYearRange() {
345
+ const d = this.viewDate();
346
+ this.viewDate.set(new Date(d.getFullYear() + YEARS_PER_PAGE, d.getMonth(), 1));
347
+ }
348
+ switchToMonthView() {
349
+ this.currentView.set('months');
350
+ }
351
+ switchToYearView() {
352
+ this.currentView.set('years');
353
+ }
354
+ selectMonth(month) {
355
+ const d = this.viewDate();
356
+ this.viewDate.set(new Date(d.getFullYear(), month, 1));
357
+ if (this.mode === 'month') {
358
+ const selectedDate = new Date(d.getFullYear(), month, 1);
359
+ this.commitDateValue(selectedDate);
360
+ this.closePanelAndFocusInput();
361
+ }
362
+ else {
363
+ this.currentView.set('days');
364
+ }
365
+ this.monthChange.emit({ month: month + 1, year: d.getFullYear() });
366
+ }
367
+ selectYear(year) {
368
+ const d = this.viewDate();
369
+ this.viewDate.set(new Date(year, d.getMonth(), 1));
370
+ this.currentView.set('months');
371
+ this.yearChange.emit({ month: d.getMonth() + 1, year });
372
+ }
373
+ // --- Day selection ---
374
+ selectDay(day) {
375
+ if (day.disabled) {
376
+ return;
377
+ }
378
+ const date = new Date(day.date);
379
+ if (this.mode === 'range') {
380
+ this.handleRangeSelection(date);
381
+ return;
382
+ }
383
+ if (this.selectionMode === 'multiple') {
384
+ this.handleMultipleSelection(date);
385
+ return;
386
+ }
387
+ // Single selection
388
+ if (this.showTimePicker()) {
389
+ date.setHours(this.hours(), this.minutes(), this.seconds());
390
+ }
391
+ this.commitDateValue(date);
392
+ if (this.mode === 'date') {
393
+ this.closePanelAndFocusInput();
394
+ }
395
+ }
396
+ // --- Time ---
397
+ incrementHours() {
398
+ const max = this.hourFormat === '12' ? HOUR_FORMAT_12_MAX : HOUR_FORMAT_24_MAX;
399
+ this.hours.set((this.hours() + 1) % (max + 1));
400
+ this.updateTimeOnValue();
401
+ }
402
+ decrementHours() {
403
+ const max = this.hourFormat === '12' ? HOUR_FORMAT_12_MAX : HOUR_FORMAT_24_MAX;
404
+ this.hours.set((this.hours() - 1 + (max + 1)) % (max + 1));
405
+ this.updateTimeOnValue();
406
+ }
407
+ incrementMinutes() {
408
+ this.minutes.set((this.minutes() + this.minuteStep) % 60);
409
+ this.updateTimeOnValue();
410
+ }
411
+ decrementMinutes() {
412
+ this.minutes.set((this.minutes() - this.minuteStep + 60) % 60);
413
+ this.updateTimeOnValue();
414
+ }
415
+ incrementSeconds() {
416
+ this.seconds.set((this.seconds() + 1) % 60);
417
+ this.updateTimeOnValue();
418
+ }
419
+ decrementSeconds() {
420
+ this.seconds.set((this.seconds() - 1 + 60) % 60);
421
+ this.updateTimeOnValue();
422
+ }
423
+ // --- Button bar actions ---
424
+ selectToday() {
425
+ const today = new Date();
426
+ if (this.mode === 'time') {
427
+ this.hours.set(today.getHours());
428
+ this.minutes.set(today.getMinutes());
429
+ this.seconds.set(today.getSeconds());
430
+ this.updateTimeOnValue();
431
+ }
432
+ else {
433
+ today.setHours(this.hours(), this.minutes(), this.seconds());
434
+ this.commitDateValue(today);
435
+ this.viewDate.set(new Date(today.getFullYear(), today.getMonth(), 1));
436
+ }
437
+ this.closePanelAndFocusInput();
438
+ }
439
+ clearValue() {
440
+ this.value = null;
441
+ this.onChange(null);
442
+ this.valueChange.emit(null);
443
+ this.selected.emit(null);
444
+ this.rangeStart.set(null);
445
+ this.rangeEnd.set(null);
446
+ this.rangeSelecting.set(false);
447
+ this.cdr.markForCheck();
448
+ }
449
+ confirmDateTime() {
450
+ if (this.value instanceof Date) {
451
+ const updated = new Date(this.value);
452
+ updated.setHours(this.hours(), this.minutes(), this.seconds());
453
+ this.commitDateValue(updated);
454
+ }
455
+ this.closePanelAndFocusInput();
456
+ }
457
+ // --- Popover events ---
458
+ onPopoverOpenChange(open) {
459
+ if (!open && this.panelOpen) {
460
+ this.closePanel();
461
+ }
462
+ }
463
+ // --- Private helpers ---
464
+ initializeViewDate() {
465
+ if (this.value instanceof Date) {
466
+ this.viewDate.set(new Date(this.value.getFullYear(), this.value.getMonth(), 1));
467
+ }
468
+ else if (this.defaultDate) {
469
+ this.viewDate.set(new Date(this.defaultDate.getFullYear(), this.defaultDate.getMonth(), 1));
470
+ }
471
+ else {
472
+ const now = new Date();
473
+ this.viewDate.set(new Date(now.getFullYear(), now.getMonth(), 1));
474
+ }
475
+ if (this.mode === 'month') {
476
+ this.currentView.set('months');
477
+ }
478
+ else {
479
+ this.currentView.set('days');
480
+ }
481
+ }
482
+ commitDateValue(date) {
483
+ this.value = date;
484
+ this.onChange(date);
485
+ this.valueChange.emit(date);
486
+ this.selected.emit(date);
487
+ this.cdr.markForCheck();
488
+ }
489
+ handleRangeSelection(date) {
490
+ if (!this.rangeSelecting()) {
491
+ // First click: set start
492
+ this.rangeStart.set(date);
493
+ this.rangeEnd.set(null);
494
+ this.rangeSelecting.set(true);
495
+ const range = { start: date, end: null };
496
+ this.value = range;
497
+ this.onChange(range);
498
+ this.valueChange.emit(range);
499
+ }
500
+ else {
501
+ // Second click: set end
502
+ let start = this.rangeStart() ?? date;
503
+ let end = date;
504
+ if (end < start) {
505
+ [start, end] = [end, start];
506
+ }
507
+ this.rangeStart.set(start);
508
+ this.rangeEnd.set(end);
509
+ this.rangeSelecting.set(false);
510
+ const range = { start, end };
511
+ this.value = range;
512
+ this.onChange(range);
513
+ this.valueChange.emit(range);
514
+ this.selected.emit(range);
515
+ this.closePanelAndFocusInput();
516
+ }
517
+ this.cdr.markForCheck();
518
+ }
519
+ handleMultipleSelection(date) {
520
+ const current = Array.isArray(this.value) ? this.value : [];
521
+ const index = current.findIndex(d => this.isSameDay(d, date));
522
+ let updated;
523
+ if (index >= 0) {
524
+ updated = [...current.slice(0, index), ...current.slice(index + 1)];
525
+ }
526
+ else {
527
+ updated = [...current, date];
528
+ }
529
+ this.value = updated;
530
+ this.onChange(updated);
531
+ this.valueChange.emit(updated);
532
+ this.selected.emit(updated);
533
+ this.cdr.markForCheck();
534
+ }
535
+ updateTimeOnValue() {
536
+ if (this.mode === 'time') {
537
+ const d = new Date();
538
+ d.setHours(this.hours(), this.minutes(), this.seconds(), 0);
539
+ this.commitDateValue(d);
540
+ return;
541
+ }
542
+ if (this.value instanceof Date) {
543
+ const updated = new Date(this.value);
544
+ updated.setHours(this.hours(), this.minutes(), this.seconds());
545
+ this.value = updated;
546
+ this.onChange(updated);
547
+ this.valueChange.emit(updated);
548
+ this.cdr.markForCheck();
549
+ }
550
+ }
551
+ isDateSelected(date) {
552
+ const val = this.value;
553
+ if (!val) {
554
+ return false;
555
+ }
556
+ if (this.mode === 'range') {
557
+ const range = val;
558
+ return (!!range.start && this.isSameDay(range.start, date)) ||
559
+ (!!range.end && this.isSameDay(range.end, date));
560
+ }
561
+ if (this.selectionMode === 'multiple' && Array.isArray(val)) {
562
+ return val.some(d => this.isSameDay(d, date));
563
+ }
564
+ if (val instanceof Date) {
565
+ return this.isSameDay(val, date);
566
+ }
567
+ return false;
568
+ }
569
+ isDateDisabled(date) {
570
+ if (this.min && date < this.min) {
571
+ return true;
572
+ }
573
+ if (this.max && date > this.max) {
574
+ return true;
575
+ }
576
+ if (this.disabledDays.includes(date.getDay())) {
577
+ return true;
578
+ }
579
+ if (this.disabledDates.some(d => this.isSameDay(d, date))) {
580
+ return true;
581
+ }
582
+ return false;
583
+ }
584
+ isInRange(date) {
585
+ if (this.mode !== 'range') {
586
+ return false;
587
+ }
588
+ const val = this.value;
589
+ if (!val?.start || !val?.end) {
590
+ return false;
591
+ }
592
+ return date > val.start && date < val.end;
593
+ }
594
+ isRangeStart(date) {
595
+ if (this.mode !== 'range') {
596
+ return false;
597
+ }
598
+ const val = this.value;
599
+ return !!val?.start && this.isSameDay(val.start, date);
600
+ }
601
+ isRangeEnd(date) {
602
+ if (this.mode !== 'range') {
603
+ return false;
604
+ }
605
+ const val = this.value;
606
+ return !!val?.end && this.isSameDay(val.end, date);
607
+ }
608
+ isMonthSelected(month, year) {
609
+ const val = this.value;
610
+ if (val instanceof Date) {
611
+ return val.getMonth() === month && val.getFullYear() === year;
612
+ }
613
+ return false;
614
+ }
615
+ isSameDay(a, b) {
616
+ return a.getFullYear() === b.getFullYear() &&
617
+ a.getMonth() === b.getMonth() &&
618
+ a.getDate() === b.getDate();
619
+ }
620
+ handleDaysKeydown(event) {
621
+ const focused = this.focusedDate() ?? this.viewDate();
622
+ let newDate = null;
623
+ switch (event.key) {
624
+ case 'ArrowLeft':
625
+ newDate = new Date(focused.getFullYear(), focused.getMonth(), focused.getDate() - 1);
626
+ break;
627
+ case 'ArrowRight':
628
+ newDate = new Date(focused.getFullYear(), focused.getMonth(), focused.getDate() + 1);
629
+ break;
630
+ case 'ArrowUp':
631
+ newDate = new Date(focused.getFullYear(), focused.getMonth(), focused.getDate() - DAYS_IN_WEEK);
632
+ break;
633
+ case 'ArrowDown':
634
+ newDate = new Date(focused.getFullYear(), focused.getMonth(), focused.getDate() + DAYS_IN_WEEK);
635
+ break;
636
+ case 'Enter':
637
+ case ' ':
638
+ if (focused) {
639
+ this.selectDay({
640
+ date: focused,
641
+ day: focused.getDate(),
642
+ currentMonth: true,
643
+ today: false,
644
+ selected: false,
645
+ disabled: this.isDateDisabled(focused),
646
+ inRange: false,
647
+ rangeStart: false,
648
+ rangeEnd: false
649
+ });
650
+ }
651
+ event.preventDefault();
652
+ return;
653
+ default:
654
+ return;
655
+ }
656
+ if (newDate) {
657
+ event.preventDefault();
658
+ this.focusedDate.set(newDate);
659
+ // Navigate month if needed
660
+ if (newDate.getMonth() !== this.viewDate().getMonth()) {
661
+ this.viewDate.set(new Date(newDate.getFullYear(), newDate.getMonth(), 1));
662
+ }
663
+ // Synchronous so the (possibly new month's) day buttons exist before we focus one.
664
+ this.cdr.detectChanges();
665
+ this.focusDayButton(newDate);
666
+ }
667
+ }
668
+ // Moves real DOM focus onto the day button matching `date`, keeping roving tabindex/focus
669
+ // in sync with `focusedDate` — without this, arrow-key navigation only updated internal
670
+ // state and the visible browser/screen-reader focus never actually moved.
671
+ focusDayButton(date) {
672
+ const index = this.calendarDays().findIndex(day => this.isSameDay(day.date, date));
673
+ if (index < 0) {
674
+ return;
675
+ }
676
+ this.dayButtonRefs?.toArray()[index]?.nativeElement.focus();
677
+ }
678
+ // Determines which day is the calendar grid's single roving tabindex=0 stop: the last
679
+ // keyboard-focused day if any, otherwise today (if visible in the current month), otherwise
680
+ // the first day belonging to the current month — so the grid always has exactly one tab stop.
681
+ isDayTabStop(day) {
682
+ const focused = this.focusedDate();
683
+ if (focused) {
684
+ return this.isSameDay(day.date, focused);
685
+ }
686
+ const days = this.calendarDays();
687
+ if (days.some(d => d.today)) {
688
+ return day.today;
689
+ }
690
+ const firstCurrentMonthDay = days.find(d => d.currentMonth) ?? days[0];
691
+ return firstCurrentMonthDay ? this.isSameDay(day.date, firstCurrentMonthDay.date) : false;
692
+ }
693
+ formatDate(date) {
694
+ const d = date.getDate().toString().padStart(2, '0');
695
+ const m = (date.getMonth() + 1).toString().padStart(2, '0');
696
+ const y = date.getFullYear().toString();
697
+ const hh = date.getHours().toString().padStart(2, '0');
698
+ const mm = date.getMinutes().toString().padStart(2, '0');
699
+ const ss = date.getSeconds().toString().padStart(2, '0');
700
+ let result = this.dateFormat
701
+ .replace('dd', d)
702
+ .replace('MM', m)
703
+ .replace('yyyy', y)
704
+ .replace('yy', y.slice(-YEAR_SHORT_LENGTH));
705
+ if (this.mode === 'datetime') {
706
+ result += ` ${hh}:${mm}`;
707
+ if (this.showSeconds) {
708
+ result += `:${ss}`;
709
+ }
710
+ }
711
+ if (this.mode === 'time') {
712
+ result = `${hh}:${mm}`;
713
+ if (this.showSeconds) {
714
+ result += `:${ss}`;
715
+ }
716
+ }
717
+ return result;
718
+ }
719
+ padTime(n) {
720
+ return n.toString().padStart(2, '0');
721
+ }
722
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DatepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
723
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DatepickerComponent, isStandalone: true, selector: "sdc-datepicker", inputs: { mode: "mode", selectionMode: "selectionMode", showIcon: "showIcon", icon: "icon", min: "min", max: "max", defaultDate: "defaultDate", dateFormat: "dateFormat", hourFormat: "hourFormat", minuteStep: "minuteStep", showSeconds: "showSeconds", rangeSeparator: "rangeSeparator", showOnFocus: "showOnFocus", readonlyInput: "readonlyInput", firstDayOfWeek: "firstDayOfWeek", showButtonBar: "showButtonBar", showClear: "showClear", disabledDates: "disabledDates", disabledDays: "disabledDays" }, outputs: { selected: "selected", closed: "closed", monthChange: "monthChange", yearChange: "yearChange" }, providers: [
724
+ {
725
+ provide: NG_VALUE_ACCESSOR,
726
+ useExisting: forwardRef(() => DatepickerComponent),
727
+ multi: true
728
+ },
729
+ {
730
+ provide: NG_VALIDATORS,
731
+ useExisting: forwardRef(() => DatepickerComponent),
732
+ multi: true
733
+ }
734
+ ], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["inputRef"], descendants: true }, { propertyName: "triggerRef", first: true, predicate: ["triggerRef"], descendants: true }, { propertyName: "panelContentRef", first: true, predicate: ["panelContentRef"], descendants: true }, { propertyName: "dayButtonRefs", predicate: ["dayBtn"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"sdc-datepicker\">\n @if (labelKey()) {\n <div class=\"sdc-datepicker__label-row\">\n <label class=\"sdc-datepicker__label\" [attr.for]=\"inputId\">\n <span class=\"sdc-datepicker__label-text\">\n {{ labelKey() | translate }}\n @if (required) {\n <span class=\"required-field\" aria-hidden=\"true\">*</span>\n }\n </span>\n </label>\n </div>\n }\n\n <sdc-popover\n [open]=\"panelOpen\"\n [toggleOnTriggerClick]=\"false\"\n [closeOnOutsideClick]=\"true\"\n [closeOnEscape]=\"true\"\n [matchTriggerWidth]=\"false\"\n [restoreFocusOnClose]=\"false\"\n [trapFocus]=\"true\"\n [ariaLabel]=\"'datepicker.calendar'\"\n panelClass=\"sdc-datepicker-popover-panel\"\n (openChange)=\"onPopoverOpenChange($event)\"\n >\n <div sdc-popover-trigger>\n <div\n class=\"sdc-datepicker__control\"\n #triggerRef\n [class.sdc-datepicker__control--invalid]=\"invalid\"\n [class.sdc-datepicker__control--disabled]=\"disabled\"\n [ngStyle]=\"getInputStyle()\"\n >\n <div class=\"sdc-datepicker__value\">\n <input\n #inputRef\n [id]=\"inputId\"\n class=\"sdc-datepicker__input\"\n type=\"text\"\n [disabled]=\"disabled\"\n [readOnly]=\"readonlyInput\"\n [placeholder]=\"placeholder || dateFormat\"\n [value]=\"displayValue()\"\n [attr.aria-label]=\"labelKey() ? (labelKey() | translate) : placeholder\"\n [attr.aria-expanded]=\"panelOpen\"\n [attr.aria-haspopup]=\"'dialog'\"\n aria-autocomplete=\"none\"\n autocomplete=\"off\"\n (click)=\"onInputClick()\"\n (focus)=\"onInputFocus()\"\n (keydown)=\"onKeydown($event)\"\n />\n </div>\n\n <div class=\"sdc-datepicker__actions\">\n @if (showClear && value) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__icon-button sdc-datepicker__icon-button--clear\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"'datepicker.clear' | translate\"\n (click)=\"clearValue(); $event.stopPropagation()\"\n >\n <i class=\"fas fa-times\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (showIcon) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__icon-button sdc-datepicker__icon-button--toggle\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"'datepicker.calendar' | translate\"\n [attr.aria-expanded]=\"panelOpen\"\n (click)=\"togglePanel(); $event.stopPropagation()\"\n >\n <i [class]=\"icon\" class=\"sdc-datepicker__icon\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n </div>\n\n <div sdc-popover-content>\n <div\n #panelContentRef\n class=\"sdc-datepicker__panel\"\n (keydown)=\"onOverlayKeydown($event)\"\n [attr.aria-label]=\"'datepicker.calendar' | translate\"\n >\n <!-- Navigation Header -->\n @if (mode !== 'time') {\n <div class=\"sdc-datepicker__header\">\n <button\n type=\"button\"\n class=\"sdc-datepicker__nav-btn\"\n [attr.aria-label]=\"'datepicker.prev' | translate\"\n (click)=\"currentView() === 'days' ? prevMonth() : currentView() === 'months' ? prevYear() : prevYearRange()\"\n >\n <i class=\"fas fa-chevron-left\" aria-hidden=\"true\"></i>\n </button>\n\n <button\n type=\"button\"\n class=\"sdc-datepicker__title-btn\"\n (click)=\"\n currentView() === 'days'\n ? switchToMonthView()\n : currentView() === 'months' ? switchToYearView() : null\n \"\n >\n {{ viewMonthYearLabel() }}\n </button>\n\n <button\n type=\"button\"\n class=\"sdc-datepicker__nav-btn\"\n [attr.aria-label]=\"'datepicker.next' | translate\"\n (click)=\"currentView() === 'days' ? nextMonth() : currentView() === 'months' ? nextYear() : nextYearRange()\"\n >\n <i class=\"fas fa-chevron-right\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- Days View -->\n @if (currentView() === 'days' && mode !== 'time') {\n <table class=\"sdc-datepicker__calendar\">\n <thead>\n <tr class=\"sdc-datepicker__weekdays\">\n @for (dayName of weekDayNames(); track dayName) {\n <th class=\"sdc-datepicker__weekday\" scope=\"col\">\n {{ dayName }}\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"sdc-datepicker__days\" (keydown)=\"onDaysGridKeydown($event)\">\n @for (week of calendarWeeks(); track $index) {\n <tr>\n @for (day of week; track day.date.getTime()) {\n <td>\n <button\n #dayBtn\n type=\"button\"\n class=\"sdc-datepicker__day\"\n [class.sdc-datepicker__day--other-month]=\"!day.currentMonth\"\n [class.sdc-datepicker__day--today]=\"day.today\"\n [class.sdc-datepicker__day--selected]=\"day.selected\"\n [class.sdc-datepicker__day--disabled]=\"day.disabled\"\n [class.sdc-datepicker__day--in-range]=\"day.inRange\"\n [class.sdc-datepicker__day--range-start]=\"day.rangeStart\"\n [class.sdc-datepicker__day--range-end]=\"day.rangeEnd\"\n [disabled]=\"day.disabled\"\n [attr.aria-label]=\"day.date.toLocaleDateString()\"\n [attr.aria-selected]=\"day.selected\"\n [attr.aria-disabled]=\"day.disabled\"\n [attr.tabindex]=\"isDayTabStop(day) ? 0 : -1\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n }\n\n <!-- Months View -->\n @if (currentView() === 'months') {\n <div class=\"sdc-datepicker__months-grid\">\n @for (m of calendarMonths(); track m.month) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__month-cell\"\n [class.sdc-datepicker__month-cell--selected]=\"m.selected\"\n (click)=\"selectMonth(m.month)\"\n >\n {{ m.name }}\n </button>\n }\n </div>\n }\n\n <!-- Years View -->\n @if (currentView() === 'years') {\n <div class=\"sdc-datepicker__years-grid\">\n @for (year of yearRange(); track year) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__year-cell\"\n [class.sdc-datepicker__year-cell--selected]=\"year === viewDate().getFullYear()\"\n (click)=\"selectYear(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n\n <!-- Time Picker -->\n @if (showTimePicker()) {\n <div class=\"sdc-datepicker__time\">\n <div class=\"sdc-datepicker__time-group\">\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"incrementHours()\"\n [attr.aria-label]=\"'datepicker.incrementHour' | translate\"\n >\n <i class=\"fas fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"sdc-datepicker__time-value\">{{ padTime(hours()) }}</span>\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"decrementHours()\"\n [attr.aria-label]=\"'datepicker.decrementHour' | translate\"\n >\n <i class=\"fas fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <span class=\"sdc-datepicker__time-separator\">:</span>\n\n <div class=\"sdc-datepicker__time-group\">\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"incrementMinutes()\"\n [attr.aria-label]=\"'datepicker.incrementMinute' | translate\"\n >\n <i class=\"fas fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"sdc-datepicker__time-value\">{{ padTime(minutes()) }}</span>\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"decrementMinutes()\"\n [attr.aria-label]=\"'datepicker.decrementMinute' | translate\"\n >\n <i class=\"fas fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n @if (showSeconds) {\n <span class=\"sdc-datepicker__time-separator\">:</span>\n <div class=\"sdc-datepicker__time-group\">\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"incrementSeconds()\"\n [attr.aria-label]=\"'datepicker.incrementSecond' | translate\"\n >\n <i class=\"fas fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"sdc-datepicker__time-value\">{{ padTime(seconds()) }}</span>\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"decrementSeconds()\"\n [attr.aria-label]=\"'datepicker.decrementSecond' | translate\"\n >\n <i class=\"fas fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n\n }\n\n <!-- Footer: Today on the left, Clear + Confirm together on the right -->\n @if (showButtonBar || mode === 'datetime' || mode === 'time') {\n <div class=\"sdc-datepicker__button-bar\">\n <div>\n @if (showButtonBar && mode !== 'time') {\n <button\n type=\"button\"\n class=\"sdc-datepicker__bar-btn\"\n (click)=\"selectToday()\"\n >\n {{ 'datepicker.today' | translate }}\n </button>\n }\n </div>\n\n <div class=\"sdc-datepicker__button-bar-end\">\n @if (showButtonBar) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__bar-btn\"\n (click)=\"clearValue()\"\n >\n {{ 'datepicker.clear' | translate }}\n </button>\n }\n @if (mode === 'datetime' || mode === 'time') {\n <button\n type=\"button\"\n class=\"sdc-datepicker__confirm-btn\"\n (click)=\"confirmDateTime()\"\n >\n {{ 'datepicker.confirm' | translate }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </sdc-popover>\n\n @if (messageKey()) {\n <small\n [ngClass]=\"getInvalidMessageClass()\"\n role=\"alert\"\n aria-live=\"polite\"\n >\n {{ messageKey() | translate }}\n </small>\n }\n</div>\n", styles: [":host{display:block}.sdc-datepicker__label-row{display:flex;align-items:center;gap:var(--sdc-form-label-row-gap);margin-bottom:var(--sdc-form-label-row-mb)}.sdc-datepicker__label{display:inline-flex;align-items:center;margin-bottom:0;line-height:1;padding-top:var(--sdc-datepicker-label-py, var(--sdc-form-label-py, 0));padding-bottom:var(--sdc-datepicker-label-py, var(--sdc-form-label-py, 0));min-width:0}.sdc-datepicker__label-text{display:inline-flex;align-items:center}.required-field{margin-left:var(--sdc-datepicker-required-ml, var(--sdc-form-required-ml, .25rem));color:var(--sdc-datepicker-required-color, var(--sdc-error-color, #dc3545));font-weight:400}.sdc-datepicker__control{display:flex;align-items:stretch;min-height:var(--sdc-datepicker-control-height, var(--sdc-formfield-default-height, 38px));border:1px solid var(--sdc-datepicker-border-color, var(--sdc-formfield-default-border, #ced4da));border-radius:var(--sdc-datepicker-border-radius, var(--sdc-formfield-border-radius, 4px));background:var(--sdc-datepicker-bg, var(--sdc-formfield-default-bg, #fff));box-sizing:border-box;cursor:pointer;transition:border-color .18s ease,box-shadow .18s ease,background-color .18s ease}.sdc-datepicker__control:hover{border-color:var(--sdc-datepicker-hover-border, var(--sdc-formfield-focus-color, #007bff))}.sdc-datepicker__control:focus-within{border-color:var(--sdc-datepicker-focus-border, var(--sdc-formfield-focus-color, #007bff));box-shadow:var(--sdc-datepicker-focus-shadow, var(--sdc-formfield-focus-shadow, 0 0 0 2px rgba(0, 123, 255, .14)))}.sdc-datepicker__control--invalid,.sdc-datepicker__control--invalid:hover,.sdc-datepicker__control--invalid:focus-within{border-color:var(--sdc-datepicker-invalid-border, var(--sdc-formfield-invalid-border, #d98888));box-shadow:var(--sdc-datepicker-invalid-shadow, var(--sdc-formfield-invalid-focus-shadow, 0 0 0 2px rgba(217, 136, 136, .16)))}.sdc-datepicker__control--disabled,.sdc-datepicker__control--disabled:hover{background-color:var(--sdc-datepicker-disabled-bg, var(--sdc-formfield-disabled-bg, #e9ecef));border-color:var(--sdc-datepicker-border-color, var(--sdc-formfield-default-border, #ced4da));box-shadow:none;cursor:not-allowed}.sdc-datepicker__value{display:flex;align-items:center;flex:1 1 auto;min-width:0;padding:0 .75rem}.sdc-datepicker__input{width:100%;min-width:0;border:0;background:transparent;box-shadow:none;outline:0;font:inherit;color:inherit;line-height:var(--sdc-datepicker-input-line-height, var(--sdc-formfield-default-line-height, 1.5));padding:0;cursor:pointer}.sdc-datepicker__input::placeholder{color:var(--sdc-datepicker-placeholder-color, var(--sdc-form-placeholder-color, #9ca3af))}.sdc-datepicker__input:disabled{cursor:not-allowed}.sdc-datepicker__actions{display:flex;align-items:stretch;flex:0 0 auto}.sdc-datepicker__icon{font-size:.875rem}.sdc-datepicker__icon-button{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;border:0;background:transparent;color:var(--sdc-button-icon-default, #333333);cursor:pointer}.sdc-datepicker__icon-button:hover:not(:disabled){background:transparent}.sdc-datepicker__icon-button--clear{min-width:2rem;padding:0 .5rem}.sdc-datepicker__icon-button--toggle{min-width:2.5rem;padding:0 .75rem;border-left:1px solid var(--sdc-formfield-default-border, #ced4da)}.sdc-datepicker__panel{background:var(--sdc-datepicker-panel-bg, #fff);border:1px solid var(--sdc-datepicker-panel-border, #e5e7eb);border-radius:var(--sdc-datepicker-panel-radius, 6px);box-shadow:var(--sdc-datepicker-panel-shadow, 0 4px 12px rgba(0, 0, 0, .1));padding:0;width:var(--sdc-datepicker-panel-width, 280px);outline:none;box-sizing:border-box}.sdc-datepicker__header{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;border-bottom:1px solid var(--sdc-datepicker-separator-color, #e5e7eb)}.sdc-datepicker__nav-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:0;background:transparent;border-radius:var(--sdc-datepicker-nav-btn-radius, 50%);color:var(--sdc-datepicker-nav-btn-color, #374151);cursor:pointer;transition:background-color .15s ease}.sdc-datepicker__nav-btn:hover{background-color:var(--sdc-datepicker-nav-btn-hover-bg, rgba(0, 0, 0, .06))}.sdc-datepicker__title-btn{border:0;background:transparent;font-weight:600;font-size:var(--sdc-datepicker-title-font-size, .875rem);color:var(--sdc-datepicker-title-color, #111827);cursor:pointer;padding:.25rem .5rem;border-radius:4px;transition:background-color .15s ease}.sdc-datepicker__title-btn:hover{background-color:var(--sdc-datepicker-title-hover-bg, rgba(0, 0, 0, .04))}.sdc-datepicker__calendar{-webkit-user-select:none;user-select:none;padding:0 .5rem .5rem;border-collapse:collapse;border-spacing:0;width:100%}.sdc-datepicker__weekdays{display:grid;grid-template-columns:repeat(7,1fr);padding-top:.5rem}.sdc-datepicker__weekday{display:flex;align-items:center;justify-content:center;height:32px;font-size:var(--sdc-datepicker-weekday-font-size, .75rem);font-weight:600;color:var(--sdc-datepicker-weekday-color, #6b7280);text-transform:uppercase}.sdc-datepicker__days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sdc-datepicker-day-gap, 2px)}.sdc-datepicker__days>tr{display:contents}.sdc-datepicker__days td{padding:0}.sdc-datepicker__day{display:flex;align-items:center;justify-content:center;width:var(--sdc-datepicker-day-size, 32px);height:var(--sdc-datepicker-day-size, 32px);margin:0 auto;border:0;border-radius:var(--sdc-datepicker-day-radius, 50%);background:transparent;font-size:var(--sdc-datepicker-day-font-size, .75rem);color:var(--sdc-datepicker-day-color, #111827);cursor:pointer;transition:background-color .12s ease,color .12s ease;position:relative;padding:0}.sdc-datepicker__day:hover:not(:disabled):not(.sdc-datepicker__day--selected){background-color:var(--sdc-datepicker-day-hover-bg, rgba(0, 0, 0, .06))}.sdc-datepicker__day--other-month{color:var(--sdc-datepicker-day-other-month-color, #d1d5db)}.sdc-datepicker__day--today{border:2px solid var(--sdc-datepicker-today-border-color, var(--sdc-tab-primary, #007bff))}.sdc-datepicker__day--selected{background-color:var(--sdc-datepicker-selected-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-selected-color, #fff);font-weight:600}.sdc-datepicker__day--selected:hover{background-color:var(--sdc-datepicker-selected-hover-bg, #0056b3)}.sdc-datepicker__day--disabled{opacity:var(--sdc-datepicker-disabled-opacity, .35);cursor:not-allowed}.sdc-datepicker__day--in-range{background-color:var(--sdc-datepicker-range-bg, rgba(0, 123, 255, .1));border-radius:0}.sdc-datepicker__day--range-start{background-color:var(--sdc-datepicker-selected-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-selected-color, #fff);border-radius:var(--sdc-datepicker-day-radius, 50%) 0 0 var(--sdc-datepicker-day-radius, 50%)}.sdc-datepicker__day--range-end{background-color:var(--sdc-datepicker-selected-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-selected-color, #fff);border-radius:0 var(--sdc-datepicker-day-radius, 50%) var(--sdc-datepicker-day-radius, 50%) 0}.sdc-datepicker__months-grid,.sdc-datepicker__years-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem;padding:.75rem}.sdc-datepicker__month-cell,.sdc-datepicker__year-cell{display:flex;align-items:center;justify-content:center;padding:.625rem .5rem;border:0;border-radius:var(--sdc-datepicker-cell-radius, 6px);background:transparent;font-size:.8125rem;color:var(--sdc-datepicker-cell-color, #374151);cursor:pointer;transition:background-color .12s ease}.sdc-datepicker__month-cell:hover,.sdc-datepicker__year-cell:hover{background-color:var(--sdc-datepicker-cell-hover-bg, rgba(0, 0, 0, .05))}.sdc-datepicker__month-cell--selected,.sdc-datepicker__year-cell--selected{background-color:var(--sdc-datepicker-selected-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-selected-color, #fff);font-weight:600}.sdc-datepicker__time{display:flex;align-items:center;justify-content:center;gap:.25rem;padding:.75rem;border-top:1px solid var(--sdc-datepicker-separator-color, #e5e7eb)}.sdc-datepicker__time-group{display:flex;flex-direction:column;align-items:center;gap:.125rem}.sdc-datepicker__time-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:24px;border:0;background:transparent;border-radius:4px;color:var(--sdc-datepicker-time-btn-color, #6b7280);cursor:pointer;transition:background-color .12s ease}.sdc-datepicker__time-btn:hover{background-color:var(--sdc-datepicker-time-btn-hover-bg, rgba(0, 0, 0, .06))}.sdc-datepicker__time-value{font-size:var(--sdc-datepicker-time-font-size, 1.125rem);font-weight:600;color:var(--sdc-datepicker-time-value-color, #111827);min-width:2ch;text-align:center}.sdc-datepicker__time-separator{font-size:1.125rem;font-weight:600;color:var(--sdc-datepicker-time-separator-color, #6b7280);padding:0 .125rem;align-self:center}.sdc-datepicker__confirm-btn{padding:.25rem .875rem;border:0;border-radius:var(--sdc-datepicker-confirm-btn-radius, 4px);background-color:var(--sdc-datepicker-confirm-btn-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-confirm-btn-color, #fff);font-size:.8125rem;font-weight:600;cursor:pointer;transition:background-color .15s ease}.sdc-datepicker__confirm-btn:hover{background-color:var(--sdc-datepicker-confirm-btn-hover-bg, #0056b3)}.sdc-datepicker__button-bar{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;border-top:1px solid var(--sdc-datepicker-separator-color, #e5e7eb)}.sdc-datepicker__button-bar-end{display:flex;align-items:center;gap:.5rem}.sdc-datepicker__bar-btn{padding:.25rem .75rem;border:0;border-radius:4px;background:transparent;font-size:.8125rem;font-weight:500;color:var(--sdc-datepicker-bar-btn-color, var(--sdc-tab-primary, #007bff));cursor:pointer;transition:background-color .12s ease}.sdc-datepicker__bar-btn:hover{background-color:var(--sdc-datepicker-bar-btn-hover-bg, rgba(0, 123, 255, .08))}.sdc-datepicker__backdrop{background:transparent}.message{display:block;margin-top:.25rem;font-size:var(--sdc-datepicker-message-font-size, .75rem);color:var(--sdc-datepicker-message-color, #6b7280)}.message.invalid{color:var(--sdc-datepicker-message-invalid-color, var(--sdc-error-color, #dc3545))}::ng-deep .sdc-datepicker-popover-panel{overflow:visible!important;max-width:none!important;max-height:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: PopoverComponent, selector: "sdc-popover", inputs: ["open", "disabled", "toggleOnTriggerClick", "closeOnOutsideClick", "closeOnScroll", "closeOnEscape", "trapFocus", "focusOnOpen", "restoreFocusOnClose", "ariaLabel", "appendTo", "zIndex", "offset", "placement", "role", "matchTriggerWidth", "panelWidth", "panelMinWidth", "panelMaxWidth", "panelMaxHeight", "panelClass"], outputs: ["openChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
735
+ }
736
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DatepickerComponent, decorators: [{
737
+ type: Component,
738
+ args: [{ imports: [
739
+ CommonModule,
740
+ FormsModule,
741
+ TranslateModule,
742
+ PopoverComponent
743
+ ], standalone: true, selector: 'sdc-datepicker', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.Emulated, providers: [
744
+ {
745
+ provide: NG_VALUE_ACCESSOR,
746
+ useExisting: forwardRef(() => DatepickerComponent),
747
+ multi: true
748
+ },
749
+ {
750
+ provide: NG_VALIDATORS,
751
+ useExisting: forwardRef(() => DatepickerComponent),
752
+ multi: true
753
+ }
754
+ ], template: "<div class=\"sdc-datepicker\">\n @if (labelKey()) {\n <div class=\"sdc-datepicker__label-row\">\n <label class=\"sdc-datepicker__label\" [attr.for]=\"inputId\">\n <span class=\"sdc-datepicker__label-text\">\n {{ labelKey() | translate }}\n @if (required) {\n <span class=\"required-field\" aria-hidden=\"true\">*</span>\n }\n </span>\n </label>\n </div>\n }\n\n <sdc-popover\n [open]=\"panelOpen\"\n [toggleOnTriggerClick]=\"false\"\n [closeOnOutsideClick]=\"true\"\n [closeOnEscape]=\"true\"\n [matchTriggerWidth]=\"false\"\n [restoreFocusOnClose]=\"false\"\n [trapFocus]=\"true\"\n [ariaLabel]=\"'datepicker.calendar'\"\n panelClass=\"sdc-datepicker-popover-panel\"\n (openChange)=\"onPopoverOpenChange($event)\"\n >\n <div sdc-popover-trigger>\n <div\n class=\"sdc-datepicker__control\"\n #triggerRef\n [class.sdc-datepicker__control--invalid]=\"invalid\"\n [class.sdc-datepicker__control--disabled]=\"disabled\"\n [ngStyle]=\"getInputStyle()\"\n >\n <div class=\"sdc-datepicker__value\">\n <input\n #inputRef\n [id]=\"inputId\"\n class=\"sdc-datepicker__input\"\n type=\"text\"\n [disabled]=\"disabled\"\n [readOnly]=\"readonlyInput\"\n [placeholder]=\"placeholder || dateFormat\"\n [value]=\"displayValue()\"\n [attr.aria-label]=\"labelKey() ? (labelKey() | translate) : placeholder\"\n [attr.aria-expanded]=\"panelOpen\"\n [attr.aria-haspopup]=\"'dialog'\"\n aria-autocomplete=\"none\"\n autocomplete=\"off\"\n (click)=\"onInputClick()\"\n (focus)=\"onInputFocus()\"\n (keydown)=\"onKeydown($event)\"\n />\n </div>\n\n <div class=\"sdc-datepicker__actions\">\n @if (showClear && value) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__icon-button sdc-datepicker__icon-button--clear\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"'datepicker.clear' | translate\"\n (click)=\"clearValue(); $event.stopPropagation()\"\n >\n <i class=\"fas fa-times\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (showIcon) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__icon-button sdc-datepicker__icon-button--toggle\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"'datepicker.calendar' | translate\"\n [attr.aria-expanded]=\"panelOpen\"\n (click)=\"togglePanel(); $event.stopPropagation()\"\n >\n <i [class]=\"icon\" class=\"sdc-datepicker__icon\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n </div>\n\n <div sdc-popover-content>\n <div\n #panelContentRef\n class=\"sdc-datepicker__panel\"\n (keydown)=\"onOverlayKeydown($event)\"\n [attr.aria-label]=\"'datepicker.calendar' | translate\"\n >\n <!-- Navigation Header -->\n @if (mode !== 'time') {\n <div class=\"sdc-datepicker__header\">\n <button\n type=\"button\"\n class=\"sdc-datepicker__nav-btn\"\n [attr.aria-label]=\"'datepicker.prev' | translate\"\n (click)=\"currentView() === 'days' ? prevMonth() : currentView() === 'months' ? prevYear() : prevYearRange()\"\n >\n <i class=\"fas fa-chevron-left\" aria-hidden=\"true\"></i>\n </button>\n\n <button\n type=\"button\"\n class=\"sdc-datepicker__title-btn\"\n (click)=\"\n currentView() === 'days'\n ? switchToMonthView()\n : currentView() === 'months' ? switchToYearView() : null\n \"\n >\n {{ viewMonthYearLabel() }}\n </button>\n\n <button\n type=\"button\"\n class=\"sdc-datepicker__nav-btn\"\n [attr.aria-label]=\"'datepicker.next' | translate\"\n (click)=\"currentView() === 'days' ? nextMonth() : currentView() === 'months' ? nextYear() : nextYearRange()\"\n >\n <i class=\"fas fa-chevron-right\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- Days View -->\n @if (currentView() === 'days' && mode !== 'time') {\n <table class=\"sdc-datepicker__calendar\">\n <thead>\n <tr class=\"sdc-datepicker__weekdays\">\n @for (dayName of weekDayNames(); track dayName) {\n <th class=\"sdc-datepicker__weekday\" scope=\"col\">\n {{ dayName }}\n </th>\n }\n </tr>\n </thead>\n <tbody class=\"sdc-datepicker__days\" (keydown)=\"onDaysGridKeydown($event)\">\n @for (week of calendarWeeks(); track $index) {\n <tr>\n @for (day of week; track day.date.getTime()) {\n <td>\n <button\n #dayBtn\n type=\"button\"\n class=\"sdc-datepicker__day\"\n [class.sdc-datepicker__day--other-month]=\"!day.currentMonth\"\n [class.sdc-datepicker__day--today]=\"day.today\"\n [class.sdc-datepicker__day--selected]=\"day.selected\"\n [class.sdc-datepicker__day--disabled]=\"day.disabled\"\n [class.sdc-datepicker__day--in-range]=\"day.inRange\"\n [class.sdc-datepicker__day--range-start]=\"day.rangeStart\"\n [class.sdc-datepicker__day--range-end]=\"day.rangeEnd\"\n [disabled]=\"day.disabled\"\n [attr.aria-label]=\"day.date.toLocaleDateString()\"\n [attr.aria-selected]=\"day.selected\"\n [attr.aria-disabled]=\"day.disabled\"\n [attr.tabindex]=\"isDayTabStop(day) ? 0 : -1\"\n (click)=\"selectDay(day)\"\n >\n {{ day.day }}\n </button>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n }\n\n <!-- Months View -->\n @if (currentView() === 'months') {\n <div class=\"sdc-datepicker__months-grid\">\n @for (m of calendarMonths(); track m.month) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__month-cell\"\n [class.sdc-datepicker__month-cell--selected]=\"m.selected\"\n (click)=\"selectMonth(m.month)\"\n >\n {{ m.name }}\n </button>\n }\n </div>\n }\n\n <!-- Years View -->\n @if (currentView() === 'years') {\n <div class=\"sdc-datepicker__years-grid\">\n @for (year of yearRange(); track year) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__year-cell\"\n [class.sdc-datepicker__year-cell--selected]=\"year === viewDate().getFullYear()\"\n (click)=\"selectYear(year)\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n\n <!-- Time Picker -->\n @if (showTimePicker()) {\n <div class=\"sdc-datepicker__time\">\n <div class=\"sdc-datepicker__time-group\">\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"incrementHours()\"\n [attr.aria-label]=\"'datepicker.incrementHour' | translate\"\n >\n <i class=\"fas fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"sdc-datepicker__time-value\">{{ padTime(hours()) }}</span>\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"decrementHours()\"\n [attr.aria-label]=\"'datepicker.decrementHour' | translate\"\n >\n <i class=\"fas fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <span class=\"sdc-datepicker__time-separator\">:</span>\n\n <div class=\"sdc-datepicker__time-group\">\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"incrementMinutes()\"\n [attr.aria-label]=\"'datepicker.incrementMinute' | translate\"\n >\n <i class=\"fas fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"sdc-datepicker__time-value\">{{ padTime(minutes()) }}</span>\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"decrementMinutes()\"\n [attr.aria-label]=\"'datepicker.decrementMinute' | translate\"\n >\n <i class=\"fas fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n @if (showSeconds) {\n <span class=\"sdc-datepicker__time-separator\">:</span>\n <div class=\"sdc-datepicker__time-group\">\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"incrementSeconds()\"\n [attr.aria-label]=\"'datepicker.incrementSecond' | translate\"\n >\n <i class=\"fas fa-chevron-up\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"sdc-datepicker__time-value\">{{ padTime(seconds()) }}</span>\n <button\n type=\"button\"\n class=\"sdc-datepicker__time-btn\"\n (click)=\"decrementSeconds()\"\n [attr.aria-label]=\"'datepicker.decrementSecond' | translate\"\n >\n <i class=\"fas fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n\n }\n\n <!-- Footer: Today on the left, Clear + Confirm together on the right -->\n @if (showButtonBar || mode === 'datetime' || mode === 'time') {\n <div class=\"sdc-datepicker__button-bar\">\n <div>\n @if (showButtonBar && mode !== 'time') {\n <button\n type=\"button\"\n class=\"sdc-datepicker__bar-btn\"\n (click)=\"selectToday()\"\n >\n {{ 'datepicker.today' | translate }}\n </button>\n }\n </div>\n\n <div class=\"sdc-datepicker__button-bar-end\">\n @if (showButtonBar) {\n <button\n type=\"button\"\n class=\"sdc-datepicker__bar-btn\"\n (click)=\"clearValue()\"\n >\n {{ 'datepicker.clear' | translate }}\n </button>\n }\n @if (mode === 'datetime' || mode === 'time') {\n <button\n type=\"button\"\n class=\"sdc-datepicker__confirm-btn\"\n (click)=\"confirmDateTime()\"\n >\n {{ 'datepicker.confirm' | translate }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n </sdc-popover>\n\n @if (messageKey()) {\n <small\n [ngClass]=\"getInvalidMessageClass()\"\n role=\"alert\"\n aria-live=\"polite\"\n >\n {{ messageKey() | translate }}\n </small>\n }\n</div>\n", styles: [":host{display:block}.sdc-datepicker__label-row{display:flex;align-items:center;gap:var(--sdc-form-label-row-gap);margin-bottom:var(--sdc-form-label-row-mb)}.sdc-datepicker__label{display:inline-flex;align-items:center;margin-bottom:0;line-height:1;padding-top:var(--sdc-datepicker-label-py, var(--sdc-form-label-py, 0));padding-bottom:var(--sdc-datepicker-label-py, var(--sdc-form-label-py, 0));min-width:0}.sdc-datepicker__label-text{display:inline-flex;align-items:center}.required-field{margin-left:var(--sdc-datepicker-required-ml, var(--sdc-form-required-ml, .25rem));color:var(--sdc-datepicker-required-color, var(--sdc-error-color, #dc3545));font-weight:400}.sdc-datepicker__control{display:flex;align-items:stretch;min-height:var(--sdc-datepicker-control-height, var(--sdc-formfield-default-height, 38px));border:1px solid var(--sdc-datepicker-border-color, var(--sdc-formfield-default-border, #ced4da));border-radius:var(--sdc-datepicker-border-radius, var(--sdc-formfield-border-radius, 4px));background:var(--sdc-datepicker-bg, var(--sdc-formfield-default-bg, #fff));box-sizing:border-box;cursor:pointer;transition:border-color .18s ease,box-shadow .18s ease,background-color .18s ease}.sdc-datepicker__control:hover{border-color:var(--sdc-datepicker-hover-border, var(--sdc-formfield-focus-color, #007bff))}.sdc-datepicker__control:focus-within{border-color:var(--sdc-datepicker-focus-border, var(--sdc-formfield-focus-color, #007bff));box-shadow:var(--sdc-datepicker-focus-shadow, var(--sdc-formfield-focus-shadow, 0 0 0 2px rgba(0, 123, 255, .14)))}.sdc-datepicker__control--invalid,.sdc-datepicker__control--invalid:hover,.sdc-datepicker__control--invalid:focus-within{border-color:var(--sdc-datepicker-invalid-border, var(--sdc-formfield-invalid-border, #d98888));box-shadow:var(--sdc-datepicker-invalid-shadow, var(--sdc-formfield-invalid-focus-shadow, 0 0 0 2px rgba(217, 136, 136, .16)))}.sdc-datepicker__control--disabled,.sdc-datepicker__control--disabled:hover{background-color:var(--sdc-datepicker-disabled-bg, var(--sdc-formfield-disabled-bg, #e9ecef));border-color:var(--sdc-datepicker-border-color, var(--sdc-formfield-default-border, #ced4da));box-shadow:none;cursor:not-allowed}.sdc-datepicker__value{display:flex;align-items:center;flex:1 1 auto;min-width:0;padding:0 .75rem}.sdc-datepicker__input{width:100%;min-width:0;border:0;background:transparent;box-shadow:none;outline:0;font:inherit;color:inherit;line-height:var(--sdc-datepicker-input-line-height, var(--sdc-formfield-default-line-height, 1.5));padding:0;cursor:pointer}.sdc-datepicker__input::placeholder{color:var(--sdc-datepicker-placeholder-color, var(--sdc-form-placeholder-color, #9ca3af))}.sdc-datepicker__input:disabled{cursor:not-allowed}.sdc-datepicker__actions{display:flex;align-items:stretch;flex:0 0 auto}.sdc-datepicker__icon{font-size:.875rem}.sdc-datepicker__icon-button{display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;border:0;background:transparent;color:var(--sdc-button-icon-default, #333333);cursor:pointer}.sdc-datepicker__icon-button:hover:not(:disabled){background:transparent}.sdc-datepicker__icon-button--clear{min-width:2rem;padding:0 .5rem}.sdc-datepicker__icon-button--toggle{min-width:2.5rem;padding:0 .75rem;border-left:1px solid var(--sdc-formfield-default-border, #ced4da)}.sdc-datepicker__panel{background:var(--sdc-datepicker-panel-bg, #fff);border:1px solid var(--sdc-datepicker-panel-border, #e5e7eb);border-radius:var(--sdc-datepicker-panel-radius, 6px);box-shadow:var(--sdc-datepicker-panel-shadow, 0 4px 12px rgba(0, 0, 0, .1));padding:0;width:var(--sdc-datepicker-panel-width, 280px);outline:none;box-sizing:border-box}.sdc-datepicker__header{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;border-bottom:1px solid var(--sdc-datepicker-separator-color, #e5e7eb)}.sdc-datepicker__nav-btn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:0;background:transparent;border-radius:var(--sdc-datepicker-nav-btn-radius, 50%);color:var(--sdc-datepicker-nav-btn-color, #374151);cursor:pointer;transition:background-color .15s ease}.sdc-datepicker__nav-btn:hover{background-color:var(--sdc-datepicker-nav-btn-hover-bg, rgba(0, 0, 0, .06))}.sdc-datepicker__title-btn{border:0;background:transparent;font-weight:600;font-size:var(--sdc-datepicker-title-font-size, .875rem);color:var(--sdc-datepicker-title-color, #111827);cursor:pointer;padding:.25rem .5rem;border-radius:4px;transition:background-color .15s ease}.sdc-datepicker__title-btn:hover{background-color:var(--sdc-datepicker-title-hover-bg, rgba(0, 0, 0, .04))}.sdc-datepicker__calendar{-webkit-user-select:none;user-select:none;padding:0 .5rem .5rem;border-collapse:collapse;border-spacing:0;width:100%}.sdc-datepicker__weekdays{display:grid;grid-template-columns:repeat(7,1fr);padding-top:.5rem}.sdc-datepicker__weekday{display:flex;align-items:center;justify-content:center;height:32px;font-size:var(--sdc-datepicker-weekday-font-size, .75rem);font-weight:600;color:var(--sdc-datepicker-weekday-color, #6b7280);text-transform:uppercase}.sdc-datepicker__days{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--sdc-datepicker-day-gap, 2px)}.sdc-datepicker__days>tr{display:contents}.sdc-datepicker__days td{padding:0}.sdc-datepicker__day{display:flex;align-items:center;justify-content:center;width:var(--sdc-datepicker-day-size, 32px);height:var(--sdc-datepicker-day-size, 32px);margin:0 auto;border:0;border-radius:var(--sdc-datepicker-day-radius, 50%);background:transparent;font-size:var(--sdc-datepicker-day-font-size, .75rem);color:var(--sdc-datepicker-day-color, #111827);cursor:pointer;transition:background-color .12s ease,color .12s ease;position:relative;padding:0}.sdc-datepicker__day:hover:not(:disabled):not(.sdc-datepicker__day--selected){background-color:var(--sdc-datepicker-day-hover-bg, rgba(0, 0, 0, .06))}.sdc-datepicker__day--other-month{color:var(--sdc-datepicker-day-other-month-color, #d1d5db)}.sdc-datepicker__day--today{border:2px solid var(--sdc-datepicker-today-border-color, var(--sdc-tab-primary, #007bff))}.sdc-datepicker__day--selected{background-color:var(--sdc-datepicker-selected-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-selected-color, #fff);font-weight:600}.sdc-datepicker__day--selected:hover{background-color:var(--sdc-datepicker-selected-hover-bg, #0056b3)}.sdc-datepicker__day--disabled{opacity:var(--sdc-datepicker-disabled-opacity, .35);cursor:not-allowed}.sdc-datepicker__day--in-range{background-color:var(--sdc-datepicker-range-bg, rgba(0, 123, 255, .1));border-radius:0}.sdc-datepicker__day--range-start{background-color:var(--sdc-datepicker-selected-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-selected-color, #fff);border-radius:var(--sdc-datepicker-day-radius, 50%) 0 0 var(--sdc-datepicker-day-radius, 50%)}.sdc-datepicker__day--range-end{background-color:var(--sdc-datepicker-selected-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-selected-color, #fff);border-radius:0 var(--sdc-datepicker-day-radius, 50%) var(--sdc-datepicker-day-radius, 50%) 0}.sdc-datepicker__months-grid,.sdc-datepicker__years-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.5rem;padding:.75rem}.sdc-datepicker__month-cell,.sdc-datepicker__year-cell{display:flex;align-items:center;justify-content:center;padding:.625rem .5rem;border:0;border-radius:var(--sdc-datepicker-cell-radius, 6px);background:transparent;font-size:.8125rem;color:var(--sdc-datepicker-cell-color, #374151);cursor:pointer;transition:background-color .12s ease}.sdc-datepicker__month-cell:hover,.sdc-datepicker__year-cell:hover{background-color:var(--sdc-datepicker-cell-hover-bg, rgba(0, 0, 0, .05))}.sdc-datepicker__month-cell--selected,.sdc-datepicker__year-cell--selected{background-color:var(--sdc-datepicker-selected-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-selected-color, #fff);font-weight:600}.sdc-datepicker__time{display:flex;align-items:center;justify-content:center;gap:.25rem;padding:.75rem;border-top:1px solid var(--sdc-datepicker-separator-color, #e5e7eb)}.sdc-datepicker__time-group{display:flex;flex-direction:column;align-items:center;gap:.125rem}.sdc-datepicker__time-btn{display:inline-flex;align-items:center;justify-content:center;width:28px;height:24px;border:0;background:transparent;border-radius:4px;color:var(--sdc-datepicker-time-btn-color, #6b7280);cursor:pointer;transition:background-color .12s ease}.sdc-datepicker__time-btn:hover{background-color:var(--sdc-datepicker-time-btn-hover-bg, rgba(0, 0, 0, .06))}.sdc-datepicker__time-value{font-size:var(--sdc-datepicker-time-font-size, 1.125rem);font-weight:600;color:var(--sdc-datepicker-time-value-color, #111827);min-width:2ch;text-align:center}.sdc-datepicker__time-separator{font-size:1.125rem;font-weight:600;color:var(--sdc-datepicker-time-separator-color, #6b7280);padding:0 .125rem;align-self:center}.sdc-datepicker__confirm-btn{padding:.25rem .875rem;border:0;border-radius:var(--sdc-datepicker-confirm-btn-radius, 4px);background-color:var(--sdc-datepicker-confirm-btn-bg, var(--sdc-tab-primary, #007bff));color:var(--sdc-datepicker-confirm-btn-color, #fff);font-size:.8125rem;font-weight:600;cursor:pointer;transition:background-color .15s ease}.sdc-datepicker__confirm-btn:hover{background-color:var(--sdc-datepicker-confirm-btn-hover-bg, #0056b3)}.sdc-datepicker__button-bar{display:flex;align-items:center;justify-content:space-between;padding:.5rem .75rem;border-top:1px solid var(--sdc-datepicker-separator-color, #e5e7eb)}.sdc-datepicker__button-bar-end{display:flex;align-items:center;gap:.5rem}.sdc-datepicker__bar-btn{padding:.25rem .75rem;border:0;border-radius:4px;background:transparent;font-size:.8125rem;font-weight:500;color:var(--sdc-datepicker-bar-btn-color, var(--sdc-tab-primary, #007bff));cursor:pointer;transition:background-color .12s ease}.sdc-datepicker__bar-btn:hover{background-color:var(--sdc-datepicker-bar-btn-hover-bg, rgba(0, 123, 255, .08))}.sdc-datepicker__backdrop{background:transparent}.message{display:block;margin-top:.25rem;font-size:var(--sdc-datepicker-message-font-size, .75rem);color:var(--sdc-datepicker-message-color, #6b7280)}.message.invalid{color:var(--sdc-datepicker-message-invalid-color, var(--sdc-error-color, #dc3545))}::ng-deep .sdc-datepicker-popover-panel{overflow:visible!important;max-width:none!important;max-height:none!important}\n"] }]
755
+ }], propDecorators: { mode: [{
756
+ type: Input
757
+ }], selectionMode: [{
758
+ type: Input
759
+ }], showIcon: [{
760
+ type: Input
761
+ }], icon: [{
762
+ type: Input
763
+ }], min: [{
764
+ type: Input
765
+ }], max: [{
766
+ type: Input
767
+ }], defaultDate: [{
768
+ type: Input
769
+ }], dateFormat: [{
770
+ type: Input
771
+ }], hourFormat: [{
772
+ type: Input
773
+ }], minuteStep: [{
774
+ type: Input
775
+ }], showSeconds: [{
776
+ type: Input
777
+ }], rangeSeparator: [{
778
+ type: Input
779
+ }], showOnFocus: [{
780
+ type: Input
781
+ }], readonlyInput: [{
782
+ type: Input
783
+ }], firstDayOfWeek: [{
784
+ type: Input
785
+ }], showButtonBar: [{
786
+ type: Input
787
+ }], showClear: [{
788
+ type: Input
789
+ }], disabledDates: [{
790
+ type: Input
791
+ }], disabledDays: [{
792
+ type: Input
793
+ }], selected: [{
794
+ type: Output
795
+ }], closed: [{
796
+ type: Output
797
+ }], monthChange: [{
798
+ type: Output
799
+ }], yearChange: [{
800
+ type: Output
801
+ }], inputRef: [{
802
+ type: ViewChild,
803
+ args: ['inputRef']
804
+ }], triggerRef: [{
805
+ type: ViewChild,
806
+ args: ['triggerRef']
807
+ }], panelContentRef: [{
808
+ type: ViewChild,
809
+ args: ['panelContentRef']
810
+ }], dayButtonRefs: [{
811
+ type: ViewChildren,
812
+ args: ['dayBtn']
813
+ }] } });
814
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWIvc3JjL2ZlYXR1cmVzL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9saWIvc3JjL2ZlYXR1cmVzL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUNILHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFFBQVEsRUFDUixVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBRU4sTUFBTSxFQUNOLFNBQVMsRUFDVCxZQUFZLEVBQ1osaUJBQWlCLEVBQ2pCLFVBQVUsRUFDVixNQUFNLEVBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxhQUFhLEVBQWdELE1BQU0sZ0JBQWdCLENBQUM7QUFDN0gsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFcEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDOzs7O0FBWWhFLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFNLGNBQWMsR0FBRyxFQUFFLENBQUM7QUFDMUIsTUFBTSxrQkFBa0IsR0FBRyxFQUFFLENBQUM7QUFD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ci9jb21tb24nO1xuaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgY29tcHV0ZWQsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSW5wdXQsXG4gICAgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG4gICAgUXVlcnlMaXN0LFxuICAgIHNpZ25hbCxcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0NoaWxkcmVuLFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uLFxuICAgIGZvcndhcmRSZWYsXG4gICAgaW5qZWN0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUsIE5HX1ZBTFVFX0FDQ0VTU09SLCBOR19WQUxJREFUT1JTLCBWYWxpZGF0b3IsIEFic3RyYWN0Q29udHJvbCwgVmFsaWRhdGlvbkVycm9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFRyYW5zbGF0ZU1vZHVsZSwgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IElucHV0c0NvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvcmUvZGlyZWN0aXZlcy9pbnB1dHMuZGlyZWN0aXZlJztcbmltcG9ydCB7IGZvY3VzRmlyc3REZXNjZW5kYW50IH0gZnJvbSAnLi4vLi4vY29yZS91dGlscy9mb2N1cy51dGlsJztcbmltcG9ydCB7IG5leHRTZXF1ZW50aWFsSWQgfSBmcm9tICcuLi8uLi9jb3JlL3V0aWxzL2lkLnV0aWwnO1xuaW1wb3J0IHsgUG9wb3ZlckNvbXBvbmVudCB9IGZyb20gJy4uL3BvcG92ZXIvcG9wb3Zlci5jb21wb25lbnQnO1xuaW1wb3J0IHR5cGUge1xuICAgIENhbGVuZGFyRGF5LFxuICAgIERhdGVQaWNrZXJNb2RlLFxuICAgIERhdGVQaWNrZXJTZWxlY3Rpb25Nb2RlLFxuICAgIERhdGVSYW5nZSxcbiAgICBEYXRlcGlja2VyTW9udGhDaGFuZ2VFdmVudCxcbiAgICBEYXRlcGlja2VyVmlld1xufSBmcm9tICcuLi8uLi9jb3JlL3R5cGVzL2RhdGVwaWNrZXIudHlwZSc7XG5cbnR5cGUgRGF0ZXBpY2tlclZhbHVlID0gRGF0ZSB8IERhdGVSYW5nZSB8IERhdGVbXSB8IG51bGw7XG5cbmNvbnN0IERBWVNfSU5fV0VFSyA9IDc7XG5jb25zdCBZRUFSU19QRVJfUEFHRSA9IDEyO1xuY29uc3QgSE9VUl9GT1JNQVRfMTJfTUFYID0gMTI7XG5jb25zdCBIT1VSX0ZPUk1BVF8yNF9NQVggPSAyMztcbmNvbnN0IFlFQVJfU0hPUlRfTEVOR1RIID0gMjtcblxuQENvbXBvbmVudCh7XG4gICAgaW1wb3J0czogW1xuICAgICAgICBDb21tb25Nb2R1bGUsXG4gICAgICAgIEZvcm1zTW9kdWxlLFxuICAgICAgICBUcmFuc2xhdGVNb2R1bGUsXG4gICAgICAgIFBvcG92ZXJDb21wb25lbnRcbiAgICBdLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdzZGMtZGF0ZXBpY2tlcicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2RhdGVwaWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsOiAnLi9kYXRlcGlja2VyLmNvbXBvbmVudC5zY3NzJyxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5FbXVsYXRlZCxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEYXRlcGlja2VyQ29tcG9uZW50KSxcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHByb3ZpZGU6IE5HX1ZBTElEQVRPUlMsXG4gICAgICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEYXRlcGlja2VyQ29tcG9uZW50KSxcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXG4gICAgICAgIH1cbiAgICBdXG59KVxuZXhwb3J0IGNsYXNzIERhdGVwaWNrZXJDb21wb25lbnQgZXh0ZW5kcyBJbnB1dHNDb21wb25lbnQ8RGF0ZXBpY2tlclZhbHVlPiBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBWYWxpZGF0b3Ige1xuICAgIHByaXZhdGUgcmVhZG9ubHkgdHJhbnNsYXRlID0gaW5qZWN0KFRyYW5zbGF0ZVNlcnZpY2UpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY2RyID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVsZW1lbnRSZWYgPSBpbmplY3QoRWxlbWVudFJlZik7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzdWJzY3JpcHRpb25zID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gICAgLy8gLS0tIElucHV0cyAtLS1cbiAgICBASW5wdXQoKSBtb2RlOiBEYXRlUGlja2VyTW9kZSA9ICdkYXRlJztcbiAgICBASW5wdXQoKSBzZWxlY3Rpb25Nb2RlOiBEYXRlUGlja2VyU2VsZWN0aW9uTW9kZSA9ICdzaW5nbGUnO1xuICAgIEBJbnB1dCgpIHNob3dJY29uID0gdHJ1ZTtcbiAgICBASW5wdXQoKSBpY29uID0gJ2ZhcyBmYS1jYWxlbmRhcic7XG4gICAgQElucHV0KCkgbWluOiBEYXRlIHwgbnVsbCA9IG51bGw7XG4gICAgQElucHV0KCkgbWF4OiBEYXRlIHwgbnVsbCA9IG51bGw7XG4gICAgQElucHV0KCkgZGVmYXVsdERhdGU6IERhdGUgfCBudWxsID0gbnVsbDtcbiAgICBASW5wdXQoKSBkYXRlRm9ybWF0ID0gJ2RkL01NL3l5eXknO1xuICAgIEBJbnB1dCgpIGhvdXJGb3JtYXQ6ICcxMicgfCAnMjQnID0gJzI0JztcbiAgICBASW5wdXQoKSBtaW51dGVTdGVwID0gNTtcbiAgICBASW5wdXQoKSBzaG93U2Vjb25kcyA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIHJhbmdlU2VwYXJhdG9yID0gJyDigJQgJztcbiAgICBASW5wdXQoKSBzaG93T25Gb2N1cyA9IHRydWU7XG4gICAgQElucHV0KCkgcmVhZG9ubHlJbnB1dCA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGZpcnN0RGF5T2ZXZWVrID0gMDtcbiAgICBASW5wdXQoKSBzaG93QnV0dG9uQmFyID0gdHJ1ZTtcbiAgICBASW5wdXQoKSBzaG93Q2xlYXIgPSBmYWxzZTtcbiAgICBASW5wdXQoKSBkaXNhYmxlZERhdGVzOiBEYXRlW10gPSBbXTtcbiAgICBASW5wdXQoKSBkaXNhYmxlZERheXM6IG51bWJlcltdID0gW107XG5cbiAgICAvLyAtLS0gT3V0cHV0cyAtLS1cbiAgICBAT3V0cHV0KCkgc2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPERhdGVwaWNrZXJWYWx1ZT4oKTtcbiAgICBAT3V0cHV0KCkgY2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICAgIEBPdXRwdXQoKSBtb250aENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZXBpY2tlck1vbnRoQ2hhbmdlRXZlbnQ+KCk7XG4gICAgQE91dHB1dCgpIHllYXJDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPERhdGVwaWNrZXJNb250aENoYW5nZUV2ZW50PigpO1xuXG4gICAgLy8gLS0tIFZpZXcgQ2hpbGRyZW4gLS0tXG4gICAgQFZpZXdDaGlsZCgnaW5wdXRSZWYnKSBpbnB1dFJlZj86IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD47XG4gICAgQFZpZXdDaGlsZCgndHJpZ2dlclJlZicpIHRyaWdnZXJSZWY/OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcbiAgICBAVmlld0NoaWxkKCdwYW5lbENvbnRlbnRSZWYnKSBwcml2YXRlIHJlYWRvbmx5IHBhbmVsQ29udGVudFJlZj86IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuICAgIEBWaWV3Q2hpbGRyZW4oJ2RheUJ0bicpIHByaXZhdGUgcmVhZG9ubHkgZGF5QnV0dG9uUmVmcz86IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPEhUTUxCdXR0b25FbGVtZW50Pj47XG5cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgaW5wdXRJZCA9IG5leHRTZXF1ZW50aWFsSWQoJ3NkYy1kYXRlcGlja2VyLWlucHV0Jyk7XG5cbiAgICAvLyAtLS0gU2lnbmFscyAtLS1cbiAgICBwdWJsaWMgcGFuZWxPcGVuID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBzdXBwcmVzc05leHRGb2N1c09wZW4gPSBmYWxzZTtcbiAgICBwdWJsaWMgcmVhZG9ubHkgY3VycmVudFZpZXcgPSBzaWduYWw8RGF0ZXBpY2tlclZpZXc+KCdkYXlzJyk7XG4gICAgcHVibGljIHJlYWRvbmx5IHZpZXdEYXRlID0gc2lnbmFsPERhdGU+KG5ldyBEYXRlKCkpO1xuICAgIHB1YmxpYyByZWFkb25seSBmb2N1c2VkRGF0ZSA9IHNpZ25hbDxEYXRlIHwgbnVsbD4obnVsbCk7XG5cbiAgICAvLyBUaW1lIHNpZ25hbHNcbiAgICBwdWJsaWMgcmVhZG9ubHkgaG91cnMgPSBzaWduYWwoMCk7XG4gICAgcHVibGljIHJlYWRvbmx5IG1pbnV0ZXMgPSBzaWduYWwoMCk7XG4gICAgcHVibGljIHJlYWRvbmx5IHNlY29uZHMgPSBzaWduYWwoMCk7XG5cbiAgICAvLyBSYW5nZSBzZWxlY3Rpb24gc3RhdGVcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJhbmdlU3RhcnQgPSBzaWduYWw8RGF0ZSB8IG51bGw+KG51bGwpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcmFuZ2VFbmQgPSBzaWduYWw8RGF0ZSB8IG51bGw+KG51bGwpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgcmFuZ2VTZWxlY3RpbmcgPSBzaWduYWwoZmFsc2UpO1xuXG4gICAgLy8gLS0tIENvbXB1dGVkIC0tLVxuXG4gICAgcHVibGljIHJlYWRvbmx5IHdlZWtEYXlOYW1lcyA9IGNvbXB1dGVkKCgpOiBzdHJpbmdbXSA9PiB7XG4gICAgICAgIGNvbnN0IGRheXMgPSBbJ1N1JywgJ01vJywgJ1R1JywgJ1dlJywgJ1RoJywgJ0ZyJywgJ1NhJ107XG4gICAgICAgIGNvbnN0IHNoaWZ0ZWQ6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgREFZU19JTl9XRUVLOyBpKyspIHtcbiAgICAgICAgICAgIHNoaWZ0ZWQucHVzaChkYXlzWyhpICsgdGhpcy5maXJzdERheU9mV2VlaykgJSBEQVlTX0lOX1dFRUtdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2hpZnRlZDtcbiAgICB9KTtcblxuICAgIC8vIE5PVEU6IGludGVudGlvbmFsbHkgYSBwbGFpbiBtZXRob2QgKG5vdCBgY29tcHV0ZWQoKWApLiBgdGhpcy52YWx1ZWAgaXMgYSBwbGFpblxuICAgIC8vIEBJbnB1dCBpbmhlcml0ZWQgZnJvbSBJbnB1dHNDb21wb25lbnQsIG5vdCBhIFNpZ25hbCwgc28gd3JhcHBpbmcgdGhpcyBpbiBgY29tcHV0ZWQoKWBcbiAgICAvLyB3b3VsZCBmcmVlemUgaXQgYWZ0ZXIgdGhlIGZpcnN0IHJlYWQgKEFuZ3VsYXIgY29tcHV0ZWQoKSBvbmx5IHJlYWN0cyB0byBTaWduYWwgcmVhZHMpLlxuICAgIC8vIE9uUHVzaCArIHRoZSBleGlzdGluZyBgbWFya0ZvckNoZWNrKClgIGNhbGxzIGFmdGVyIGV2ZXJ5IHZhbHVlIG11dGF0aW9uIGtlZXAgdGhpcyBjb3JyZWN0LlxuICAgIHB1YmxpYyBjYWxlbmRhckRheXMoKTogQ2FsZW5kYXJEYXlbXSB7XG4gICAgICAgIGNvbnN0IHZpZXdEID0gdGhpcy52aWV3RGF0ZSgpO1xuICAgICAgICBjb25zdCB5ZWFyID0gdmlld0QuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgY29uc3QgbW9udGggPSB2aWV3RC5nZXRNb250aCgpO1xuICAgICAgICBjb25zdCBmaXJzdE9mTW9udGggPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSk7XG4gICAgICAgIGNvbnN0IHN0YXJ0RGF5ID0gZmlyc3RPZk1vbnRoLmdldERheSgpO1xuICAgICAgICBjb25zdCBkYXlzQmVmb3JlU3RhcnQgPSAoc3RhcnREYXkgLSB0aGlzLmZpcnN0RGF5T2ZXZWVrICsgREFZU19JTl9XRUVLKSAlIERBWVNfSU5fV0VFSztcbiAgICAgICAgY29uc3Qgc3RhcnREYXRlID0gbmV3IERhdGUoeWVhciwgbW9udGgsIDEgLSBkYXlzQmVmb3JlU3RhcnQpO1xuICAgICAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIHRvZGF5LnNldEhvdXJzKDAsIDAsIDAsIDApO1xuXG4gICAgICAgIGNvbnN0IGRheXM6IENhbGVuZGFyRGF5W10gPSBbXTtcbiAgICAgICAgY29uc3QgZGF5c0luTW9udGggPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCArIDEsIDApLmdldERhdGUoKTtcbiAgICAgICAgLy8gRHluYW1pYyByb3cgY291bnQgKDUsIDYsIG9yIHJhcmVseSA0IHdlZWtzKSBpbnN0ZWFkIG9mIGEgZml4ZWQgNDItY2VsbCAoNiByb3cpIGdyaWQsXG4gICAgICAgIC8vIG1hdGNoaW5nIEFuZ3VsYXIgQ29tcG9uZW50cyBiZWhhdmlvci4gQXZvaWRzIGEgdHJhaWxpbmcgYWxsLWRpc2FibGVkL2JsYW5rIHdlZWtcbiAgICAgICAgLy8gZm9yIG1vbnRocyB0aGF0IG9ubHkgbmVlZCA1IHJvd3MuXG4gICAgICAgIGNvbnN0IHRvdGFsQ2VsbHMgPSBNYXRoLmNlaWwoKGRheXNCZWZvcmVTdGFydCArIGRheXNJbk1vbnRoKSAvIERBWVNfSU5fV0VFSykgKiBEQVlTX0lOX1dFRUs7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b3RhbENlbGxzOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShzdGFydERhdGUuZ2V0RnVsbFllYXIoKSwgc3RhcnREYXRlLmdldE1vbnRoKCksIHN0YXJ0RGF0ZS5nZXREYXRlKCkgKyBpKTtcbiAgICAgICAgICAgIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gICAgICAgICAgICBkYXlzLnB1c2goe1xuICAgICAgICAgICAgICAgIGRhdGUsXG4gICAgICAgICAgICAgICAgZGF5OiBkYXRlLmdldERhdGUoKSxcbiAgICAgICAgICAgICAgICBjdXJyZW50TW9udGg6IGRhdGUuZ2V0TW9udGgoKSA9PT0gbW9udGgsXG4gICAgICAgICAgICAgICAgdG9kYXk6IGRhdGUuZ2V0VGltZSgpID09PSB0b2RheS5nZXRUaW1lKCksXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IHRoaXMuaXNEYXRlU2VsZWN0ZWQoZGF0ZSksXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IHRoaXMuaXNEYXRlRGlzYWJsZWQoZGF0ZSksXG4gICAgICAgICAgICAgICAgaW5SYW5nZTogdGhpcy5pc0luUmFuZ2UoZGF0ZSksXG4gICAgICAgICAgICAgICAgcmFuZ2VTdGFydDogdGhpcy5pc1JhbmdlU3RhcnQoZGF0ZSksXG4gICAgICAgICAgICAgICAgcmFuZ2VFbmQ6IHRoaXMuaXNSYW5nZUVuZChkYXRlKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRheXM7XG4gICAgfVxuXG4gICAgLy8gR3JvdXBzIGBjYWxlbmRhckRheXMoKWAgaW50byA3LWRheSB3ZWVrcyBzbyB0aGUgdGVtcGxhdGUgY2FuIHJlbmRlciBhIHJlYWxcbiAgICAvLyA8dGFibGU+Lzx0cj4vPHRkPiBncmlkIChuYXRpdmUgcm93L2dyaWRjZWxsIHNlbWFudGljcykgaW5zdGVhZCBvZiBBUklBIHJvbGVzIG9uIDxkaXY+cy5cbiAgICBwdWJsaWMgY2FsZW5kYXJXZWVrcygpOiBDYWxlbmRhckRheVtdW10ge1xuICAgICAgICBjb25zdCBkYXlzID0gdGhpcy5jYWxlbmRhckRheXMoKTtcbiAgICAgICAgY29uc3Qgd2Vla3M6IENhbGVuZGFyRGF5W11bXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRheXMubGVuZ3RoOyBpICs9IERBWVNfSU5fV0VFSykge1xuICAgICAgICAgICAgd2Vla3MucHVzaChkYXlzLnNsaWNlKGksIGkgKyBEQVlTX0lOX1dFRUspKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gd2Vla3M7XG4gICAgfVxuXG4gICAgLy8gTk9URTogcGxhaW4gbWV0aG9kIGZvciB0aGUgc2FtZSByZWFzb24gYXMgYGNhbGVuZGFyRGF5c2AgYWJvdmUgKGRlcGVuZHMgb24gYHRoaXMudmFsdWVgLFxuICAgIC8vIGEgbm9uLVNpZ25hbCBASW5wdXQpLlxuICAgIHB1YmxpYyBjYWxlbmRhck1vbnRocygpOiB7IG1vbnRoOiBudW1iZXI7IG5hbWU6IHN0cmluZzsgc2VsZWN0ZWQ6IGJvb2xlYW4gfVtdIHtcbiAgICAgICAgY29uc3QgbW9udGhOYW1lcyA9IFsnSmFuJywgJ0ZlYicsICdNYXInLCAnQXByJywgJ01heScsICdKdW4nLCAnSnVsJywgJ0F1ZycsICdTZXAnLCAnT2N0JywgJ05vdicsICdEZWMnXTtcbiAgICAgICAgY29uc3Qgdmlld0QgPSB0aGlzLnZpZXdEYXRlKCk7XG4gICAgICAgIHJldHVybiBtb250aE5hbWVzLm1hcCgobmFtZSwgaW5kZXgpID0+ICh7XG4gICAgICAgICAgICBtb250aDogaW5kZXgsXG4gICAgICAgICAgICBzZWxlY3RlZDogdGhpcy5pc01vbnRoU2VsZWN0ZWQoaW5kZXgsIHZpZXdELmdldEZ1bGxZZWFyKCkpLFxuICAgICAgICAgICAgbmFtZVxuICAgICAgICB9KSk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlYWRvbmx5IHllYXJSYW5nZSA9IGNvbXB1dGVkKCgpOiBudW1iZXJbXSA9PiB7XG4gICAgICAgIGNvbnN0IHZpZXdEID0gdGhpcy52aWV3RGF0ZSgpO1xuICAgICAgICBjb25zdCBjdXJyZW50WWVhciA9IHZpZXdELmdldEZ1bGxZZWFyKCk7XG4gICAgICAgIGNvbnN0IHN0YXJ0WWVhciA9IGN1cnJlbnRZZWFyIC0gKGN1cnJlbnRZZWFyICUgWUVBUlNfUEVSX1BBR0UpO1xuICAgICAgICBjb25zdCB5ZWFyczogbnVtYmVyW10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBZRUFSU19QRVJfUEFHRTsgaSsrKSB7XG4gICAgICAgICAgICB5ZWFycy5wdXNoKHN0YXJ0WWVhciArIGkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB5ZWFycztcbiAgICB9KTtcblxuICAgIC8vIE5PVEU6IHBsYWluIG1ldGhvZCBmb3IgdGhlIHNhbWUgcmVhc29uIGFzIGBjYWxlbmRhckRheXNgIGFib3ZlIChkZXBlbmRzIG9uIGB0aGlzLnZhbHVlYCxcbiAgICAvLyBhIG5vbi1TaWduYWwgQElucHV0KS5cbiAgICBwdWJsaWMgZGlzcGxheVZhbHVlKCk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMudmFsdWU7XG4gICAgICAgIGlmICghdmFsKSB7IHJldHVybiAnJzsgfVxuICAgICAgICBpZiAodGhpcy5tb2RlID09PSAncmFuZ2UnKSB7XG4gICAgICAgICAgICBjb25zdCByYW5nZSA9IHZhbCBhcyBEYXRlUmFuZ2U7XG4gICAgICAgICAgICBjb25zdCBzdGFydFN0ciA9IHJhbmdlLnN0YXJ0ID8gdGhpcy5mb3JtYXREYXRlKHJhbmdlLnN0YXJ0KSA6ICcnO1xuICAgICAgICAgICAgY29uc3QgZW5kU3RyID0gcmFuZ2UuZW5kID8gdGhpcy5mb3JtYXREYXRlKHJhbmdlLmVuZCkgOiAnJztcbiAgICAgICAgICAgIHJldHVybiBzdGFydFN0ciAmJiBlbmRTdHIgPyBgJHtzdGFydFN0cn0ke3RoaXMucmFuZ2VTZXBhcmF0b3J9JHtlbmRTdHJ9YCA6IHN0YXJ0U3RyO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGlvbk1vZGUgPT09ICdtdWx0aXBsZScgJiYgQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsLm1hcChkID0+IHRoaXMuZm9ybWF0RGF0ZShkKSkuam9pbignLCAnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0RGF0ZSh2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVhZG9ubHkgdmlld01vbnRoWWVhckxhYmVsID0gY29tcHV0ZWQoKCk6IHN0cmluZyA9PiB7XG4gICAgICAgIGNvbnN0IG1vbnRoTmFtZXMgPSBbJ0phbnVhcnknLCAnRmVicnVhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLFxuICAgICAgICAgICAgJ0p1bHknLCAnQXVndXN0JywgJ1NlcHRlbWJlcicsICdPY3RvYmVyJywgJ05vdmVtYmVyJywgJ0RlY2VtYmVyJ107XG4gICAgICAgIGNvbnN0IHZpZXdEID0gdGhpcy52aWV3RGF0ZSgpO1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50VmlldygpID09PSAneWVhcnMnKSB7XG4gICAgICAgICAgICBjb25zdCB5ZWFycyA9IHRoaXMueWVhclJhbmdlKCk7XG4gICAgICAgICAgICByZXR1cm4gYCR7eWVhcnNbMF19IC0gJHt5ZWFyc1t5ZWFycy5sZW5ndGggLSAxXX1gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgJHttb250aE5hbWVzW3ZpZXdELmdldE1vbnRoKCldfSAke3ZpZXdELmdldEZ1bGxZZWFyKCl9YDtcbiAgICB9KTtcblxuICAgIHB1YmxpYyByZWFkb25seSBzaG93VGltZVBpY2tlciA9IGNvbXB1dGVkKCgpOiBib29sZWFuID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMubW9kZSA9PT0gJ2RhdGV0aW1lJyB8fCB0aGlzLm1vZGUgPT09ICd0aW1lJztcbiAgICB9KTtcblxuICAgIC8vIC0tLSBMaWZlY3ljbGUgLS0tXG4gICAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWV3RGF0ZSgpO1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuYWRkKFxuICAgICAgICAgICAgdGhpcy50cmFuc2xhdGUub25MYW5nQ2hhbmdlLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgLy8gLS0tIENvbnRyb2xWYWx1ZUFjY2Vzc29yIG92ZXJyaWRlIC0tLVxuICAgIHB1YmxpYyBvdmVycmlkZSB3cml0ZVZhbHVlKHZhbHVlOiBEYXRlcGlja2VyVmFsdWUpOiB2b2lkIHtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdEYXRlLnNldChuZXcgRGF0ZSh2YWx1ZS5nZXRGdWxsWWVhcigpLCB2YWx1ZS5nZXRNb250aCgpLCAxKSk7XG4gICAgICAgICAgICB0aGlzLmhvdXJzLnNldCh2YWx1ZS5nZXRIb3VycygpKTtcbiAgICAgICAgICAgIHRoaXMubWludXRlcy5zZXQodmFsdWUuZ2V0TWludXRlcygpKTtcbiAgICAgICAgICAgIHRoaXMuc2Vjb25kcy5zZXQodmFsdWUuZ2V0U2Vjb25kcygpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICAvLyAtLS0gVmFsaWRhdG9yIC0tLVxuICAgIHB1YmxpYyB2YWxpZGF0ZShjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7XG4gICAgICAgIGNvbnN0IHZhbCA9IGNvbnRyb2wudmFsdWU7XG4gICAgICAgIGlmICghdmFsKSB7IHJldHVybiBudWxsOyB9XG5cbiAgICAgICAgaWYgKHRoaXMubWluICYmIHZhbCBpbnN0YW5jZW9mIERhdGUgJiYgdmFsIDwgdGhpcy5taW4pIHtcbiAgICAgICAgICAgIHJldHVybiB7IHNkY0RhdGVwaWNrZXJNaW46IHsgbWluOiB0aGlzLm1pbiwgYWN0dWFsOiB2YWwgfSB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm1heCAmJiB2YWwgaW5zdGFuY2VvZiBEYXRlICYmIHZhbCA+IHRoaXMubWF4KSB7XG4gICAgICAgICAgICByZXR1cm4geyBzZGNEYXRlcGlja2VyTWF4OiB7IG1heDogdGhpcy5tYXgsIGFjdHVhbDogdmFsIH0gfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyAtLS0gUGFuZWwgYWN0aW9ucyAtLS1cbiAgICBwdWJsaWMgb3BlblBhbmVsKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5kaXNhYmxlZCB8fCB0aGlzLnBhbmVsT3BlbikgeyByZXR1cm47IH1cbiAgICAgICAgdGhpcy5wYW5lbE9wZW4gPSB0cnVlO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVWaWV3RGF0ZSgpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7IC8vIEZvcmNlIGltbWVkaWF0ZSBDRCBmb3IgQ0RLIG92ZXJsYXlcbiAgICB9XG5cbiAgICBwdWJsaWMgY2xvc2VQYW5lbCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnBhbmVsT3BlbikgeyByZXR1cm47IH1cbiAgICAgICAgdGhpcy5wYW5lbE9wZW4gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jbG9zZWQuZW1pdCgpO1xuICAgICAgICB0aGlzLm9uVG91Y2hlZCgpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7IC8vIEZvcmNlIGltbWVkaWF0ZSBDRCBmb3IgQ0RLIG92ZXJsYXlcbiAgICB9XG5cbiAgICAvLyBDbG9zZXMgdGhlIHBhbmVsIGFuZCByZXR1cm5zIGZvY3VzIHRvIHRoZSB0cmlnZ2VyIGlucHV0LiBPbmx5IHVzZWQgZm9yIGNsb3NlcyBkcml2ZW5cbiAgICAvLyBkaXJlY3RseSBieSBhbiBpbi13aWRnZXQgYWN0aW9uIChFc2NhcGUsIGEgZGF5L2Zvb3Rlci1idXR0b24gc2VsZWN0aW9uKSDigJQgdGhlIGRheSBidXR0b25cbiAgICAvLyBvciBmb290ZXIgYnV0dG9uIHRoYXQgaGFkIGZvY3VzIGlzIGFib3V0IHRvIGJlIGRlc3Ryb3llZCwgc28gcmVzdG9yaW5nIGZvY3VzIHRvIHRoZSBpbnB1dFxuICAgIC8vIGlzIGFsd2F5cyBjb3JyZWN0IHRoZXJlLiBOT1QgdXNlZCBmb3IgYG9uUG9wb3Zlck9wZW5DaGFuZ2VgIChvdXRzaWRlLWNsaWNrKSwgd2hlcmUgZm9yY2luZ1xuICAgIC8vIGZvY3VzIGJhY2sgd291bGQgZmlnaHQgdGhlIGNsaWNrIHRoZSB1c2VyIGp1c3QgbWFkZSBvbiBzb21ldGhpbmcgZWxzZS5cbiAgICBwcml2YXRlIGNsb3NlUGFuZWxBbmRGb2N1c0lucHV0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmNsb3NlUGFuZWwoKTtcbiAgICAgICAgLy8gYHNob3dPbkZvY3VzYCByZW9wZW5zIHRoZSBwYW5lbCBvbiAoZm9jdXMpIOKAlCB3aXRob3V0IHRoaXMgZ3VhcmQsIGZvY3VzaW5nIHRoZSBpbnB1dFxuICAgICAgICAvLyBiYWNrIGhlcmUgd291bGQgaW1tZWRpYXRlbHkgcmVvcGVuIHRoZSBwYW5lbCB3ZSBqdXN0IGNsb3NlZC5cbiAgICAgICAgdGhpcy5zdXBwcmVzc05leHRGb2N1c09wZW4gPSB0cnVlO1xuICAgICAgICB0aGlzLmlucHV0UmVmPy5uYXRpdmVFbGVtZW50Py5mb2N1cygpO1xuICAgIH1cblxuICAgIHB1YmxpYyB0b2dnbGVQYW5lbCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMucGFuZWxPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlUGFuZWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3BlblBhbmVsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgb25JbnB1dENsaWNrKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5zaG93T25Gb2N1cyAmJiAhdGhpcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5vcGVuUGFuZWwoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBvbklucHV0Rm9jdXMoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnN1cHByZXNzTmV4dEZvY3VzT3Blbikge1xuICAgICAgICAgICAgdGhpcy5zdXBwcmVzc05leHRGb2N1c09wZW4gPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uSW5wdXRDbGljaygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBvbk92ZXJsYXlLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGlmIChldmVudC5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlUGFuZWxBbmRGb2N1c0lucHV0KCk7XG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG9uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgICAgICBpZiAoZXZlbnQua2V5ID09PSAnVGFiJyAmJiAhZXZlbnQuc2hpZnRLZXkgJiYgdGhpcy5wYW5lbE9wZW4pIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXNJbnRvUGFuZWwoZXZlbnQpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZpZXcgPSB0aGlzLmN1cnJlbnRWaWV3KCk7XG4gICAgICAgIGlmICh2aWV3ID09PSAnZGF5cycpIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRGF5c0tleWRvd24oZXZlbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gVGFiIGZyb20gdGhlIGlucHV0IHdvdWxkIG90aGVyd2lzZSBlc2NhcGUgc3RyYWlnaHQgcGFzdCB0aGUgY2FsZW5kYXI6IHRoZSBwb3BvdmVyJ3MgcGFuZWxcbiAgICAvLyBpcyBwb3J0YWxlZCB0byA8Ym9keT4gKGZhciBmcm9tIHRoZSBpbnB1dCBpbiBET00gb3JkZXIpLCBzbyB3aXRob3V0IHRoaXMgaXQganVtcHMgdG9cbiAgICAvLyB3aGF0ZXZlciBwYWdlIGVsZW1lbnQgaGFwcGVucyB0byBjb21lIG5leHQsIG5ldmVyIHJlYWNoaW5nIHRoZSBjYWxlbmRhciBhdCBhbGwuIFRoaXNcbiAgICAvLyByZWRpcmVjdHMgVGFiIGludG8gdGhlIHBhbmVsIGluc3RlYWQg4oCUIGRlbGliZXJhdGVseSBOT1QgZG9uZSBvbiBvcGVuL2ZvY3VzIChlLmcuIHZpYVxuICAgIC8vIGBmb2N1c09uT3BlbmApLCB3aGljaCB3b3VsZCBzdGVhbCBmb2N1cyBmcm9tIHRoZSBpbnB1dCBhbmQgYnJlYWsgdHlwaW5nIGEgZGF0ZSBtYW51YWxseS5cbiAgICBwcml2YXRlIGZvY3VzSW50b1BhbmVsKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRWaWV3KCkgPT09ICdkYXlzJykge1xuICAgICAgICAgICAgY29uc3QgZGF5cyA9IHRoaXMuY2FsZW5kYXJEYXlzKCk7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVEYXRlID0gdGhpcy5mb2N1c2VkRGF0ZSgpXG4gICAgICAgICAgICAgICAgPz8gZGF5cy5maW5kKGQgPT4gZC50b2RheSk/LmRhdGVcbiAgICAgICAgICAgICAgICA/PyBkYXlzLmZpbmQoZCA9PiBkLmN1cnJlbnRNb250aCk/LmRhdGU7XG5cbiAgICAgICAgICAgIGlmIChhY3RpdmVEYXRlKSB7XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZvY3VzRGF5QnV0dG9uKGFjdGl2ZURhdGUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBhbmVsID0gdGhpcy5wYW5lbENvbnRlbnRSZWY/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGlmIChwYW5lbCkge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGZvY3VzRmlyc3REZXNjZW5kYW50KHBhbmVsLCBwYW5lbCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBCb3VuZCBvbiB0aGUgY2FsZW5kYXIgZ3JpZCBpdHNlbGYgKGAuc2RjLWRhdGVwaWNrZXJfX2RheXNgKSwgd2hpY2ggbGl2ZXMgaW4gdGhlIHBvcG92ZXInc1xuICAgIC8vIHBvcnRhbCDigJQgYSBzZXBhcmF0ZSBET00gc3VidHJlZSBmcm9tIHRoZSBpbnB1dCwgc28gYG9uS2V5ZG93bmAgYWJvdmUgKGJvdW5kIG9uIHRoZSBpbnB1dClcbiAgICAvLyBuZXZlciBzZWVzIGtleWRvd25zIHRoYXQgb3JpZ2luYXRlIGZyb20gYSBkYXkgYnV0dG9uIHRoYXQgYWxyZWFkeSBoYXMgcmVhbCBmb2N1cy4gT25seVxuICAgIC8vIGFycm93IGtleXMgYXJlIGZvcndhcmRlZCBoZXJlOiBFbnRlci9TcGFjZSBhcmUgbGVmdCB0byB0aGUgYnV0dG9uJ3MgbmF0aXZlIGFjdGl2YXRpb25cbiAgICAvLyAod2hpY2ggYWxyZWFkeSBmaXJlcyBgc2VsZWN0RGF5YCB2aWEgYChjbGljaylgKSwgb3RoZXJ3aXNlIHRoZXknZCBkb3VibGUtZmlyZS5cbiAgICBwdWJsaWMgb25EYXlzR3JpZEtleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFZpZXcoKSAhPT0gJ2RheXMnKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LmtleSAhPT0gJ0Fycm93TGVmdCcgJiYgZXZlbnQua2V5ICE9PSAnQXJyb3dSaWdodCcgJiYgZXZlbnQua2V5ICE9PSAnQXJyb3dVcCcgJiYgZXZlbnQua2V5ICE9PSAnQXJyb3dEb3duJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaGFuZGxlRGF5c0tleWRvd24oZXZlbnQpO1xuICAgIH1cblxuICAgIC8vIC0tLSBOYXZpZ2F0aW9uIC0tLVxuICAgIHB1YmxpYyBwcmV2TW9udGgoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGQgPSB0aGlzLnZpZXdEYXRlKCk7XG4gICAgICAgIGNvbnN0IG5ld0RhdGUgPSBuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCksIGQuZ2V0TW9udGgoKSAtIDEsIDEpO1xuICAgICAgICB0aGlzLnZpZXdEYXRlLnNldChuZXdEYXRlKTtcbiAgICAgICAgdGhpcy5tb250aENoYW5nZS5lbWl0KHsgbW9udGg6IG5ld0RhdGUuZ2V0TW9udGgoKSArIDEsIHllYXI6IG5ld0RhdGUuZ2V0RnVsbFllYXIoKSB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmV4dE1vbnRoKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBkID0gdGhpcy52aWV3RGF0ZSgpO1xuICAgICAgICBjb25zdCBuZXdEYXRlID0gbmV3IERhdGUoZC5nZXRGdWxsWWVhcigpLCBkLmdldE1vbnRoKCkgKyAxLCAxKTtcbiAgICAgICAgdGhpcy52aWV3RGF0ZS5zZXQobmV3RGF0ZSk7XG4gICAgICAgIHRoaXMubW9udGhDaGFuZ2UuZW1pdCh7IG1vbnRoOiBuZXdEYXRlLmdldE1vbnRoKCkgKyAxLCB5ZWFyOiBuZXdEYXRlLmdldEZ1bGxZZWFyKCkgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHByZXZZZWFyKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBkID0gdGhpcy52aWV3RGF0ZSgpO1xuICAgICAgICB0aGlzLnZpZXdEYXRlLnNldChuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCkgLSAxLCBkLmdldE1vbnRoKCksIDEpKTtcbiAgICAgICAgdGhpcy55ZWFyQ2hhbmdlLmVtaXQoeyBtb250aDogZC5nZXRNb250aCgpICsgMSwgeWVhcjogZC5nZXRGdWxsWWVhcigpIC0gMSB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmV4dFllYXIoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGQgPSB0aGlzLnZpZXdEYXRlKCk7XG4gICAgICAgIHRoaXMudmlld0RhdGUuc2V0KG5ldyBEYXRlKGQuZ2V0RnVsbFllYXIoKSArIDEsIGQuZ2V0TW9udGgoKSwgMSkpO1xuICAgICAgICB0aGlzLnllYXJDaGFuZ2UuZW1pdCh7IG1vbnRoOiBkLmdldE1vbnRoKCkgKyAxLCB5ZWFyOiBkLmdldEZ1bGxZZWFyKCkgKyAxIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBwcmV2WWVhclJhbmdlKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBkID0gdGhpcy52aWV3RGF0ZSgpO1xuICAgICAgICB0aGlzLnZpZXdEYXRlLnNldChuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCkgLSBZRUFSU19QRVJfUEFHRSwgZC5nZXRNb250aCgpLCAxKSk7XG4gICAgfVxuXG4gICAgcHVibGljIG5leHRZZWFyUmFuZ2UoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGQgPSB0aGlzLnZpZXdEYXRlKCk7XG4gICAgICAgIHRoaXMudmlld0RhdGUuc2V0KG5ldyBEYXRlKGQuZ2V0RnVsbFllYXIoKSArIFlFQVJTX1BFUl9QQUdFLCBkLmdldE1vbnRoKCksIDEpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3dpdGNoVG9Nb250aFZpZXcoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY3VycmVudFZpZXcuc2V0KCdtb250aHMnKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3dpdGNoVG9ZZWFyVmlldygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jdXJyZW50Vmlldy5zZXQoJ3llYXJzJyk7XG4gICAgfVxuXG4gICAgcHVibGljIHNlbGVjdE1vbnRoKG1vbnRoOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZCA9IHRoaXMudmlld0RhdGUoKTtcbiAgICAgICAgdGhpcy52aWV3RGF0ZS5zZXQobmV3IERhdGUoZC5nZXRGdWxsWWVhcigpLCBtb250aCwgMSkpO1xuICAgICAgICBpZiAodGhpcy5tb2RlID09PSAnbW9udGgnKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZERhdGUgPSBuZXcgRGF0ZShkLmdldEZ1bGxZZWFyKCksIG1vbnRoLCAxKTtcbiAgICAgICAgICAgIHRoaXMuY29tbWl0RGF0ZVZhbHVlKHNlbGVjdGVkRGF0ZSk7XG4gICAgICAgICAgICB0aGlzLmNsb3NlUGFuZWxBbmRGb2N1c0lucHV0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3LnNldCgnZGF5cycpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubW9udGhDaGFuZ2UuZW1pdCh7IG1vbnRoOiBtb250aCArIDEsIHllYXI6IGQuZ2V0RnVsbFllYXIoKSB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2VsZWN0WWVhcih5ZWFyOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZCA9IHRoaXMudmlld0RhdGUoKTtcbiAgICAgICAgdGhpcy52aWV3RGF0ZS5zZXQobmV3IERhdGUoeWVhciwgZC5nZXRNb250aCgpLCAxKSk7XG4gICAgICAgIHRoaXMuY3VycmVudFZpZXcuc2V0KCdtb250aHMnKTtcbiAgICAgICAgdGhpcy55ZWFyQ2hhbmdlLmVtaXQoeyBtb250aDogZC5nZXRNb250aCgpICsgMSwgeWVhciB9KTtcbiAgICB9XG5cbiAgICAvLyAtLS0gRGF5IHNlbGVjdGlvbiAtLS1cbiAgICBwdWJsaWMgc2VsZWN0RGF5KGRheTogQ2FsZW5kYXJEYXkpOiB2b2lkIHtcbiAgICAgICAgaWYgKGRheS5kaXNhYmxlZCkgeyByZXR1cm47IH1cblxuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoZGF5LmRhdGUpO1xuXG4gICAgICAgIGlmICh0aGlzLm1vZGUgPT09ICdyYW5nZScpIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlUmFuZ2VTZWxlY3Rpb24oZGF0ZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zZWxlY3Rpb25Nb2RlID09PSAnbXVsdGlwbGUnKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZU11bHRpcGxlU2VsZWN0aW9uKGRhdGUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2luZ2xlIHNlbGVjdGlvblxuICAgICAgICBpZiAodGhpcy5zaG93VGltZVBpY2tlcigpKSB7XG4gICAgICAgICAgICBkYXRlLnNldEhvdXJzKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIHRoaXMuc2Vjb25kcygpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvbW1pdERhdGVWYWx1ZShkYXRlKTtcblxuICAgICAgICBpZiAodGhpcy5tb2RlID09PSAnZGF0ZScpIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2VQYW5lbEFuZEZvY3VzSW5wdXQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIC0tLSBUaW1lIC0tLVxuICAgIHB1YmxpYyBpbmNyZW1lbnRIb3VycygpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbWF4ID0gdGhpcy5ob3VyRm9ybWF0ID09PSAnMTInID8gSE9VUl9GT1JNQVRfMTJfTUFYIDogSE9VUl9GT1JNQVRfMjRfTUFYO1xuICAgICAgICB0aGlzLmhvdXJzLnNldCgodGhpcy5ob3VycygpICsgMSkgJSAobWF4ICsgMSkpO1xuICAgICAgICB0aGlzLnVwZGF0ZVRpbWVPblZhbHVlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlY3JlbWVudEhvdXJzKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBtYXggPSB0aGlzLmhvdXJGb3JtYXQgPT09ICcxMicgPyBIT1VSX0ZPUk1BVF8xMl9NQVggOiBIT1VSX0ZPUk1BVF8yNF9NQVg7XG4gICAgICAgIHRoaXMuaG91cnMuc2V0KCh0aGlzLmhvdXJzKCkgLSAxICsgKG1heCArIDEpKSAlIChtYXggKyAxKSk7XG4gICAgICAgIHRoaXMudXBkYXRlVGltZU9uVmFsdWUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaW5jcmVtZW50TWludXRlcygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5taW51dGVzLnNldCgodGhpcy5taW51dGVzKCkgKyB0aGlzLm1pbnV0ZVN0ZXApICUgNjApO1xuICAgICAgICB0aGlzLnVwZGF0ZVRpbWVPblZhbHVlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlY3JlbWVudE1pbnV0ZXMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWludXRlcy5zZXQoKHRoaXMubWludXRlcygpIC0gdGhpcy5taW51dGVTdGVwICsgNjApICUgNjApO1xuICAgICAgICB0aGlzLnVwZGF0ZVRpbWVPblZhbHVlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGluY3JlbWVudFNlY29uZHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2Vjb25kcy5zZXQoKHRoaXMuc2Vjb25kcygpICsgMSkgJSA2MCk7XG4gICAgICAgIHRoaXMudXBkYXRlVGltZU9uVmFsdWUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGVjcmVtZW50U2Vjb25kcygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZWNvbmRzLnNldCgodGhpcy5zZWNvbmRzKCkgLSAxICsgNjApICUgNjApO1xuICAgICAgICB0aGlzLnVwZGF0ZVRpbWVPblZhbHVlKCk7XG4gICAgfVxuXG4gICAgLy8gLS0tIEJ1dHRvbiBiYXIgYWN0aW9ucyAtLS1cbiAgICBwdWJsaWMgc2VsZWN0VG9kYXkoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICAgICAgaWYgKHRoaXMubW9kZSA9PT0gJ3RpbWUnKSB7XG4gICAgICAgICAgICB0aGlzLmhvdXJzLnNldCh0b2RheS5nZXRIb3VycygpKTtcbiAgICAgICAgICAgIHRoaXMubWludXRlcy5zZXQodG9kYXkuZ2V0TWludXRlcygpKTtcbiAgICAgICAgICAgIHRoaXMuc2Vjb25kcy5zZXQodG9kYXkuZ2V0U2Vjb25kcygpKTtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlVGltZU9uVmFsdWUoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRvZGF5LnNldEhvdXJzKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIHRoaXMuc2Vjb25kcygpKTtcbiAgICAgICAgICAgIHRoaXMuY29tbWl0RGF0ZVZhbHVlKHRvZGF5KTtcbiAgICAgICAgICAgIHRoaXMudmlld0RhdGUuc2V0KG5ldyBEYXRlKHRvZGF5LmdldEZ1bGxZZWFyKCksIHRvZGF5LmdldE1vbnRoKCksIDEpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNsb3NlUGFuZWxBbmRGb2N1c0lucHV0KCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNsZWFyVmFsdWUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudmFsdWUgPSBudWxsO1xuICAgICAgICB0aGlzLm9uQ2hhbmdlKG51bGwpO1xuICAgICAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQobnVsbCk7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWQuZW1pdChudWxsKTtcbiAgICAgICAgdGhpcy5yYW5nZVN0YXJ0LnNldChudWxsKTtcbiAgICAgICAgdGhpcy5yYW5nZUVuZC5zZXQobnVsbCk7XG4gICAgICAgIHRoaXMucmFuZ2VTZWxlY3Rpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbmZpcm1EYXRlVGltZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkID0gbmV3IERhdGUodGhpcy52YWx1ZSk7XG4gICAgICAgICAgICB1cGRhdGVkLnNldEhvdXJzKHRoaXMuaG91cnMoKSwgdGhpcy5taW51dGVzKCksIHRoaXMuc2Vjb25kcygpKTtcbiAgICAgICAgICAgIHRoaXMuY29tbWl0RGF0ZVZhbHVlKHVwZGF0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xvc2VQYW5lbEFuZEZvY3VzSW5wdXQoKTtcbiAgICB9XG5cbiAgICAvLyAtLS0gUG9wb3ZlciBldmVudHMgLS0tXG4gICAgcHVibGljIG9uUG9wb3Zlck9wZW5DaGFuZ2Uob3BlbjogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAoIW9wZW4gJiYgdGhpcy5wYW5lbE9wZW4pIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2VQYW5lbCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gLS0tIFByaXZhdGUgaGVscGVycyAtLS1cbiAgICBwcml2YXRlIGluaXRpYWxpemVWaWV3RGF0ZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICB0aGlzLnZpZXdEYXRlLnNldChuZXcgRGF0ZSh0aGlzLnZhbHVlLmdldEZ1bGxZZWFyKCksIHRoaXMudmFsdWUuZ2V0TW9udGgoKSwgMSkpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGVmYXVsdERhdGUpIHtcbiAgICAgICAgICAgIHRoaXMudmlld0RhdGUuc2V0KG5ldyBEYXRlKHRoaXMuZGVmYXVsdERhdGUuZ2V0RnVsbFllYXIoKSwgdGhpcy5kZWZhdWx0RGF0ZS5nZXRNb250aCgpLCAxKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgdGhpcy52aWV3RGF0ZS5zZXQobmV3IERhdGUobm93LmdldEZ1bGxZZWFyKCksIG5vdy5nZXRNb250aCgpLCAxKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5tb2RlID09PSAnbW9udGgnKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3LnNldCgnbW9udGhzJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3LnNldCgnZGF5cycpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjb21taXREYXRlVmFsdWUoZGF0ZTogRGF0ZSk6IHZvaWQge1xuICAgICAgICB0aGlzLnZhbHVlID0gZGF0ZTtcbiAgICAgICAgdGhpcy5vbkNoYW5nZShkYXRlKTtcbiAgICAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KGRhdGUpO1xuICAgICAgICB0aGlzLnNlbGVjdGVkLmVtaXQoZGF0ZSk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlUmFuZ2VTZWxlY3Rpb24oZGF0ZTogRGF0ZSk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMucmFuZ2VTZWxlY3RpbmcoKSkge1xuICAgICAgICAgICAgLy8gRmlyc3QgY2xpY2s6IHNldCBzdGFydFxuICAgICAgICAgICAgdGhpcy5yYW5nZVN0YXJ0LnNldChkYXRlKTtcbiAgICAgICAgICAgIHRoaXMucmFuZ2VFbmQuc2V0KG51bGwpO1xuICAgICAgICAgICAgdGhpcy5yYW5nZVNlbGVjdGluZy5zZXQodHJ1ZSk7XG4gICAgICAgICAgICBjb25zdCByYW5nZTogRGF0ZVJhbmdlID0geyBzdGFydDogZGF0ZSwgZW5kOiBudWxsIH07XG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gcmFuZ2U7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKHJhbmdlKTtcbiAgICAgICAgICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdChyYW5nZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZWNvbmQgY2xpY2s6IHNldCBlbmRcbiAgICAgICAgICAgIGxldCBzdGFydCA9IHRoaXMucmFuZ2VTdGFydCgpID8/IGRhdGU7XG4gICAgICAgICAgICBsZXQgZW5kID0gZGF0ZTtcbiAgICAgICAgICAgIGlmIChlbmQgPCBzdGFydCkge1xuICAgICAgICAgICAgICAgIFtzdGFydCwgZW5kXSA9IFtlbmQsIHN0YXJ0XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucmFuZ2VTdGFydC5zZXQoc3RhcnQpO1xuICAgICAgICAgICAgdGhpcy5yYW5nZUVuZC5zZXQoZW5kKTtcbiAgICAgICAgICAgIHRoaXMucmFuZ2VTZWxlY3Rpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlOiBEYXRlUmFuZ2UgPSB7IHN0YXJ0LCBlbmQgfTtcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSByYW5nZTtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UocmFuZ2UpO1xuICAgICAgICAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KHJhbmdlKTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWQuZW1pdChyYW5nZSk7XG4gICAgICAgICAgICB0aGlzLmNsb3NlUGFuZWxBbmRGb2N1c0lucHV0KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoYW5kbGVNdWx0aXBsZVNlbGVjdGlvbihkYXRlOiBEYXRlKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSBBcnJheS5pc0FycmF5KHRoaXMudmFsdWUpID8gdGhpcy52YWx1ZSA6IFtdO1xuICAgICAgICBjb25zdCBpbmRleCA9IGN1cnJlbnQuZmluZEluZGV4KGQgPT4gdGhpcy5pc1NhbWVEYXkoZCwgZGF0ZSkpO1xuICAgICAgICBsZXQgdXBkYXRlZDogRGF0ZVtdO1xuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgICAgdXBkYXRlZCA9IFsuLi5jdXJyZW50LnNsaWNlKDAsIGluZGV4KSwgLi4uY3VycmVudC5zbGljZShpbmRleCArIDEpXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVwZGF0ZWQgPSBbLi4uY3VycmVudCwgZGF0ZV07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy52YWx1ZSA9IHVwZGF0ZWQ7XG4gICAgICAgIHRoaXMub25DaGFuZ2UodXBkYXRlZCk7XG4gICAgICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCh1cGRhdGVkKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZC5lbWl0KHVwZGF0ZWQpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVRpbWVPblZhbHVlKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tb2RlID09PSAndGltZScpIHtcbiAgICAgICAgICAgIGNvbnN0IGQgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgZC5zZXRIb3Vycyh0aGlzLmhvdXJzKCksIHRoaXMubWludXRlcygpLCB0aGlzLnNlY29uZHMoKSwgMCk7XG4gICAgICAgICAgICB0aGlzLmNvbW1pdERhdGVWYWx1ZShkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy52YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWQgPSBuZXcgRGF0ZSh0aGlzLnZhbHVlKTtcbiAgICAgICAgICAgIHVwZGF0ZWQuc2V0SG91cnModGhpcy5ob3VycygpLCB0aGlzLm1pbnV0ZXMoKSwgdGhpcy5zZWNvbmRzKCkpO1xuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHVwZGF0ZWQ7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKHVwZGF0ZWQpO1xuICAgICAgICAgICAgdGhpcy52YWx1ZUNoYW5nZS5lbWl0KHVwZGF0ZWQpO1xuICAgICAgICAgICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGlzRGF0ZVNlbGVjdGVkKGRhdGU6IERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdmFsID0gdGhpcy52YWx1ZTtcbiAgICAgICAgaWYgKCF2YWwpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICAgICAgaWYgKHRoaXMubW9kZSA9PT0gJ3JhbmdlJykge1xuICAgICAgICAgICAgY29uc3QgcmFuZ2UgPSB2YWwgYXMgRGF0ZVJhbmdlO1xuICAgICAgICAgICAgcmV0dXJuICghIXJhbmdlLnN0YXJ0ICYmIHRoaXMuaXNTYW1lRGF5KHJhbmdlLnN0YXJ0LCBkYXRlKSkgfHxcbiAgICAgICAgICAgICAgICAoISFyYW5nZS5lbmQgJiYgdGhpcy5pc1NhbWVEYXkocmFuZ2UuZW5kLCBkYXRlKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5zZWxlY3Rpb25Nb2RlID09PSAnbXVsdGlwbGUnICYmIEFycmF5LmlzQXJyYXkodmFsKSkge1xuICAgICAgICAgICAgcmV0dXJuIHZhbC5zb21lKGQgPT4gdGhpcy5pc1NhbWVEYXkoZCwgZGF0ZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmlzU2FtZURheSh2YWwsIGRhdGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzRGF0ZURpc2FibGVkKGRhdGU6IERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMubWluICYmIGRhdGUgPCB0aGlzLm1pbikgeyByZXR1cm4gdHJ1ZTsgfVxuICAgICAgICBpZiAodGhpcy5tYXggJiYgZGF0ZSA+IHRoaXMubWF4KSB7IHJldHVybiB0cnVlOyB9XG4gICAgICAgIGlmICh0aGlzLmRpc2FibGVkRGF5cy5pbmNsdWRlcyhkYXRlLmdldERheSgpKSkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgICAgICBpZiAodGhpcy5kaXNhYmxlZERhdGVzLnNvbWUoZCA9PiB0aGlzLmlzU2FtZURheShkLCBkYXRlKSkpIHsgcmV0dXJuIHRydWU7IH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNJblJhbmdlKGRhdGU6IERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMubW9kZSAhPT0gJ3JhbmdlJykgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAgICAgY29uc3QgdmFsID0gdGhpcy52YWx1ZSBhcyBEYXRlUmFuZ2UgfCBudWxsO1xuICAgICAgICBpZiAoIXZhbD8uc3RhcnQgfHwgIXZhbD8uZW5kKSB7IHJldHVybiBmYWxzZTsgfVxuICAgICAgICByZXR1cm4gZGF0ZSA+IHZhbC5zdGFydCAmJiBkYXRlIDwgdmFsLmVuZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzUmFuZ2VTdGFydChkYXRlOiBEYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLm1vZGUgIT09ICdyYW5nZScpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMudmFsdWUgYXMgRGF0ZVJhbmdlIHwgbnVsbDtcbiAgICAgICAgcmV0dXJuICEhdmFsPy5zdGFydCAmJiB0aGlzLmlzU2FtZURheSh2YWwuc3RhcnQsIGRhdGUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNSYW5nZUVuZChkYXRlOiBEYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLm1vZGUgIT09ICdyYW5nZScpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMudmFsdWUgYXMgRGF0ZVJhbmdlIHwgbnVsbDtcbiAgICAgICAgcmV0dXJuICEhdmFsPy5lbmQgJiYgdGhpcy5pc1NhbWVEYXkodmFsLmVuZCwgZGF0ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc01vbnRoU2VsZWN0ZWQobW9udGg6IG51bWJlciwgeWVhcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMudmFsdWU7XG4gICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICAgICAgICByZXR1cm4gdmFsLmdldE1vbnRoKCkgPT09IG1vbnRoICYmIHZhbC5nZXRGdWxsWWVhcigpID09PSB5ZWFyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzU2FtZURheShhOiBEYXRlLCBiOiBEYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBhLmdldEZ1bGxZZWFyKCkgPT09IGIuZ2V0RnVsbFllYXIoKSAmJlxuICAgICAgICAgICAgYS5nZXRNb250aCgpID09PSBiLmdldE1vbnRoKCkgJiZcbiAgICAgICAgICAgIGEuZ2V0RGF0ZSgpID09PSBiLmdldERhdGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGhhbmRsZURheXNLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGZvY3VzZWQgPSB0aGlzLmZvY3VzZWREYXRlKCkgPz8gdGhpcy52aWV3RGF0ZSgpO1xuICAgICAgICBsZXQgbmV3RGF0ZTogRGF0ZSB8IG51bGwgPSBudWxsO1xuXG4gICAgICAgIHN3aXRjaCAoZXZlbnQua2V5KSB7XG4gICAgICAgICAgICBjYXNlICdBcnJvd0xlZnQnOlxuICAgICAgICAgICAgICAgIG5ld0RhdGUgPSBuZXcgRGF0ZShmb2N1c2VkLmdldEZ1bGxZZWFyKCksIGZvY3VzZWQuZ2V0TW9udGgoKSwgZm9jdXNlZC5nZXREYXRlKCkgLSAxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0Fycm93UmlnaHQnOlxuICAgICAgICAgICAgICAgIG5ld0RhdGUgPSBuZXcgRGF0ZShmb2N1c2VkLmdldEZ1bGxZZWFyKCksIGZvY3VzZWQuZ2V0TW9udGgoKSwgZm9jdXNlZC5nZXREYXRlKCkgKyAxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgICAgICAgICAgIG5ld0RhdGUgPSBuZXcgRGF0ZShmb2N1c2VkLmdldEZ1bGxZZWFyKCksIGZvY3VzZWQuZ2V0TW9udGgoKSwgZm9jdXNlZC5nZXREYXRlKCkgLSBEQVlTX0lOX1dFRUspO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgICAgICAgICBuZXdEYXRlID0gbmV3IERhdGUoZm9jdXNlZC5nZXRGdWxsWWVhcigpLCBmb2N1c2VkLmdldE1vbnRoKCksIGZvY3VzZWQuZ2V0RGF0ZSgpICsgREFZU19JTl9XRUVLKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgICAgICAgIGNhc2UgJyAnOlxuICAgICAgICAgICAgICAgIGlmIChmb2N1c2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0RGF5KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGU6IGZvY3VzZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXk6IGZvY3VzZWQuZ2V0RGF0ZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE1vbnRoOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9kYXk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IHRoaXMuaXNEYXRlRGlzYWJsZWQoZm9jdXNlZCksXG4gICAgICAgICAgICAgICAgICAgICAgICBpblJhbmdlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJhbmdlU3RhcnQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmFuZ2VFbmQ6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5ld0RhdGUpIHtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLmZvY3VzZWREYXRlLnNldChuZXdEYXRlKTtcbiAgICAgICAgICAgIC8vIE5hdmlnYXRlIG1vbnRoIGlmIG5lZWRlZFxuICAgICAgICAgICAgaWYgKG5ld0RhdGUuZ2V0TW9udGgoKSAhPT0gdGhpcy52aWV3RGF0ZSgpLmdldE1vbnRoKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdEYXRlLnNldChuZXcgRGF0ZShuZXdEYXRlLmdldEZ1bGxZZWFyKCksIG5ld0RhdGUuZ2V0TW9udGgoKSwgMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gU3luY2hyb25vdXMgc28gdGhlIChwb3NzaWJseSBuZXcgbW9udGgncykgZGF5IGJ1dHRvbnMgZXhpc3QgYmVmb3JlIHdlIGZvY3VzIG9uZS5cbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICAgIHRoaXMuZm9jdXNEYXlCdXR0b24obmV3RGF0ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNb3ZlcyByZWFsIERPTSBmb2N1cyBvbnRvIHRoZSBkYXkgYnV0dG9uIG1hdGNoaW5nIGBkYXRlYCwga2VlcGluZyByb3ZpbmcgdGFiaW5kZXgvZm9jdXNcbiAgICAvLyBpbiBzeW5jIHdpdGggYGZvY3VzZWREYXRlYCDigJQgd2l0aG91dCB0aGlzLCBhcnJvdy1rZXkgbmF2aWdhdGlvbiBvbmx5IHVwZGF0ZWQgaW50ZXJuYWxcbiAgICAvLyBzdGF0ZSBhbmQgdGhlIHZpc2libGUgYnJvd3Nlci9zY3JlZW4tcmVhZGVyIGZvY3VzIG5ldmVyIGFjdHVhbGx5IG1vdmVkLlxuICAgIHByaXZhdGUgZm9jdXNEYXlCdXR0b24oZGF0ZTogRGF0ZSk6IHZvaWQge1xuICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuY2FsZW5kYXJEYXlzKCkuZmluZEluZGV4KGRheSA9PiB0aGlzLmlzU2FtZURheShkYXkuZGF0ZSwgZGF0ZSkpO1xuICAgICAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kYXlCdXR0b25SZWZzPy50b0FycmF5KClbaW5kZXhdPy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lcyB3aGljaCBkYXkgaXMgdGhlIGNhbGVuZGFyIGdyaWQncyBzaW5nbGUgcm92aW5nIHRhYmluZGV4PTAgc3RvcDogdGhlIGxhc3RcbiAgICAvLyBrZXlib2FyZC1mb2N1c2VkIGRheSBpZiBhbnksIG90aGVyd2lzZSB0b2RheSAoaWYgdmlzaWJsZSBpbiB0aGUgY3VycmVudCBtb250aCksIG90aGVyd2lzZVxuICAgIC8vIHRoZSBmaXJzdCBkYXkgYmVsb25naW5nIHRvIHRoZSBjdXJyZW50IG1vbnRoIOKAlCBzbyB0aGUgZ3JpZCBhbHdheXMgaGFzIGV4YWN0bHkgb25lIHRhYiBzdG9wLlxuICAgIHB1YmxpYyBpc0RheVRhYlN0b3AoZGF5OiBDYWxlbmRhckRheSk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBmb2N1c2VkID0gdGhpcy5mb2N1c2VkRGF0ZSgpO1xuICAgICAgICBpZiAoZm9jdXNlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNTYW1lRGF5KGRheS5kYXRlLCBmb2N1c2VkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRheXMgPSB0aGlzLmNhbGVuZGFyRGF5cygpO1xuICAgICAgICBpZiAoZGF5cy5zb21lKGQgPT4gZC50b2RheSkpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXkudG9kYXk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaXJzdEN1cnJlbnRNb250aERheSA9IGRheXMuZmluZChkID0+IGQuY3VycmVudE1vbnRoKSA/PyBkYXlzWzBdO1xuICAgICAgICByZXR1cm4gZmlyc3RDdXJyZW50TW9udGhEYXkgPyB0aGlzLmlzU2FtZURheShkYXkuZGF0ZSwgZmlyc3RDdXJyZW50TW9udGhEYXkuZGF0ZSkgOiBmYWxzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZvcm1hdERhdGUoZGF0ZTogRGF0ZSk6IHN0cmluZyB7XG4gICAgICAgIGNvbnN0IGQgPSBkYXRlLmdldERhdGUoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgICAgIGNvbnN0IG0gPSAoZGF0ZS5nZXRNb250aCgpICsgMSkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xuICAgICAgICBjb25zdCB5ID0gZGF0ZS5nZXRGdWxsWWVhcigpLnRvU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGhoID0gZGF0ZS5nZXRIb3VycygpLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICAgICAgY29uc3QgbW0gPSBkYXRlLmdldE1pbnV0ZXMoKS50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgICAgIGNvbnN0IHNzID0gZGF0ZS5nZXRTZWNvbmRzKCkudG9TdHJpbmcoKS5wYWRTdGFydCgyLCAnMCcpO1xuXG4gICAgICAgIGxldCByZXN1bHQgPSB0aGlzLmRhdGVGb3JtYXRcbiAgICAgICAgICAgIC5yZXBsYWNlKCdkZCcsIGQpXG4gICAgICAgICAgICAucmVwbGFjZSgnTU0nLCBtKVxuICAgICAgICAgICAgLnJlcGxhY2UoJ3l5eXknLCB5KVxuICAgICAgICAgICAgLnJlcGxhY2UoJ3l5JywgeS5zbGljZSgtWUVBUl9TSE9SVF9MRU5HVEgpKTtcblxuICAgICAgICBpZiAodGhpcy5tb2RlID09PSAnZGF0ZXRpbWUnKSB7XG4gICAgICAgICAgICByZXN1bHQgKz0gYCAke2hofToke21tfWA7XG4gICAgICAgICAgICBpZiAodGhpcy5zaG93U2Vjb25kcykge1xuICAgICAgICAgICAgICAgIHJlc3VsdCArPSBgOiR7c3N9YDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLm1vZGUgPT09ICd0aW1lJykge1xuICAgICAgICAgICAgcmVzdWx0ID0gYCR7aGh9OiR7bW19YDtcbiAgICAgICAgICAgIGlmICh0aGlzLnNob3dTZWNvbmRzKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ICs9IGA6JHtzc31gO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBwdWJsaWMgcGFkVGltZShuOiBudW1iZXIpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gbi50b1N0cmluZygpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cInNkYy1kYXRlcGlja2VyXCI+XG4gIEBpZiAobGFiZWxLZXkoKSkge1xuICAgIDxkaXYgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fbGFiZWwtcm93XCI+XG4gICAgICA8bGFiZWwgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fbGFiZWxcIiBbYXR0ci5mb3JdPVwiaW5wdXRJZFwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNkYy1kYXRlcGlja2VyX19sYWJlbC10ZXh0XCI+XG4gICAgICAgICAge3sgbGFiZWxLZXkoKSB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIEBpZiAocmVxdWlyZWQpIHtcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicmVxdWlyZWQtZmllbGRcIiBhcmlhLWhpZGRlbj1cInRydWVcIj4qPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9sYWJlbD5cbiAgICA8L2Rpdj5cbiAgfVxuXG4gIDxzZGMtcG9wb3ZlclxuICAgIFtvcGVuXT1cInBhbmVsT3BlblwiXG4gICAgW3RvZ2dsZU9uVHJpZ2dlckNsaWNrXT1cImZhbHNlXCJcbiAgICBbY2xvc2VPbk91dHNpZGVDbGlja109XCJ0cnVlXCJcbiAgICBbY2xvc2VPbkVzY2FwZV09XCJ0cnVlXCJcbiAgICBbbWF0Y2hUcmlnZ2VyV2lkdGhdPVwiZmFsc2VcIlxuICAgIFtyZXN0b3JlRm9jdXNPbkNsb3NlXT1cImZhbHNlXCJcbiAgICBbdHJhcEZvY3VzXT1cInRydWVcIlxuICAgIFthcmlhTGFiZWxdPVwiJ2RhdGVwaWNrZXIuY2FsZW5kYXInXCJcbiAgICBwYW5lbENsYXNzPVwic2RjLWRhdGVwaWNrZXItcG9wb3Zlci1wYW5lbFwiXG4gICAgKG9wZW5DaGFuZ2UpPVwib25Qb3BvdmVyT3BlbkNoYW5nZSgkZXZlbnQpXCJcbiAgPlxuICAgIDxkaXYgc2RjLXBvcG92ZXItdHJpZ2dlcj5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fY29udHJvbFwiXG4gICAgICAgICN0cmlnZ2VyUmVmXG4gICAgICAgIFtjbGFzcy5zZGMtZGF0ZXBpY2tlcl9fY29udHJvbC0taW52YWxpZF09XCJpbnZhbGlkXCJcbiAgICAgICAgW2NsYXNzLnNkYy1kYXRlcGlja2VyX19jb250cm9sLS1kaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgIFtuZ1N0eWxlXT1cImdldElucHV0U3R5bGUoKVwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fdmFsdWVcIj5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICNpbnB1dFJlZlxuICAgICAgICAgICAgW2lkXT1cImlucHV0SWRcIlxuICAgICAgICAgICAgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9faW5wdXRcIlxuICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgIFtyZWFkT25seV09XCJyZWFkb25seUlucHV0XCJcbiAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlciB8fCBkYXRlRm9ybWF0XCJcbiAgICAgICAgICAgIFt2YWx1ZV09XCJkaXNwbGF5VmFsdWUoKVwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImxhYmVsS2V5KCkgPyAobGFiZWxLZXkoKSB8IHRyYW5zbGF0ZSkgOiBwbGFjZWhvbGRlclwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cInBhbmVsT3BlblwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWhhc3BvcHVwXT1cIidkaWFsb2cnXCJcbiAgICAgICAgICAgIGFyaWEtYXV0b2NvbXBsZXRlPVwibm9uZVwiXG4gICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIm9uSW5wdXRDbGljaygpXCJcbiAgICAgICAgICAgIChmb2N1cyk9XCJvbklucHV0Rm9jdXMoKVwiXG4gICAgICAgICAgICAoa2V5ZG93bik9XCJvbktleWRvd24oJGV2ZW50KVwiXG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNkYy1kYXRlcGlja2VyX19hY3Rpb25zXCI+XG4gICAgICAgICAgQGlmIChzaG93Q2xlYXIgJiYgdmFsdWUpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX2ljb24tYnV0dG9uIHNkYy1kYXRlcGlja2VyX19pY29uLWJ1dHRvbi0tY2xlYXJcIlxuICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidkYXRlcGlja2VyLmNsZWFyJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJjbGVhclZhbHVlKCk7ICRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLXRpbWVzXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfVxuICAgICAgICAgIEBpZiAoc2hvd0ljb24pIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX2ljb24tYnV0dG9uIHNkYy1kYXRlcGlja2VyX19pY29uLWJ1dHRvbi0tdG9nZ2xlXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInZGF0ZXBpY2tlci5jYWxlbmRhcicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cInBhbmVsT3BlblwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVQYW5lbCgpOyAkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8aSBbY2xhc3NdPVwiaWNvblwiIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX2ljb25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IHNkYy1wb3BvdmVyLWNvbnRlbnQ+XG4gICAgICA8ZGl2XG4gICAgICAjcGFuZWxDb250ZW50UmVmXG4gICAgICBjbGFzcz1cInNkYy1kYXRlcGlja2VyX19wYW5lbFwiXG4gICAgICAoa2V5ZG93bik9XCJvbk92ZXJsYXlLZXlkb3duKCRldmVudClcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInZGF0ZXBpY2tlci5jYWxlbmRhcicgfCB0cmFuc2xhdGVcIlxuICAgID5cbiAgICAgIDwhLS0gTmF2aWdhdGlvbiBIZWFkZXIgLS0+XG4gICAgICBAaWYgKG1vZGUgIT09ICd0aW1lJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX2hlYWRlclwiPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fbmF2LWJ0blwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidkYXRlcGlja2VyLnByZXYnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIChjbGljayk9XCJjdXJyZW50VmlldygpID09PSAnZGF5cycgPyBwcmV2TW9udGgoKSA6IGN1cnJlbnRWaWV3KCkgPT09ICdtb250aHMnID8gcHJldlllYXIoKSA6IHByZXZZZWFyUmFuZ2UoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtY2hldnJvbi1sZWZ0XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cInNkYy1kYXRlcGlja2VyX190aXRsZS1idG5cIlxuICAgICAgICAgICAgKGNsaWNrKT1cIlxuICAgICAgICAgICAgICBjdXJyZW50VmlldygpID09PSAnZGF5cydcbiAgICAgICAgICAgICAgICA/IHN3aXRjaFRvTW9udGhWaWV3KClcbiAgICAgICAgICAgICAgICA6IGN1cnJlbnRWaWV3KCkgPT09ICdtb250aHMnID8gc3dpdGNoVG9ZZWFyVmlldygpIDogbnVsbFxuICAgICAgICAgICAgXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyB2aWV3TW9udGhZZWFyTGFiZWwoKSB9fVxuICAgICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cInNkYy1kYXRlcGlja2VyX19uYXYtYnRuXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ2RhdGVwaWNrZXIubmV4dCcgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgKGNsaWNrKT1cImN1cnJlbnRWaWV3KCkgPT09ICdkYXlzJyA/IG5leHRNb250aCgpIDogY3VycmVudFZpZXcoKSA9PT0gJ21vbnRocycgPyBuZXh0WWVhcigpIDogbmV4dFllYXJSYW5nZSgpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1jaGV2cm9uLXJpZ2h0XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgPCEtLSBEYXlzIFZpZXcgLS0+XG4gICAgICBAaWYgKGN1cnJlbnRWaWV3KCkgPT09ICdkYXlzJyAmJiBtb2RlICE9PSAndGltZScpIHtcbiAgICAgICAgPHRhYmxlIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX2NhbGVuZGFyXCI+XG4gICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgPHRyIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX3dlZWtkYXlzXCI+XG4gICAgICAgICAgICAgIEBmb3IgKGRheU5hbWUgb2Ygd2Vla0RheU5hbWVzKCk7IHRyYWNrIGRheU5hbWUpIHtcbiAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fd2Vla2RheVwiIHNjb3BlPVwiY29sXCI+XG4gICAgICAgICAgICAgICAgICB7eyBkYXlOYW1lIH19XG4gICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgIDx0Ym9keSBjbGFzcz1cInNkYy1kYXRlcGlja2VyX19kYXlzXCIgKGtleWRvd24pPVwib25EYXlzR3JpZEtleWRvd24oJGV2ZW50KVwiPlxuICAgICAgICAgICAgQGZvciAod2VlayBvZiBjYWxlbmRhcldlZWtzKCk7IHRyYWNrICRpbmRleCkge1xuICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgQGZvciAoZGF5IG9mIHdlZWs7IHRyYWNrIGRheS5kYXRlLmdldFRpbWUoKSkge1xuICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgI2RheUJ0blxuICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX2RheVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLnNkYy1kYXRlcGlja2VyX19kYXktLW90aGVyLW1vbnRoXT1cIiFkYXkuY3VycmVudE1vbnRoXCJcbiAgICAgICAgICAgICAgICAgICAgICBbY2xhc3Muc2RjLWRhdGVwaWNrZXJfX2RheS0tdG9kYXldPVwiZGF5LnRvZGF5XCJcbiAgICAgICAgICAgICAgICAgICAgICBbY2xhc3Muc2RjLWRhdGVwaWNrZXJfX2RheS0tc2VsZWN0ZWRdPVwiZGF5LnNlbGVjdGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICBbY2xhc3Muc2RjLWRhdGVwaWNrZXJfX2RheS0tZGlzYWJsZWRdPVwiZGF5LmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICBbY2xhc3Muc2RjLWRhdGVwaWNrZXJfX2RheS0taW4tcmFuZ2VdPVwiZGF5LmluUmFuZ2VcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5zZGMtZGF0ZXBpY2tlcl9fZGF5LS1yYW5nZS1zdGFydF09XCJkYXkucmFuZ2VTdGFydFwiXG4gICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLnNkYy1kYXRlcGlja2VyX19kYXktLXJhbmdlLWVuZF09XCJkYXkucmFuZ2VFbmRcIlxuICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkYXkuZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiZGF5LmRhdGUudG9Mb2NhbGVEYXRlU3RyaW5nKClcIlxuICAgICAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtc2VsZWN0ZWRdPVwiZGF5LnNlbGVjdGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWRpc2FibGVkXT1cImRheS5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgICAgICAgICAgW2F0dHIudGFiaW5kZXhdPVwiaXNEYXlUYWJTdG9wKGRheSkgPyAwIDogLTFcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3REYXkoZGF5KVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBkYXkuZGF5IH19XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgPC90YWJsZT5cbiAgICAgIH1cblxuICAgICAgPCEtLSBNb250aHMgVmlldyAtLT5cbiAgICAgIEBpZiAoY3VycmVudFZpZXcoKSA9PT0gJ21vbnRocycpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInNkYy1kYXRlcGlja2VyX19tb250aHMtZ3JpZFwiPlxuICAgICAgICAgIEBmb3IgKG0gb2YgY2FsZW5kYXJNb250aHMoKTsgdHJhY2sgbS5tb250aCkge1xuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fbW9udGgtY2VsbFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5zZGMtZGF0ZXBpY2tlcl9fbW9udGgtY2VsbC0tc2VsZWN0ZWRdPVwibS5zZWxlY3RlZFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RNb250aChtLm1vbnRoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IG0ubmFtZSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgPCEtLSBZZWFycyBWaWV3IC0tPlxuICAgICAgQGlmIChjdXJyZW50VmlldygpID09PSAneWVhcnMnKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9feWVhcnMtZ3JpZFwiPlxuICAgICAgICAgIEBmb3IgKHllYXIgb2YgeWVhclJhbmdlKCk7IHRyYWNrIHllYXIpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX3llYXItY2VsbFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5zZGMtZGF0ZXBpY2tlcl9feWVhci1jZWxsLS1zZWxlY3RlZF09XCJ5ZWFyID09PSB2aWV3RGF0ZSgpLmdldEZ1bGxZZWFyKClcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0WWVhcih5ZWFyKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IHllYXIgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG5cbiAgICAgIDwhLS0gVGltZSBQaWNrZXIgLS0+XG4gICAgICBAaWYgKHNob3dUaW1lUGlja2VyKCkpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInNkYy1kYXRlcGlja2VyX190aW1lXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNkYy1kYXRlcGlja2VyX190aW1lLWdyb3VwXCI+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cInNkYy1kYXRlcGlja2VyX190aW1lLWJ0blwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJpbmNyZW1lbnRIb3VycygpXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInZGF0ZXBpY2tlci5pbmNyZW1lbnRIb3VyJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWNoZXZyb24tdXBcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX3RpbWUtdmFsdWVcIj57eyBwYWRUaW1lKGhvdXJzKCkpIH19PC9zcGFuPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fdGltZS1idG5cIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZGVjcmVtZW50SG91cnMoKVwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ2RhdGVwaWNrZXIuZGVjcmVtZW50SG91cicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1jaGV2cm9uLWRvd25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX3RpbWUtc2VwYXJhdG9yXCI+Ojwvc3Bhbj5cblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fdGltZS1ncm91cFwiPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fdGltZS1idG5cIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiaW5jcmVtZW50TWludXRlcygpXCJcbiAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInZGF0ZXBpY2tlci5pbmNyZW1lbnRNaW51dGUnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtY2hldnJvbi11cFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fdGltZS12YWx1ZVwiPnt7IHBhZFRpbWUobWludXRlcygpKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX3RpbWUtYnRuXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImRlY3JlbWVudE1pbnV0ZXMoKVwiXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ2RhdGVwaWNrZXIuZGVjcmVtZW50TWludXRlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWNoZXZyb24tZG93blwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgQGlmIChzaG93U2Vjb25kcykge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fdGltZS1zZXBhcmF0b3JcIj46PC9zcGFuPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNkYy1kYXRlcGlja2VyX190aW1lLWdyb3VwXCI+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNkYy1kYXRlcGlja2VyX190aW1lLWJ0blwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImluY3JlbWVudFNlY29uZHMoKVwiXG4gICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInZGF0ZXBpY2tlci5pbmNyZW1lbnRTZWNvbmQnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWNoZXZyb24tdXBcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNkYy1kYXRlcGlja2VyX190aW1lLXZhbHVlXCI+e3sgcGFkVGltZShzZWNvbmRzKCkpIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fdGltZS1idG5cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJkZWNyZW1lbnRTZWNvbmRzKClcIlxuICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ2RhdGVwaWNrZXIuZGVjcmVtZW50U2Vjb25kJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1jaGV2cm9uLWRvd25cIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cblxuICAgICAgfVxuXG4gICAgICA8IS0tIEZvb3RlcjogVG9kYXkgb24gdGhlIGxlZnQsIENsZWFyICsgQ29uZmlybSB0b2dldGhlciBvbiB0aGUgcmlnaHQgLS0+XG4gICAgICBAaWYgKHNob3dCdXR0b25CYXIgfHwgbW9kZSA9PT0gJ2RhdGV0aW1lJyB8fCBtb2RlID09PSAndGltZScpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInNkYy1kYXRlcGlja2VyX19idXR0b24tYmFyXCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIEBpZiAoc2hvd0J1dHRvbkJhciAmJiBtb2RlICE9PSAndGltZScpIHtcbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwic2RjLWRhdGVwaWNrZXJfX2Jhci1idG5cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RUb2RheSgpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7ICdkYXRlcGlja2VyLnRvZGF5JyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fYnV0dG9uLWJhci1lbmRcIj5cbiAgICAgICAgICAgIEBpZiAoc2hvd0J1dHRvbkJhcikge1xuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzZGMtZGF0ZXBpY2tlcl9fYmFyLWJ0blwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyVmFsdWUoKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyAnZGF0ZXBpY2tlci5jbGVhcicgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAaWYgKG1vZGUgPT09ICdkYXRldGltZScgfHwgbW9kZSA9PT0gJ3RpbWUnKSB7XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNkYy1kYXRlcGlja2VyX19jb25maXJtLWJ0blwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbmZpcm1EYXRlVGltZSgpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7ICdkYXRlcGlja2VyLmNvbmZpcm0nIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9zZGMtcG9wb3Zlcj5cblxuICBAaWYgKG1lc3NhZ2VLZXkoKSkge1xuICAgIDxzbWFsbFxuICAgICAgW25nQ2xhc3NdPVwiZ2V0SW52YWxpZE1lc3NhZ2VDbGFzcygpXCJcbiAgICAgIHJvbGU9XCJhbGVydFwiXG4gICAgICBhcmlhLWxpdmU9XCJwb2xpdGVcIlxuICAgID5cbiAgICAgIHt7IG1lc3NhZ2VLZXkoKSB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvc21hbGw+XG4gIH1cbjwvZGl2PlxuIl19