@natec/mef-dev-ui-kit 16.2.5 → 16.3.49

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 (79) hide show
  1. package/esm2022/lib/markup-kit/card/card/card.component.mjs +6 -6
  2. package/esm2022/lib/markup-kit/card/card-long/card-long.component.mjs +6 -6
  3. package/esm2022/lib/markup-kit/card/card-simple/card-simple.component.mjs +6 -6
  4. package/esm2022/lib/markup-kit/card/card.module.mjs +9 -9
  5. package/esm2022/lib/markup-kit/collapse/collapse/collapse.component.mjs +6 -6
  6. package/esm2022/lib/markup-kit/collapse/collapse-set/collapse-set.component.mjs +4 -4
  7. package/esm2022/lib/markup-kit/collapse/collapse.module.mjs +5 -5
  8. package/esm2022/lib/markup-kit/executors/mefdev-executor-page/mefdev-executor-page.component.mjs +4 -4
  9. package/esm2022/lib/markup-kit/executors/stage/stage.component.mjs +4 -4
  10. package/esm2022/lib/markup-kit/executors/step-executor/step-executor.component.mjs +74 -10
  11. package/esm2022/lib/markup-kit/executors/step-executor.module.mjs +10 -6
  12. package/esm2022/lib/markup-kit/modals/fill/fill.component.mjs +6 -6
  13. package/esm2022/lib/markup-kit/modals/markup-kit.module.mjs +5 -5
  14. package/esm2022/lib/markup-kit/modals/right-filter/right-filter.component.mjs +4 -4
  15. package/esm2022/lib/markup-kit/modals/slide-right/slide-right.component.mjs +5 -5
  16. package/esm2022/lib/markup-kit/modals/slide-up/slide-up.component.mjs +5 -5
  17. package/esm2022/lib/markup-kit/page-layouts/central-page/central-page.component.mjs +5 -5
  18. package/esm2022/lib/markup-kit/page-layouts/central-page-row/central-page-row.component.mjs +4 -4
  19. package/esm2022/lib/markup-kit/page-layouts/manage-page/manage-page.component.mjs +6 -6
  20. package/esm2022/lib/markup-kit/page-layouts/page-layouts.module.mjs +5 -5
  21. package/esm2022/lib/markup-kit/page-layouts/profile/profile.component.mjs +6 -6
  22. package/esm2022/lib/markup-kit/page-layouts/table-page/table-page.component.mjs +5 -5
  23. package/esm2022/lib/markup-kit/slider/slider/slider.component.mjs +6 -6
  24. package/esm2022/lib/markup-kit/slider/slider.module.mjs +5 -5
  25. package/esm2022/lib/markup-kit/utils/datepicker/datepicker/datepicker.component.mjs +140 -135
  26. package/esm2022/lib/markup-kit/utils/datepicker/datepicker.module.mjs +5 -5
  27. package/esm2022/lib/markup-kit/utils/filtered-field/filtered-field-container/filtered-field-container.component.mjs +5 -5
  28. package/esm2022/lib/markup-kit/utils/filtered-field/filtered-field-item/filtered-field-item.component.mjs +5 -5
  29. package/esm2022/lib/markup-kit/utils/filtered-field/filtered-field.module.mjs +5 -5
  30. package/esm2022/lib/markup-kit/utils/filtered-field/filtered-field.service.mjs +4 -4
  31. package/esm2022/lib/markup-kit/utils/help-block/help-block.component.mjs +6 -6
  32. package/esm2022/lib/markup-kit/utils/help-block/hepl-block.module.mjs +5 -5
  33. package/esm2022/lib/pg-components/card/card.components.mjs +11 -8
  34. package/esm2022/lib/pg-components/card/card.module.mjs +10 -10
  35. package/esm2022/lib/pg-components/progress/progress.component.mjs +4 -4
  36. package/esm2022/lib/pg-components/progress/progress.config.mjs +4 -4
  37. package/esm2022/lib/pg-components/progress/progress.module.mjs +5 -5
  38. package/esm2022/lib/pg-components/select/option.component.mjs +4 -4
  39. package/esm2022/lib/pg-components/select/option.pipe.mjs +4 -4
  40. package/esm2022/lib/pg-components/select/select.component.mjs +5 -5
  41. package/esm2022/lib/pg-components/select/select.module.mjs +5 -5
  42. package/esm2022/lib/pg-components/spec-flow-test/spec-flow-test/spec-flow-test.component.mjs +4 -4
  43. package/esm2022/lib/pg-components/spec-flow-test/spec-flow-test.module.mjs +5 -5
  44. package/esm2022/lib/pg-components/switch/switch.component.mjs +5 -5
  45. package/esm2022/lib/pg-components/switch/switch.module.mjs +5 -5
  46. package/esm2022/lib/pg-components/tabs/tab-body.component.mjs +4 -4
  47. package/esm2022/lib/pg-components/tabs/tab-label.directive.mjs +4 -4
  48. package/esm2022/lib/pg-components/tabs/tab.component.mjs +4 -4
  49. package/esm2022/lib/pg-components/tabs/tabs-ink-bar.directive.mjs +4 -4
  50. package/esm2022/lib/pg-components/tabs/tabs-nav.component.mjs +4 -4
  51. package/esm2022/lib/pg-components/tabs/tabs.module.mjs +5 -5
  52. package/esm2022/lib/pg-components/tabs/tabset.component.mjs +5 -5
  53. package/fesm2022/natec-mef-dev-ui-kit.mjs +418 -345
  54. package/fesm2022/natec-mef-dev-ui-kit.mjs.map +1 -1
  55. package/lib/markup-kit/card/card/card.component.d.ts +1 -1
  56. package/lib/markup-kit/card/card-long/card-long.component.d.ts +1 -1
  57. package/lib/markup-kit/card/card-simple/card-simple.component.d.ts +1 -1
  58. package/lib/markup-kit/card/card.module.d.ts +1 -1
  59. package/lib/markup-kit/collapse/collapse/collapse.component.d.ts +1 -1
  60. package/lib/markup-kit/executors/step-executor/step-executor.component.d.ts +45 -3
  61. package/lib/markup-kit/executors/step-executor.module.d.ts +4 -3
  62. package/lib/markup-kit/modals/fill/fill.component.d.ts +1 -1
  63. package/lib/markup-kit/modals/slide-right/slide-right.component.d.ts +1 -1
  64. package/lib/markup-kit/modals/slide-up/slide-up.component.d.ts +1 -1
  65. package/lib/markup-kit/page-layouts/central-page/central-page.component.d.ts +1 -1
  66. package/lib/markup-kit/page-layouts/manage-page/manage-page.component.d.ts +1 -1
  67. package/lib/markup-kit/page-layouts/profile/profile.component.d.ts +1 -1
  68. package/lib/markup-kit/page-layouts/table-page/table-page.component.d.ts +1 -1
  69. package/lib/markup-kit/slider/slider/slider.component.d.ts +1 -1
  70. package/lib/markup-kit/utils/datepicker/datepicker/datepicker.component.d.ts +104 -104
  71. package/lib/markup-kit/utils/filtered-field/filtered-field-container/filtered-field-container.component.d.ts +1 -1
  72. package/lib/markup-kit/utils/help-block/help-block.component.d.ts +1 -1
  73. package/lib/pg-components/card/card.components.d.ts +5 -5
  74. package/lib/pg-components/card/card.module.d.ts +5 -5
  75. package/lib/pg-components/select/select.component.d.ts +1 -1
  76. package/lib/pg-components/switch/switch.component.d.ts +1 -1
  77. package/lib/pg-components/tabs/tabset.component.d.ts +1 -1
  78. package/package.json +1 -1
  79. package/src/lib/styles/designe-colors.scss +16 -1
@@ -1,81 +1,91 @@
1
- import { Component, HostListener, Input, Output, EventEmitter } from '@angular/core';
1
+ import { Component, HostListener, Input, Output, EventEmitter, } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
3
  import * as i1 from "@angular/common";
4
4
  import * as i2 from "@angular/forms";
5
5
  import * as i3 from "../../../../pg-components/select/option.component";
6
6
  import * as i4 from "../../../../pg-components/select/select.component";
7
7
  /**
8
- * Datepicker Component for selecting dates.
9
- *
10
- * This component allows users to pick a date from a calendar interface.
11
- * It supports various configuration options such as language, date format, and date range.
12
- *
13
- * @example
14
- * <mefdev-datepicker
15
- * [lang]="'uk'"
16
- * [dateFormat]="'dd/MM/yyyy'"
17
- * [range]="{startYear: 1900, toYear: 300}"
18
- * [disabled]="false"
19
- * (dateChanged)="onDateChanged($event)"
20
- * [topOffset]="'20'"
21
- * [leftOffset]="'10'">
22
- * </mefdev-datepicker>
23
- *
24
- * <example-url>https://mef.dev/ui_kit_demo/view/utils/datepicker</example-url>
25
- */
8
+ * Datepicker Component for selecting dates.
9
+ *
10
+ * This component allows users to pick a date from a calendar interface.
11
+ * It supports various configuration options such as language, date format, and date range.
12
+ *
13
+ * @example
14
+ * <mefdev-datepicker
15
+ * [labelContentText]="'Select your date'"
16
+ * [lang]="'uk'"
17
+ * [dateFormat]="'dd/MM/yyyy'"
18
+ * [range]="{startYear: 1900, toYear: 300}"
19
+ * [disabled]="false"
20
+ * (dateChanged)="onDateChanged($event)"
21
+ * [topOffset]="'20'"
22
+ * [leftOffset]="'10'">
23
+ * </mefdev-datepicker>
24
+ *
25
+ * <example-url>https://mef.dev/ui_kit_demo/view/utils/datepicker</example-url>
26
+ */
26
27
  export class DatepickerComponent {
27
28
  datePipe;
28
29
  elementRef;
30
+ /**
31
+ * A flag that checks whether a valid date has been entered and whether the entered date exists.
32
+ * If the two previous conditions are not true, the datepicker will be highlighted in red
33
+ */
34
+ isUserDateValid = true;
29
35
  /**
30
36
  * Flag to determine if the calendar is open or closed.
31
37
  * Default value: false (closed).
32
- */
38
+ */
33
39
  isCalendarOpen = false;
34
- /**
35
- * Flag to determine if the component is in editing mode.
36
- * Default value: false (not in editing mode).
37
- */
38
- isEditing = false;
39
40
  /**
40
41
  * The currently selected date.
41
42
  * Default value: Today's date.
42
- */
43
+ */
43
44
  selectedDate = new Date();
44
45
  /**
45
- * The formatted date for display in the input.
46
- * Default value: Formatted representation of the selected date.
47
- */
46
+ * The formatted date for display in the input.
47
+ * Default value: Formatted representation of the selected date.
48
+ */
48
49
  formattedDate;
49
50
  /**
50
- * Track the edited date separately when in editing mode.
51
- * Default value: An empty string.
52
- */
51
+ * Track the edited date separately when in editing mode.
52
+ * Default value: An empty string.
53
+ */
53
54
  editedDate = '';
54
55
  /**
55
56
  * Flag to determine if the month dropdown is open or closed.
56
57
  * Default value: true (open).
57
- */
58
+ */
58
59
  isMonthDropdownOpen = true;
59
60
  /**
60
61
  * Flag to determine if the year dropdown is open or closed.
61
62
  * Default value: true (open).
62
- */
63
+ */
63
64
  isYearDropdownOpen = true;
64
65
  /**
65
66
  * The selected month (0-11).
66
67
  * Default value: The month of the selected date.
67
- */
68
+ */
68
69
  selectedDateMonth = this.selectedDate.getMonth();
69
70
  /**
70
71
  * The selected year.
71
72
  * Default value: The year of the selected date.
72
- */
73
+ */
73
74
  selectedDateYear = this.selectedDate.getFullYear();
74
75
  /**
75
- * An array of years for the year dropdown.
76
- * Default value: An array of years within the specified range.
77
- */
76
+ * An array of years for the year dropdown.
77
+ * Default value: An array of years within the specified range.
78
+ */
78
79
  years;
80
+ /**
81
+ * Label text for the datepicker.
82
+ * Default value: 'en' (English).
83
+ * @example
84
+ * <mefdev-datepicker
85
+ * [labelContentText] = "'Chose your date'">
86
+ * </mefdev-datepicker>
87
+ */
88
+ labelContentText;
79
89
  /**
80
90
  * The language/locale for the datepicker.
81
91
  * Default value: 'en' (English).
@@ -83,7 +93,7 @@ export class DatepickerComponent {
83
93
  * <mefdev-datepicker
84
94
  * [lang] = "'uk'">
85
95
  * </mefdev-datepicker>
86
- */
96
+ */
87
97
  lang = 'en';
88
98
  /**
89
99
  * The date format for displaying the selected date.
@@ -92,7 +102,7 @@ export class DatepickerComponent {
92
102
  * <mefdev-datepicker
93
103
  * [dateFormat]="'dd/MM/yyyy'">
94
104
  * </mefdev-datepicker>
95
- */
105
+ */
96
106
  dateFormat = 'EEE MMM dd yyyy';
97
107
  /**
98
108
  * The range of years available in the year dropdown.
@@ -101,7 +111,7 @@ export class DatepickerComponent {
101
111
  * <mefdev-datepicker
102
112
  * [range]="{startYear: 1900, toYear: 300}">
103
113
  * </mefdev-datepicker>
104
- */
114
+ */
105
115
  yearsRange = { startYear: 1900, toYear: 300 };
106
116
  /**
107
117
  * Whether the datepicker is disabled or not.
@@ -110,7 +120,7 @@ export class DatepickerComponent {
110
120
  * <mefdev-datepicker
111
121
  * [disabled]="false">
112
122
  * </mefdev-datepicker>
113
- */
123
+ */
114
124
  disabled = false;
115
125
  /**
116
126
  * The top offset for positioning the datepicker.
@@ -119,7 +129,7 @@ export class DatepickerComponent {
119
129
  * <mefdev-datepicker
120
130
  * [topOffset]="'20'">
121
131
  * </mefdev-datepicker>
122
- */
132
+ */
123
133
  topOffset = '20';
124
134
  /**
125
135
  * The left offset for positioning the datepicker.
@@ -128,7 +138,7 @@ export class DatepickerComponent {
128
138
  * <mefdev-datepicker
129
139
  * [leftOffset]="'10'">
130
140
  * </mefdev-datepicker>
131
- */
141
+ */
132
142
  leftOffset = '10'; //Default value
133
143
  /**
134
144
  * Event emitted when the selected date in the datepicker changes.
@@ -137,19 +147,19 @@ export class DatepickerComponent {
137
147
  * <mefdev-datepicker
138
148
  * (dateChanged)="onDateChanged($event)">
139
149
  * </mefdev-datepicker>
140
- */
150
+ */
141
151
  dateChanged = new EventEmitter();
142
152
  /**
143
153
  * Regular expression to validate user input for date in the format "dd/MM/yyyy".
144
154
  * - The day (dd) should be between 01 and 31.
145
155
  * - The month (MM) should be between 01 and 12.
146
156
  * - The year (yyyy) should be a 4-digit number.
147
- */
157
+ */
148
158
  dateRegExp = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/;
149
159
  /**
150
160
  * The string entered by the user for date input.
151
161
  * This variable stores the user's input as they type in the date field.
152
- */
162
+ */
153
163
  userInput = '';
154
164
  /**
155
165
  * Host listener for document click events to handle calendar interaction.
@@ -157,30 +167,26 @@ export class DatepickerComponent {
157
167
  * - If the click occurred within the calendar, no action is taken.
158
168
  * - If the click occurred within the input element and the component is not in editing mode,
159
169
  * it opens the calendar.
160
- * - If the click occurred outside the calendar and input, it closes the calendar.
161
170
  * @param event The MouseEvent object representing the click event.
162
- */
171
+ */
163
172
  onClick(event) {
164
173
  const targetElement = event.target;
174
+ const datepickerContainer = this.elementRef.nativeElement.querySelector('.datepicker-container');
165
175
  const calendar = this.elementRef.nativeElement.querySelector('.calendar');
166
176
  const monthDropdown = this.elementRef.nativeElement.querySelector('.monthDropdown');
167
177
  const yearDropdown = this.elementRef.nativeElement.querySelector('.yearDropdown');
168
178
  const inputElement = this.elementRef.nativeElement.querySelector('input');
169
- if (monthDropdown.contains(targetElement) && yearDropdown.contains(targetElement)) {
170
- this.toggleMonthDropdown(event);
171
- this.toggleYearDropdown(event);
172
- }
173
- if (calendar && calendar.contains(targetElement)) {
174
- return;
175
- }
176
- if (inputElement && inputElement.contains(targetElement) && !this.isEditing) {
177
- // Клік відбувся на елементі input, відкриваємо календар
178
- this.isCalendarOpen = true;
179
- }
180
- else {
181
- // Клік відбувся поза календарем та input, закриваємо календар
182
- this.isCalendarOpen = false;
183
- this.isEditing = false;
179
+ if (datepickerContainer && datepickerContainer.contains(calendar)) {
180
+ if (calendar && calendar.contains(targetElement))
181
+ return;
182
+ if (this.isMonthDropdownOpen && !calendar.contains(targetElement))
183
+ return;
184
+ if (this.isYearDropdownOpen && !calendar.contains(targetElement))
185
+ return;
186
+ if ((monthDropdown && monthDropdown.contains(targetElement)) && (yearDropdown && yearDropdown.contains(targetElement))) {
187
+ this.toggleMonthDropdown(event);
188
+ this.toggleYearDropdown(event);
189
+ }
184
190
  }
185
191
  }
186
192
  /**
@@ -188,7 +194,7 @@ export class DatepickerComponent {
188
194
  * @param datePipe A service for formatting and parsing dates.
189
195
  * @param elementRef A reference to the element on which this component is attached.
190
196
  * It is used to access DOM elements.
191
- */
197
+ */
192
198
  constructor(datePipe, elementRef) {
193
199
  this.datePipe = datePipe;
194
200
  this.elementRef = elementRef;
@@ -197,28 +203,28 @@ export class DatepickerComponent {
197
203
  /**
198
204
  * Lifecycle hook called after the component is initialized.
199
205
  * It initializes the years for the year select dropdown.
200
- */
206
+ */
201
207
  ngOnInit() {
202
208
  this.initializeYears();
203
209
  }
204
210
  /**
205
211
  * Lifecycle hook called whenever the input properties of the component change.
206
212
  * It updates the input value.
207
- */
213
+ */
208
214
  ngOnChanges() {
209
215
  this.updateInputValue();
210
216
  }
211
217
  /**
212
218
  * An array of month names based on the selected language.
213
219
  * It provides localized month names for display in the datepicker.
214
- */
220
+ */
215
221
  get months() {
216
222
  return this.getMonthList(this.lang);
217
223
  }
218
224
  /**
219
225
  * An array of weekday names based on the selected language.
220
226
  * It provides localized weekday names for display in the datepicker.
221
- */
227
+ */
222
228
  get weekdays() {
223
229
  return this.getWeekdayList(this.lang);
224
230
  }
@@ -231,16 +237,14 @@ export class DatepickerComponent {
231
237
  * // After calling initializeYears(), 'years' might contain [1900, 1901, ..., 300]
232
238
  * this.initializeYears();
233
239
  * ```
234
- */
240
+ */
235
241
  initializeYears() {
236
242
  this.years = Array.from({ length: this.yearsRange.toYear }, (_, index) => index + this.yearsRange.startYear);
237
243
  }
238
244
  /**
239
245
  * Toggle the editing mode for the date input. When enabled, the user can edit the date directly in the input field.
240
- * This method sets the 'isEditing' flag to true and stores the current formatted date for editing.
241
- */
246
+ */
242
247
  toggleEdit() {
243
- this.isEditing = !this.isEditing;
244
248
  this.editedDate = this.formatSelectedDate(); // Store the current formatted date for editing
245
249
  this.isCalendarOpen = false;
246
250
  }
@@ -253,7 +257,7 @@ export class DatepickerComponent {
253
257
  * // Get a list of month names in the default language and long format
254
258
  * const months = this.getMonthList(this.lang);
255
259
  * ```
256
- */
260
+ */
257
261
  getMonthList(locales, format = "long") {
258
262
  const year = new Date().getFullYear();
259
263
  const monthList = [...Array(12).keys()];
@@ -270,7 +274,7 @@ export class DatepickerComponent {
270
274
  * // Get a list of weekday names in the default language and short format
271
275
  * const weekdays = this.getWeekdayList();
272
276
  * ```
273
- */
277
+ */
274
278
  getWeekdayList(locales, format = "short") {
275
279
  const weekdays = [...Array(7).keys()];
276
280
  const mondayIndex = weekdays.indexOf(0);
@@ -282,22 +286,6 @@ export class DatepickerComponent {
282
286
  };
283
287
  return weekdays.map(getWeekdayName);
284
288
  }
285
- /**
286
- * Toggle the visibility of the calendar component. When called, this method changes the 'isCalendarOpen' flag
287
- * to show or hide the calendar interface.
288
- * ```
289
- * // Toggle the visibility of the calendar
290
- * this.toggleCalendar();
291
- * ```
292
- */
293
- toggleCalendar() {
294
- if (this.isEditing) {
295
- this.isCalendarOpen = false;
296
- }
297
- else {
298
- this.isCalendarOpen = !this.isCalendarOpen;
299
- }
300
- }
301
289
  /**
302
290
  * Save the edited date input by the user, provided it matches the specified date format.
303
291
  * This method checks if the entered date is in a valid format, disables the editing mode, and applies
@@ -306,25 +294,24 @@ export class DatepickerComponent {
306
294
  * // Save the edited date and update the selected date
307
295
  * this.saveEditedDate();
308
296
  * ```
309
- */
297
+ */
310
298
  saveEditedDate() {
311
299
  if (this.isDateValid(this.editedDate)) {
312
- this.isEditing = false;
313
300
  const [day, month, year] = this.editedDate.split('/');
314
301
  this.selectedDate = new Date(+year, +month - 1, +day);
315
302
  this.formatDate();
316
303
  }
317
304
  }
318
305
  /**
319
- * Handle user input in the editable input field for date editing. This method captures the input value
320
- * and stores it in the 'editedDate' variable. If the input matches the valid date format, it updates
321
- * 'selectedDateMonth' and 'selectedDateYear' accordingly.
322
- * @param event - The input event containing the user's input.
323
- * ```
324
- * // Handle user input in the editable input field
325
- * this.onDateInput(event);
326
- * ```
327
- */
306
+ * Handle user input in the editable input field for date editing. This method captures the input value
307
+ * and stores it in the 'editedDate' variable. If the input matches the valid date format, it updates
308
+ * 'selectedDateMonth' and 'selectedDateYear' accordingly.
309
+ * @param event - The input event containing the user's input.
310
+ * ```
311
+ * // Handle user input in the editable input field
312
+ * this.onDateInput(event);
313
+ * ```
314
+ */
328
315
  onDateInput(event) {
329
316
  const inputDate = event.target.value;
330
317
  if (this.isDateValid(inputDate)) {
@@ -332,7 +319,10 @@ export class DatepickerComponent {
332
319
  const parsedDate = inputDate.split('/');
333
320
  this.selectedDateMonth = +parsedDate[1] - 1;
334
321
  this.selectedDateYear = +parsedDate[2];
322
+ this.selectedDate = new Date(+parsedDate[2], +parsedDate[1] - 1, +parsedDate[0]);
323
+ this.calculateFirstDayOfCalendar();
335
324
  }
325
+ this.isUserDateValid = this.isDateValid(inputDate);
336
326
  }
337
327
  /**
338
328
  * Toggle the visibility of the month dropdown in the calendar interface.
@@ -342,19 +332,19 @@ export class DatepickerComponent {
342
332
  * // Toggle the visibility of the month dropdown
343
333
  * this.toggleMonthDropdown(event);
344
334
  * ```
345
- */
335
+ */
346
336
  toggleMonthDropdown(event) {
347
337
  this.isMonthDropdownOpen = !this.isMonthDropdownOpen;
348
338
  }
349
339
  /**
350
- * Toggle the visibility of the year dropdown in the calendar interface.
351
- * This method is used to open or close the dropdown for selecting years.
352
- * @param event - The event triggering the toggle action (e.g., a click event).
353
- * ```
354
- * // Toggle the visibility of the year dropdown
355
- * this.toggleYearDropdown(event);
356
- * ```
357
- */
340
+ * Toggle the visibility of the year dropdown in the calendar interface.
341
+ * This method is used to open or close the dropdown for selecting years.
342
+ * @param event - The event triggering the toggle action (e.g., a click event).
343
+ * ```
344
+ * // Toggle the visibility of the year dropdown
345
+ * this.toggleYearDropdown(event);
346
+ * ```
347
+ */
358
348
  toggleYearDropdown(event) {
359
349
  this.isYearDropdownOpen = !this.isYearDropdownOpen;
360
350
  }
@@ -366,10 +356,11 @@ export class DatepickerComponent {
366
356
  * // Handle the change of the selected month
367
357
  * this.onMonthChange();
368
358
  * ```
369
- */
359
+ */
370
360
  onMonthChange() {
371
361
  this.updateInputValue();
372
362
  this.selectedDate = new Date(this.selectedDateYear, this.selectedDateMonth, 1);
363
+ this.formatDate();
373
364
  this.calculateFirstDayOfCalendar();
374
365
  }
375
366
  /**
@@ -380,7 +371,7 @@ export class DatepickerComponent {
380
371
  * // Handle the change of the selected year
381
372
  * this.onYearChange();
382
373
  * ```
383
- */
374
+ */
384
375
  onYearChange() {
385
376
  this.updateInputValue();
386
377
  this.selectedDate = new Date(this.selectedDateYear, this.selectedDateMonth, 1);
@@ -392,7 +383,7 @@ export class DatepickerComponent {
392
383
  * This method sets the selected date, formats it, closes the calendar, and emits a dateChanged event.
393
384
  * It also updates the selected month and year dropdown values.
394
385
  * @param date - The date to be selected in the calendar.
395
- */
386
+ */
396
387
  selectDate(date) {
397
388
  this.selectedDate = date;
398
389
  this.formatDate();
@@ -408,7 +399,7 @@ export class DatepickerComponent {
408
399
  * // Format the selected date
409
400
  * this.formatDate();
410
401
  * ```
411
- */
402
+ */
412
403
  formatDate() {
413
404
  this.formattedDate = this.datePipe.transform(this.selectedDate, this.dateFormat) || '';
414
405
  }
@@ -420,7 +411,7 @@ export class DatepickerComponent {
420
411
  * // Format the selected date with language
421
412
  * const formatted = this.formatSelectedDate();
422
413
  * ```
423
- */
414
+ */
424
415
  formatSelectedDate() {
425
416
  return this.datePipe.transform(this.selectedDate, this.dateFormat, this.lang) || '';
426
417
  }
@@ -432,9 +423,9 @@ export class DatepickerComponent {
432
423
  * // Update the input value
433
424
  * this.updateInputValue();
434
425
  * ```
435
- */
426
+ */
436
427
  updateInputValue() {
437
- this.formattedDate = this.isEditing ? this.editedDate : this.formatSelectedDate();
428
+ this.formattedDate = this.isCalendarOpen ? this.editedDate : this.formatSelectedDate();
438
429
  }
439
430
  /**
440
431
  * Get an array of arrays representing the days of the current month.
@@ -444,7 +435,7 @@ export class DatepickerComponent {
444
435
  * // Get an array of arrays representing the days of the current month
445
436
  * const calendar = this.calendarDays;
446
437
  * ```
447
- */
438
+ */
448
439
  get calendarDays() {
449
440
  return this.calculateFirstDayOfCalendar();
450
441
  }
@@ -458,7 +449,7 @@ export class DatepickerComponent {
458
449
  * // Get the previous month's date to display in empty cells
459
450
  * const previousMonthDate = this.getPreviousMonthDate(new Date(2023, 8, 1));
460
451
  * ```
461
- */
452
+ */
462
453
  getPreviousMonthDate(date) {
463
454
  if (!date) {
464
455
  return '';
@@ -478,7 +469,7 @@ export class DatepickerComponent {
478
469
  * // Navigate to the previous month
479
470
  * this.getPreviousMonth();
480
471
  * ```
481
- */
472
+ */
482
473
  getPreviousMonth() {
483
474
  const currentMonth = this.selectedDate.getMonth();
484
475
  this.selectedDate = new Date(this.selectedDate.getFullYear(), currentMonth - 1, 1);
@@ -492,7 +483,7 @@ export class DatepickerComponent {
492
483
  * // Navigate to the next month
493
484
  * this.getNextMonth();
494
485
  * ```
495
- */
486
+ */
496
487
  getNextMonth() {
497
488
  const currentMonth = this.selectedDate.getMonth();
498
489
  this.selectedDate = new Date(this.selectedDate.getFullYear(), currentMonth + 1, 1);
@@ -504,7 +495,7 @@ export class DatepickerComponent {
504
495
  * @param year - The year for which you want to determine the number of days.
505
496
  * @param month - The month (0-based index) for which you want to determine the number of days.
506
497
  * @returns The number of days in the specified month of the given year.
507
- */
498
+ */
508
499
  daysInMonth(year, month) {
509
500
  return new Date(year, month + 1, 0).getDate();
510
501
  }
@@ -513,7 +504,7 @@ export class DatepickerComponent {
513
504
  * This method generates a matrix of day data objects representing the days in the calendar.
514
505
  * Each day data object contains the date and whether it belongs to the current month.
515
506
  * @returns A matrix of day data objects for the calendar display.
516
- */
507
+ */
517
508
  calculateFirstDayOfCalendar() {
518
509
  const year = this.selectedDate.getFullYear();
519
510
  const month = this.selectedDate.getMonth();
@@ -545,21 +536,33 @@ export class DatepickerComponent {
545
536
  * // Check if a date is selected
546
537
  * const isSelected = this.isDateSelected(someDate);
547
538
  * ```
548
- */
539
+ */
549
540
  isDateSelected(date) {
550
541
  return date.toDateString() === this.selectedDate.toDateString();
551
542
  }
552
543
  /**
553
544
  * Check if a date string is valid based on the specified date format.
545
+ * It also checks whether the specified number, month is correct and whether the specified one exists among calendar years
554
546
  * @param inputDate - The date string to validate.
555
547
  * @returns `true` if the input date string is valid, otherwise `false`.
556
548
  * ```
557
549
  * // Check if a date string is valid
558
550
  * const isValidDate = this.isDateValid('05/25/2023');
559
551
  * ```
560
- */
552
+ */
561
553
  isDateValid(inputDate) {
562
- return this.dateRegExp.test(inputDate);
554
+ if (!this.dateRegExp.test(inputDate)) {
555
+ return false;
556
+ }
557
+ const parts = inputDate.split('/');
558
+ const day = parseInt(parts[0], 10);
559
+ const month = parseInt(parts[1], 10);
560
+ const year = parseInt(parts[2], 10);
561
+ if (year > this.years[this.years.length - 1] || year < this.years[0]) {
562
+ return false;
563
+ }
564
+ const daysInMonth = new Date(year, month, 0).getDate();
565
+ return day <= daysInMonth;
563
566
  }
564
567
  /**
565
568
  * Check if a given date is today's date.
@@ -569,18 +572,20 @@ export class DatepickerComponent {
569
572
  * // Check if a date is today's date
570
573
  * const isToday = this.isDateToday(someDate);
571
574
  * ```
572
- */
575
+ */
573
576
  isDateToday(date) {
574
577
  const today = new Date();
575
578
  return date.toDateString() === today.toDateString();
576
579
  }
577
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: DatepickerComponent, deps: [{ token: i1.DatePipe }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
578
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.6", type: DatepickerComponent, selector: "mefdev-datepicker", inputs: { lang: "lang", dateFormat: "dateFormat", yearsRange: ["range", "yearsRange"], disabled: "disabled", topOffset: "topOffset", leftOffset: "leftOffset" }, outputs: { dateChanged: "dateChanged" }, host: { listeners: { "document:click": "onClick($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"datepicker-container\"\r\n[class.disabled]=\"disabled\"\r\n>\r\n\r\n <!-- Input, save & edit buttons -->\r\n <div class=\"input-container\">\r\n\r\n <div *ngIf=\"!isEditing\">\r\n\r\n <input\r\n type=\"text\"\r\n (click)=\"toggleCalendar()\"\r\n [value]=\"formattedDate\"\r\n [readOnly]=\"true\"\r\n [disabled]=\"isEditing\"\r\n >\r\n </div>\r\n <!-- Edit -->\r\n <i class=\"fa fa-pencil-square-o edit-button\" aria-hidden=\"true\" (click)=\"toggleEdit()\"></i> \r\n\r\n <div *ngIf=\"isEditing\">\r\n <input\r\n type=\"text\"\r\n [value]=\"editedDate\"\r\n (input)=\"onDateInput($event)\"\r\n class=\"border-3\"\r\n (click)=\"toggleCalendar()\"\r\n >\r\n <i class=\"fa fa-floppy-o edit-button\" (click)=\"saveEditedDate()\" aria-hidden=\"true\"></i>\r\n </div> \r\n </div>\r\n\r\n<!-- Calendar(Dropdowns, dates) -->\r\n <div *ngIf=\"isCalendarOpen\" class=\"calendar\" #calendarContainer \r\n [style.top]=\"topOffset\"\r\n [style.left]=\"leftOffset\">\r\n <div class=\"calendar-header\">\r\n <div class=\"monthButtonContainer\">\r\n <!-- Month dropdown -->\r\n <ng-container *ngIf=\"isMonthDropdownOpen; else monthLabel\">\r\n <mefdev-select \r\n class=\"monthDropdown\"\r\n [(ngModel)]=\"selectedDateMonth\" \r\n (ngModelChange)=\"onMonthChange()\"\r\n [PlaceHolder]=\"'month'\"\r\n >\r\n <mefdev-option \r\n *ngFor=\"let month of months; let i = index\" \r\n [Value]=\"i\"\r\n [Label] = \"month\" \r\n \r\n >{{ month }}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #monthLabel>\r\n <span (click)=\"toggleMonthDropdown($event)\"></span>\r\n </ng-template>\r\n\r\n <!-- Year dropdown -->\r\n <ng-container *ngIf=\"isYearDropdownOpen; else yearLabel\">\r\n <mefdev-select \r\n class=\"yearDropdown\" \r\n [(ngModel)]=\"selectedDateYear\" \r\n (ngModelChange)=\"onYearChange()\"\r\n [PlaceHolder]=\"'year'\"\r\n >\r\n <mefdev-option \r\n *ngFor=\"let year of years\" \r\n [Label] = \"year\" \r\n [Value]=\"year\" \r\n >{{year}}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #yearLabel>\r\n <span (click)=\"toggleYearDropdown($event)\">{{ selectedDateYear }}</span>\r\n </ng-template>\r\n </div>\r\n <!-- Calendar exit button -->\r\n <div>\r\n <i class=\"fa fa-times toggleCalendarButton\" (click)=\"toggleCalendar()\" aria-hidden=\"true\"></i>\r\n </div>\r\n </div>\r\n \r\n <div class=\"calendar-body\">\r\n <table>\r\n <tr>\r\n <th class=\"align-items-center\" *ngFor=\"let weekday of weekdays\">{{ weekday }}</th>\r\n </tr>\r\n <tr *ngFor=\"let week of calendarDays\">\r\n <td *ngFor=\"let dayData of week\" \r\n (click)=\"selectDate(dayData.date)\"\r\n [ngClass]=\"{ 'selected': isDateSelected(dayData.date), 'prev-month': !dayData.isCurrentMonth }\">\r\n\r\n <span class=\"date\" \r\n [class.prev-month]=\"!dayData.isCurrentMonth\"\r\n >\r\n {{ dayData.date.getDate() }}\r\n </span>\r\n </td>\r\n </tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n", styles: [".color-Dark-Gray-1{color:#373737!important}.color-Dark-Gray-2{color:#4d4d4d!important}.color-Red{color:#cf0106!important}.color-Green{color:#28b446!important}.color-Light-Gray-1{color:#929292!important}.color-Light-Gray-2{color:#eaeaea!important}.color-Light-Gray-3{color:#f3f3f3!important}.color-White{color:#fff!important}.color-Link{color:#0185cf!important}.b-color-Dark-Gray-1{background-color:#373737!important}.b-color-Dark-Gray-2{background-color:#4d4d4d!important}.b-color-Red{background-color:#cf0106!important}.b-color-Green{background-color:#28b446!important}.b-color-Light-Gray-1{background-color:#929292!important}.b-color-Light-Gray-2{background-color:#eaeaea!important}.b-color-Light-Gray-3{background-color:#f3f3f3!important}.b-color-White{background-color:#fff!important}.b-color-Link{background-color:#0185cf!important}.datepicker-container{position:relative;display:inline-block}.datepicker-container.disabled{pointer-events:none;opacity:.8}.input-container{position:relative;display:inline-block}.input-container input[type=text]{cursor:pointer;padding:5px;border:1px solid #929292;border-radius:4px}.input-container input[type=text]:hover{border:1px solid #4D4D4D}.input-container .edit-button{position:absolute;top:0;right:0;height:100%;margin:0;padding:5px 10px;background-color:#eaeaea;border:1px solid #929292;border-left:none;border-radius:0 4px 4px 0;cursor:pointer;display:flex;justify-content:center;align-items:center}.calendar{position:absolute;top:35px;left:10%;border:1px solid #929292;background-color:#eaeaea;border-radius:4px;z-index:1}.calendar .calendar-header{background-color:#fff;text-align:center;justify-content:space-between;display:flex;padding:5px 0}.calendar .calendar-header i.fa{display:flex;justify-content:center;align-items:center;width:30px;height:30px;font-size:20px;border-radius:50%;cursor:pointer;background-color:transparent;border:none;color:#cf0106}.calendar .calendar-header .monthButtonContainer{padding-left:10px;height:45px;min-width:140px;display:flex;align-items:center}.calendar .calendar-header .monthDropdown,.calendar .calendar-header .yearDropdown{height:45px;width:105px;cursor:pointer;display:inline-block;padding:6px 5px;border:1px solid #EAEAEA;border-radius:4px;background-color:#fff;color:#4d4d4d}.calendar .calendar-header .monthDropdown{margin:0 8px 0 0;width:130px}.calendar .calendar-header .monthDropdown:hover,.calendar .calendar-header .yearDropdown:hover{border-color:#f3f3f3}.calendar .calendar-body{padding:5px;width:260px}.calendar .calendar-body td{padding:10px;position:relative}.calendar .calendar-body td.selected{position:relative;color:#fff}.calendar .calendar-body td.selected:before{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);border-radius:20%;background-color:#cf0106;z-index:-1;width:30px;height:30px;color:#fff;border:1px solid #373737}.calendar .calendar-body td:hover{color:#fff;font-weight:700;background-color:#929292;border-radius:20%;cursor:pointer}.calendar .calendar-body .date{display:flex;justify-content:center}.calendar .calendar-body .date.prev-month{color:#f3f3f3}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MefDevOptionComponent, selector: "mefdev-option", inputs: ["Value", "Label", "Disabled"] }, { kind: "component", type: i4.MefDevSelectComponent, selector: "mefdev-select", inputs: ["Filter", "MaxMultiple", "FirstDefault", "AllowClear", "KeepUnListOptions", "Mode", "Multiple", "PlaceHolder", "NotFoundContent", "Size", "ShowSearch", "Tags", "Disabled", "Open"], outputs: ["SearchChange", "change", "OpenChange", "ScrollToBottom"] }] });
580
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatepickerComponent, deps: [{ token: i1.DatePipe }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
581
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DatepickerComponent, selector: "mefdev-datepicker", inputs: { labelContentText: "labelContentText", lang: "lang", dateFormat: "dateFormat", yearsRange: ["range", "yearsRange"], disabled: "disabled", topOffset: "topOffset", leftOffset: "leftOffset" }, outputs: { dateChanged: "dateChanged" }, host: { listeners: { "document:click": "onClick($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"datepicker-container\" [class.disabled]=\"disabled\">\r\n\r\n <!-- Input, save & edit buttons -->\r\n <div class=\"input-container form-group\">\r\n <label *ngIf=\"labelContentText\" class=\"form-label\"> {{ labelContentText }} </label>\r\n <input\r\n [ngClass]=\"{ 'calendarNotOpened': !isCalendarOpen }\"\r\n [ngStyle]=\"{ 'border-color': isUserDateValid ? '' : 'red' }\"\r\n type=\"text\"\r\n class=\"form-control\"\r\n (input)=\"onDateInput($event)\"\r\n (click)=\"isCalendarOpen = true\"\r\n [value]=\"formattedDate\"\r\n [readOnly]=\"!isCalendarOpen\"\r\n >\r\n </div>\r\n\r\n <!-- Calendar(Dropdowns, dates) -->\r\n <div *ngIf=\"isCalendarOpen\" class=\"calendar\" #calendarContainer\r\n [style.top]=\"topOffset\"\r\n [style.left]=\"leftOffset\">\r\n <div class=\"calendar-header\">\r\n <div class=\"monthButtonContainer\">\r\n <!-- Month dropdown -->\r\n <ng-container *ngIf=\"isMonthDropdownOpen; else monthLabel\">\r\n <mefdev-select\r\n class=\"monthDropdown\"\r\n [(ngModel)]=\"selectedDateMonth\"\r\n (ngModelChange)=\"onMonthChange()\"\r\n [PlaceHolder]=\"'month'\"\r\n >\r\n <mefdev-option\r\n *ngFor=\"let month of months; let i = index\"\r\n [Value]=\"i\"\r\n [Label]=\"month\"\r\n style=\"z-index: 1\"\r\n >{{ month }}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #monthLabel>\r\n <span (click)=\"toggleMonthDropdown($event)\"></span>\r\n </ng-template>\r\n\r\n <!-- Year dropdown -->\r\n <ng-container *ngIf=\"isYearDropdownOpen; else yearLabel\">\r\n <mefdev-select\r\n class=\"yearDropdown\"\r\n [(ngModel)]=\"selectedDateYear\"\r\n (ngModelChange)=\"onYearChange()\"\r\n [PlaceHolder]=\"'year'\"\r\n >\r\n <mefdev-option\r\n *ngFor=\"let year of years\"\r\n [Label]=\"year\"\r\n [Value]=\"year\"\r\n >{{year}}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #yearLabel>\r\n <span (click)=\"toggleYearDropdown($event)\">{{ selectedDateYear }}</span>\r\n </ng-template>\r\n </div>\r\n <!-- Calendar exit button -->\r\n <div>\r\n <i class=\"fa fa-times toggleCalendarButton\" (click)=\"isCalendarOpen = false\" aria-hidden=\"true\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"calendar-body\">\r\n <table>\r\n <tr>\r\n <th class=\"text-center\" *ngFor=\"let weekday of weekdays\">{{ weekday }}</th>\r\n </tr>\r\n <tr *ngFor=\"let week of calendarDays\">\r\n <td *ngFor=\"let dayData of week\"\r\n (click)=\"selectDate(dayData.date)\"\r\n [ngClass]=\"{ 'selected': isDateSelected(dayData.date), 'prev-month': !dayData.isCurrentMonth }\">\r\n\r\n <span class=\"date\" [class.prev-month]=\"!dayData.isCurrentMonth\">\r\n {{ dayData.date.getDate() }}\r\n </span>\r\n </td>\r\n </tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".color-black{color:#000!important}.color-Dark-Gray-1{color:#373737!important}.color-Dark-Gray-2{color:#4d4d4d!important}.color-Red{color:#cf0106!important}.color-Green{color:#28b446!important}.color-Light-Gray-1{color:#929292!important}.color-Light-Gray-2{color:#eaeaea!important}.color-Light-Gray-3{color:#f3f3f3!important}.color-White{color:#fff!important}.color-Link{color:#0185cf!important}.color-dark-link{color:#50c0ff!important}.b-color-black{background-color:#000!important}.b-color-Dark-Gray-1{background-color:#373737!important}.b-color-Dark-Gray-2{background-color:#4d4d4d!important}.b-color-Red{background-color:#cf0106!important}.b-color-Green{background-color:#28b446!important}.b-color-Light-Gray-1{background-color:#929292!important}.b-color-Light-Gray-2{background-color:#eaeaea!important}.b-color-Light-Gray-3{background-color:#f3f3f3!important}.b-color-White{background-color:#fff!important}.b-color-Link{background-color:#0185cf!important}.b-color-dark-link{background-color:#50c0ff!important}.datepicker-container{position:relative;display:inline-block}.datepicker-container.disabled{pointer-events:none;opacity:.8}.input-container{position:relative;display:inline-block}.input-container input[type=text]{padding:5px 5px 5px 15px;border:1px solid #929292}.input-container .calendarNotOpened{cursor:pointer}.calendar{position:absolute;border:1px solid #929292;background-color:#eaeaea;z-index:1}.calendar .calendar-header{background-color:#fff;text-align:center;justify-content:space-between;display:flex;padding:5px 0}.calendar .calendar-header i.fa{display:flex;justify-content:center;align-items:center;width:30px;height:30px;font-size:20px;border-radius:50%;cursor:pointer;background-color:transparent;border:none;color:#cf0106}.calendar .calendar-header .monthButtonContainer{padding-left:10px;height:45px;min-width:140px;display:flex;align-items:center}.calendar .calendar-header .monthDropdown,.calendar .calendar-header .yearDropdown{height:45px;width:105px;cursor:pointer;display:inline-block;padding:6px 5px;border:1px solid #EAEAEA;border-radius:4px;background-color:#fff;color:#4d4d4d}.calendar .calendar-header .monthDropdown{margin:0 8px 0 0;width:130px}.calendar .calendar-header .monthDropdown:hover,.calendar .calendar-header .yearDropdown:hover{border-color:#f3f3f3}.calendar .calendar-body{padding:5px}.calendar .calendar-body table{width:100%}.calendar .calendar-body td{padding:10px;position:relative}.calendar .calendar-body td.selected{position:relative;color:#fff}.calendar .calendar-body td.selected:before{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);border-radius:20%;background-color:#cf0106;z-index:-1;width:30px;height:30px;color:#fff;border:1px solid #373737}.calendar .calendar-body td:hover{color:#fff;font-weight:700;background-color:#929292;border-radius:20%;cursor:pointer}.calendar .calendar-body .date{display:flex;justify-content:center}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MefDevOptionComponent, selector: "mefdev-option", inputs: ["Value", "Label", "Disabled"] }, { kind: "component", type: i4.MefDevSelectComponent, selector: "mefdev-select", inputs: ["Filter", "MaxMultiple", "FirstDefault", "AllowClear", "KeepUnListOptions", "Mode", "Multiple", "PlaceHolder", "NotFoundContent", "Size", "ShowSearch", "Tags", "Disabled", "Open"], outputs: ["SearchChange", "change", "OpenChange", "ScrollToBottom"] }] });
579
582
  }
580
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImport: i0, type: DatepickerComponent, decorators: [{
583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DatepickerComponent, decorators: [{
581
584
  type: Component,
582
- args: [{ selector: 'mefdev-datepicker', template: "<div class=\"datepicker-container\"\r\n[class.disabled]=\"disabled\"\r\n>\r\n\r\n <!-- Input, save & edit buttons -->\r\n <div class=\"input-container\">\r\n\r\n <div *ngIf=\"!isEditing\">\r\n\r\n <input\r\n type=\"text\"\r\n (click)=\"toggleCalendar()\"\r\n [value]=\"formattedDate\"\r\n [readOnly]=\"true\"\r\n [disabled]=\"isEditing\"\r\n >\r\n </div>\r\n <!-- Edit -->\r\n <i class=\"fa fa-pencil-square-o edit-button\" aria-hidden=\"true\" (click)=\"toggleEdit()\"></i> \r\n\r\n <div *ngIf=\"isEditing\">\r\n <input\r\n type=\"text\"\r\n [value]=\"editedDate\"\r\n (input)=\"onDateInput($event)\"\r\n class=\"border-3\"\r\n (click)=\"toggleCalendar()\"\r\n >\r\n <i class=\"fa fa-floppy-o edit-button\" (click)=\"saveEditedDate()\" aria-hidden=\"true\"></i>\r\n </div> \r\n </div>\r\n\r\n<!-- Calendar(Dropdowns, dates) -->\r\n <div *ngIf=\"isCalendarOpen\" class=\"calendar\" #calendarContainer \r\n [style.top]=\"topOffset\"\r\n [style.left]=\"leftOffset\">\r\n <div class=\"calendar-header\">\r\n <div class=\"monthButtonContainer\">\r\n <!-- Month dropdown -->\r\n <ng-container *ngIf=\"isMonthDropdownOpen; else monthLabel\">\r\n <mefdev-select \r\n class=\"monthDropdown\"\r\n [(ngModel)]=\"selectedDateMonth\" \r\n (ngModelChange)=\"onMonthChange()\"\r\n [PlaceHolder]=\"'month'\"\r\n >\r\n <mefdev-option \r\n *ngFor=\"let month of months; let i = index\" \r\n [Value]=\"i\"\r\n [Label] = \"month\" \r\n \r\n >{{ month }}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #monthLabel>\r\n <span (click)=\"toggleMonthDropdown($event)\"></span>\r\n </ng-template>\r\n\r\n <!-- Year dropdown -->\r\n <ng-container *ngIf=\"isYearDropdownOpen; else yearLabel\">\r\n <mefdev-select \r\n class=\"yearDropdown\" \r\n [(ngModel)]=\"selectedDateYear\" \r\n (ngModelChange)=\"onYearChange()\"\r\n [PlaceHolder]=\"'year'\"\r\n >\r\n <mefdev-option \r\n *ngFor=\"let year of years\" \r\n [Label] = \"year\" \r\n [Value]=\"year\" \r\n >{{year}}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #yearLabel>\r\n <span (click)=\"toggleYearDropdown($event)\">{{ selectedDateYear }}</span>\r\n </ng-template>\r\n </div>\r\n <!-- Calendar exit button -->\r\n <div>\r\n <i class=\"fa fa-times toggleCalendarButton\" (click)=\"toggleCalendar()\" aria-hidden=\"true\"></i>\r\n </div>\r\n </div>\r\n \r\n <div class=\"calendar-body\">\r\n <table>\r\n <tr>\r\n <th class=\"align-items-center\" *ngFor=\"let weekday of weekdays\">{{ weekday }}</th>\r\n </tr>\r\n <tr *ngFor=\"let week of calendarDays\">\r\n <td *ngFor=\"let dayData of week\" \r\n (click)=\"selectDate(dayData.date)\"\r\n [ngClass]=\"{ 'selected': isDateSelected(dayData.date), 'prev-month': !dayData.isCurrentMonth }\">\r\n\r\n <span class=\"date\" \r\n [class.prev-month]=\"!dayData.isCurrentMonth\"\r\n >\r\n {{ dayData.date.getDate() }}\r\n </span>\r\n </td>\r\n </tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n", styles: [".color-Dark-Gray-1{color:#373737!important}.color-Dark-Gray-2{color:#4d4d4d!important}.color-Red{color:#cf0106!important}.color-Green{color:#28b446!important}.color-Light-Gray-1{color:#929292!important}.color-Light-Gray-2{color:#eaeaea!important}.color-Light-Gray-3{color:#f3f3f3!important}.color-White{color:#fff!important}.color-Link{color:#0185cf!important}.b-color-Dark-Gray-1{background-color:#373737!important}.b-color-Dark-Gray-2{background-color:#4d4d4d!important}.b-color-Red{background-color:#cf0106!important}.b-color-Green{background-color:#28b446!important}.b-color-Light-Gray-1{background-color:#929292!important}.b-color-Light-Gray-2{background-color:#eaeaea!important}.b-color-Light-Gray-3{background-color:#f3f3f3!important}.b-color-White{background-color:#fff!important}.b-color-Link{background-color:#0185cf!important}.datepicker-container{position:relative;display:inline-block}.datepicker-container.disabled{pointer-events:none;opacity:.8}.input-container{position:relative;display:inline-block}.input-container input[type=text]{cursor:pointer;padding:5px;border:1px solid #929292;border-radius:4px}.input-container input[type=text]:hover{border:1px solid #4D4D4D}.input-container .edit-button{position:absolute;top:0;right:0;height:100%;margin:0;padding:5px 10px;background-color:#eaeaea;border:1px solid #929292;border-left:none;border-radius:0 4px 4px 0;cursor:pointer;display:flex;justify-content:center;align-items:center}.calendar{position:absolute;top:35px;left:10%;border:1px solid #929292;background-color:#eaeaea;border-radius:4px;z-index:1}.calendar .calendar-header{background-color:#fff;text-align:center;justify-content:space-between;display:flex;padding:5px 0}.calendar .calendar-header i.fa{display:flex;justify-content:center;align-items:center;width:30px;height:30px;font-size:20px;border-radius:50%;cursor:pointer;background-color:transparent;border:none;color:#cf0106}.calendar .calendar-header .monthButtonContainer{padding-left:10px;height:45px;min-width:140px;display:flex;align-items:center}.calendar .calendar-header .monthDropdown,.calendar .calendar-header .yearDropdown{height:45px;width:105px;cursor:pointer;display:inline-block;padding:6px 5px;border:1px solid #EAEAEA;border-radius:4px;background-color:#fff;color:#4d4d4d}.calendar .calendar-header .monthDropdown{margin:0 8px 0 0;width:130px}.calendar .calendar-header .monthDropdown:hover,.calendar .calendar-header .yearDropdown:hover{border-color:#f3f3f3}.calendar .calendar-body{padding:5px;width:260px}.calendar .calendar-body td{padding:10px;position:relative}.calendar .calendar-body td.selected{position:relative;color:#fff}.calendar .calendar-body td.selected:before{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);border-radius:20%;background-color:#cf0106;z-index:-1;width:30px;height:30px;color:#fff;border:1px solid #373737}.calendar .calendar-body td:hover{color:#fff;font-weight:700;background-color:#929292;border-radius:20%;cursor:pointer}.calendar .calendar-body .date{display:flex;justify-content:center}.calendar .calendar-body .date.prev-month{color:#f3f3f3}\n"] }]
583
- }], ctorParameters: function () { return [{ type: i1.DatePipe }, { type: i0.ElementRef }]; }, propDecorators: { lang: [{
585
+ args: [{ selector: 'mefdev-datepicker', template: "<div class=\"datepicker-container\" [class.disabled]=\"disabled\">\r\n\r\n <!-- Input, save & edit buttons -->\r\n <div class=\"input-container form-group\">\r\n <label *ngIf=\"labelContentText\" class=\"form-label\"> {{ labelContentText }} </label>\r\n <input\r\n [ngClass]=\"{ 'calendarNotOpened': !isCalendarOpen }\"\r\n [ngStyle]=\"{ 'border-color': isUserDateValid ? '' : 'red' }\"\r\n type=\"text\"\r\n class=\"form-control\"\r\n (input)=\"onDateInput($event)\"\r\n (click)=\"isCalendarOpen = true\"\r\n [value]=\"formattedDate\"\r\n [readOnly]=\"!isCalendarOpen\"\r\n >\r\n </div>\r\n\r\n <!-- Calendar(Dropdowns, dates) -->\r\n <div *ngIf=\"isCalendarOpen\" class=\"calendar\" #calendarContainer\r\n [style.top]=\"topOffset\"\r\n [style.left]=\"leftOffset\">\r\n <div class=\"calendar-header\">\r\n <div class=\"monthButtonContainer\">\r\n <!-- Month dropdown -->\r\n <ng-container *ngIf=\"isMonthDropdownOpen; else monthLabel\">\r\n <mefdev-select\r\n class=\"monthDropdown\"\r\n [(ngModel)]=\"selectedDateMonth\"\r\n (ngModelChange)=\"onMonthChange()\"\r\n [PlaceHolder]=\"'month'\"\r\n >\r\n <mefdev-option\r\n *ngFor=\"let month of months; let i = index\"\r\n [Value]=\"i\"\r\n [Label]=\"month\"\r\n style=\"z-index: 1\"\r\n >{{ month }}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #monthLabel>\r\n <span (click)=\"toggleMonthDropdown($event)\"></span>\r\n </ng-template>\r\n\r\n <!-- Year dropdown -->\r\n <ng-container *ngIf=\"isYearDropdownOpen; else yearLabel\">\r\n <mefdev-select\r\n class=\"yearDropdown\"\r\n [(ngModel)]=\"selectedDateYear\"\r\n (ngModelChange)=\"onYearChange()\"\r\n [PlaceHolder]=\"'year'\"\r\n >\r\n <mefdev-option\r\n *ngFor=\"let year of years\"\r\n [Label]=\"year\"\r\n [Value]=\"year\"\r\n >{{year}}</mefdev-option>\r\n </mefdev-select>\r\n </ng-container>\r\n <ng-template #yearLabel>\r\n <span (click)=\"toggleYearDropdown($event)\">{{ selectedDateYear }}</span>\r\n </ng-template>\r\n </div>\r\n <!-- Calendar exit button -->\r\n <div>\r\n <i class=\"fa fa-times toggleCalendarButton\" (click)=\"isCalendarOpen = false\" aria-hidden=\"true\"></i>\r\n </div>\r\n </div>\r\n\r\n <div class=\"calendar-body\">\r\n <table>\r\n <tr>\r\n <th class=\"text-center\" *ngFor=\"let weekday of weekdays\">{{ weekday }}</th>\r\n </tr>\r\n <tr *ngFor=\"let week of calendarDays\">\r\n <td *ngFor=\"let dayData of week\"\r\n (click)=\"selectDate(dayData.date)\"\r\n [ngClass]=\"{ 'selected': isDateSelected(dayData.date), 'prev-month': !dayData.isCurrentMonth }\">\r\n\r\n <span class=\"date\" [class.prev-month]=\"!dayData.isCurrentMonth\">\r\n {{ dayData.date.getDate() }}\r\n </span>\r\n </td>\r\n </tr>\r\n </table>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".color-black{color:#000!important}.color-Dark-Gray-1{color:#373737!important}.color-Dark-Gray-2{color:#4d4d4d!important}.color-Red{color:#cf0106!important}.color-Green{color:#28b446!important}.color-Light-Gray-1{color:#929292!important}.color-Light-Gray-2{color:#eaeaea!important}.color-Light-Gray-3{color:#f3f3f3!important}.color-White{color:#fff!important}.color-Link{color:#0185cf!important}.color-dark-link{color:#50c0ff!important}.b-color-black{background-color:#000!important}.b-color-Dark-Gray-1{background-color:#373737!important}.b-color-Dark-Gray-2{background-color:#4d4d4d!important}.b-color-Red{background-color:#cf0106!important}.b-color-Green{background-color:#28b446!important}.b-color-Light-Gray-1{background-color:#929292!important}.b-color-Light-Gray-2{background-color:#eaeaea!important}.b-color-Light-Gray-3{background-color:#f3f3f3!important}.b-color-White{background-color:#fff!important}.b-color-Link{background-color:#0185cf!important}.b-color-dark-link{background-color:#50c0ff!important}.datepicker-container{position:relative;display:inline-block}.datepicker-container.disabled{pointer-events:none;opacity:.8}.input-container{position:relative;display:inline-block}.input-container input[type=text]{padding:5px 5px 5px 15px;border:1px solid #929292}.input-container .calendarNotOpened{cursor:pointer}.calendar{position:absolute;border:1px solid #929292;background-color:#eaeaea;z-index:1}.calendar .calendar-header{background-color:#fff;text-align:center;justify-content:space-between;display:flex;padding:5px 0}.calendar .calendar-header i.fa{display:flex;justify-content:center;align-items:center;width:30px;height:30px;font-size:20px;border-radius:50%;cursor:pointer;background-color:transparent;border:none;color:#cf0106}.calendar .calendar-header .monthButtonContainer{padding-left:10px;height:45px;min-width:140px;display:flex;align-items:center}.calendar .calendar-header .monthDropdown,.calendar .calendar-header .yearDropdown{height:45px;width:105px;cursor:pointer;display:inline-block;padding:6px 5px;border:1px solid #EAEAEA;border-radius:4px;background-color:#fff;color:#4d4d4d}.calendar .calendar-header .monthDropdown{margin:0 8px 0 0;width:130px}.calendar .calendar-header .monthDropdown:hover,.calendar .calendar-header .yearDropdown:hover{border-color:#f3f3f3}.calendar .calendar-body{padding:5px}.calendar .calendar-body table{width:100%}.calendar .calendar-body td{padding:10px;position:relative}.calendar .calendar-body td.selected{position:relative;color:#fff}.calendar .calendar-body td.selected:before{content:\"\";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);border-radius:20%;background-color:#cf0106;z-index:-1;width:30px;height:30px;color:#fff;border:1px solid #373737}.calendar .calendar-body td:hover{color:#fff;font-weight:700;background-color:#929292;border-radius:20%;cursor:pointer}.calendar .calendar-body .date{display:flex;justify-content:center}\n"] }]
586
+ }], ctorParameters: function () { return [{ type: i1.DatePipe }, { type: i0.ElementRef }]; }, propDecorators: { labelContentText: [{
587
+ type: Input
588
+ }], lang: [{
584
589
  type: Input
585
590
  }], dateFormat: [{
586
591
  type: Input
@@ -599,4 +604,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.6", ngImpor
599
604
  type: HostListener,
600
605
  args: ['document:click', ['$event']]
601
606
  }] } });
602
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS1raXQtbGliL3NyYy9saWIvbWFya3VwLWtpdC91dGlscy9kYXRlcGlja2VyL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS1raXQtbGliL3NyYy9saWIvbWFya3VwLWtpdC91dGlscy9kYXRlcGlja2VyL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUF5QixZQUFZLEVBQWEsS0FBSyxFQUFxQixNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7Ozs7QUFJMUk7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQWtCRTtBQVFGLE1BQU0sT0FBTyxtQkFBbUI7SUEwTFY7SUFBNEI7SUF4TGxEOzs7TUFHRTtJQUNGLGNBQWMsR0FBWSxLQUFLLENBQUM7SUFFaEM7OztNQUdFO0lBQ0YsU0FBUyxHQUFZLEtBQUssQ0FBQztJQUUzQjs7O01BR0U7SUFDRixZQUFZLEdBQVMsSUFBSSxJQUFJLEVBQUUsQ0FBQztJQUUvQjs7O0tBR0M7SUFDRixhQUFhLENBQU87SUFFbkI7OztLQUdDO0lBQ0YsVUFBVSxHQUFXLEVBQUUsQ0FBQztJQUV4Qjs7O01BR0U7SUFDRixtQkFBbUIsR0FBWSxJQUFJLENBQUM7SUFFcEM7OztNQUdFO0lBQ0Ysa0JBQWtCLEdBQVksSUFBSSxDQUFDO0lBRW5DOzs7TUFHRTtJQUNGLGlCQUFpQixHQUFXLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7SUFFekQ7OztNQUdFO0lBQ0YsZ0JBQWdCLEdBQVcsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUUxRDs7O0tBR0M7SUFD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QUFJO3NCQUFaLEtBQUs7Z0JBVUcsVUFBVTtzQkFBbEIsS0FBSztnQkFVVSxVQUFVO3NCQUF6QixLQUFLO3VCQUFDLE9BQU87Z0JBVUwsUUFBUTtzQkFBaEIsS0FBSztnQkFVRyxTQUFTO3NCQUFqQixLQUFLO2dCQVVHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBVUksV0FBVztzQkFBcEIsTUFBTTtnQkEwQkwsT0FBTztzQkFETixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciwgT25EZXN0cm95LCBJbnB1dCwgT25DaGFuZ2VzLCBPbkluaXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERhdGVQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcblxyXG4vKipcclxuICAqIERhdGVwaWNrZXIgQ29tcG9uZW50IGZvciBzZWxlY3RpbmcgZGF0ZXMuXHJcbiAgKlxyXG4gICogVGhpcyBjb21wb25lbnQgYWxsb3dzIHVzZXJzIHRvIHBpY2sgYSBkYXRlIGZyb20gYSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAgKiBJdCBzdXBwb3J0cyB2YXJpb3VzIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyBzdWNoIGFzIGxhbmd1YWdlLCBkYXRlIGZvcm1hdCwgYW5kIGRhdGUgcmFuZ2UuXHJcbiAgKlxyXG4gICogQGV4YW1wbGVcclxuICAqIDxtZWZkZXYtZGF0ZXBpY2tlclxyXG4gICogICBbbGFuZ109XCIndWsnXCJcclxuICAqICAgW2RhdGVGb3JtYXRdPVwiJ2RkL01NL3l5eXknXCJcclxuICAqICAgW3JhbmdlXT1cIntzdGFydFllYXI6IDE5MDAsIHRvWWVhcjogMzAwfVwiXHJcbiAgKiAgIFtkaXNhYmxlZF09XCJmYWxzZVwiXHJcbiAgKiAgIChkYXRlQ2hhbmdlZCk9XCJvbkRhdGVDaGFuZ2VkKCRldmVudClcIlxyXG4gICogICBbdG9wT2Zmc2V0XT1cIicyMCdcIlxyXG4gICogICBbbGVmdE9mZnNldF09XCInMTAnXCI+XHJcbiAgKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4gICpcclxuICAqIDxleGFtcGxlLXVybD5odHRwczovL21lZi5kZXYvdWlfa2l0X2RlbW8vdmlldy91dGlscy9kYXRlcGlja2VyPC9leGFtcGxlLXVybD5cclxuKi9cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbWVmZGV2LWRhdGVwaWNrZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlcGlja2VyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9kYXRlcGlja2VyLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBEYXRlcGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgIE9uQ2hhbmdlcywgT25Jbml0IHtcclxuXHJcbi8qKlxyXG4gKiBGbGFnIHRvIGRldGVybWluZSBpZiB0aGUgY2FsZW5kYXIgaXMgb3BlbiBvciBjbG9zZWQuXHJcbiAqIERlZmF1bHQgdmFsdWU6IGZhbHNlIChjbG9zZWQpLlxyXG4qL1xyXG5pc0NhbGVuZGFyT3BlbjogYm9vbGVhbiA9IGZhbHNlOyBcclxuXHJcbi8qKlxyXG4gKiBGbGFnIHRvIGRldGVybWluZSBpZiB0aGUgY29tcG9uZW50IGlzIGluIGVkaXRpbmcgbW9kZS5cclxuICogRGVmYXVsdCB2YWx1ZTogZmFsc2UgKG5vdCBpbiBlZGl0aW5nIG1vZGUpLlxyXG4qL1xyXG5pc0VkaXRpbmc6IGJvb2xlYW4gPSBmYWxzZTsgIFxyXG5cclxuLyoqXHJcbiAqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZGF0ZS5cclxuICogRGVmYXVsdCB2YWx1ZTogVG9kYXkncyBkYXRlLlxyXG4qL1xyXG5zZWxlY3RlZERhdGU6IERhdGUgPSBuZXcgRGF0ZSgpOyBcclxuXHJcbiAvKipcclxuICogVGhlIGZvcm1hdHRlZCBkYXRlIGZvciBkaXNwbGF5IGluIHRoZSBpbnB1dC5cclxuICogRGVmYXVsdCB2YWx1ZTogRm9ybWF0dGVkIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzZWxlY3RlZCBkYXRlLlxyXG4qL1xyXG5mb3JtYXR0ZWREYXRlOiBhbnkgOyBcclxuXHJcbiAvKipcclxuICogVHJhY2sgdGhlIGVkaXRlZCBkYXRlIHNlcGFyYXRlbHkgd2hlbiBpbiBlZGl0aW5nIG1vZGUuXHJcbiAqIERlZmF1bHQgdmFsdWU6IEFuIGVtcHR5IHN0cmluZy5cclxuKi9cclxuZWRpdGVkRGF0ZTogc3RyaW5nID0gJyc7IFxyXG5cclxuLyoqXHJcbiAqIEZsYWcgdG8gZGV0ZXJtaW5lIGlmIHRoZSBtb250aCBkcm9wZG93biBpcyBvcGVuIG9yIGNsb3NlZC5cclxuICogRGVmYXVsdCB2YWx1ZTogdHJ1ZSAob3BlbikuXHJcbiovXHJcbmlzTW9udGhEcm9wZG93bk9wZW46IGJvb2xlYW4gPSB0cnVlOyBcclxuXHJcbi8qKlxyXG4gKiBGbGFnIHRvIGRldGVybWluZSBpZiB0aGUgeWVhciBkcm9wZG93biBpcyBvcGVuIG9yIGNsb3NlZC5cclxuICogRGVmYXVsdCB2YWx1ZTogdHJ1ZSAob3BlbikuXHJcbiovXHJcbmlzWWVhckRyb3Bkb3duT3BlbjogYm9vbGVhbiA9IHRydWU7IFxyXG5cclxuLyoqXHJcbiAqIFRoZSBzZWxlY3RlZCBtb250aCAoMC0xMSkuXHJcbiAqIERlZmF1bHQgdmFsdWU6IFRoZSBtb250aCBvZiB0aGUgc2VsZWN0ZWQgZGF0ZS5cclxuKi9cclxuc2VsZWN0ZWREYXRlTW9udGg6IG51bWJlciA9IHRoaXMuc2VsZWN0ZWREYXRlLmdldE1vbnRoKCk7IFxyXG5cclxuLyoqXHJcbiAqIFRoZSBzZWxlY3RlZCB5ZWFyLlxyXG4gKiBEZWZhdWx0IHZhbHVlOiBUaGUgeWVhciBvZiB0aGUgc2VsZWN0ZWQgZGF0ZS5cclxuKi9cclxuc2VsZWN0ZWREYXRlWWVhcjogbnVtYmVyID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKTsgXHJcblxyXG4gLyoqXHJcbiAqIEFuIGFycmF5IG9mIHllYXJzIGZvciB0aGUgeWVhciBkcm9wZG93bi5cclxuICogRGVmYXVsdCB2YWx1ZTogQW4gYXJyYXkgb2YgeWVhcnMgd2l0aGluIHRoZSBzcGVjaWZpZWQgcmFuZ2UuXHJcbiovXHJcbnllYXJzOiBudW1iZXJbXSBcclxuXHJcbi8qKlxyXG4gKiBUaGUgbGFuZ3VhZ2UvbG9jYWxlIGZvciB0aGUgZGF0ZXBpY2tlci5cclxuICogRGVmYXVsdCB2YWx1ZTogJ2VuJyAoRW5nbGlzaCkuXHJcbiAqIEBleGFtcGxlXHJcbiAqIDxtZWZkZXYtZGF0ZXBpY2tlclxyXG4gKiAgIFtsYW5nXSA9IFwiJ3VrJ1wiPlxyXG4gKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4qL1xyXG5ASW5wdXQoKSBsYW5nOiBzdHJpbmcgPSAnZW4nOyBcclxuXHJcbi8qKlxyXG4gKiBUaGUgZGF0ZSBmb3JtYXQgZm9yIGRpc3BsYXlpbmcgdGhlIHNlbGVjdGVkIGRhdGUuXHJcbiAqIERlZmF1bHQgdmFsdWU6ICdFRUUgTU1NIGRkIHl5eXknLlxyXG4gKiBAZXhhbXBsZVxyXG4gKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICogICBbZGF0ZUZvcm1hdF09XCInZGQvTU0veXl5eSdcIj5cclxuICogPC9tZWZkZXYtZGF0ZXBpY2tlcj5cclxuKi9cclxuQElucHV0KCkgZGF0ZUZvcm1hdDogc3RyaW5nID0gJ0VFRSBNTU0gZGQgeXl5eSc7IFxyXG5cclxuLyoqXHJcbiAqIFRoZSByYW5nZSBvZiB5ZWFycyBhdmFpbGFibGUgaW4gdGhlIHllYXIgZHJvcGRvd24uXHJcbiAqIERlZmF1bHQgdmFsdWU6IHsgc3RhcnRZZWFyOiAxOTAwLCB0b1llYXI6IDMwMCB9LlxyXG4gKiBAZXhhbXBsZVxyXG4gKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICogICBbcmFuZ2VdPVwie3N0YXJ0WWVhcjogMTkwMCwgdG9ZZWFyOiAzMDB9XCI+XHJcbiAqIDwvbWVmZGV2LWRhdGVwaWNrZXI+XHJcbiovXHJcbkBJbnB1dCgncmFuZ2UnKSB5ZWFyc1JhbmdlOntzdGFydFllYXI6bnVtYmVyLCB0b1llYXI6bnVtYmVyfSA9IHtzdGFydFllYXI6MTkwMCwgdG9ZZWFyOjMwMH07IFxyXG5cclxuLyoqXHJcbiAqIFdoZXRoZXIgdGhlIGRhdGVwaWNrZXIgaXMgZGlzYWJsZWQgb3Igbm90LlxyXG4gKiBEZWZhdWx0IHZhbHVlOiBmYWxzZSAoZW5hYmxlZCkuXHJcbiAqIEBleGFtcGxlXHJcbiAqIDxtZWZkZXYtZGF0ZXBpY2tlclxyXG4gKiAgIFtkaXNhYmxlZF09XCJmYWxzZVwiPlxyXG4gKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4qL1xyXG5ASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlOyBcclxuXHJcbi8qKlxyXG4gKiBUaGUgdG9wIG9mZnNldCBmb3IgcG9zaXRpb25pbmcgdGhlIGRhdGVwaWNrZXIuXHJcbiAqIERlZmF1bHQgdmFsdWU6ICcyMCcuXHJcbiAqIEBleGFtcGxlXHJcbiAqIDxtZWZkZXYtZGF0ZXBpY2tlclxyXG4gKiAgIFt0b3BPZmZzZXRdPVwiJzIwJ1wiPlxyXG4gKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4qL1xyXG5ASW5wdXQoKSB0b3BPZmZzZXQ6IHN0cmluZyA9ICcyMCc7XHJcblxyXG4vKipcclxuICogVGhlIGxlZnQgb2Zmc2V0IGZvciBwb3NpdGlvbmluZyB0aGUgZGF0ZXBpY2tlci5cclxuICogRGVmYXVsdCB2YWx1ZTogJzEwJy5cclxuICogQGV4YW1wbGVcclxuICogPG1lZmRldi1kYXRlcGlja2VyXHJcbiAqICAgW2xlZnRPZmZzZXRdPVwiJzEwJ1wiPlxyXG4gKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4qL1xyXG5ASW5wdXQoKSBsZWZ0T2Zmc2V0OiBzdHJpbmcgPSAnMTAnOyAvL0RlZmF1bHQgdmFsdWVcclxuXHJcbi8qKlxyXG4gKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIHNlbGVjdGVkIGRhdGUgaW4gdGhlIGRhdGVwaWNrZXIgY2hhbmdlcy5cclxuICogSXQgZW1pdHMgYSBgRGF0ZWAgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgc2VsZWN0ZWQgZGF0ZS5cclxuICogQGV4YW1wbGVcclxuICogPG1lZmRldi1kYXRlcGlja2VyXHJcbiAqICAgKGRhdGVDaGFuZ2VkKT1cIm9uRGF0ZUNoYW5nZWQoJGV2ZW50KVwiPlxyXG4gKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4qL1xyXG5AT3V0cHV0KCkgZGF0ZUNoYW5nZWQ6IEV2ZW50RW1pdHRlcjxEYXRlPiA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZT4oKTtcclxuXHJcbi8qKlxyXG4gKiBSZWd1bGFyIGV4cHJlc3Npb24gdG8gdmFsaWRhdGUgdXNlciBpbnB1dCBmb3IgZGF0ZSBpbiB0aGUgZm9ybWF0IFwiZGQvTU0veXl5eVwiLlxyXG4gKiAtIFRoZSBkYXkgKGRkKSBzaG91bGQgYmUgYmV0d2VlbiAwMSBhbmQgMzEuXHJcbiAqIC0gVGhlIG1vbnRoIChNTSkgc2hvdWxkIGJlIGJldHdlZW4gMDEgYW5kIDEyLlxyXG4gKiAtIFRoZSB5ZWFyICh5eXl5KSBzaG91bGQgYmUgYSA0LWRpZ2l0IG51bWJlci5cclxuKi9cclxuICBwcml2YXRlIGRhdGVSZWdFeHA6IFJlZ0V4cCA9IC9eKDBbMS05XXxbMTJdWzAtOV18M1swMV0pXFwvKDBbMS05XXwxWzAtMl0pXFwvXFxkezR9JC87XHJcblxyXG4vKipcclxuICogVGhlIHN0cmluZyBlbnRlcmVkIGJ5IHRoZSB1c2VyIGZvciBkYXRlIGlucHV0LlxyXG4gKiBUaGlzIHZhcmlhYmxlIHN0b3JlcyB0aGUgdXNlcidzIGlucHV0IGFzIHRoZXkgdHlwZSBpbiB0aGUgZGF0ZSBmaWVsZC5cclxuKi9cclxuICB1c2VySW5wdXQ6IHN0cmluZyA9ICcnO1xyXG4gIFxyXG4vKipcclxuICogSG9zdCBsaXN0ZW5lciBmb3IgZG9jdW1lbnQgY2xpY2sgZXZlbnRzIHRvIGhhbmRsZSBjYWxlbmRhciBpbnRlcmFjdGlvbi5cclxuICogVGhpcyBmdW5jdGlvbiBjaGVja3MgaWYgYSBjbGljayBldmVudCBvY2N1cnJlZCB3aXRoaW4gdGhlIGNhbGVuZGFyIG9yIGlucHV0IGVsZW1lbnRzLlxyXG4gKiAtIElmIHRoZSBjbGljayBvY2N1cnJlZCB3aXRoaW4gdGhlIGNhbGVuZGFyLCBubyBhY3Rpb24gaXMgdGFrZW4uXHJcbiAqIC0gSWYgdGhlIGNsaWNrIG9jY3VycmVkIHdpdGhpbiB0aGUgaW5wdXQgZWxlbWVudCBhbmQgdGhlIGNvbXBvbmVudCBpcyBub3QgaW4gZWRpdGluZyBtb2RlLFxyXG4gKiAgIGl0IG9wZW5zIHRoZSBjYWxlbmRhci5cclxuICogLSBJZiB0aGUgY2xpY2sgb2NjdXJyZWQgb3V0c2lkZSB0aGUgY2FsZW5kYXIgYW5kIGlucHV0LCBpdCBjbG9zZXMgdGhlIGNhbGVuZGFyLlxyXG4gKiBAcGFyYW0gZXZlbnQgVGhlIE1vdXNlRXZlbnQgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgY2xpY2sgZXZlbnQuXHJcbiovXHJcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxyXG4gIG9uQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIGNvbnN0IHRhcmdldEVsZW1lbnQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICBjb25zdCBjYWxlbmRhciA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jYWxlbmRhcicpO1xyXG4gICAgY29uc3QgbW9udGhEcm9wZG93biA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tb250aERyb3Bkb3duJyk7XHJcbiAgICBjb25zdCB5ZWFyRHJvcGRvd24gPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcueWVhckRyb3Bkb3duJyk7XHJcbiAgICBjb25zdCBpbnB1dEVsZW1lbnQgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dCcpO1xyXG4gICAgaWYobW9udGhEcm9wZG93bi5jb250YWlucyh0YXJnZXRFbGVtZW50KSAmJiB5ZWFyRHJvcGRvd24uY29udGFpbnModGFyZ2V0RWxlbWVudCkgKXtcclxuICAgICAgdGhpcy50b2dnbGVNb250aERyb3Bkb3duKGV2ZW50KVxyXG4gICAgICB0aGlzLnRvZ2dsZVllYXJEcm9wZG93bihldmVudClcclxuICAgIH1cclxuICAgIGlmIChjYWxlbmRhciAmJiBjYWxlbmRhci5jb250YWlucyh0YXJnZXRFbGVtZW50KSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAoaW5wdXRFbGVtZW50ICYmIGlucHV0RWxlbWVudC5jb250YWlucyh0YXJnZXRFbGVtZW50KSAmJiAhdGhpcy5pc0VkaXRpbmcpIHtcclxuICAgICAgLy8g0JrQu9GW0Log0LLRltC00LHRg9Cy0YHRjyDQvdCwINC10LvQtdC80LXQvdGC0ZYgaW5wdXQsINCy0ZbQtNC60YDQuNCy0LDRlNC80L4g0LrQsNC70LXQvdC00LDRgFxyXG4gICAgICB0aGlzLmlzQ2FsZW5kYXJPcGVuID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAgIC8vINCa0LvRltC6INCy0ZbQtNCx0YPQstGB0Y8g0L/QvtC30LAg0LrQsNC70LXQvdC00LDRgNC10Lwg0YLQsCBpbnB1dCwg0LfQsNC60YDQuNCy0LDRlNC80L4g0LrQsNC70LXQvdC00LDRgFxyXG4gICAgICAgIHRoaXMuaXNDYWxlbmRhck9wZW4gPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmlzRWRpdGluZyA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIENvbnN0cnVjdG9yIGZvciB0aGUgRGF0ZXBpY2tlckNvbXBvbmVudCBjbGFzcy5cclxuICogQHBhcmFtIGRhdGVQaXBlIEEgc2VydmljZSBmb3IgZm9ybWF0dGluZyBhbmQgcGFyc2luZyBkYXRlcy5cclxuICogQHBhcmFtIGVsZW1lbnRSZWYgQSByZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgb24gd2hpY2ggdGhpcyBjb21wb25lbnQgaXMgYXR0YWNoZWQuXHJcbiAqIEl0IGlzIHVzZWQgdG8gYWNjZXNzIERPTSBlbGVtZW50cy5cclxuKi9cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGVQaXBlOiBEYXRlUGlwZSwgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmKSB7XHJcbiAgICB0aGlzLnVwZGF0ZUlucHV0VmFsdWUoKVxyXG4gIH1cclxuICBcclxuLyoqXHJcbiAqIExpZmVjeWNsZSBob29rIGNhbGxlZCBhZnRlciB0aGUgY29tcG9uZW50IGlzIGluaXRpYWxpemVkLlxyXG4gKiBJdCBpbml0aWFsaXplcyB0aGUgeWVhcnMgZm9yIHRoZSB5ZWFyIHNlbGVjdCBkcm9wZG93bi5cclxuKi9cclxuICBuZ09uSW5pdCgpe1xyXG4gICAgdGhpcy5pbml0aWFsaXplWWVhcnMoKTtcclxuICB9XHJcbi8qKlxyXG4gKiBMaWZlY3ljbGUgaG9vayBjYWxsZWQgd2hlbmV2ZXIgdGhlIGlucHV0IHByb3BlcnRpZXMgb2YgdGhlIGNvbXBvbmVudCBjaGFuZ2UuXHJcbiAqIEl0IHVwZGF0ZXMgdGhlIGlucHV0IHZhbHVlLlxyXG4qL1xyXG4gIG5nT25DaGFuZ2VzKCkge1xyXG4gICAgdGhpcy51cGRhdGVJbnB1dFZhbHVlKCk7XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIEFuIGFycmF5IG9mIG1vbnRoIG5hbWVzIGJhc2VkIG9uIHRoZSBzZWxlY3RlZCBsYW5ndWFnZS5cclxuICogSXQgcHJvdmlkZXMgbG9jYWxpemVkIG1vbnRoIG5hbWVzIGZvciBkaXNwbGF5IGluIHRoZSBkYXRlcGlja2VyLlxyXG4qL1xyXG4gIHByaXZhdGUgZ2V0IG1vbnRocygpe1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9udGhMaXN0KHRoaXMubGFuZyk7XHJcbiAgfSAgXHJcblxyXG4vKipcclxuICogQW4gYXJyYXkgb2Ygd2Vla2RheSBuYW1lcyBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgbGFuZ3VhZ2UuXHJcbiAqIEl0IHByb3ZpZGVzIGxvY2FsaXplZCB3ZWVrZGF5IG5hbWVzIGZvciBkaXNwbGF5IGluIHRoZSBkYXRlcGlja2VyLlxyXG4qL1xyXG4gIHByaXZhdGUgZ2V0IHdlZWtkYXlzKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0V2Vla2RheUxpc3QodGhpcy5sYW5nKTtcclxuICB9XHJcblxyXG4vKipcclxuICogSW5pdGlhbGl6ZSB0aGUgbGlzdCBvZiB5ZWFycyB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIHllYXIgZHJvcGRvd24uXHJcbiAqIFRoaXMgbWV0aG9kIHBvcHVsYXRlcyB0aGUgJ3llYXJzJyBhcnJheSB3aXRoIGEgcmFuZ2Ugb2YgeWVhcnMgYmFzZWQgb24gdGhlIHByb3ZpZGVkICd5ZWFyc1JhbmdlJyBjb25maWd1cmF0aW9uLlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGBcclxuICogLy8gQXNzdW1pbmcgJ3llYXJzUmFuZ2UnIGlzIHsgc3RhcnRZZWFyOiAxOTAwLCB0b1llYXI6IDMwMCB9XHJcbiAqIC8vIEFmdGVyIGNhbGxpbmcgaW5pdGlhbGl6ZVllYXJzKCksICd5ZWFycycgbWlnaHQgY29udGFpbiBbMTkwMCwgMTkwMSwgLi4uLCAzMDBdXHJcbiAqIHRoaXMuaW5pdGlhbGl6ZVllYXJzKCk7XHJcbiAqIGBgYFxyXG4qL1xyXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVllYXJzKCkge1xyXG4gICAgdGhpcy55ZWFycyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IHRoaXMueWVhcnNSYW5nZS50b1llYXIgfSwgKF8sIGluZGV4KSA9PiBpbmRleCArIHRoaXMueWVhcnNSYW5nZS5zdGFydFllYXIpO1xyXG4gIH1cclxuXHJcbi8qKlxyXG4gKiBUb2dnbGUgdGhlIGVkaXRpbmcgbW9kZSBmb3IgdGhlIGRhdGUgaW5wdXQuIFdoZW4gZW5hYmxlZCwgdGhlIHVzZXIgY2FuIGVkaXQgdGhlIGRhdGUgZGlyZWN0bHkgaW4gdGhlIGlucHV0IGZpZWxkLlxyXG4gKiBUaGlzIG1ldGhvZCBzZXRzIHRoZSAnaXNFZGl0aW5nJyBmbGFnIHRvIHRydWUgYW5kIHN0b3JlcyB0aGUgY3VycmVudCBmb3JtYXR0ZWQgZGF0ZSBmb3IgZWRpdGluZy5cclxuKi9cclxuICB0b2dnbGVFZGl0KCkge1xyXG4gICAgdGhpcy5pc0VkaXRpbmcgPSAhdGhpcy5pc0VkaXRpbmc7XHJcbiAgICB0aGlzLmVkaXRlZERhdGUgPSB0aGlzLmZvcm1hdFNlbGVjdGVkRGF0ZSgpOyAvLyBTdG9yZSB0aGUgY3VycmVudCBmb3JtYXR0ZWQgZGF0ZSBmb3IgZWRpdGluZ1xyXG4gICAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBsaXN0IG9mIG1vbnRoIG5hbWVzIGluIHRoZSBzcGVjaWZpZWQgbGFuZ3VhZ2UgYW5kIGZvcm1hdC5cclxuICogQHBhcmFtIGxvY2FsZXMgLSBBbiBvcHRpb25hbCBwYXJhbWV0ZXIgc3BlY2lmeWluZyB0aGUgbG9jYWxlIG9yIGxvY2FsZXMgdG8gdXNlIGZvciBmb3JtYXR0aW5nLlxyXG4gKiBAcGFyYW0gZm9ybWF0IC0gVGhlIGZvcm1hdCBmb3IgbW9udGggbmFtZXMsIGVpdGhlciBcImxvbmdcIiAoZGVmYXVsdCkgb3IgXCJzaG9ydFwiLlxyXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBtb250aCBuYW1lcyBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgZm9ybWF0IGFuZCBsb2NhbGUuXHJcbiAqIGBgYFxyXG4gKiAvLyBHZXQgYSBsaXN0IG9mIG1vbnRoIG5hbWVzIGluIHRoZSBkZWZhdWx0IGxhbmd1YWdlIGFuZCBsb25nIGZvcm1hdFxyXG4gKiBjb25zdCBtb250aHMgPSB0aGlzLmdldE1vbnRoTGlzdCh0aGlzLmxhbmcpO1xyXG4gKiBgYGBcclxuKi9cclxuICBwcml2YXRlIGdldE1vbnRoTGlzdCggIGxvY2FsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSwgIGZvcm1hdDogXCJsb25nXCIgfCBcInNob3J0XCIgPSBcImxvbmdcIik6IHN0cmluZ1tdIHsgIFxyXG4gICAgY29uc3QgeWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcclxuICAgIGNvbnN0IG1vbnRoTGlzdCA9IFsuLi5BcnJheSgxMikua2V5cygpXTtcclxuICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KGxvY2FsZXMsIHsgICAgbW9udGg6IGZvcm1hdCAgfSk7XHJcbiAgICBjb25zdCBnZXRNb250aE5hbWUgPSAobW9udGhJbmRleDogbnVtYmVyKSA9PiBmb3JtYXR0ZXIuZm9ybWF0KG5ldyBEYXRlKHllYXIsIG1vbnRoSW5kZXgpKTtcclxuICAgICByZXR1cm4gbW9udGhMaXN0Lm1hcChnZXRNb250aE5hbWUpO1xyXG4gIH1cclxuICBcclxuLyoqXHJcbiAqIEdldCBhIGxpc3Qgb2Ygd2Vla2RheSBuYW1lcyBpbiB0aGUgc3BlY2lmaWVkIGxhbmd1YWdlIGFuZCBmb3JtYXQuXHJcbiAqIEBwYXJhbSBsb2NhbGVzIC0gQW4gb3B0aW9uYWwgcGFyYW1ldGVyIHNwZWNpZnlpbmcgdGhlIGxvY2FsZSBvciBsb2NhbGVzIHRvIHVzZSBmb3IgZm9ybWF0dGluZy5cclxuICogQHBhcmFtIGZvcm1hdCAtIFRoZSBmb3JtYXQgZm9yIHdlZWtkYXkgbmFtZXMsIGVpdGhlciBcInNob3J0XCIgKGRlZmF1bHQpIG9yIFwibG9uZ1wiLlxyXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiB3ZWVrZGF5IG5hbWVzIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBmb3JtYXQgYW5kIGxvY2FsZS5cclxuICogYGBgXHJcbiAqIC8vIEdldCBhIGxpc3Qgb2Ygd2Vla2RheSBuYW1lcyBpbiB0aGUgZGVmYXVsdCBsYW5ndWFnZSBhbmQgc2hvcnQgZm9ybWF0XHJcbiAqIGNvbnN0IHdlZWtkYXlzID0gdGhpcy5nZXRXZWVrZGF5TGlzdCgpO1xyXG4gKiBgYGBcclxuKi9cclxuICBwcml2YXRlIGdldFdlZWtkYXlMaXN0KGxvY2FsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSwgZm9ybWF0OiBcInNob3J0XCIgfCBcImxvbmdcIiA9IFwic2hvcnRcIik6IHN0cmluZ1tdIHtcclxuICAgICAgY29uc3Qgd2Vla2RheXMgPSBbLi4uQXJyYXkoNykua2V5cygpXTtcclxuICAgICAgY29uc3QgbW9uZGF5SW5kZXggPSB3ZWVrZGF5cy5pbmRleE9mKDApO1xyXG4gICAgICB3ZWVrZGF5cy5zcGxpY2UobW9uZGF5SW5kZXgsIDEpOyBcclxuICAgICAgd2Vla2RheXMucHVzaCgwKTsgXHJcbiAgICAgIGNvbnN0IGZvcm1hdHRlciA9IG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KGxvY2FsZXMsIHsgd2Vla2RheTogZm9ybWF0IH0pOyAgICBcclxuICAgICAgY29uc3QgZ2V0V2Vla2RheU5hbWUgPSAod2Vla2RheUluZGV4OiBudW1iZXIpID0+IHtcclxuICAgICAgICByZXR1cm4gZm9ybWF0dGVyLmZvcm1hdChuZXcgRGF0ZSgyMDIzLCA5LCB3ZWVrZGF5SW5kZXggKyAxKSk7IFxyXG4gICAgICB9O1xyXG4gICAgICByZXR1cm4gd2Vla2RheXMubWFwKGdldFdlZWtkYXlOYW1lKTtcclxuICB9XHJcbiAgICBcclxuICAgIFxyXG4vKipcclxuICogVG9nZ2xlIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBjYWxlbmRhciBjb21wb25lbnQuIFdoZW4gY2FsbGVkLCB0aGlzIG1ldGhvZCBjaGFuZ2VzIHRoZSAnaXNDYWxlbmRhck9wZW4nIGZsYWdcclxuICogdG8gc2hvdyBvciBoaWRlIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAqIGBgYFxyXG4gKiAvLyBUb2dnbGUgdGhlIHZpc2liaWxpdHkgb2YgdGhlIGNhbGVuZGFyXHJcbiAqIHRoaXMudG9nZ2xlQ2FsZW5kYXIoKTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSB0b2dnbGVDYWxlbmRhcigpIHtcclxuICAgIGlmKHRoaXMuaXNFZGl0aW5nKXtcclxuICAgICAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gICAgfWVsc2V7XHJcbiAgICAgIHRoaXMuaXNDYWxlbmRhck9wZW4gPSAhdGhpcy5pc0NhbGVuZGFyT3BlblxyXG4gICAgfVxyXG4gIH1cclxuXHJcbi8qKlxyXG4gKiBTYXZlIHRoZSBlZGl0ZWQgZGF0ZSBpbnB1dCBieSB0aGUgdXNlciwgcHJvdmlkZWQgaXQgbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIGRhdGUgZm9ybWF0LlxyXG4gKiBUaGlzIG1ldGhvZCBjaGVja3MgaWYgdGhlIGVudGVyZWQgZGF0ZSBpcyBpbiBhIHZhbGlkIGZvcm1hdCwgZGlzYWJsZXMgdGhlIGVkaXRpbmcgbW9kZSwgYW5kIGFwcGxpZXNcclxuICogdGhlIGVkaXRlZCBkYXRlIHRvIHRoZSAnc2VsZWN0ZWREYXRlJy4gSXQgdGhlbiByZWZvcm1hdHMgdGhlIHNlbGVjdGVkIGRhdGUgYW5kIGNsb3NlcyB0aGUgY2FsZW5kYXIuXHJcbiAqIGBgYFxyXG4gKiAvLyBTYXZlIHRoZSBlZGl0ZWQgZGF0ZSBhbmQgdXBkYXRlIHRoZSBzZWxlY3RlZCBkYXRlXHJcbiAqIHRoaXMuc2F2ZUVkaXRlZERhdGUoKTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSBzYXZlRWRpdGVkRGF0ZSgpIHtcclxuICAgIGlmICh0aGlzLmlzRGF0ZVZhbGlkKHRoaXMuZWRpdGVkRGF0ZSkpIHtcclxuICAgICAgdGhpcy5pc0VkaXRpbmcgPSBmYWxzZTsgXHJcbiAgICAgIGNvbnN0IFtkYXksIG1vbnRoLCB5ZWFyXSA9IHRoaXMuZWRpdGVkRGF0ZS5zcGxpdCgnLycpO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IG5ldyBEYXRlKCt5ZWFyLCArbW9udGggLSAxLCArZGF5KTtcclxuICAgICAgdGhpcy5mb3JtYXREYXRlKCk7IFxyXG4gICAgfSBcclxuICB9XHJcblxyXG4vKipcclxuICAqIEhhbmRsZSB1c2VyIGlucHV0IGluIHRoZSBlZGl0YWJsZSBpbnB1dCBmaWVsZCBmb3IgZGF0ZSBlZGl0aW5nLiBUaGlzIG1ldGhvZCBjYXB0dXJlcyB0aGUgaW5wdXQgdmFsdWVcclxuICAqIGFuZCBzdG9yZXMgaXQgaW4gdGhlICdlZGl0ZWREYXRlJyB2YXJpYWJsZS4gSWYgdGhlIGlucHV0IG1hdGNoZXMgdGhlIHZhbGlkIGRhdGUgZm9ybWF0LCBpdCB1cGRhdGVzXHJcbiAgKiAnc2VsZWN0ZWREYXRlTW9udGgnIGFuZCAnc2VsZWN0ZWREYXRlWWVhcicgYWNjb3JkaW5nbHkuXHJcbiAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgaW5wdXQgZXZlbnQgY29udGFpbmluZyB0aGUgdXNlcidzIGlucHV0LlxyXG4gICogYGBgXHJcbiAgKiAvLyBIYW5kbGUgdXNlciBpbnB1dCBpbiB0aGUgZWRpdGFibGUgaW5wdXQgZmllbGRcclxuICAqIHRoaXMub25EYXRlSW5wdXQoZXZlbnQpO1xyXG4gICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSBvbkRhdGVJbnB1dChldmVudDogYW55KSB7XHJcbiAgICBjb25zdCBpbnB1dERhdGU6IHN0cmluZyA9IGV2ZW50LnRhcmdldC52YWx1ZTtcclxuICAgIGlmICh0aGlzLmlzRGF0ZVZhbGlkKGlucHV0RGF0ZSkpIHtcclxuICAgICAgdGhpcy5lZGl0ZWREYXRlID0gaW5wdXREYXRlO1xyXG4gICAgICBjb25zdCBwYXJzZWREYXRlID0gaW5wdXREYXRlLnNwbGl0KCcvJyk7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlTW9udGggPSArcGFyc2VkRGF0ZVsxXSAtIDE7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlWWVhciA9ICtwYXJzZWREYXRlWzJdO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbi8qKlxyXG4gKiBUb2dnbGUgdGhlIHZpc2liaWxpdHkgb2YgdGhlIG1vbnRoIGRyb3Bkb3duIGluIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gb3BlbiBvciBjbG9zZSB0aGUgZHJvcGRvd24gZm9yIHNlbGVjdGluZyBtb250aHMuXHJcbiAqIEBwYXJhbSBldmVudCAtIFRoZSBldmVudCB0cmlnZ2VyaW5nIHRoZSB0b2dnbGUgYWN0aW9uIChlLmcuLCBhIGNsaWNrIGV2ZW50KS5cclxuICogYGBgXHJcbiAqIC8vIFRvZ2dsZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgbW9udGggZHJvcGRvd25cclxuICogdGhpcy50b2dnbGVNb250aERyb3Bkb3duKGV2ZW50KTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSB0b2dnbGVNb250aERyb3Bkb3duKGV2ZW50OiBFdmVudCkge1xyXG4gICAgdGhpcy5pc01vbnRoRHJvcGRvd25PcGVuID0gIXRoaXMuaXNNb250aERyb3Bkb3duT3BlbjtcclxuICB9XHJcblxyXG4vKipcclxuICAqIFRvZ2dsZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgeWVhciBkcm9wZG93biBpbiB0aGUgY2FsZW5kYXIgaW50ZXJmYWNlLlxyXG4gICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBvcGVuIG9yIGNsb3NlIHRoZSBkcm9wZG93biBmb3Igc2VsZWN0aW5nIHllYXJzLlxyXG4gICogQHBhcmFtIGV2ZW50IC0gVGhlIGV2ZW50IHRyaWdnZXJpbmcgdGhlIHRvZ2dsZSBhY3Rpb24gKGUuZy4sIGEgY2xpY2sgZXZlbnQpLlxyXG4gICogYGBgXHJcbiAgKiAvLyBUb2dnbGUgdGhlIHZpc2liaWxpdHkgb2YgdGhlIHllYXIgZHJvcGRvd25cclxuICAqIHRoaXMudG9nZ2xlWWVhckRyb3Bkb3duKGV2ZW50KTtcclxuICAqIGBgYFxyXG4qL1xyXG4gIHByaXZhdGUgdG9nZ2xlWWVhckRyb3Bkb3duKGV2ZW50OiBFdmVudCkge1xyXG4gICAgdGhpcy5pc1llYXJEcm9wZG93bk9wZW4gPSAhdGhpcy5pc1llYXJEcm9wZG93bk9wZW47XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIEhhbmRsZSB0aGUgY2hhbmdlIG9mIHRoZSBzZWxlY3RlZCBtb250aCBpbiB0aGUgY2FsZW5kYXIgaW50ZXJmYWNlLlxyXG4gKiBUaGlzIG1ldGhvZCB1cGRhdGVzIHRoZSBpbnB1dCB2YWx1ZSwgc2V0cyB0aGUgc2VsZWN0ZWQgZGF0ZSB0byB0aGUgZmlyc3QgZGF5IG9mIHRoZSBjaG9zZW4gbW9udGgsXHJcbiAqIGFuZCByZWNhbGN1bGF0ZXMgdGhlIGNhbGVuZGFyIGRpc3BsYXkgYWNjb3JkaW5nbHkuXHJcbiAqIGBgYFxyXG4gKiAvLyBIYW5kbGUgdGhlIGNoYW5nZSBvZiB0aGUgc2VsZWN0ZWQgbW9udGhcclxuICogdGhpcy5vbk1vbnRoQ2hhbmdlKCk7XHJcbiAqIGBgYFxyXG4qL1xyXG4gIHByaXZhdGUgb25Nb250aENoYW5nZSgpIHtcclxuICAgIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpO1xyXG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZVllYXIsIHRoaXMuc2VsZWN0ZWREYXRlTW9udGgsIDEpO1xyXG4gICAgdGhpcy5jYWxjdWxhdGVGaXJzdERheU9mQ2FsZW5kYXIoKTtcclxuICB9XHJcblxyXG4vKipcclxuICogSGFuZGxlIHRoZSBjaGFuZ2Ugb2YgdGhlIHNlbGVjdGVkIHllYXIgaW4gdGhlIGNhbGVuZGFyIGludGVyZmFjZS5cclxuICogVGhpcyBtZXRob2QgdXBkYXRlcyB0aGUgaW5wdXQgdmFsdWUsIHNldHMgdGhlIHNlbGVjdGVkIGRhdGUgdG8gdGhlIGZpcnN0IGRheSBvZiB0aGUgY2hvc2VuIHllYXIsXHJcbiAqIHJlZm9ybWF0cyB0aGUgc2VsZWN0ZWQgZGF0ZSwgYW5kIHJlY2FsY3VsYXRlcyB0aGUgY2FsZW5kYXIgZGlzcGxheS5cclxuICogYGBgXHJcbiAqIC8vIEhhbmRsZSB0aGUgY2hhbmdlIG9mIHRoZSBzZWxlY3RlZCB5ZWFyXHJcbiAqIHRoaXMub25ZZWFyQ2hhbmdlKCk7XHJcbiAqIGBgYFxyXG4qL1xyXG4gIHByaXZhdGUgb25ZZWFyQ2hhbmdlKCkge1xyXG4gICAgdGhpcy51cGRhdGVJbnB1dFZhbHVlKCk7XHJcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IG5ldyBEYXRlKHRoaXMuc2VsZWN0ZWREYXRlWWVhciwgdGhpcy5zZWxlY3RlZERhdGVNb250aCwgMSk7XHJcbiAgICB0aGlzLmZvcm1hdERhdGUoKTtcclxuICAgIHRoaXMuY2FsY3VsYXRlRmlyc3REYXlPZkNhbGVuZGFyKCk7XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIFNlbGVjdCBhIGRhdGUgaW4gdGhlIGNhbGVuZGFyIGludGVyZmFjZSBhbmQgcGVyZm9ybSBuZWNlc3NhcnkgdXBkYXRlcy5cclxuICogVGhpcyBtZXRob2Qgc2V0cyB0aGUgc2VsZWN0ZWQgZGF0ZSwgZm9ybWF0cyBpdCwgY2xvc2VzIHRoZSBjYWxlbmRhciwgYW5kIGVtaXRzIGEgZGF0ZUNoYW5nZWQgZXZlbnQuXHJcbiAqIEl0IGFsc28gdXBkYXRlcyB0aGUgc2VsZWN0ZWQgbW9udGggYW5kIHllYXIgZHJvcGRvd24gdmFsdWVzLlxyXG4gKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIGJlIHNlbGVjdGVkIGluIHRoZSBjYWxlbmRhci5cclxuKi9cclxuICBzZWxlY3REYXRlKGRhdGU6IERhdGUpIHtcclxuICB0aGlzLnNlbGVjdGVkRGF0ZSA9IGRhdGU7XHJcbiAgdGhpcy5mb3JtYXREYXRlKCk7XHJcbiAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gIHRoaXMuZGF0ZUNoYW5nZWQubmV4dCh0aGlzLnNlbGVjdGVkRGF0ZSk7XHJcbiAgdGhpcy5zZWxlY3RlZERhdGVNb250aCA9IHRoaXMuc2VsZWN0ZWREYXRlLmdldE1vbnRoKCk7XHJcbiAgdGhpcy5zZWxlY3RlZERhdGVZZWFyID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKTtcclxuICB9XHJcblxyXG4vKipcclxuICogRm9ybWF0IHRoZSBzZWxlY3RlZCBkYXRlIGJhc2VkIG9uIHRoZSBjaG9zZW4gZGF0ZSBmb3JtYXQgYW5kIGxhbmd1YWdlLlxyXG4gKiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBBbmd1bGFyIERhdGVQaXBlIHRvIGZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSBhbmQgdXBkYXRlcyB0aGUgZm9ybWF0dGVkRGF0ZSB2YXJpYWJsZS5cclxuICogYGBgXHJcbiAqIC8vIEZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZVxyXG4gKiB0aGlzLmZvcm1hdERhdGUoKTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSBmb3JtYXREYXRlKCkge1xyXG4gICAgdGhpcy5mb3JtYXR0ZWREYXRlID0gdGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0odGhpcy5zZWxlY3RlZERhdGUsIHRoaXMuZGF0ZUZvcm1hdCkgfHwgJyc7XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIEZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSBiYXNlZCBvbiB0aGUgY2hvc2VuIGRhdGUgZm9ybWF0LCBsYW5ndWFnZSwgYW5kIGxvY2FsZS5cclxuICogVGhpcyBtZXRob2QgdXNlcyB0aGUgQW5ndWxhciBEYXRlUGlwZSB0byBmb3JtYXQgdGhlIHNlbGVjdGVkIGRhdGUgd2l0aCB0aGUgc3BlY2lmaWVkIGxhbmd1YWdlIGFuZCB1cGRhdGVzIHRoZSBmb3JtYXR0ZWQgZGF0ZSBhcyBhIHN0cmluZy5cclxuICogQHJldHVybnMgQSBmb3JtYXR0ZWQgZGF0ZSBzdHJpbmcuXHJcbiAqIGBgYFxyXG4gKiAvLyBGb3JtYXQgdGhlIHNlbGVjdGVkIGRhdGUgd2l0aCBsYW5ndWFnZVxyXG4gKiBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLmZvcm1hdFNlbGVjdGVkRGF0ZSgpO1xyXG4gKiBgYGBcclxuKi9cclxuICBwcml2YXRlIGZvcm1hdFNlbGVjdGVkRGF0ZSgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKHRoaXMuc2VsZWN0ZWREYXRlLCB0aGlzLmRhdGVGb3JtYXQsIHRoaXMubGFuZykgfHwgJyc7XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIFVwZGF0ZSB0aGUgaW5wdXQgdmFsdWUgZGlzcGxheWVkIGluIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAqIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIGlucHV0IHZhbHVlIHRvIGVpdGhlciB0aGUgZWRpdGVkIGRhdGUgb3IgdGhlIGZvcm1hdHRlZCBzZWxlY3RlZCBkYXRlLFxyXG4gKiBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgdXNlciBpcyBpbiBlZGl0IG1vZGUgb3Igbm90LlxyXG4gKiBgYGBcclxuICogLy8gVXBkYXRlIHRoZSBpbnB1dCB2YWx1ZVxyXG4gKiB0aGlzLnVwZGF0ZUlucHV0VmFsdWUoKTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSB1cGRhdGVJbnB1dFZhbHVlKCkge1xyXG4gICAgdGhpcy5mb3JtYXR0ZWREYXRlID0gdGhpcy5pc0VkaXRpbmcgPyB0aGlzLmVkaXRlZERhdGUgOiB0aGlzLmZvcm1hdFNlbGVjdGVkRGF0ZSgpO1xyXG4gIH1cclxuXHJcbi8qKlxyXG4gKiBHZXQgYW4gYXJyYXkgb2YgYXJyYXlzIHJlcHJlc2VudGluZyB0aGUgZGF5cyBvZiB0aGUgY3VycmVudCBtb250aC5cclxuICogRWFjaCBzdWItYXJyYXkgY29udGFpbnMgdGhlIGRheSBkYXRhIGZvciBhIHdlZWssIGFuZCBlYWNoIGRheSBkYXRhIG9iamVjdCBpbmNsdWRlcyB0aGUgZGF0ZSBhbmQgd2hldGhlciBpdCBiZWxvbmdzIHRvIHRoZSBjdXJyZW50IG1vbnRoLlxyXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBhcnJheXMgcmVwcmVzZW50aW5nIHRoZSBkYXlzIG9mIHRoZSBjdXJyZW50IG1vbnRoLlxyXG4gKiBgYGBcclxuICogLy8gR2V0IGFuIGFycmF5IG9mIGFycmF5cyByZXByZXNlbnRpbmcgdGhlIGRheXMgb2YgdGhlIGN1cnJlbnQgbW9udGhcclxuICogY29uc3QgY2FsZW5kYXIgPSB0aGlzLmNhbGVuZGFyRGF5cztcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSBnZXQgY2FsZW5kYXJEYXlzKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuY2FsY3VsYXRlRmlyc3REYXlPZkNhbGVuZGFyKCk7XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgZGF0ZSBvZiB0aGUgcHJldmlvdXMgbW9udGggdG8gZGlzcGxheSBpbiBlbXB0eSBjZWxscyBvZiB0aGUgY3VycmVudCBtb250aC5cclxuICogVGhpcyBtZXRob2QgcmV0dXJucyB0aGUgZGF0ZSBvZiB0aGUgcHJldmlvdXMgbW9udGggaWYgdGhlIHByb3ZpZGVkIGRhdGUgaXMgbm90IGluIHRoZSBjdXJyZW50IG1vbnRoLlxyXG4gKiBJZiB0aGUgcHJvdmlkZWQgZGF0ZSBpcyBpbiB0aGUgY3VycmVudCBtb250aCwgaXQgcmV0dXJucyB0aGUgZGF0ZSdzIGRheSBhcyBhIHN0cmluZy5cclxuICogQHBhcmFtIGRhdGUgLSBUaGUgZGF0ZSB0byBldmFsdWF0ZS5cclxuICogQHJldHVybnMgVGhlIGRhdGUgb2YgdGhlIHByZXZpb3VzIG1vbnRoIG9yIGEgZGF5IHN0cmluZy5cclxuICogYGBgXHJcbiAqIC8vIEdldCB0aGUgcHJldmlvdXMgbW9udGgncyBkYXRlIHRvIGRpc3BsYXkgaW4gZW1wdHkgY2VsbHNcclxuICogY29uc3QgcHJldmlvdXNNb250aERhdGUgPSB0aGlzLmdldFByZXZpb3VzTW9udGhEYXRlKG5ldyBEYXRlKDIwMjMsIDgsIDEpKTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSBnZXRQcmV2aW91c01vbnRoRGF0ZShkYXRlOiBEYXRlKTogYW55IHtcclxuICAgIGlmICghZGF0ZSkge1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICBjb25zdCBjdXJyZW50RGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICBpZiAoZGF0ZS5nZXRNb250aCgpID09PSBjdXJyZW50RGF0ZS5nZXRNb250aCgpICYmIGRhdGUuZ2V0RnVsbFllYXIoKSA9PT0gY3VycmVudERhdGUuZ2V0RnVsbFllYXIoKSkge1xyXG4gICAgICByZXR1cm4gZGF0ZS5nZXREYXRlKCkudG9TdHJpbmcoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybShkYXRlLCAnZGQnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4vKipcclxuICogTmF2aWdhdGUgdG8gdGhlIHByZXZpb3VzIG1vbnRoIGluIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAqIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIHNlbGVjdGVkRGF0ZSwgZm9ybWF0cyBpdCwgYW5kIHJlY2FsY3VsYXRlcyB0aGUgZmlyc3QgZGF5IG9mIHRoZSBjYWxlbmRhci5cclxuICogYGBgXHJcbiAqIC8vIE5hdmlnYXRlIHRvIHRoZSBwcmV2aW91cyBtb250aFxyXG4gKiB0aGlzLmdldFByZXZpb3VzTW9udGgoKTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSBnZXRQcmV2aW91c01vbnRoKCkge1xyXG4gICAgY29uc3QgY3VycmVudE1vbnRoID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0TW9udGgoKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbmV3IERhdGUodGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKSwgY3VycmVudE1vbnRoIC0gMSwgMSk7XHJcbiAgICB0aGlzLmZvcm1hdERhdGUoKTtcclxuICAgIHRoaXMuY2FsY3VsYXRlRmlyc3REYXlPZkNhbGVuZGFyKCk7XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIE5hdmlnYXRlIHRvIHRoZSBuZXh0IG1vbnRoIGluIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAqIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIHNlbGVjdGVkRGF0ZSwgZm9ybWF0cyBpdCwgYW5kIHJlY2FsY3VsYXRlcyB0aGUgZmlyc3QgZGF5IG9mIHRoZSBjYWxlbmRhci5cclxuICogYGBgXHJcbiAqIC8vIE5hdmlnYXRlIHRvIHRoZSBuZXh0IG1vbnRoXHJcbiAqIHRoaXMuZ2V0TmV4dE1vbnRoKCk7XHJcbiAqIGBgYFxyXG4qL1xyXG4gIHByaXZhdGUgZ2V0TmV4dE1vbnRoKCkge1xyXG4gICAgY29uc3QgY3VycmVudE1vbnRoID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0TW9udGgoKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbmV3IERhdGUodGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKSwgY3VycmVudE1vbnRoICsgMSwgMSk7XHJcbiAgICB0aGlzLmZvcm1hdERhdGUoKTtcclxuICAgIHRoaXMuY2FsY3VsYXRlRmlyc3REYXlPZkNhbGVuZGFyKCk7XHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgbnVtYmVyIG9mIGRheXMgaW4gYSBnaXZlbiBtb250aCBvZiBhIHNwZWNpZmljIHllYXIuXHJcbiAqIEBwYXJhbSB5ZWFyIC0gVGhlIHllYXIgZm9yIHdoaWNoIHlvdSB3YW50IHRvIGRldGVybWluZSB0aGUgbnVtYmVyIG9mIGRheXMuXHJcbiAqIEBwYXJhbSBtb250aCAtIFRoZSBtb250aCAoMC1iYXNlZCBpbmRleCkgZm9yIHdoaWNoIHlvdSB3YW50IHRvIGRldGVybWluZSB0aGUgbnVtYmVyIG9mIGRheXMuXHJcbiAqIEByZXR1cm5zIFRoZSBudW1iZXIgb2YgZGF5cyBpbiB0aGUgc3BlY2lmaWVkIG1vbnRoIG9mIHRoZSBnaXZlbiB5ZWFyLlxyXG4qL1xyXG4gIHByaXZhdGUgZGF5c0luTW9udGgoeWVhcjogbnVtYmVyLCBtb250aDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIHJldHVybiBuZXcgRGF0ZSh5ZWFyLCBtb250aCArIDEsIDApLmdldERhdGUoKTtcclxuICB9XHJcblxyXG4vKipcclxuICogQ2FsY3VsYXRlIHRoZSBzdHJ1Y3R1cmUgb2YgZGF5cyBpbiBhIG1vbnRoIGZvciB0aGUgY2FsZW5kYXIgZGlzcGxheS5cclxuICogVGhpcyBtZXRob2QgZ2VuZXJhdGVzIGEgbWF0cml4IG9mIGRheSBkYXRhIG9iamVjdHMgcmVwcmVzZW50aW5nIHRoZSBkYXlzIGluIHRoZSBjYWxlbmRhci5cclxuICogRWFjaCBkYXkgZGF0YSBvYmplY3QgY29udGFpbnMgdGhlIGRhdGUgYW5kIHdoZXRoZXIgaXQgYmVsb25ncyB0byB0aGUgY3VycmVudCBtb250aC5cclxuICogQHJldHVybnMgQSBtYXRyaXggb2YgZGF5IGRhdGEgb2JqZWN0cyBmb3IgdGhlIGNhbGVuZGFyIGRpc3BsYXkuXHJcbiovXHJcbiAgcHJpdmF0ZSBjYWxjdWxhdGVGaXJzdERheU9mQ2FsZW5kYXIoKSB7XHJcbiAgICBjb25zdCB5ZWFyID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKTtcclxuICAgIGNvbnN0IG1vbnRoID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0TW9udGgoKTtcclxuICAgIGNvbnN0IGZpcnN0RGF5T2ZNb250aCA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCAxKTtcclxuICAgIGNvbnN0IGZpcnN0V2Vla2RheSA9IGZpcnN0RGF5T2ZNb250aC5nZXREYXkoKTtcclxuICAgIGNvbnN0IHN0YXJ0RGF5ID0gZmlyc3RXZWVrZGF5ID09PSAwID8gLTUgOiAyIC0gZmlyc3RXZWVrZGF5O1xyXG4gICAgY29uc3QgY2FsZW5kYXJEYXlzID0gW107XHJcbiAgICBsZXQgY3VycmVudERheSA9IHN0YXJ0RGF5O1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcclxuICAgICAgY29uc3Qgd2VlayA9IFtdO1xyXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IDc7IGorKykge1xyXG4gICAgICAgIGNvbnN0IGRheSA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCBjdXJyZW50RGF5KTtcclxuICAgICAgICBjb25zdCBkYXlEYXRhID0ge1xyXG4gICAgICAgICAgZGF0ZTogZGF5LFxyXG4gICAgICAgICAgaXNDdXJyZW50TW9udGg6IGN1cnJlbnREYXkgPj0gMSAmJiBjdXJyZW50RGF5IDw9IHRoaXMuZGF5c0luTW9udGgoeWVhciwgbW9udGgpLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgd2Vlay5wdXNoKGRheURhdGEpO1xyXG4gICAgICAgIGN1cnJlbnREYXkrKztcclxuICAgICAgfVxyXG4gICAgICBjYWxlbmRhckRheXMucHVzaCh3ZWVrKTtcclxuICAgIH1cclxuICAgIHJldHVybiBjYWxlbmRhckRheXM7XHJcbiAgfVxyXG4gIFxyXG4vKipcclxuICogQ2hlY2sgaWYgYSBnaXZlbiBkYXRlIGlzIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZGF0ZSBpbiB0aGUgY2FsZW5kYXIuXHJcbiAqIEBwYXJhbSBkYXRlIC0gVGhlIGRhdGUgdG8gY2hlY2suXHJcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvdmlkZWQgZGF0ZSBtYXRjaGVzIHRoZSBzZWxlY3RlZCBkYXRlLCBvdGhlcndpc2UgYGZhbHNlYC5cclxuICogYGBgXHJcbiAqIC8vIENoZWNrIGlmIGEgZGF0ZSBpcyBzZWxlY3RlZFxyXG4gKiBjb25zdCBpc1NlbGVjdGVkID0gdGhpcy5pc0RhdGVTZWxlY3RlZChzb21lRGF0ZSk7XHJcbiAqIGBgYFxyXG4qL1xyXG4gIHByaXZhdGUgaXNEYXRlU2VsZWN0ZWQoZGF0ZTogRGF0ZSkge1xyXG4gICAgcmV0dXJuIGRhdGUudG9EYXRlU3RyaW5nKCkgPT09IHRoaXMuc2VsZWN0ZWREYXRlLnRvRGF0ZVN0cmluZygpO1xyXG4gIH1cclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiBhIGRhdGUgc3RyaW5nIGlzIHZhbGlkIGJhc2VkIG9uIHRoZSBzcGVjaWZpZWQgZGF0ZSBmb3JtYXQuXHJcbiAqIEBwYXJhbSBpbnB1dERhdGUgLSBUaGUgZGF0ZSBzdHJpbmcgdG8gdmFsaWRhdGUuXHJcbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgaW5wdXQgZGF0ZSBzdHJpbmcgaXMgdmFsaWQsIG90aGVyd2lzZSBgZmFsc2VgLlxyXG4gKiBgYGBcclxuICogLy8gQ2hlY2sgaWYgYSBkYXRlIHN0cmluZyBpcyB2YWxpZFxyXG4gKiBjb25zdCBpc1ZhbGlkRGF0ZSA9IHRoaXMuaXNEYXRlVmFsaWQoJzA1LzI1LzIwMjMnKTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSBpc0RhdGVWYWxpZChpbnB1dERhdGU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuZGF0ZVJlZ0V4cC50ZXN0KGlucHV0RGF0ZSk7XHJcbiAgfVxyXG4gIFxyXG4vKipcclxuICogQ2hlY2sgaWYgYSBnaXZlbiBkYXRlIGlzIHRvZGF5J3MgZGF0ZS5cclxuICogQHBhcmFtIGRhdGUgLSBUaGUgZGF0ZSB0byBjaGVjay5cclxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBwcm92aWRlZCBkYXRlIGlzIHRvZGF5J3MgZGF0ZSwgb3RoZXJ3aXNlIGBmYWxzZWAuXHJcbiAqIGBgYFxyXG4gKiAvLyBDaGVjayBpZiBhIGRhdGUgaXMgdG9kYXkncyBkYXRlXHJcbiAqIGNvbnN0IGlzVG9kYXkgPSB0aGlzLmlzRGF0ZVRvZGF5KHNvbWVEYXRlKTtcclxuICogYGBgXHJcbiovXHJcbiAgcHJpdmF0ZSBpc0RhdGVUb2RheShkYXRlOiBEYXRlKSB7XHJcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XHJcbiAgICByZXR1cm4gZGF0ZS50b0RhdGVTdHJpbmcoKSA9PT0gdG9kYXkudG9EYXRlU3RyaW5nKCk7XHJcbiAgfVxyXG59IiwiPGRpdiBjbGFzcz1cImRhdGVwaWNrZXItY29udGFpbmVyXCJcclxuW2NsYXNzLmRpc2FibGVkXT1cImRpc2FibGVkXCJcclxuPlxyXG5cclxuICA8IS0tIElucHV0LCBzYXZlICYgZWRpdCBidXR0b25zIC0tPlxyXG4gICAgPGRpdiBjbGFzcz1cImlucHV0LWNvbnRhaW5lclwiPlxyXG5cclxuICAgICAgPGRpdiAqbmdJZj1cIiFpc0VkaXRpbmdcIj5cclxuXHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgdHlwZT1cInRleHRcIlxyXG4gICAgICAgIChjbGljayk9XCJ0b2dnbGVDYWxlbmRhcigpXCJcclxuICAgICAgICBbdmFsdWVdPVwiZm9ybWF0dGVkRGF0ZVwiXHJcbiAgICAgICAgW3JlYWRPbmx5XT1cInRydWVcIlxyXG4gICAgICAgIFtkaXNhYmxlZF09XCJpc0VkaXRpbmdcIlxyXG4gICAgICA+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwhLS0gRWRpdCAtLT5cclxuICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXBlbmNpbC1zcXVhcmUtbyBlZGl0LWJ1dHRvblwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiIChjbGljayk9XCJ0b2dnbGVFZGl0KClcIj48L2k+IFxyXG5cclxuICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNFZGl0aW5nXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICAgIFt2YWx1ZV09XCJlZGl0ZWREYXRlXCJcclxuICAgICAgICAgICAgKGlucHV0KT1cIm9uRGF0ZUlucHV0KCRldmVudClcIlxyXG4gICAgICAgICAgICBjbGFzcz1cImJvcmRlci0zXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZUNhbGVuZGFyKClcIlxyXG4gICAgICAgICAgICA+XHJcbiAgICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtZmxvcHB5LW8gZWRpdC1idXR0b25cIiAoY2xpY2spPVwic2F2ZUVkaXRlZERhdGUoKVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cclxuICAgICA8L2Rpdj4gICAgIFxyXG4gICAgPC9kaXY+XHJcblxyXG48IS0tIENhbGVuZGFyKERyb3Bkb3ducywgZGF0ZXMpIC0tPlxyXG4gIDxkaXYgKm5nSWY9XCJpc0NhbGVuZGFyT3BlblwiIGNsYXNzPVwiY2FsZW5kYXJcIiAjY2FsZW5kYXJDb250YWluZXIgXHJcbiAgW3N0eWxlLnRvcF09XCJ0b3BPZmZzZXRcIlxyXG4gIFtzdHlsZS5sZWZ0XT1cImxlZnRPZmZzZXRcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1oZWFkZXJcIj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9udGhCdXR0b25Db250YWluZXJcIj5cclxuICAgICAgICAgICAgPCEtLSBNb250aCBkcm9wZG93biAtLT5cclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTW9udGhEcm9wZG93bk9wZW47IGVsc2UgbW9udGhMYWJlbFwiPlxyXG4gICAgICAgICAgICAgIDxtZWZkZXYtc2VsZWN0ICAgIFxyXG4gICAgICAgICAgICAgIGNsYXNzPVwibW9udGhEcm9wZG93blwiXHJcbiAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJzZWxlY3RlZERhdGVNb250aFwiIFxyXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uTW9udGhDaGFuZ2UoKVwiXHJcbiAgICAgICAgICAgICAgW1BsYWNlSG9sZGVyXT1cIidtb250aCdcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDxtZWZkZXYtb3B0aW9uIFxyXG4gICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IG1vbnRoIG9mIG1vbnRoczsgbGV0IGkgPSBpbmRleFwiIFxyXG4gICAgICAgICAgICAgICAgW1ZhbHVlXT1cImlcIlxyXG4gICAgICAgICAgICAgICAgW0xhYmVsXSA9IFwibW9udGhcIiBcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgPnt7IG1vbnRoIH19PC9tZWZkZXYtb3B0aW9uPlxyXG4gICAgICAgICAgICAgIDwvbWVmZGV2LXNlbGVjdD5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjbW9udGhMYWJlbD5cclxuICAgICAgICAgICAgICA8c3BhbiAoY2xpY2spPVwidG9nZ2xlTW9udGhEcm9wZG93bigkZXZlbnQpXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxyXG5cclxuICAgICAgICAgICAgPCEtLSBZZWFyIGRyb3Bkb3duIC0tPlxyXG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNZZWFyRHJvcGRvd25PcGVuOyBlbHNlIHllYXJMYWJlbFwiPlxyXG4gICAgICAgICAgICAgIDxtZWZkZXYtc2VsZWN0IFxyXG4gICAgICAgICAgICAgIGNsYXNzPVwieWVhckRyb3Bkb3duXCIgXHJcbiAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJzZWxlY3RlZERhdGVZZWFyXCIgXHJcbiAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25ZZWFyQ2hhbmdlKClcIlxyXG4gICAgICAgICAgICAgIFtQbGFjZUhvbGRlcl09XCIneWVhcidcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgICAgPG1lZmRldi1vcHRpb24gXHJcbiAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCB5ZWFyIG9mIHllYXJzXCIgXHJcbiAgICAgICAgICAgICAgICAgIFtMYWJlbF0gPSBcInllYXJcIiBcclxuICAgICAgICAgICAgICAgICAgW1ZhbHVlXT1cInllYXJcIiBcclxuICAgICAgICAgICAgICAgICAgPnt7eWVhcn19PC9tZWZkZXYtb3B0aW9uPlxyXG4gICAgICAgICAgICAgIDwvbWVmZGV2LXNlbGVjdD5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjeWVhckxhYmVsPlxyXG4gICAgICAgICAgICAgIDxzcGFuIChjbGljayk9XCJ0b2dnbGVZZWFyRHJvcGRvd24oJGV2ZW50KVwiPnt7IHNlbGVjdGVkRGF0ZVllYXIgfX08L3NwYW4+XHJcbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgPCEtLSBDYWxlbmRhciBleGl0IGJ1dHRvbiAtLT5cclxuICAgICAgICAgICA8ZGl2PlxyXG4gICAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLXRpbWVzIHRvZ2dsZUNhbGVuZGFyQnV0dG9uXCIgKGNsaWNrKT1cInRvZ2dsZUNhbGVuZGFyKClcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgICBcclxuICAgIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1ib2R5XCI+XHJcbiAgICAgIDx0YWJsZT5cclxuICAgICAgICA8dHI+XHJcbiAgICAgICAgICA8dGggY2xhc3M9XCJhbGlnbi1pdGVtcy1jZW50ZXJcIiAqbmdGb3I9XCJsZXQgd2Vla2RheSBvZiB3ZWVrZGF5c1wiPnt7IHdlZWtkYXkgfX08L3RoPlxyXG4gICAgICAgIDwvdHI+XHJcbiAgICAgICAgPHRyICpuZ0Zvcj1cImxldCB3ZWVrIG9mIGNhbGVuZGFyRGF5c1wiPlxyXG4gICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCBkYXlEYXRhIG9mIHdlZWtcIiBcclxuICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0RGF0ZShkYXlEYXRhLmRhdGUpXCJcclxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdzZWxlY3RlZCc6IGlzRGF0ZVNlbGVjdGVkKGRheURhdGEuZGF0ZSksICdwcmV2LW1vbnRoJzogIWRheURhdGEuaXNDdXJyZW50TW9udGggfVwiPlxyXG5cclxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkYXRlXCIgXHJcbiAgICAgICAgICAgICAgW2NsYXNzLnByZXYtbW9udGhdPVwiIWRheURhdGEuaXNDdXJyZW50TW9udGhcIlxyXG4gICAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICB7eyBkYXlEYXRhLmRhdGUuZ2V0RGF0ZSgpIH19XHJcbiAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgPC90cj5cclxuICAgICAgPC90YWJsZT5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG48L2Rpdj5cclxuXHJcbiJdfQ==
607
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS1raXQtbGliL3NyYy9saWIvbWFya3VwLWtpdC91dGlscy9kYXRlcGlja2VyL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS1raXQtbGliL3NyYy9saWIvbWFya3VwLWtpdC91dGlscy9kYXRlcGlja2VyL2RhdGVwaWNrZXIvZGF0ZXBpY2tlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFlBQVksR0FDYixNQUFNLGVBQWUsQ0FBQzs7Ozs7O0FBR3ZCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBUUgsTUFBTSxPQUFPLG1CQUFtQjtJQThMVjtJQUE0QjtJQTVMaEQ7OztPQUdHO0lBQ0gsZUFBZSxHQUFZLElBQUksQ0FBQztJQUVoQzs7O09BR0c7SUFDSCxjQUFjLEdBQVksS0FBSyxDQUFDO0lBRWhDOzs7T0FHRztJQUNILFlBQVksR0FBUyxJQUFJLElBQUksRUFBRSxDQUFDO0lBRWhDOzs7T0FHRztJQUNILGFBQWEsQ0FBTztJQUVwQjs7O09BR0c7SUFDSCxVQUFVLEdBQVcsRUFBRSxDQUFDO0lBRXhCOzs7T0FHRztJQUNILG1CQUFtQixHQUFZLElBQUksQ0FBQztJQUVwQzs7O09BR0c7SUFDSCxrQkFBa0IsR0FBWSxJQUFJLENBQUM7SUFFbkM7OztPQUdHO0lBQ0gsaUJBQWlCLEdBQVcsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUV6RDs7O09BR0c7SUFDSCxnQkFBZ0IsR0FBVyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRTNEOzs7T0FHRztJQUNI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O3NCQUFwQixNQUFNO2dCQXlCUCxPQUFPO3NCQUROLFlBQVk7dUJBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBJbnB1dCxcclxuICBPbkNoYW5nZXMsXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERhdGVQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuXHJcbi8qKlxyXG4gKiBEYXRlcGlja2VyIENvbXBvbmVudCBmb3Igc2VsZWN0aW5nIGRhdGVzLlxyXG4gKlxyXG4gKiBUaGlzIGNvbXBvbmVudCBhbGxvd3MgdXNlcnMgdG8gcGljayBhIGRhdGUgZnJvbSBhIGNhbGVuZGFyIGludGVyZmFjZS5cclxuICogSXQgc3VwcG9ydHMgdmFyaW91cyBjb25maWd1cmF0aW9uIG9wdGlvbnMgc3VjaCBhcyBsYW5ndWFnZSwgZGF0ZSBmb3JtYXQsIGFuZCBkYXRlIHJhbmdlLlxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICogICBbbGFiZWxDb250ZW50VGV4dF09XCInU2VsZWN0IHlvdXIgZGF0ZSdcIlxyXG4gKiAgIFtsYW5nXT1cIid1aydcIlxyXG4gKiAgIFtkYXRlRm9ybWF0XT1cIidkZC9NTS95eXl5J1wiXHJcbiAqICAgW3JhbmdlXT1cIntzdGFydFllYXI6IDE5MDAsIHRvWWVhcjogMzAwfVwiXHJcbiAqICAgW2Rpc2FibGVkXT1cImZhbHNlXCJcclxuICogICAoZGF0ZUNoYW5nZWQpPVwib25EYXRlQ2hhbmdlZCgkZXZlbnQpXCJcclxuICogICBbdG9wT2Zmc2V0XT1cIicyMCdcIlxyXG4gKiAgIFtsZWZ0T2Zmc2V0XT1cIicxMCdcIj5cclxuICogPC9tZWZkZXYtZGF0ZXBpY2tlcj5cclxuICpcclxuICogPGV4YW1wbGUtdXJsPmh0dHBzOi8vbWVmLmRldi91aV9raXRfZGVtby92aWV3L3V0aWxzL2RhdGVwaWNrZXI8L2V4YW1wbGUtdXJsPlxyXG4gKi9cclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbWVmZGV2LWRhdGVwaWNrZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlcGlja2VyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9kYXRlcGlja2VyLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBEYXRlcGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgIE9uQ2hhbmdlcywgT25Jbml0IHtcclxuXHJcbiAgLyoqXHJcbiAgICogQSBmbGFnIHRoYXQgY2hlY2tzIHdoZXRoZXIgYSB2YWxpZCBkYXRlIGhhcyBiZWVuIGVudGVyZWQgYW5kIHdoZXRoZXIgdGhlIGVudGVyZWQgZGF0ZSBleGlzdHMuXHJcbiAgICogSWYgdGhlIHR3byBwcmV2aW91cyBjb25kaXRpb25zIGFyZSBub3QgdHJ1ZSwgdGhlIGRhdGVwaWNrZXIgd2lsbCBiZSBoaWdobGlnaHRlZCBpbiByZWRcclxuICAgKi9cclxuICBpc1VzZXJEYXRlVmFsaWQ6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICAvKipcclxuICAgKiBGbGFnIHRvIGRldGVybWluZSBpZiB0aGUgY2FsZW5kYXIgaXMgb3BlbiBvciBjbG9zZWQuXHJcbiAgICogRGVmYXVsdCB2YWx1ZTogZmFsc2UgKGNsb3NlZCkuXHJcbiAgICovXHJcbiAgaXNDYWxlbmRhck9wZW46IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGN1cnJlbnRseSBzZWxlY3RlZCBkYXRlLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6IFRvZGF5J3MgZGF0ZS5cclxuICAgKi9cclxuICBzZWxlY3RlZERhdGU6IERhdGUgPSBuZXcgRGF0ZSgpO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgZm9ybWF0dGVkIGRhdGUgZm9yIGRpc3BsYXkgaW4gdGhlIGlucHV0LlxyXG4gICAqIERlZmF1bHQgdmFsdWU6IEZvcm1hdHRlZCByZXByZXNlbnRhdGlvbiBvZiB0aGUgc2VsZWN0ZWQgZGF0ZS5cclxuICAgKi9cclxuICBmb3JtYXR0ZWREYXRlOiBhbnkgO1xyXG5cclxuICAvKipcclxuICAgKiBUcmFjayB0aGUgZWRpdGVkIGRhdGUgc2VwYXJhdGVseSB3aGVuIGluIGVkaXRpbmcgbW9kZS5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiBBbiBlbXB0eSBzdHJpbmcuXHJcbiAgICovXHJcbiAgZWRpdGVkRGF0ZTogc3RyaW5nID0gJyc7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZsYWcgdG8gZGV0ZXJtaW5lIGlmIHRoZSBtb250aCBkcm9wZG93biBpcyBvcGVuIG9yIGNsb3NlZC5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiB0cnVlIChvcGVuKS5cclxuICAgKi9cclxuICBpc01vbnRoRHJvcGRvd25PcGVuOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogRmxhZyB0byBkZXRlcm1pbmUgaWYgdGhlIHllYXIgZHJvcGRvd24gaXMgb3BlbiBvciBjbG9zZWQuXHJcbiAgICogRGVmYXVsdCB2YWx1ZTogdHJ1ZSAob3BlbikuXHJcbiAgICovXHJcbiAgaXNZZWFyRHJvcGRvd25PcGVuOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHNlbGVjdGVkIG1vbnRoICgwLTExKS5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiBUaGUgbW9udGggb2YgdGhlIHNlbGVjdGVkIGRhdGUuXHJcbiAgICovXHJcbiAgc2VsZWN0ZWREYXRlTW9udGg6IG51bWJlciA9IHRoaXMuc2VsZWN0ZWREYXRlLmdldE1vbnRoKCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBzZWxlY3RlZCB5ZWFyLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6IFRoZSB5ZWFyIG9mIHRoZSBzZWxlY3RlZCBkYXRlLlxyXG4gICAqL1xyXG4gIHNlbGVjdGVkRGF0ZVllYXI6IG51bWJlciA9IHRoaXMuc2VsZWN0ZWREYXRlLmdldEZ1bGxZZWFyKCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEFuIGFycmF5IG9mIHllYXJzIGZvciB0aGUgeWVhciBkcm9wZG93bi5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiBBbiBhcnJheSBvZiB5ZWFycyB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZS5cclxuICAgKi9cclxuICB5ZWFyczogbnVtYmVyW11cclxuXHJcbiAgLyoqXHJcbiAgICogTGFiZWwgdGV4dCBmb3IgdGhlIGRhdGVwaWNrZXIuXHJcbiAgICogRGVmYXVsdCB2YWx1ZTogJ2VuJyAoRW5nbGlzaCkuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFtsYWJlbENvbnRlbnRUZXh0XSA9IFwiJ0Nob3NlIHlvdXIgZGF0ZSdcIj5cclxuICAgKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGxhYmVsQ29udGVudFRleHQ6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGxhbmd1YWdlL2xvY2FsZSBmb3IgdGhlIGRhdGVwaWNrZXIuXHJcbiAgICogRGVmYXVsdCB2YWx1ZTogJ2VuJyAoRW5nbGlzaCkuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFtsYW5nXSA9IFwiJ3VrJ1wiPlxyXG4gICAqIDwvbWVmZGV2LWRhdGVwaWNrZXI+XHJcbiAgICovXHJcbiAgQElucHV0KCkgbGFuZzogc3RyaW5nID0gJ2VuJztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGRhdGUgZm9ybWF0IGZvciBkaXNwbGF5aW5nIHRoZSBzZWxlY3RlZCBkYXRlLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6ICdFRUUgTU1NIGRkIHl5eXknLlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogPG1lZmRldi1kYXRlcGlja2VyXHJcbiAgICogICBbZGF0ZUZvcm1hdF09XCInZGQvTU0veXl5eSdcIj5cclxuICAgKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGRhdGVGb3JtYXQ6IHN0cmluZyA9ICdFRUUgTU1NIGRkIHl5eXknO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgcmFuZ2Ugb2YgeWVhcnMgYXZhaWxhYmxlIGluIHRoZSB5ZWFyIGRyb3Bkb3duLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6IHsgc3RhcnRZZWFyOiAxOTAwLCB0b1llYXI6IDMwMCB9LlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogPG1lZmRldi1kYXRlcGlja2VyXHJcbiAgICogICBbcmFuZ2VdPVwie3N0YXJ0WWVhcjogMTkwMCwgdG9ZZWFyOiAzMDB9XCI+XHJcbiAgICogPC9tZWZkZXYtZGF0ZXBpY2tlcj5cclxuICAgKi9cclxuICBASW5wdXQoJ3JhbmdlJykgeWVhcnNSYW5nZTp7c3RhcnRZZWFyOm51bWJlciwgdG9ZZWFyOm51bWJlcn0gPSB7c3RhcnRZZWFyOjE5MDAsIHRvWWVhcjozMDB9O1xyXG5cclxuICAvKipcclxuICAgKiBXaGV0aGVyIHRoZSBkYXRlcGlja2VyIGlzIGRpc2FibGVkIG9yIG5vdC5cclxuICAgKiBEZWZhdWx0IHZhbHVlOiBmYWxzZSAoZW5hYmxlZCkuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFtkaXNhYmxlZF09XCJmYWxzZVwiPlxyXG4gICAqIDwvbWVmZGV2LWRhdGVwaWNrZXI+XHJcbiAgICovXHJcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHRvcCBvZmZzZXQgZm9yIHBvc2l0aW9uaW5nIHRoZSBkYXRlcGlja2VyLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6ICcyMCcuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFt0b3BPZmZzZXRdPVwiJzIwJ1wiPlxyXG4gICAqIDwvbWVmZGV2LWRhdGVwaWNrZXI+XHJcbiAgICovXHJcbiAgQElucHV0KCkgdG9wT2Zmc2V0OiBzdHJpbmcgPSAnMjAnO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgbGVmdCBvZmZzZXQgZm9yIHBvc2l0aW9uaW5nIHRoZSBkYXRlcGlja2VyLlxyXG4gICAqIERlZmF1bHQgdmFsdWU6ICcxMCcuXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiA8bWVmZGV2LWRhdGVwaWNrZXJcclxuICAgKiAgIFtsZWZ0T2Zmc2V0XT1cIicxMCdcIj5cclxuICAgKiA8L21lZmRldi1kYXRlcGlja2VyPlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGxlZnRPZmZzZXQ6IHN0cmluZyA9ICcxMCc7IC8vRGVmYXVsdCB2YWx1ZVxyXG5cclxuICAvKipcclxuICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIHNlbGVjdGVkIGRhdGUgaW4gdGhlIGRhdGVwaWNrZXIgY2hhbmdlcy5cclxuICAgKiBJdCBlbWl0cyBhIGBEYXRlYCBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBzZWxlY3RlZCBkYXRlLlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogPG1lZmRldi1kYXRlcGlja2VyXHJcbiAgICogICAoZGF0ZUNoYW5nZWQpPVwib25EYXRlQ2hhbmdlZCgkZXZlbnQpXCI+XHJcbiAgICogPC9tZWZkZXYtZGF0ZXBpY2tlcj5cclxuICAgKi9cclxuICBAT3V0cHV0KCkgZGF0ZUNoYW5nZWQ6IEV2ZW50RW1pdHRlcjxEYXRlPiA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZT4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogUmVndWxhciBleHByZXNzaW9uIHRvIHZhbGlkYXRlIHVzZXIgaW5wdXQgZm9yIGRhdGUgaW4gdGhlIGZvcm1hdCBcImRkL01NL3l5eXlcIi5cclxuICAgKiAtIFRoZSBkYXkgKGRkKSBzaG91bGQgYmUgYmV0d2VlbiAwMSBhbmQgMzEuXHJcbiAgICogLSBUaGUgbW9udGggKE1NKSBzaG91bGQgYmUgYmV0d2VlbiAwMSBhbmQgMTIuXHJcbiAgICogLSBUaGUgeWVhciAoeXl5eSkgc2hvdWxkIGJlIGEgNC1kaWdpdCBudW1iZXIuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBkYXRlUmVnRXhwOiBSZWdFeHAgPSAvXigwWzEtOV18WzEyXVswLTldfDNbMDFdKVxcLygwWzEtOV18MVswLTJdKVxcL1xcZHs0fSQvO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgc3RyaW5nIGVudGVyZWQgYnkgdGhlIHVzZXIgZm9yIGRhdGUgaW5wdXQuXHJcbiAgICogVGhpcyB2YXJpYWJsZSBzdG9yZXMgdGhlIHVzZXIncyBpbnB1dCBhcyB0aGV5IHR5cGUgaW4gdGhlIGRhdGUgZmllbGQuXHJcbiAgICovXHJcbiAgdXNlcklucHV0OiBzdHJpbmcgPSAnJztcclxuXHJcbiAgLyoqXHJcbiAgICogSG9zdCBsaXN0ZW5lciBmb3IgZG9jdW1lbnQgY2xpY2sgZXZlbnRzIHRvIGhhbmRsZSBjYWxlbmRhciBpbnRlcmFjdGlvbi5cclxuICAgKiBUaGlzIGZ1bmN0aW9uIGNoZWNrcyBpZiBhIGNsaWNrIGV2ZW50IG9jY3VycmVkIHdpdGhpbiB0aGUgY2FsZW5kYXIgb3IgaW5wdXQgZWxlbWVudHMuXHJcbiAgICogLSBJZiB0aGUgY2xpY2sgb2NjdXJyZWQgd2l0aGluIHRoZSBjYWxlbmRhciwgbm8gYWN0aW9uIGlzIHRha2VuLlxyXG4gICAqIC0gSWYgdGhlIGNsaWNrIG9jY3VycmVkIHdpdGhpbiB0aGUgaW5wdXQgZWxlbWVudCBhbmQgdGhlIGNvbXBvbmVudCBpcyBub3QgaW4gZWRpdGluZyBtb2RlLFxyXG4gICAqICAgaXQgb3BlbnMgdGhlIGNhbGVuZGFyLlxyXG4gICAqIEBwYXJhbSBldmVudCBUaGUgTW91c2VFdmVudCBvYmplY3QgcmVwcmVzZW50aW5nIHRoZSBjbGljayBldmVudC5cclxuICAgKi9cclxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXHJcbiAgb25DbGljayhldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgY29uc3QgdGFyZ2V0RWxlbWVudCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcclxuICAgIGNvbnN0IGRhdGVwaWNrZXJDb250YWluZXIgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuZGF0ZXBpY2tlci1jb250YWluZXInKTtcclxuICAgIGNvbnN0IGNhbGVuZGFyID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNhbGVuZGFyJyk7XHJcbiAgICBjb25zdCBtb250aERyb3Bkb3duID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLm1vbnRoRHJvcGRvd24nKTtcclxuICAgIGNvbnN0IHllYXJEcm9wZG93biA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy55ZWFyRHJvcGRvd24nKTtcclxuICAgIGNvbnN0IGlucHV0RWxlbWVudCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0Jyk7XHJcblxyXG4gICAgaWYgKGRhdGVwaWNrZXJDb250YWluZXIgJiYgZGF0ZXBpY2tlckNvbnRhaW5lci5jb250YWlucyhjYWxlbmRhcikpIHtcclxuICAgICAgaWYgKGNhbGVuZGFyICYmIGNhbGVuZGFyLmNvbnRhaW5zKHRhcmdldEVsZW1lbnQpKSByZXR1cm47XHJcbiAgICAgIGlmICh0aGlzLmlzTW9udGhEcm9wZG93bk9wZW4gJiYgIWNhbGVuZGFyLmNvbnRhaW5zKHRhcmdldEVsZW1lbnQpKSByZXR1cm47XHJcbiAgICAgIGlmICh0aGlzLmlzWWVhckRyb3Bkb3duT3BlbiAmJiAhY2FsZW5kYXIuY29udGFpbnModGFyZ2V0RWxlbWVudCkpIHJldHVybjtcclxuICAgICAgaWYgKChtb250aERyb3Bkb3duICYmIG1vbnRoRHJvcGRvd24uY29udGFpbnModGFyZ2V0RWxlbWVudCkpICYmICh5ZWFyRHJvcGRvd24gJiYgeWVhckRyb3Bkb3duLmNvbnRhaW5zKHRhcmdldEVsZW1lbnQpKSkge1xyXG4gICAgICAgIHRoaXMudG9nZ2xlTW9udGhEcm9wZG93bihldmVudClcclxuICAgICAgICB0aGlzLnRvZ2dsZVllYXJEcm9wZG93bihldmVudClcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ29uc3RydWN0b3IgZm9yIHRoZSBEYXRlcGlja2VyQ29tcG9uZW50IGNsYXNzLlxyXG4gICAqIEBwYXJhbSBkYXRlUGlwZSBBIHNlcnZpY2UgZm9yIGZvcm1hdHRpbmcgYW5kIHBhcnNpbmcgZGF0ZXMuXHJcbiAgICogQHBhcmFtIGVsZW1lbnRSZWYgQSByZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgb24gd2hpY2ggdGhpcyBjb21wb25lbnQgaXMgYXR0YWNoZWQuXHJcbiAgICogSXQgaXMgdXNlZCB0byBhY2Nlc3MgRE9NIGVsZW1lbnRzLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0ZVBpcGU6IERhdGVQaXBlLCBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHtcclxuICAgIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMaWZlY3ljbGUgaG9vayBjYWxsZWQgYWZ0ZXIgdGhlIGNvbXBvbmVudCBpcyBpbml0aWFsaXplZC5cclxuICAgKiBJdCBpbml0aWFsaXplcyB0aGUgeWVhcnMgZm9yIHRoZSB5ZWFyIHNlbGVjdCBkcm9wZG93bi5cclxuICAgKi9cclxuICBuZ09uSW5pdCgpe1xyXG4gICAgdGhpcy5pbml0aWFsaXplWWVhcnMoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExpZmVjeWNsZSBob29rIGNhbGxlZCB3aGVuZXZlciB0aGUgaW5wdXQgcHJvcGVydGllcyBvZiB0aGUgY29tcG9uZW50IGNoYW5nZS5cclxuICAgKiBJdCB1cGRhdGVzIHRoZSBpbnB1dCB2YWx1ZS5cclxuICAgKi9cclxuICBuZ09uQ2hhbmdlcygpIHtcclxuICAgIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQW4gYXJyYXkgb2YgbW9udGggbmFtZXMgYmFzZWQgb24gdGhlIHNlbGVjdGVkIGxhbmd1YWdlLlxyXG4gICAqIEl0IHByb3ZpZGVzIGxvY2FsaXplZCBtb250aCBuYW1lcyBmb3IgZGlzcGxheSBpbiB0aGUgZGF0ZXBpY2tlci5cclxuICAgKi9cclxuICBwcml2YXRlIGdldCBtb250aHMoKXtcclxuICAgIHJldHVybiB0aGlzLmdldE1vbnRoTGlzdCh0aGlzLmxhbmcpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQW4gYXJyYXkgb2Ygd2Vla2RheSBuYW1lcyBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgbGFuZ3VhZ2UuXHJcbiAgICogSXQgcHJvdmlkZXMgbG9jYWxpemVkIHdlZWtkYXkgbmFtZXMgZm9yIGRpc3BsYXkgaW4gdGhlIGRhdGVwaWNrZXIuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXQgd2Vla2RheXMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5nZXRXZWVrZGF5TGlzdCh0aGlzLmxhbmcpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZSB0aGUgbGlzdCBvZiB5ZWFycyB0byBiZSBkaXNwbGF5ZWQgaW4gdGhlIHllYXIgZHJvcGRvd24uXHJcbiAgICogVGhpcyBtZXRob2QgcG9wdWxhdGVzIHRoZSAneWVhcnMnIGFycmF5IHdpdGggYSByYW5nZSBvZiB5ZWFycyBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgJ3llYXJzUmFuZ2UnIGNvbmZpZ3VyYXRpb24uXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiBgYGBcclxuICAgKiAvLyBBc3N1bWluZyAneWVhcnNSYW5nZScgaXMgeyBzdGFydFllYXI6IDE5MDAsIHRvWWVhcjogMzAwIH1cclxuICAgKiAvLyBBZnRlciBjYWxsaW5nIGluaXRpYWxpemVZZWFycygpLCAneWVhcnMnIG1pZ2h0IGNvbnRhaW4gWzE5MDAsIDE5MDEsIC4uLiwgMzAwXVxyXG4gICAqIHRoaXMuaW5pdGlhbGl6ZVllYXJzKCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpbml0aWFsaXplWWVhcnMoKSB7XHJcbiAgICB0aGlzLnllYXJzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogdGhpcy55ZWFyc1JhbmdlLnRvWWVhciB9LCAoXywgaW5kZXgpID0+IGluZGV4ICsgdGhpcy55ZWFyc1JhbmdlLnN0YXJ0WWVhcik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGUgdGhlIGVkaXRpbmcgbW9kZSBmb3IgdGhlIGRhdGUgaW5wdXQuIFdoZW4gZW5hYmxlZCwgdGhlIHVzZXIgY2FuIGVkaXQgdGhlIGRhdGUgZGlyZWN0bHkgaW4gdGhlIGlucHV0IGZpZWxkLlxyXG4gICAqL1xyXG4gIHRvZ2dsZUVkaXQoKSB7XHJcbiAgICB0aGlzLmVkaXRlZERhdGUgPSB0aGlzLmZvcm1hdFNlbGVjdGVkRGF0ZSgpOyAvLyBTdG9yZSB0aGUgY3VycmVudCBmb3JtYXR0ZWQgZGF0ZSBmb3IgZWRpdGluZ1xyXG4gICAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGEgbGlzdCBvZiBtb250aCBuYW1lcyBpbiB0aGUgc3BlY2lmaWVkIGxhbmd1YWdlIGFuZCBmb3JtYXQuXHJcbiAgICogQHBhcmFtIGxvY2FsZXMgLSBBbiBvcHRpb25hbCBwYXJhbWV0ZXIgc3BlY2lmeWluZyB0aGUgbG9jYWxlIG9yIGxvY2FsZXMgdG8gdXNlIGZvciBmb3JtYXR0aW5nLlxyXG4gICAqIEBwYXJhbSBmb3JtYXQgLSBUaGUgZm9ybWF0IGZvciBtb250aCBuYW1lcywgZWl0aGVyIFwibG9uZ1wiIChkZWZhdWx0KSBvciBcInNob3J0XCIuXHJcbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgbW9udGggbmFtZXMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGZvcm1hdCBhbmQgbG9jYWxlLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIEdldCBhIGxpc3Qgb2YgbW9udGggbmFtZXMgaW4gdGhlIGRlZmF1bHQgbGFuZ3VhZ2UgYW5kIGxvbmcgZm9ybWF0XHJcbiAgICogY29uc3QgbW9udGhzID0gdGhpcy5nZXRNb250aExpc3QodGhpcy5sYW5nKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIGdldE1vbnRoTGlzdCggIGxvY2FsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSwgIGZvcm1hdDogXCJsb25nXCIgfCBcInNob3J0XCIgPSBcImxvbmdcIik6IHN0cmluZ1tdIHtcclxuICAgIGNvbnN0IHllYXIgPSBuZXcgRGF0ZSgpLmdldEZ1bGxZZWFyKCk7XHJcbiAgICBjb25zdCBtb250aExpc3QgPSBbLi4uQXJyYXkoMTIpLmtleXMoKV07XHJcbiAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgSW50bC5EYXRlVGltZUZvcm1hdChsb2NhbGVzLCB7ICAgIG1vbnRoOiBmb3JtYXQgIH0pO1xyXG4gICAgY29uc3QgZ2V0TW9udGhOYW1lID0gKG1vbnRoSW5kZXg6IG51bWJlcikgPT4gZm9ybWF0dGVyLmZvcm1hdChuZXcgRGF0ZSh5ZWFyLCBtb250aEluZGV4KSk7XHJcbiAgICByZXR1cm4gbW9udGhMaXN0Lm1hcChnZXRNb250aE5hbWUpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGEgbGlzdCBvZiB3ZWVrZGF5IG5hbWVzIGluIHRoZSBzcGVjaWZpZWQgbGFuZ3VhZ2UgYW5kIGZvcm1hdC5cclxuICAgKiBAcGFyYW0gbG9jYWxlcyAtIEFuIG9wdGlvbmFsIHBhcmFtZXRlciBzcGVjaWZ5aW5nIHRoZSBsb2NhbGUgb3IgbG9jYWxlcyB0byB1c2UgZm9yIGZvcm1hdHRpbmcuXHJcbiAgICogQHBhcmFtIGZvcm1hdCAtIFRoZSBmb3JtYXQgZm9yIHdlZWtkYXkgbmFtZXMsIGVpdGhlciBcInNob3J0XCIgKGRlZmF1bHQpIG9yIFwibG9uZ1wiLlxyXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIHdlZWtkYXkgbmFtZXMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGZvcm1hdCBhbmQgbG9jYWxlLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIEdldCBhIGxpc3Qgb2Ygd2Vla2RheSBuYW1lcyBpbiB0aGUgZGVmYXVsdCBsYW5ndWFnZSBhbmQgc2hvcnQgZm9ybWF0XHJcbiAgICogY29uc3Qgd2Vla2RheXMgPSB0aGlzLmdldFdlZWtkYXlMaXN0KCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRXZWVrZGF5TGlzdChsb2NhbGVzPzogc3RyaW5nIHwgc3RyaW5nW10sIGZvcm1hdDogXCJzaG9ydFwiIHwgXCJsb25nXCIgPSBcInNob3J0XCIpOiBzdHJpbmdbXSB7XHJcbiAgICBjb25zdCB3ZWVrZGF5cyA9IFsuLi5BcnJheSg3KS5rZXlzKCldO1xyXG4gICAgY29uc3QgbW9uZGF5SW5kZXggPSB3ZWVrZGF5cy5pbmRleE9mKDApO1xyXG4gICAgd2Vla2RheXMuc3BsaWNlKG1vbmRheUluZGV4LCAxKTtcclxuICAgIHdlZWtkYXlzLnB1c2goMCk7XHJcbiAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgSW50bC5EYXRlVGltZUZvcm1hdChsb2NhbGVzLCB7IHdlZWtkYXk6IGZvcm1hdCB9KTtcclxuICAgIGNvbnN0IGdldFdlZWtkYXlOYW1lID0gKHdlZWtkYXlJbmRleDogbnVtYmVyKSA9PiB7XHJcbiAgICAgIHJldHVybiBmb3JtYXR0ZXIuZm9ybWF0KG5ldyBEYXRlKDIwMjMsIDksIHdlZWtkYXlJbmRleCArIDEpKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gd2Vla2RheXMubWFwKGdldFdlZWtkYXlOYW1lKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNhdmUgdGhlIGVkaXRlZCBkYXRlIGlucHV0IGJ5IHRoZSB1c2VyLCBwcm92aWRlZCBpdCBtYXRjaGVzIHRoZSBzcGVjaWZpZWQgZGF0ZSBmb3JtYXQuXHJcbiAgICogVGhpcyBtZXRob2QgY2hlY2tzIGlmIHRoZSBlbnRlcmVkIGRhdGUgaXMgaW4gYSB2YWxpZCBmb3JtYXQsIGRpc2FibGVzIHRoZSBlZGl0aW5nIG1vZGUsIGFuZCBhcHBsaWVzXHJcbiAgICogdGhlIGVkaXRlZCBkYXRlIHRvIHRoZSAnc2VsZWN0ZWREYXRlJy4gSXQgdGhlbiByZWZvcm1hdHMgdGhlIHNlbGVjdGVkIGRhdGUgYW5kIGNsb3NlcyB0aGUgY2FsZW5kYXIuXHJcbiAgICogYGBgXHJcbiAgICogLy8gU2F2ZSB0aGUgZWRpdGVkIGRhdGUgYW5kIHVwZGF0ZSB0aGUgc2VsZWN0ZWQgZGF0ZVxyXG4gICAqIHRoaXMuc2F2ZUVkaXRlZERhdGUoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIHNhdmVFZGl0ZWREYXRlKCkge1xyXG4gICAgaWYgKHRoaXMuaXNEYXRlVmFsaWQodGhpcy5lZGl0ZWREYXRlKSkge1xyXG4gICAgICBjb25zdCBbZGF5LCBtb250aCwgeWVhcl0gPSB0aGlzLmVkaXRlZERhdGUuc3BsaXQoJy8nKTtcclxuICAgICAgdGhpcy5zZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSgreWVhciwgK21vbnRoIC0gMSwgK2RheSk7XHJcbiAgICAgIHRoaXMuZm9ybWF0RGF0ZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIHVzZXIgaW5wdXQgaW4gdGhlIGVkaXRhYmxlIGlucHV0IGZpZWxkIGZvciBkYXRlIGVkaXRpbmcuIFRoaXMgbWV0aG9kIGNhcHR1cmVzIHRoZSBpbnB1dCB2YWx1ZVxyXG4gICAqIGFuZCBzdG9yZXMgaXQgaW4gdGhlICdlZGl0ZWREYXRlJyB2YXJpYWJsZS4gSWYgdGhlIGlucHV0IG1hdGNoZXMgdGhlIHZhbGlkIGRhdGUgZm9ybWF0LCBpdCB1cGRhdGVzXHJcbiAgICogJ3NlbGVjdGVkRGF0ZU1vbnRoJyBhbmQgJ3NlbGVjdGVkRGF0ZVllYXInIGFjY29yZGluZ2x5LlxyXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBpbnB1dCBldmVudCBjb250YWluaW5nIHRoZSB1c2VyJ3MgaW5wdXQuXHJcbiAgICogYGBgXHJcbiAgICogLy8gSGFuZGxlIHVzZXIgaW5wdXQgaW4gdGhlIGVkaXRhYmxlIGlucHV0IGZpZWxkXHJcbiAgICogdGhpcy5vbkRhdGVJbnB1dChldmVudCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHVibGljIG9uRGF0ZUlucHV0KGV2ZW50OiBhbnkpIHtcclxuICAgIGNvbnN0IGlucHV0RGF0ZTogc3RyaW5nID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xyXG4gICAgaWYgKHRoaXMuaXNEYXRlVmFsaWQoaW5wdXREYXRlKSkge1xyXG4gICAgICB0aGlzLmVkaXRlZERhdGUgPSBpbnB1dERhdGU7XHJcbiAgICAgIGNvbnN0IHBhcnNlZERhdGUgPSBpbnB1dERhdGUuc3BsaXQoJy8nKTtcclxuICAgICAgdGhpcy5zZWxlY3RlZERhdGVNb250aCA9ICtwYXJzZWREYXRlWzFdIC0gMTtcclxuICAgICAgdGhpcy5zZWxlY3RlZERhdGVZZWFyID0gK3BhcnNlZERhdGVbMl07XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbmV3IERhdGUoK3BhcnNlZERhdGVbMl0sICtwYXJzZWREYXRlWzFdIC0gMSwgK3BhcnNlZERhdGVbMF0pO1xyXG4gICAgICB0aGlzLmNhbGN1bGF0ZUZpcnN0RGF5T2ZDYWxlbmRhcigpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5pc1VzZXJEYXRlVmFsaWQgPSB0aGlzLmlzRGF0ZVZhbGlkKGlucHV0RGF0ZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGUgdGhlIHZpc2liaWxpdHkgb2YgdGhlIG1vbnRoIGRyb3Bkb3duIGluIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAgICogVGhpcyBtZXRob2QgaXMgdXNlZCB0byBvcGVuIG9yIGNsb3NlIHRoZSBkcm9wZG93biBmb3Igc2VsZWN0aW5nIG1vbnRocy5cclxuICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgZXZlbnQgdHJpZ2dlcmluZyB0aGUgdG9nZ2xlIGFjdGlvbiAoZS5nLiwgYSBjbGljayBldmVudCkuXHJcbiAgICogYGBgXHJcbiAgICogLy8gVG9nZ2xlIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSBtb250aCBkcm9wZG93blxyXG4gICAqIHRoaXMudG9nZ2xlTW9udGhEcm9wZG93bihldmVudCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB0b2dnbGVNb250aERyb3Bkb3duKGV2ZW50OiBFdmVudCkge1xyXG4gICAgdGhpcy5pc01vbnRoRHJvcGRvd25PcGVuID0gIXRoaXMuaXNNb250aERyb3Bkb3duT3BlbjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgeWVhciBkcm9wZG93biBpbiB0aGUgY2FsZW5kYXIgaW50ZXJmYWNlLlxyXG4gICAqIFRoaXMgbWV0aG9kIGlzIHVzZWQgdG8gb3BlbiBvciBjbG9zZSB0aGUgZHJvcGRvd24gZm9yIHNlbGVjdGluZyB5ZWFycy5cclxuICAgKiBAcGFyYW0gZXZlbnQgLSBUaGUgZXZlbnQgdHJpZ2dlcmluZyB0aGUgdG9nZ2xlIGFjdGlvbiAoZS5nLiwgYSBjbGljayBldmVudCkuXHJcbiAgICogYGBgXHJcbiAgICogLy8gVG9nZ2xlIHRoZSB2aXNpYmlsaXR5IG9mIHRoZSB5ZWFyIGRyb3Bkb3duXHJcbiAgICogdGhpcy50b2dnbGVZZWFyRHJvcGRvd24oZXZlbnQpO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIHByaXZhdGUgdG9nZ2xlWWVhckRyb3Bkb3duKGV2ZW50OiBFdmVudCkge1xyXG4gICAgdGhpcy5pc1llYXJEcm9wZG93bk9wZW4gPSAhdGhpcy5pc1llYXJEcm9wZG93bk9wZW47XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgdGhlIGNoYW5nZSBvZiB0aGUgc2VsZWN0ZWQgbW9udGggaW4gdGhlIGNhbGVuZGFyIGludGVyZmFjZS5cclxuICAgKiBUaGlzIG1ldGhvZCB1cGRhdGVzIHRoZSBpbnB1dCB2YWx1ZSwgc2V0cyB0aGUgc2VsZWN0ZWQgZGF0ZSB0byB0aGUgZmlyc3QgZGF5IG9mIHRoZSBjaG9zZW4gbW9udGgsXHJcbiAgICogYW5kIHJlY2FsY3VsYXRlcyB0aGUgY2FsZW5kYXIgZGlzcGxheSBhY2NvcmRpbmdseS5cclxuICAgKiBgYGBcclxuICAgKiAvLyBIYW5kbGUgdGhlIGNoYW5nZSBvZiB0aGUgc2VsZWN0ZWQgbW9udGhcclxuICAgKiB0aGlzLm9uTW9udGhDaGFuZ2UoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIG9uTW9udGhDaGFuZ2UoKSB7XHJcbiAgICB0aGlzLnVwZGF0ZUlucHV0VmFsdWUoKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbmV3IERhdGUodGhpcy5zZWxlY3RlZERhdGVZZWFyLCB0aGlzLnNlbGVjdGVkRGF0ZU1vbnRoLCAxKTtcclxuICAgIHRoaXMuZm9ybWF0RGF0ZSgpO1xyXG4gICAgdGhpcy5jYWxjdWxhdGVGaXJzdERheU9mQ2FsZW5kYXIoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSB0aGUgY2hhbmdlIG9mIHRoZSBzZWxlY3RlZCB5ZWFyIGluIHRoZSBjYWxlbmRhciBpbnRlcmZhY2UuXHJcbiAgICogVGhpcyBtZXRob2QgdXBkYXRlcyB0aGUgaW5wdXQgdmFsdWUsIHNldHMgdGhlIHNlbGVjdGVkIGRhdGUgdG8gdGhlIGZpcnN0IGRheSBvZiB0aGUgY2hvc2VuIHllYXIsXHJcbiAgICogcmVmb3JtYXRzIHRoZSBzZWxlY3RlZCBkYXRlLCBhbmQgcmVjYWxjdWxhdGVzIHRoZSBjYWxlbmRhciBkaXNwbGF5LlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIEhhbmRsZSB0aGUgY2hhbmdlIG9mIHRoZSBzZWxlY3RlZCB5ZWFyXHJcbiAgICogdGhpcy5vblllYXJDaGFuZ2UoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIG9uWWVhckNoYW5nZSgpIHtcclxuICAgIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpO1xyXG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZVllYXIsIHRoaXMuc2VsZWN0ZWREYXRlTW9udGgsIDEpO1xyXG4gICAgdGhpcy5mb3JtYXREYXRlKCk7XHJcbiAgICB0aGlzLmNhbGN1bGF0ZUZpcnN0RGF5T2ZDYWxlbmRhcigpO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIFNlbGVjdCBhIGRhdGUgaW4gdGhlIGNhbGVuZGFyIGludGVyZmFjZSBhbmQgcGVyZm9ybSBuZWNlc3NhcnkgdXBkYXRlcy5cclxuICAgKiBUaGlzIG1ldGhvZCBzZXRzIHRoZSBzZWxlY3RlZCBkYXRlLCBmb3JtYXRzIGl0LCBjbG9zZXMgdGhlIGNhbGVuZGFyLCBhbmQgZW1pdHMgYSBkYXRlQ2hhbmdlZCBldmVudC5cclxuICAgKiBJdCBhbHNvIHVwZGF0ZXMgdGhlIHNlbGVjdGVkIG1vbnRoIGFuZCB5ZWFyIGRyb3Bkb3duIHZhbHVlcy5cclxuICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIGJlIHNlbGVjdGVkIGluIHRoZSBjYWxlbmRhci5cclxuICAgKi9cclxuICBzZWxlY3REYXRlKGRhdGU6IERhdGUpIHtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gZGF0ZTtcclxuICAgIHRoaXMuZm9ybWF0RGF0ZSgpO1xyXG4gICAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gICAgdGhpcy5kYXRlQ2hhbmdlZC5uZXh0KHRoaXMuc2VsZWN0ZWREYXRlKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlTW9udGggPSB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRNb250aCgpO1xyXG4gICAgdGhpcy5zZWxlY3RlZERhdGVZZWFyID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSBiYXNlZCBvbiB0aGUgY2hvc2VuIGRhdGUgZm9ybWF0IGFuZCBsYW5ndWFnZS5cclxuICAgKiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBBbmd1bGFyIERhdGVQaXBlIHRvIGZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSBhbmQgdXBkYXRlcyB0aGUgZm9ybWF0dGVkRGF0ZSB2YXJpYWJsZS5cclxuICAgKiBgYGBcclxuICAgKiAvLyBGb3JtYXQgdGhlIHNlbGVjdGVkIGRhdGVcclxuICAgKiB0aGlzLmZvcm1hdERhdGUoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIGZvcm1hdERhdGUoKSB7XHJcbiAgICB0aGlzLmZvcm1hdHRlZERhdGUgPSB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybSh0aGlzLnNlbGVjdGVkRGF0ZSwgdGhpcy5kYXRlRm9ybWF0KSB8fCAnJztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSBiYXNlZCBvbiB0aGUgY2hvc2VuIGRhdGUgZm9ybWF0LCBsYW5ndWFnZSwgYW5kIGxvY2FsZS5cclxuICAgKiBUaGlzIG1ldGhvZCB1c2VzIHRoZSBBbmd1bGFyIERhdGVQaXBlIHRvIGZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSB3aXRoIHRoZSBzcGVjaWZpZWQgbGFuZ3VhZ2UgYW5kIHVwZGF0ZXMgdGhlIGZvcm1hdHRlZCBkYXRlIGFzIGEgc3RyaW5nLlxyXG4gICAqIEByZXR1cm5zIEEgZm9ybWF0dGVkIGRhdGUgc3RyaW5nLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIEZvcm1hdCB0aGUgc2VsZWN0ZWQgZGF0ZSB3aXRoIGxhbmd1YWdlXHJcbiAgICogY29uc3QgZm9ybWF0dGVkID0gdGhpcy5mb3JtYXRTZWxlY3RlZERhdGUoKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIGZvcm1hdFNlbGVjdGVkRGF0ZSgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKHRoaXMuc2VsZWN0ZWREYXRlLCB0aGlzLmRhdGVGb3JtYXQsIHRoaXMubGFuZykgfHwgJyc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGUgdGhlIGlucHV0IHZhbHVlIGRpc3BsYXllZCBpbiB0aGUgY2FsZW5kYXIgaW50ZXJmYWNlLlxyXG4gICAqIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIGlucHV0IHZhbHVlIHRvIGVpdGhlciB0aGUgZWRpdGVkIGRhdGUgb3IgdGhlIGZvcm1hdHRlZCBzZWxlY3RlZCBkYXRlLFxyXG4gICAqIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSB1c2VyIGlzIGluIGVkaXQgbW9kZSBvciBub3QuXHJcbiAgICogYGBgXHJcbiAgICogLy8gVXBkYXRlIHRoZSBpbnB1dCB2YWx1ZVxyXG4gICAqIHRoaXMudXBkYXRlSW5wdXRWYWx1ZSgpO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIHByaXZhdGUgdXBkYXRlSW5wdXRWYWx1ZSgpIHtcclxuICAgIHRoaXMuZm9ybWF0dGVkRGF0ZSA9IHRoaXMuaXNDYWxlbmRhck9wZW4gPyB0aGlzLmVkaXRlZERhdGUgOiB0aGlzLmZvcm1hdFNlbGVjdGVkRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGFuIGFycmF5IG9mIGFycmF5cyByZXByZXNlbnRpbmcgdGhlIGRheXMgb2YgdGhlIGN1cnJlbnQgbW9udGguXHJcbiAgICogRWFjaCBzdWItYXJyYXkgY29udGFpbnMgdGhlIGRheSBkYXRhIGZvciBhIHdlZWssIGFuZCBlYWNoIGRheSBkYXRhIG9iamVjdCBpbmNsdWRlcyB0aGUgZGF0ZSBhbmQgd2hldGhlciBpdCBiZWxvbmdzIHRvIHRoZSBjdXJyZW50IG1vbnRoLlxyXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGFycmF5cyByZXByZXNlbnRpbmcgdGhlIGRheXMgb2YgdGhlIGN1cnJlbnQgbW9udGguXHJcbiAgICogYGBgXHJcbiAgICogLy8gR2V0IGFuIGFycmF5IG9mIGFycmF5cyByZXByZXNlbnRpbmcgdGhlIGRheXMgb2YgdGhlIGN1cnJlbnQgbW9udGhcclxuICAgKiBjb25zdCBjYWxlbmRhciA9IHRoaXMuY2FsZW5kYXJEYXlzO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0IGNhbGVuZGFyRGF5cygpIHtcclxuICAgIHJldHVybiB0aGlzLmNhbGN1bGF0ZUZpcnN0RGF5T2ZDYWxlbmRhcigpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBkYXRlIG9mIHRoZSBwcmV2aW91cyBtb250aCB0byBkaXNwbGF5IGluIGVtcHR5IGNlbGxzIG9mIHRoZSBjdXJyZW50IG1vbnRoLlxyXG4gICAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGRhdGUgb2YgdGhlIHByZXZpb3VzIG1vbnRoIGlmIHRoZSBwcm92aWRlZCBkYXRlIGlzIG5vdCBpbiB0aGUgY3VycmVudCBtb250aC5cclxuICAgKiBJZiB0aGUgcHJvdmlkZWQgZGF0ZSBpcyBpbiB0aGUgY3VycmVudCBtb250aCwgaXQgcmV0dXJucyB0aGUgZGF0ZSdzIGRheSBhcyBhIHN0cmluZy5cclxuICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIGV2YWx1YXRlLlxyXG4gICAqIEByZXR1cm5zIFRoZSBkYXRlIG9mIHRoZSBwcmV2aW91cyBtb250aCBvciBhIGRheSBzdHJpbmcuXHJcbiAgICogYGBgXHJcbiAgICogLy8gR2V0IHRoZSBwcmV2aW91cyBtb250aCdzIGRhdGUgdG8gZGlzcGxheSBpbiBlbXB0eSBjZWxsc1xyXG4gICAqIGNvbnN0IHByZXZpb3VzTW9udGhEYXRlID0gdGhpcy5nZXRQcmV2aW91c01vbnRoRGF0ZShuZXcgRGF0ZSgyMDIzLCA4LCAxKSk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRQcmV2aW91c01vbnRoRGF0ZShkYXRlOiBEYXRlKTogYW55IHtcclxuICAgIGlmICghZGF0ZSkge1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcbiAgICBjb25zdCBjdXJyZW50RGF0ZSA9IG5ldyBEYXRlKCk7XHJcbiAgICBpZiAoZGF0ZS5nZXRNb250aCgpID09PSBjdXJyZW50RGF0ZS5nZXRNb250aCgpICYmIGRhdGUuZ2V0RnVsbFllYXIoKSA9PT0gY3VycmVudERhdGUuZ2V0RnVsbFllYXIoKSkge1xyXG4gICAgICByZXR1cm4gZGF0ZS5nZXREYXRlKCkudG9TdHJpbmcoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybShkYXRlLCAnZGQnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICAgKiBOYXZpZ2F0ZSB0byB0aGUgcHJldmlvdXMgbW9udGggaW4gdGhlIGNhbGVuZGFyIGludGVyZmFjZS5cclxuICAgKiBUaGlzIG1ldGhvZCB1cGRhdGVzIHRoZSBzZWxlY3RlZERhdGUsIGZvcm1hdHMgaXQsIGFuZCByZWNhbGN1bGF0ZXMgdGhlIGZpcnN0IGRheSBvZiB0aGUgY2FsZW5kYXIuXHJcbiAgICogYGBgXHJcbiAgICogLy8gTmF2aWdhdGUgdG8gdGhlIHByZXZpb3VzIG1vbnRoXHJcbiAgICogdGhpcy5nZXRQcmV2aW91c01vbnRoKCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRQcmV2aW91c01vbnRoKCkge1xyXG4gICAgY29uc3QgY3VycmVudE1vbnRoID0gdGhpcy5zZWxlY3RlZERhdGUuZ2V0TW9udGgoKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbmV3IERhdGUodGhpcy5zZWxlY3RlZERhdGUuZ2V0RnVsbFllYXIoKSwgY3VycmVudE1vbnRoIC0gMSwgMSk7XHJcbiAgICB0aGlzLmZvcm1hdERhdGUoKTtcclxuICAgIHRoaXMuY2FsY3VsYXRlRmlyc3REYXlPZkNhbGVuZGFyKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBOYXZpZ2F0ZSB0byB0aGUgbmV4dCBtb250aCBpbiB0aGUgY2FsZW5kYXIgaW50ZXJmYWNlLlxyXG4gICAqIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIHNlbGVjdGVkRGF0ZSwgZm9ybWF0cyBpdCwgYW5kIHJlY2FsY3VsYXRlcyB0aGUgZmlyc3QgZGF5IG9mIHRoZSBjYWxlbmRhci5cclxuICAgKiBgYGBcclxuICAgKiAvLyBOYXZpZ2F0ZSB0byB0aGUgbmV4dCBtb250aFxyXG4gICAqIHRoaXMuZ2V0TmV4dE1vbnRoKCk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXROZXh0TW9udGgoKSB7XHJcbiAgICBjb25zdCBjdXJyZW50TW9udGggPSB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRNb250aCgpO1xyXG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBuZXcgRGF0ZSh0aGlzLnNlbGVjdGVkRGF0ZS5nZXRGdWxsWWVhcigpLCBjdXJyZW50TW9udGggKyAxLCAxKTtcclxuICAgIHRoaXMuZm9ybWF0RGF0ZSgpO1xyXG4gICAgdGhpcy5jYWxjdWxhdGVGaXJzdERheU9mQ2FsZW5kYXIoKTtcclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICAgKiBHZXQgdGhlIG51bWJlciBvZiBkYXlzIGluIGEgZ2l2ZW4gbW9udGggb2YgYSBzcGVjaWZpYyB5ZWFyLlxyXG4gICAqIEBwYXJhbSB5ZWFyIC0gVGhlIHllYXIgZm9yIHdoaWNoIHlvdSB3YW50IHRvIGRldGVybWluZSB0aGUgbnVtYmVyIG9mIGRheXMuXHJcbiAgICogQHBhcmFtIG1vbnRoIC0gVGhlIG1vbnRoICgwLWJhc2VkIGluZGV4KSBmb3Igd2hpY2ggeW91IHdhbnQgdG8gZGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgZGF5cy5cclxuICAgKiBAcmV0dXJucyBUaGUgbnVtYmVyIG9mIGRheXMgaW4gdGhlIHNwZWNpZmllZCBtb250aCBvZiB0aGUgZ2l2ZW4geWVhci5cclxuICAgKi9cclxuICBwcml2YXRlIGRheXNJbk1vbnRoKHllYXI6IG51bWJlciwgbW9udGg6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGggKyAxLCAwKS5nZXREYXRlKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDYWxjdWxhdGUgdGhlIHN0cnVjdHVyZSBvZiBkYXlzIGluIGEgbW9udGggZm9yIHRoZSBjYWxlbmRhciBkaXNwbGF5LlxyXG4gICAqIFRoaXMgbWV0aG9kIGdlbmVyYXRlcyBhIG1hdHJpeCBvZiBkYXkgZGF0YSBvYmplY3RzIHJlcHJlc2VudGluZyB0aGUgZGF5cyBpbiB0aGUgY2FsZW5kYXIuXHJcbiAgICogRWFjaCBkYXkgZGF0YSBvYmplY3QgY29udGFpbnMgdGhlIGRhdGUgYW5kIHdoZXRoZXIgaXQgYmVsb25ncyB0byB0aGUgY3VycmVudCBtb250aC5cclxuICAgKiBAcmV0dXJucyBBIG1hdHJpeCBvZiBkYXkgZGF0YSBvYmplY3RzIGZvciB0aGUgY2FsZW5kYXIgZGlzcGxheS5cclxuICAgKi9cclxuICBwcml2YXRlIGNhbGN1bGF0ZUZpcnN0RGF5T2ZDYWxlbmRhcigpIHtcclxuICAgIGNvbnN0IHllYXIgPSB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRGdWxsWWVhcigpO1xyXG4gICAgY29uc3QgbW9udGggPSB0aGlzLnNlbGVjdGVkRGF0ZS5nZXRNb250aCgpO1xyXG4gICAgY29uc3QgZmlyc3REYXlPZk1vbnRoID0gbmV3IERhdGUoeWVhciwgbW9udGgsIDEpO1xyXG4gICAgY29uc3QgZmlyc3RXZWVrZGF5ID0gZmlyc3REYXlPZk1vbnRoLmdldERheSgpO1xyXG4gICAgY29uc3Qgc3RhcnREYXkgPSBmaXJzdFdlZWtkYXkgPT09IDAgPyAtNSA6IDIgLSBmaXJzdFdlZWtkYXk7XHJcbiAgICBjb25zdCBjYWxlbmRhckRheXMgPSBbXTtcclxuICAgIGxldCBjdXJyZW50RGF5ID0gc3RhcnREYXk7XHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDY7IGkrKykge1xyXG4gICAgICBjb25zdCB3ZWVrID0gW107XHJcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgNzsgaisrKSB7XHJcbiAgICAgICAgY29uc3QgZGF5ID0gbmV3IERhdGUoeWVhciwgbW9udGgsIGN1cnJlbnREYXkpO1xyXG4gICAgICAgIGNvbnN0IGRheURhdGEgPSB7XHJcbiAgICAgICAgICBkYXRlOiBkYXksXHJcbiAgICAgICAgICBpc0N1cnJlbnRNb250aDogY3VycmVudERheSA+PSAxICYmIGN1cnJlbnREYXkgPD0gdGhpcy5kYXlzSW5Nb250aCh5ZWFyLCBtb250aCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICB3ZWVrLnB1c2goZGF5RGF0YSk7XHJcbiAgICAgICAgY3VycmVudERheSsrO1xyXG4gICAgICB9XHJcbiAgICAgIGNhbGVuZGFyRGF5cy5wdXNoKHdlZWspO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNhbGVuZGFyRGF5cztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGEgZ2l2ZW4gZGF0ZSBpcyB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGRhdGUgaW4gdGhlIGNhbGVuZGFyLlxyXG4gICAqIEBwYXJhbSBkYXRlIC0gVGhlIGRhdGUgdG8gY2hlY2suXHJcbiAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBwcm92aWRlZCBkYXRlIG1hdGNoZXMgdGhlIHNlbGVjdGVkIGRhdGUsIG90aGVyd2lzZSBgZmFsc2VgLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIENoZWNrIGlmIGEgZGF0ZSBpcyBzZWxlY3RlZFxyXG4gICAqIGNvbnN0IGlzU2VsZWN0ZWQgPSB0aGlzLmlzRGF0ZVNlbGVjdGVkKHNvbWVEYXRlKTtcclxuICAgKiBgYGBcclxuICAgKi9cclxuICBwcml2YXRlIGlzRGF0ZVNlbGVjdGVkKGRhdGU6IERhdGUpIHtcclxuICAgIHJldHVybiBkYXRlLnRvRGF0ZVN0cmluZygpID09PSB0aGlzLnNlbGVjdGVkRGF0ZS50b0RhdGVTdHJpbmcoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIGEgZGF0ZSBzdHJpbmcgaXMgdmFsaWQgYmFzZWQgb24gdGhlIHNwZWNpZmllZCBkYXRlIGZvcm1hdC5cclxuICAgKiBJdCBhbHNvIGNoZWNrcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgbnVtYmVyLCBtb250aCBpcyBjb3JyZWN0IGFuZCB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgb25lIGV4aXN0cyBhbW9uZyBjYWxlbmRhciB5ZWFyc1xyXG4gICAqIEBwYXJhbSBpbnB1dERhdGUgLSBUaGUgZGF0ZSBzdHJpbmcgdG8gdmFsaWRhdGUuXHJcbiAgICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBpbnB1dCBkYXRlIHN0cmluZyBpcyB2YWxpZCwgb3RoZXJ3aXNlIGBmYWxzZWAuXHJcbiAgICogYGBgXHJcbiAgICogLy8gQ2hlY2sgaWYgYSBkYXRlIHN0cmluZyBpcyB2YWxpZFxyXG4gICAqIGNvbnN0IGlzVmFsaWREYXRlID0gdGhpcy5pc0RhdGVWYWxpZCgnMDUvMjUvMjAyMycpO1xyXG4gICAqIGBgYFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaXNEYXRlVmFsaWQoaW5wdXREYXRlOiBzdHJpbmcpIHtcclxuICAgIGlmICghdGhpcy5kYXRlUmVnRXhwLnRlc3QoaW5wdXREYXRlKSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcGFydHMgPSBpbnB1dERhdGUuc3BsaXQoJy8nKTtcclxuICAgIGNvbnN0IGRheSA9IHBhcnNlSW50KHBhcnRzWzBdLCAxMCk7XHJcbiAgICBjb25zdCBtb250aCA9IHBhcnNlSW50KHBhcnRzWzFdLCAxMCk7XHJcbiAgICBjb25zdCB5ZWFyID0gcGFyc2VJbnQocGFydHNbMl0sIDEwKTtcclxuXHJcbiAgICBpZiAoeWVhciA+IHRoaXMueWVhcnNbdGhpcy55ZWFycy5sZW5ndGggLSAxXSB8fCB5ZWFyIDwgdGhpcy55ZWFyc1swXSkge1xyXG4gICAgICByZXR1cm4gZmFsc2VcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBkYXlzSW5Nb250aCA9IG5ldyBEYXRlKHllYXIsIG1vbnRoLCAwKS5nZXREYXRlKCk7XHJcbiAgICByZXR1cm4gZGF5IDw9IGRheXNJbk1vbnRoO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgaWYgYSBnaXZlbiBkYXRlIGlzIHRvZGF5J3MgZGF0ZS5cclxuICAgKiBAcGFyYW0gZGF0ZSAtIFRoZSBkYXRlIHRvIGNoZWNrLlxyXG4gICAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgcHJvdmlkZWQgZGF0ZSBpcyB0b2RheSdzIGRhdGUsIG90aGVyd2lzZSBgZmFsc2VgLlxyXG4gICAqIGBgYFxyXG4gICAqIC8vIENoZWNrIGlmIGEgZGF0ZSBpcyB0b2RheSdzIGRhdGVcclxuICAgKiBjb25zdCBpc1RvZGF5ID0gdGhpcy5pc0RhdGVUb2RheShzb21lRGF0ZSk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpc0RhdGVUb2RheShkYXRlOiBEYXRlKSB7XHJcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XHJcbiAgICByZXR1cm4gZGF0ZS50b0RhdGVTdHJpbmcoKSA9PT0gdG9kYXkudG9EYXRlU3RyaW5nKCk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJkYXRlcGlja2VyLWNvbnRhaW5lclwiIFtjbGFzcy5kaXNhYmxlZF09XCJkaXNhYmxlZFwiPlxyXG5cclxuICA8IS0tIElucHV0LCBzYXZlICYgZWRpdCBidXR0b25zIC0tPlxyXG4gICAgPGRpdiBjbGFzcz1cImlucHV0LWNvbnRhaW5lciBmb3JtLWdyb3VwXCI+XHJcbiAgICAgICAgPGxhYmVsICpuZ0lmPVwibGFiZWxDb250ZW50VGV4dFwiIGNsYXNzPVwiZm9ybS1sYWJlbFwiPiB7eyBsYWJlbENvbnRlbnRUZXh0IH19IDwvbGFiZWw+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7ICdjYWxlbmRhck5vdE9wZW5lZCc6ICFpc0NhbGVuZGFyT3BlbiB9XCJcclxuICAgICAgICAgIFtuZ1N0eWxlXT1cInsgJ2JvcmRlci1jb2xvcic6IGlzVXNlckRhdGVWYWxpZCA/ICcnIDogJ3JlZCcgfVwiXHJcbiAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXHJcbiAgICAgICAgICAoaW5wdXQpPVwib25EYXRlSW5wdXQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAoY2xpY2spPVwiaXNDYWxlbmRhck9wZW4gPSB0cnVlXCJcclxuICAgICAgICAgIFt2YWx1ZV09XCJmb3JtYXR0ZWREYXRlXCJcclxuICAgICAgICAgIFtyZWFkT25seV09XCIhaXNDYWxlbmRhck9wZW5cIlxyXG4gICAgICAgID5cclxuICAgIDwvZGl2PlxyXG5cclxuICA8IS0tIENhbGVuZGFyKERyb3Bkb3ducywgZGF0ZXMpIC0tPlxyXG4gIDxkaXYgKm5nSWY9XCJpc0NhbGVuZGFyT3BlblwiIGNsYXNzPVwiY2FsZW5kYXJcIiAjY2FsZW5kYXJDb250YWluZXJcclxuICAgICAgIFtzdHlsZS50b3BdPVwidG9wT2Zmc2V0XCJcclxuICAgICAgIFtzdHlsZS5sZWZ0XT1cImxlZnRPZmZzZXRcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1oZWFkZXJcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cIm1vbnRoQnV0dG9uQ29udGFpbmVyXCI+XHJcbiAgICAgICAgPCEtLSBNb250aCBkcm9wZG93biAtLT5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNNb250aERyb3Bkb3duT3BlbjsgZWxzZSBtb250aExhYmVsXCI+XHJcbiAgICAgICAgICA8bWVmZGV2LXNlbGVjdFxyXG4gICAgICAgICAgICBjbGFzcz1cIm1vbnRoRHJvcGRvd25cIlxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRGF0ZU1vbnRoXCJcclxuICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib25Nb250aENoYW5nZSgpXCJcclxuICAgICAgICAgICAgW1BsYWNlSG9sZGVyXT1cIidtb250aCdcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8bWVmZGV2LW9wdGlvblxyXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBtb250aCBvZiBtb250aHM7IGxldCBpID0gaW5kZXhcIlxyXG4gICAgICAgICAgICAgIFtWYWx1ZV09XCJpXCJcclxuICAgICAgICAgICAgICBbTGFiZWxdPVwibW9udGhcIlxyXG4gICAgICAgICAgICAgIHN0eWxlPVwiei1pbmRleDogMVwiXHJcbiAgICAgICAgICAgID57eyBtb250aCB9fTwvbWVmZGV2LW9wdGlvbj5cclxuICAgICAgICAgIDwvbWVmZGV2LXNlbGVjdD5cclxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuICAgICAgICA8bmctdGVtcGxhdGUgI21vbnRoTGFiZWw+XHJcbiAgICAgICAgICA8c3BhbiAoY2xpY2spPVwidG9nZ2xlTW9udGhEcm9wZG93bigkZXZlbnQpXCI+PC9zcGFuPlxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+XHJcblxyXG4gICAgICAgIDwhLS0gWWVhciBkcm9wZG93biAtLT5cclxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNZZWFyRHJvcGRvd25PcGVuOyBlbHNlIHllYXJMYWJlbFwiPlxyXG4gICAgICAgICAgPG1lZmRldi1zZWxlY3RcclxuICAgICAgICAgICAgY2xhc3M9XCJ5ZWFyRHJvcGRvd25cIlxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRGF0ZVllYXJcIlxyXG4gICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvblllYXJDaGFuZ2UoKVwiXHJcbiAgICAgICAgICAgIFtQbGFjZUhvbGRlcl09XCIneWVhcidcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8bWVmZGV2LW9wdGlvblxyXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCB5ZWFyIG9mIHllYXJzXCJcclxuICAgICAgICAgICAgICBbTGFiZWxdPVwieWVhclwiXHJcbiAgICAgICAgICAgICAgW1ZhbHVlXT1cInllYXJcIlxyXG4gICAgICAgICAgICA+e3t5ZWFyfX08L21lZmRldi1vcHRpb24+XHJcbiAgICAgICAgICA8L21lZmRldi1zZWxlY3Q+XHJcbiAgICAgICAgPC9uZy1jb250YWluZXI+XHJcbiAgICAgICAgPG5nLXRlbXBsYXRlICN5ZWFyTGFiZWw+XHJcbiAgICAgICAgICA8c3BhbiAoY2xpY2spPVwidG9nZ2xlWWVhckRyb3Bkb3duKCRldmVudClcIj57eyBzZWxlY3RlZERhdGVZZWFyIH19PC9zcGFuPlxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8IS0tIENhbGVuZGFyIGV4aXQgYnV0dG9uIC0tPlxyXG4gICAgICA8ZGl2PlxyXG4gICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtdGltZXMgdG9nZ2xlQ2FsZW5kYXJCdXR0b25cIiAoY2xpY2spPVwiaXNDYWxlbmRhck9wZW4gPSBmYWxzZVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8ZGl2IGNsYXNzPVwiY2FsZW5kYXItYm9keVwiPlxyXG4gICAgICA8dGFibGU+XHJcbiAgICAgICAgPHRyPlxyXG4gICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1jZW50ZXJcIiAqbmdGb3I9XCJsZXQgd2Vla2RheSBvZiB3ZWVrZGF5c1wiPnt7IHdlZWtkYXkgfX08L3RoPlxyXG4gICAgICAgIDwvdHI+XHJcbiAgICAgICAgPHRyICpuZ0Zvcj1cImxldCB3ZWVrIG9mIGNhbGVuZGFyRGF5c1wiPlxyXG4gICAgICAgICAgPHRkICpuZ0Zvcj1cImxldCBkYXlEYXRhIG9mIHdlZWtcIlxyXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3REYXRlKGRheURhdGEuZGF0ZSlcIlxyXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3NlbGVjdGVkJzogaXNEYXRlU2VsZWN0ZWQoZGF5RGF0YS5kYXRlKSwgJ3ByZXYtbW9udGgnOiAhZGF5RGF0YS5pc0N1cnJlbnRNb250aCB9XCI+XHJcblxyXG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRhdGVcIiBbY2xhc3MucHJldi1tb250aF09XCIhZGF5RGF0YS5pc0N1cnJlbnRNb250aFwiPlxyXG4gICAgICAgICAgICAgIHt7IGRheURhdGEuZGF0ZS5nZXREYXRlKCkgfX1cclxuICAgICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgICAgPC90ZD5cclxuICAgICAgICA8L3RyPlxyXG4gICAgICA8L3RhYmxlPlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG4iXX0=