primekit 0.0.64 → 0.0.66

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 (35) hide show
  1. package/esm2022/lib/lib/atomix-alert/atomix-alert.component.mjs +3 -3
  2. package/esm2022/lib/lib/atomix-button/atomix-button.component.mjs +4 -4
  3. package/esm2022/lib/lib/atomix-calendar/atomix-calendar.component.mjs +4 -4
  4. package/esm2022/lib/lib/atomix-card/atomix-card.component.mjs +3 -3
  5. package/esm2022/lib/lib/atomix-confirmation-dialog/atomix-confirmation-dialog.component.mjs +3 -3
  6. package/esm2022/lib/lib/atomix-daterange-calendar/atomix-daterange-calendar.component.mjs +407 -73
  7. package/esm2022/lib/lib/atomix-dropdown/atomix-dropdown.component.mjs +4 -4
  8. package/esm2022/lib/lib/atomix-dynamic-dialog/atomix-dynamic-dialog.component.mjs +3 -3
  9. package/esm2022/lib/lib/atomix-form/atomix-form-autocomplete/atomix-form-autocomplete.component.mjs +3 -3
  10. package/esm2022/lib/lib/atomix-form/atomix-form-calendar/atomix-form-calendar.component.mjs +3 -3
  11. package/esm2022/lib/lib/atomix-form/atomix-form-checkbox/atomix-form-checkbox.component.mjs +3 -3
  12. package/esm2022/lib/lib/atomix-form/atomix-form-chips/atomix-form-chips.component.mjs +3 -3
  13. package/esm2022/lib/lib/atomix-form/atomix-form-dropdown/atomix-form-dropdown.component.mjs +3 -3
  14. package/esm2022/lib/lib/atomix-form/atomix-form-input-component/atomix-form-input-component.component.mjs +3 -3
  15. package/esm2022/lib/lib/atomix-form/atomix-form-inputmask-component/atomix-form-inputmask-component.component.mjs +3 -3
  16. package/esm2022/lib/lib/atomix-form/atomix-form-password-component/atomix-form-password-component.component.mjs +3 -3
  17. package/esm2022/lib/lib/atomix-form/atomix-form-radio-button/atomix-radio-button.component.mjs +3 -3
  18. package/esm2022/lib/lib/atomix-form/atomix-form-textarea/atomix-form-textarea.component.mjs +3 -3
  19. package/esm2022/lib/lib/atomix-input/atomix-input.component.mjs +3 -3
  20. package/esm2022/lib/lib/atomix-messages/messages.component.mjs +3 -3
  21. package/esm2022/lib/lib/atomix-pagination/atomix-pagination.component.mjs +4 -4
  22. package/esm2022/lib/lib/atomix-radio-button/atomix-radio-button.component.mjs +3 -3
  23. package/esm2022/lib/lib/atomix-search-dropdown/atomix-search-dropdown.component.mjs +3 -3
  24. package/esm2022/lib/lib/atomix-select-button/atomix-select-button.component.mjs +3 -3
  25. package/esm2022/lib/lib/atomix-snackbar/atomix-snackbar.component.mjs +3 -3
  26. package/esm2022/lib/lib/atomix-spinner/atomix-spinner.component.mjs +3 -3
  27. package/esm2022/lib/lib/atomix-table/atomix-table.component.mjs +7 -6
  28. package/esm2022/lib/lib/atomix-tag/atomix-tag.component.mjs +3 -3
  29. package/esm2022/lib/primekit.component.mjs +3 -3
  30. package/esm2022/lib/primekit.module.mjs +4 -4
  31. package/esm2022/lib/primekit.service.mjs +3 -3
  32. package/fesm2022/primekit.mjs +502 -168
  33. package/fesm2022/primekit.mjs.map +1 -1
  34. package/lib/lib/atomix-daterange-calendar/atomix-daterange-calendar.component.d.ts +32 -7
  35. package/package.json +1 -1
@@ -8,18 +8,23 @@ import * as i5 from "primeng/overlaypanel";
8
8
  import * as i6 from "@angular/forms";
9
9
  export class AtomixDaterangeCalendarComponent {
10
10
  datePipe;
11
+ renderer;
11
12
  placeholder = '';
12
13
  styleClass = '';
13
14
  selectionMode = 'range';
14
15
  inputStyleClass = '';
16
+ inline = false;
15
17
  disabled = false;
16
18
  selectedDate = null;
17
19
  maxDate;
18
20
  minDate;
21
+ defaultPreset = null;
19
22
  customRangeMode = false;
20
- selectedPreset = null; // 'today' | 'yesterday' | 'lastWeek' | 'lastMonth' | 'lastQuarter' | 'custom' | null
23
+ selectedPreset = null; // 'today' | 'yesterday' | 'last7days' | 'last30days' | 'last3months' | 'last6months' | 'custom' | null
21
24
  overlayPanel;
22
25
  dateRangeChange = new EventEmitter();
26
+ // internal model bound to p-calendar to avoid changing external selection during first-click selection
27
+ modelDate = null;
23
28
  enLocale = {
24
29
  firstDayOfWeek: 0,
25
30
  dayNames: [
@@ -64,8 +69,30 @@ export class AtomixDaterangeCalendarComponent {
64
69
  today: 'Today',
65
70
  clear: 'Clear',
66
71
  };
67
- constructor(datePipe) {
72
+ // temporary storage for overlay session
73
+ _overlayInitialDate = null;
74
+ _overlayInitialPreset = null;
75
+ _calendarObservers = [];
76
+ _observedElements = [];
77
+ _parentObservers = [];
78
+ _observedParentElements = [];
79
+ _updateRafId = null; // requestAnimationFrame id
80
+ constructor(datePipe, renderer) {
68
81
  this.datePipe = datePipe;
82
+ this.renderer = renderer;
83
+ }
84
+ ngOnInit() {
85
+ if (!this.selectedDate && this.defaultPreset) {
86
+ this.applyPreset(this.defaultPreset);
87
+ }
88
+ // initialize internal model
89
+ this.modelDate = this.selectedDate ? [...this.selectedDate] : null;
90
+ // initial class update if there is a pre-selected range
91
+ this._scheduleUpdate();
92
+ // start observers if inline calendar is used
93
+ if (this.inline) {
94
+ this._startCalendarObservers();
95
+ }
69
96
  }
70
97
  ngOnChanges(changes) {
71
98
  if (changes['selectedDate']) {
@@ -73,9 +100,12 @@ export class AtomixDaterangeCalendarComponent {
73
100
  if (sel && Array.isArray(sel) && sel.length === 2 && sel[0] && sel[1]) {
74
101
  const preset = this.detectPreset(sel[0], sel[1]);
75
102
  this.selectedPreset = preset ?? 'custom';
103
+ // sync internal model when external value changes
104
+ this.modelDate = [...sel];
76
105
  }
77
106
  else if (sel == null) {
78
107
  this.selectedPreset = null;
108
+ this.modelDate = null;
79
109
  }
80
110
  }
81
111
  }
@@ -88,17 +118,92 @@ export class AtomixDaterangeCalendarComponent {
88
118
  event.preventDefault();
89
119
  }
90
120
  }
91
- clearAndStop(event) {
92
- // Prevent toggle from happening when clear icon is clicked
93
- try {
94
- event.stopPropagation();
121
+ onOverlayShow() {
122
+ // store a deep copy of current selection/preset when overlay opens
123
+ if (this.selectedDate && Array.isArray(this.selectedDate)) {
124
+ this._overlayInitialDate = this.selectedDate.map(d => (d ? new Date(d.getFullYear(), d.getMonth(), d.getDate()) : d));
95
125
  }
96
- catch (e) { }
97
- try {
98
- event.preventDefault();
126
+ else {
127
+ this._overlayInitialDate = null;
99
128
  }
100
- catch (e) { }
101
- this.clearDateRange();
129
+ this._overlayInitialPreset = this.selectedPreset;
130
+ // ensure calendar model shows the currently committed selection when opening
131
+ this.modelDate = this.selectedDate ? [...this.selectedDate] : null;
132
+ // ensure preset buttons reflect current selection when overlay opens
133
+ if (this.selectedDate && Array.isArray(this.selectedDate) && this.selectedDate.length === 2) {
134
+ const preset = this.detectPreset(this.selectedDate[0], this.selectedDate[1]);
135
+ this.selectedPreset = preset ?? 'custom';
136
+ }
137
+ else if (!this.selectedDate) {
138
+ this.selectedPreset = null;
139
+ }
140
+ // add start/end classes to range cells for styling
141
+ this._scheduleUpdate();
142
+ // observe DOM changes (PrimeNG may re-render inside overlay)
143
+ this._startCalendarObservers();
144
+ }
145
+ onOverlayHide() {
146
+ // if internal calendar model has an incomplete selection (partial range) revert to initial
147
+ const model = this.modelDate;
148
+ const isPartialModel = Boolean(model && Array.isArray(model) && model.length > 0 && model[0] && !model[1]);
149
+ if (isPartialModel) {
150
+ this.selectedDate = this._overlayInitialDate;
151
+ this.selectedPreset = this._overlayInitialPreset;
152
+ // reset internal model to synced value
153
+ this.modelDate = this.selectedDate ? [...this.selectedDate] : null;
154
+ }
155
+ this._overlayInitialDate = null;
156
+ this._overlayInitialPreset = null;
157
+ this.customRangeMode = false;
158
+ // cleanup any start/end classes to avoid stale classes
159
+ this._scheduleUpdate();
160
+ // stop observing
161
+ this._stopCalendarObservers();
162
+ }
163
+ onModelChange(dateRange) {
164
+ // When user clicks a first date, PrimeNG may emit an array with 1 value. We don't want to
165
+ // update the external selectedDate until the range is completed (two dates) so that
166
+ // the calendar does not jump back to a previously selected end date's month.
167
+ this.modelDate = dateRange ? [...dateRange] : null;
168
+ if (dateRange && Array.isArray(dateRange) && dateRange.length === 2 && dateRange[0] && dateRange[1]) {
169
+ this.selectedPreset = this.detectPreset(dateRange[0], dateRange[1]);
170
+ this.customRangeMode = false;
171
+ this.selectedDate = [...dateRange];
172
+ this.dateRangeChange.emit(this.selectedDate);
173
+ // close overlay like when applying a preset
174
+ try {
175
+ this.overlayPanel?.hide();
176
+ }
177
+ catch (e) { }
178
+ }
179
+ else if (!dateRange) {
180
+ // cleared selection
181
+ this.selectedPreset = null;
182
+ this.customRangeMode = false;
183
+ this.selectedDate = null;
184
+ this.dateRangeChange.emit(null);
185
+ }
186
+ else {
187
+ // single date selecting (partial range) - do not emit change yet; just keep internal model
188
+ // so the calendar's view remains where the user navigated to.
189
+ this.selectedPreset = null;
190
+ this.customRangeMode = false;
191
+ }
192
+ // update start/end classes while user is selecting or when range completes
193
+ this._scheduleUpdate();
194
+ }
195
+ // Called when the calendar's visible month/year changes
196
+ onCalendarViewChanged(event) {
197
+ // Reapply classes after PrimeNG re-render
198
+ this._scheduleUpdate();
199
+ // Reattach observers after a small delay since PrimeNG will likely replace DOM nodes
200
+ setTimeout(() => {
201
+ try {
202
+ this._stopCalendarObservers();
203
+ this._startCalendarObservers();
204
+ }
205
+ catch (e) { }
206
+ }, 40);
102
207
  }
103
208
  get hasSelection() {
104
209
  return Boolean(this.selectedDate &&
@@ -127,30 +232,30 @@ export class AtomixDaterangeCalendarComponent {
127
232
  y.setDate(y.getDate() - 1);
128
233
  if (this.isSameDate(start, y) && this.isSameDate(end, y))
129
234
  return 'yesterday';
130
- // lastWeek (last 7 days where end = yesterday and start = end - 6)
131
- const lwEnd = new Date(today);
132
- lwEnd.setDate(lwEnd.getDate() - 1);
133
- const lwStart = new Date(lwEnd);
134
- lwStart.setDate(lwEnd.getDate() - 6);
135
- if (this.isSameDate(start, lwStart) && this.isSameDate(end, lwEnd))
136
- return 'lastWeek';
137
- // lastMonth
138
- const firstDayOfCurrentMonth = new Date(today.getFullYear(), today.getMonth(), 1);
139
- const lastDayOfPrevMonth = new Date(firstDayOfCurrentMonth);
140
- lastDayOfPrevMonth.setDate(0);
141
- const firstDayOfPrevMonth = new Date(lastDayOfPrevMonth.getFullYear(), lastDayOfPrevMonth.getMonth(), 1);
142
- if (this.isSameDate(start, firstDayOfPrevMonth) &&
143
- this.isSameDate(end, lastDayOfPrevMonth))
144
- return 'lastMonth';
145
- // lastQuarter
146
- const month = today.getMonth();
147
- const quarter = Math.floor(month / 3);
148
- const prevQuarterEndMonth = quarter * 3 - 1;
149
- const prevQuarterEnd = new Date(today.getFullYear(), prevQuarterEndMonth + 1, 0);
150
- const prevQuarterStartMonth = prevQuarterEndMonth - 2;
151
- const prevQuarterStart = new Date(today.getFullYear(), prevQuarterStartMonth, 1);
152
- if (this.isSameDate(start, prevQuarterStart) && this.isSameDate(end, prevQuarterEnd))
153
- return 'lastQuarter';
235
+ // last7days (last 7 days including today: start = today - 6, end = today)
236
+ const l7End = new Date(today);
237
+ const l7Start = new Date(today);
238
+ l7Start.setDate(today.getDate() - 6);
239
+ if (this.isSameDate(start, l7Start) && this.isSameDate(end, l7End))
240
+ return 'last7days';
241
+ // last30days (last 30 days including today: start = today - 29, end = today)
242
+ const l30End = new Date(today);
243
+ const l30Start = new Date(today);
244
+ l30Start.setDate(today.getDate() - 29);
245
+ if (this.isSameDate(start, l30Start) && this.isSameDate(end, l30End))
246
+ return 'last30days';
247
+ // last3months (last 3 months including today: start = today - 3 months, end = today)
248
+ const l3mEnd = new Date(today);
249
+ const l3mStart = new Date(today);
250
+ l3mStart.setMonth(today.getMonth() - 3);
251
+ if (this.isSameDate(start, l3mStart) && this.isSameDate(end, l3mEnd))
252
+ return 'last3months';
253
+ // last6months (last 6 months including today: start = today - 6 months, end = today)
254
+ const l6mEnd = new Date(today);
255
+ const l6mStart = new Date(today);
256
+ l6mStart.setMonth(today.getMonth() - 6);
257
+ if (this.isSameDate(start, l6mStart) && this.isSameDate(end, l6mEnd))
258
+ return 'last6months';
154
259
  return null;
155
260
  }
156
261
  clearDateRange() {
@@ -158,6 +263,7 @@ export class AtomixDaterangeCalendarComponent {
158
263
  this.dateRangeChange.emit(this.selectedDate);
159
264
  this.selectedPreset = null;
160
265
  this.customRangeMode = false;
266
+ this.modelDate = null;
161
267
  }
162
268
  resetAndClose() {
163
269
  this.clearDateRange();
@@ -168,12 +274,18 @@ export class AtomixDaterangeCalendarComponent {
168
274
  catch (e) { }
169
275
  }
170
276
  }
277
+ clearAndStop(event) {
278
+ this.clearDateRange();
279
+ event.stopPropagation();
280
+ }
171
281
  toggleCustomRange() {
172
282
  this.customRangeMode = !this.customRangeMode;
173
283
  if (this.customRangeMode)
174
284
  this.selectedPreset = 'custom';
175
285
  }
176
286
  applyCustomRange() {
287
+ // ensure external selectedDate is in sync with internal model
288
+ this.selectedDate = this.modelDate ? [...this.modelDate] : null;
177
289
  this.dateRangeChange.emit(this.selectedDate);
178
290
  if (this.overlayPanel) {
179
291
  try {
@@ -185,14 +297,24 @@ export class AtomixDaterangeCalendarComponent {
185
297
  this.selectedPreset = 'custom';
186
298
  }
187
299
  getDateRangeLabel() {
188
- if (!this.selectedDate || !Array.isArray(this.selectedDate))
189
- return this.placeholder || 'Select date range';
190
- const [start, end] = this.selectedDate;
191
- if (!start || !end)
192
- return 'Select date range';
193
- const startStr = this.datePipe.transform(start, 'MM/dd/yyyy');
194
- const endStr = this.datePipe.transform(end, 'MM/dd/yyyy');
195
- return `${startStr} ${endStr}`;
300
+ // Check the internal model first to show real-time updates while selecting
301
+ const dateArray = this.modelDate || this.selectedDate;
302
+ if (!dateArray || !Array.isArray(dateArray))
303
+ return '';
304
+ const [start, end] = dateArray;
305
+ const arrow = '\u2794';
306
+ // Show just the first date with an arrow if only first date is selected
307
+ if (start && !end) {
308
+ const startStr = this.datePipe.transform(start, 'MM/dd/yyyy');
309
+ return `${startStr} ${arrow} `;
310
+ }
311
+ // Show the complete range if both dates are selected
312
+ if (start && end) {
313
+ const startStr = this.datePipe.transform(start, 'MM/dd/yyyy');
314
+ const endStr = this.datePipe.transform(end, 'MM/dd/yyyy');
315
+ return `${startStr} ${arrow} ${endStr}`;
316
+ }
317
+ return '';
196
318
  }
197
319
  applyPreset(preset) {
198
320
  const today = new Date();
@@ -207,33 +329,28 @@ export class AtomixDaterangeCalendarComponent {
207
329
  y.setDate(y.getDate() - 1);
208
330
  start = end = new Date(y.getFullYear(), y.getMonth(), y.getDate());
209
331
  break;
210
- case 'lastWeek': {
211
- const lwEnd = new Date(today);
212
- lwEnd.setDate(lwEnd.getDate() - 1);
213
- const lwStart = new Date(lwEnd);
214
- lwStart.setDate(lwEnd.getDate() - 6);
215
- start = new Date(lwStart.getFullYear(), lwStart.getMonth(), lwStart.getDate());
216
- end = new Date(lwEnd.getFullYear(), lwEnd.getMonth(), lwEnd.getDate());
332
+ case 'last7days': {
333
+ end = new Date(today.getFullYear(), today.getMonth(), today.getDate());
334
+ start = new Date(end);
335
+ start.setDate(end.getDate() - 6);
217
336
  break;
218
337
  }
219
- case 'lastMonth': {
220
- const firstDayOfCurrentMonth = new Date(today.getFullYear(), today.getMonth(), 1);
221
- const lastDayOfPrevMonth = new Date(firstDayOfCurrentMonth);
222
- lastDayOfPrevMonth.setDate(0);
223
- const firstDayOfPrevMonth = new Date(lastDayOfPrevMonth.getFullYear(), lastDayOfPrevMonth.getMonth(), 1);
224
- start = new Date(firstDayOfPrevMonth.getFullYear(), firstDayOfPrevMonth.getMonth(), 1);
225
- end = new Date(lastDayOfPrevMonth.getFullYear(), lastDayOfPrevMonth.getMonth(), lastDayOfPrevMonth.getDate());
338
+ case 'last30days': {
339
+ end = new Date(today.getFullYear(), today.getMonth(), today.getDate());
340
+ start = new Date(end);
341
+ start.setDate(end.getDate() - 29);
226
342
  break;
227
343
  }
228
- case 'lastQuarter': {
229
- const month = today.getMonth();
230
- const quarter = Math.floor(month / 3);
231
- const prevQuarterEndMonth = quarter * 3 - 1;
232
- const prevQuarterEnd = new Date(today.getFullYear(), prevQuarterEndMonth + 1, 0);
233
- const prevQuarterStartMonth = prevQuarterEndMonth - 2;
234
- const prevQuarterStart = new Date(today.getFullYear(), prevQuarterStartMonth, 1);
235
- start = prevQuarterStart;
236
- end = prevQuarterEnd;
344
+ case 'last3months': {
345
+ end = new Date(today.getFullYear(), today.getMonth(), today.getDate());
346
+ start = new Date(end);
347
+ start.setMonth(end.getMonth() - 3);
348
+ break;
349
+ }
350
+ case 'last6months': {
351
+ end = new Date(today.getFullYear(), today.getMonth(), today.getDate());
352
+ start = new Date(end);
353
+ start.setMonth(end.getMonth() - 6);
237
354
  break;
238
355
  }
239
356
  default:
@@ -241,6 +358,7 @@ export class AtomixDaterangeCalendarComponent {
241
358
  }
242
359
  if (start && end) {
243
360
  this.selectedDate = [start, end];
361
+ this.modelDate = [start, end];
244
362
  this.dateRangeChange.emit(this.selectedDate);
245
363
  this.selectedPreset = preset;
246
364
  this.customRangeMode = false;
@@ -249,6 +367,8 @@ export class AtomixDaterangeCalendarComponent {
249
367
  this.overlayPanel?.hide();
250
368
  }
251
369
  catch (e) { }
370
+ // ensure we update start/end classes after applying a preset
371
+ this._scheduleUpdate();
252
372
  }
253
373
  onDateRangeChange(dateRange) {
254
374
  this.dateRangeChange.emit(dateRange);
@@ -260,14 +380,224 @@ export class AtomixDaterangeCalendarComponent {
260
380
  this.selectedPreset = null;
261
381
  this.customRangeMode = false;
262
382
  }
383
+ this._scheduleUpdate();
384
+ }
385
+ ngOnDestroy() {
386
+ this._stopCalendarObservers();
387
+ this._cancelScheduledUpdate();
388
+ }
389
+ // Walk the rendered calendar DOM(s) (overlay + inline) and add start-range/end-range classes
390
+ _updateStartEndRangeClasses() {
391
+ try {
392
+ const calendarElements = this._getCalendarElements();
393
+ calendarElements.forEach((calEl) => {
394
+ // Remove existing classes from spans first
395
+ const allSpans = calEl.querySelectorAll('td > span');
396
+ allSpans.forEach((span) => {
397
+ this.renderer.removeClass(span, 'start-range');
398
+ this.renderer.removeClass(span, 'end-range');
399
+ this.renderer.removeClass(span, 'between-range');
400
+ });
401
+ // Collect span/date pairs, prefer data-date attribute
402
+ // Cache header month/year for this calendar to avoid querying per-span
403
+ const panelNode = calEl.closest('.p-datepicker') || calEl;
404
+ const headerMonthNode = panelNode.querySelector('.p-datepicker-header .p-datepicker-title .p-datepicker-month');
405
+ const headerYearNode = panelNode.querySelector('.p-datepicker-header .p-datepicker-title .p-datepicker-year');
406
+ const headerMonthIdx = headerMonthNode && headerMonthNode.textContent ? (this.enLocale.monthNames || []).indexOf(headerMonthNode.textContent.trim()) : NaN;
407
+ const headerYearVal = headerYearNode && headerYearNode.textContent ? parseInt(headerYearNode.textContent.trim(), 10) : NaN;
408
+ const items = [];
409
+ const spans = calEl.querySelectorAll('td > span.p-highlight');
410
+ spans.forEach((span) => {
411
+ const td = span.closest('td');
412
+ // Try to read data-date attribute, which some PrimeNG versions render on span/td
413
+ let dataDate = span.getAttribute('data-date');
414
+ if (!dataDate && td)
415
+ dataDate = td.getAttribute('data-date');
416
+ if (dataDate) {
417
+ const parts = dataDate.split('-').map((p) => parseInt(p, 10));
418
+ if (parts.length >= 3 && parts.every((n) => !isNaN(n))) {
419
+ const [y, m, d] = parts;
420
+ const dt = new Date(y, m - 1, d);
421
+ items.push({ dt, td, span });
422
+ return;
423
+ }
424
+ }
425
+ // Fallback: parse day number and infer month/year from nearby header in the same .p-datepicker
426
+ const dayText = (span.textContent || '').trim();
427
+ const day = parseInt(dayText, 10);
428
+ if (!isNaN(day) && td) {
429
+ // Use cached header month/year when available
430
+ if (!isNaN(headerMonthIdx) && !isNaN(headerYearVal)) {
431
+ const dt = new Date(headerYearVal, headerMonthIdx, day);
432
+ items.push({ dt, td, span });
433
+ return;
434
+ }
435
+ }
436
+ // last resort: ignore span if date cannot be determined
437
+ });
438
+ if (items.length === 0)
439
+ return;
440
+ // Sort items to find min/max (start & end)
441
+ items.sort((a, b) => a.dt.getTime() - b.dt.getTime());
442
+ const detectedStart = items[0].dt;
443
+ const detectedEnd = items[items.length - 1].dt;
444
+ // Preferred range is modelDate/selectedDate if present
445
+ const range = (this.selectedDate && this.selectedDate.length === 2) ? this.selectedDate : (this.modelDate && this.modelDate.length === 2 ? this.modelDate : [detectedStart, detectedEnd]);
446
+ const startDate = range && range[0] ? this.normalizeDate(range[0]) : detectedStart;
447
+ const endDate = range && range[1] ? this.normalizeDate(range[1]) : detectedEnd;
448
+ // For each item, add start-range,end-range, or between-range based on date
449
+ const sTime = startDate.getTime();
450
+ const eTime = endDate.getTime();
451
+ for (const it of items) {
452
+ const t = it.dt.getTime();
453
+ if (sTime === eTime && t === sTime) {
454
+ // single-day range, mark both start & end
455
+ this.renderer.addClass(it.span, 'start-range');
456
+ this.renderer.addClass(it.span, 'end-range');
457
+ }
458
+ else if (t === sTime) {
459
+ this.renderer.addClass(it.span, 'start-range');
460
+ }
461
+ else if (t === eTime) {
462
+ this.renderer.addClass(it.span, 'end-range');
463
+ }
464
+ else if (t > sTime && t < eTime) {
465
+ this.renderer.addClass(it.span, 'between-range');
466
+ }
467
+ }
468
+ });
469
+ }
470
+ catch (e) {
471
+ // ignore DOM errors (e.g., server-side rendering / missing elements)
472
+ }
473
+ }
474
+ isoDate(d) {
475
+ const y = d.getFullYear();
476
+ const m = String(d.getMonth() + 1).padStart(2, '0');
477
+ const day = String(d.getDate()).padStart(2, '0');
478
+ return `${y}-${m}-${day}`;
479
+ }
480
+ _findElementByDate(date) {
481
+ if (!date)
482
+ return undefined;
483
+ const y = date.getFullYear();
484
+ const m = date.getMonth() + 1; // 1..12
485
+ const d = date.getDate();
486
+ const isoUnpadded = `${y}-${m}-${d}`; // e.g. 2025-11-1
487
+ const isoPadded = `${y}-${String(m).padStart(2, '0')}-${String(d).padStart(2, '0')}`; // 2025-11-01
488
+ const selectors = [`[data-date="${isoUnpadded}"]`, `[data-date="${isoPadded}"]`];
489
+ for (const sel of selectors) {
490
+ const foundInOverlay = document.querySelector(`.atomix-overlay-calendar ${sel}`);
491
+ if (foundInOverlay)
492
+ return foundInOverlay.closest('td') || foundInOverlay;
493
+ }
494
+ for (const sel of selectors) {
495
+ const found = document.querySelector(sel);
496
+ if (found)
497
+ return found.closest('td') || found;
498
+ }
499
+ return undefined;
500
+ }
501
+ _startCalendarObservers() {
502
+ // stop first to avoid duplicates
503
+ this._stopCalendarObservers();
504
+ try {
505
+ const calEls = this._getCalendarElements();
506
+ try {
507
+ const panel = this.overlayPanel;
508
+ if (panel && panel.el && panel.el.nativeElement) {
509
+ const el = panel.el.nativeElement.querySelector('.p-datepicker');
510
+ if (el)
511
+ calEls.push(el);
512
+ }
513
+ }
514
+ catch (e) { }
515
+ calEls.forEach((el) => {
516
+ const obs = new MutationObserver(() => {
517
+ // Reapply classes after DOM changes (debounced)
518
+ this._scheduleUpdate();
519
+ });
520
+ // Watch childList, subtree and class attribute changes (span class toggles are common)
521
+ obs.observe(el, { childList: true, subtree: true, attributes: true, attributeFilter: ['class'] });
522
+ this._calendarObservers.push(obs);
523
+ this._observedElements.push(el);
524
+ // Also observe parent - if PrimeNG replaces the .p-datepicker element, parent childList changes will fire
525
+ const parent = el.parentElement;
526
+ if (parent && this._observedParentElements.indexOf(parent) === -1) {
527
+ const parentObs = new MutationObserver(() => {
528
+ // reattach observers since the calEl may have been replaced
529
+ this._scheduleUpdate();
530
+ // detach and re-attach observers after DOM settles
531
+ setTimeout(() => {
532
+ try {
533
+ this._stopCalendarObservers();
534
+ this._startCalendarObservers();
535
+ }
536
+ catch (e) { }
537
+ }, 100); // slightly larger delay to let PrimeNG finish the month rendering
538
+ });
539
+ parentObs.observe(parent, { childList: true, subtree: false });
540
+ this._parentObservers.push(parentObs);
541
+ this._observedParentElements.push(parent);
542
+ }
543
+ });
544
+ }
545
+ catch (e) {
546
+ // ignore
547
+ }
548
+ }
549
+ _stopCalendarObservers() {
550
+ try {
551
+ this._calendarObservers.forEach((obs) => obs.disconnect());
552
+ this._parentObservers.forEach((obs) => obs.disconnect());
553
+ }
554
+ catch (e) { }
555
+ this._calendarObservers = [];
556
+ this._observedElements = [];
557
+ this._parentObservers = [];
558
+ this._observedParentElements = [];
559
+ }
560
+ _scheduleUpdate() {
561
+ if (this._updateRafId != null)
562
+ return; // already scheduled
563
+ this._updateRafId = window.requestAnimationFrame(() => {
564
+ this._updateRafId = null;
565
+ this._updateStartEndRangeClasses();
566
+ });
567
+ }
568
+ _cancelScheduledUpdate() {
569
+ if (this._updateRafId != null) {
570
+ window.cancelAnimationFrame(this._updateRafId);
571
+ this._updateRafId = null;
572
+ }
263
573
  }
264
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AtomixDaterangeCalendarComponent, deps: [{ token: i1.DatePipe }], target: i0.ɵɵFactoryTarget.Component });
265
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AtomixDaterangeCalendarComponent, selector: "atomix-daterange-calendar", inputs: { placeholder: "placeholder", styleClass: "styleClass", selectionMode: "selectionMode", inputStyleClass: "inputStyleClass", disabled: "disabled", selectedDate: "selectedDate", maxDate: "maxDate", minDate: "minDate" }, outputs: { dateRangeChange: "dateRangeChange" }, viewQueries: [{ propertyName: "overlayPanel", first: true, predicate: ["op"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div>\n <div class=\"input-wrapper\">\n <input\n pInputText\n type=\"text\"\n [ngClass]=\"inputStyleClass\"\n [placeholder]=\"placeholder\"\n [value]=\"getDateRangeLabel()\"\n readonly\n [disabled]=\"disabled\"\n (click)=\"op.toggle($event)\"\n (keydown)=\"onInputKeyDown($event)\"\n />\n <i *ngIf=\"hasSelection\" class=\"pi pi-times input-clear-icon\" title=\"Clear\" tabindex=\"0\" (click)=\"clearAndStop($event)\" (keydown.enter)=\"clearAndStop($event)\" (keydown.space)=\"clearAndStop($event)\"></i>\n <i class=\"pi pi-calendar input-icon\" title=\"Open calendar\" (click)=\"op.toggle($event)\"></i>\n </div>\n <p-overlayPanel #op [dismissable]=\"true\" appendTo=\"body\" styleClass=\"atomix-date-range-overlay\">\n <div class=\"overlay-inner\">\n <div class=\"overlay-left\">\n <div class=\"preset-list\">\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('today')\" [ngClass]=\"{ 'active': selectedPreset === 'today' }\" label=\"Today\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('yesterday')\" [ngClass]=\"{ 'active': selectedPreset === 'yesterday' }\" label=\"Yesterday\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('lastWeek')\" [ngClass]=\"{ 'active': selectedPreset === 'lastWeek' }\" label=\"Last week\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('lastMonth')\" [ngClass]=\"{ 'active': selectedPreset === 'lastMonth' }\" label=\"Last month\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('lastQuarter')\" [ngClass]=\"{ 'active': selectedPreset === 'lastQuarter' }\" label=\"Last quarter\"></button>\n <!-- <button pButton pRipple type=\"button\" class=\"preset-btn p-button-outlined\" (click)=\"toggleCustomRange()\" [ngClass]=\"{ 'custom-active': customRangeMode }\" label=\"Custom range\"></button> -->\n </div>\n <a class=\"reset-link\" (click)=\"resetAndClose()\">Reset</a>\n </div>\n <div class=\"overlay-right\">\n <p-calendar [(ngModel)]=\"selectedDate\" [selectionMode]=\"'range'\" [inline]=\"true\" [dateFormat]=\"'mm/dd/yyyy'\" [showOtherMonths]=\"true\" [locale]=\"enLocale\" [showIcon]=\"false\" [styleClass]=\"'atomix-overlay-calendar'\" (ngModelChange)=\"onDateRangeChange($event)\" [disabled]=\"disabled\" [maxDate]=\"maxDate\" [minDate]=\"minDate\"></p-calendar>\n <!-- <div class=\"overlay-actions\" *ngIf=\"!inline\">\n <button pButton pRipple type=\"button\" class=\"p-button-help p-button-sm\" (click)=\"applyCustomRange()\">Apply</button>\n <button pButton pRipple type=\"button\" class=\"p-button-text p-button-sm\" (click)=\"resetAndClose()\">Cancel</button>\n </div> -->\n </div>\n </div>\n </p-overlayPanel>\n</div>\n", styles: ["::ng-deep .p-calendar{button{background-color:transparent!important}}.overlay-inner{display:flex;gap:1rem;align-items:flex-start;flex-wrap:nowrap}.overlay-left{padding-right:.75rem;display:flex;flex-direction:column;gap:.5rem}.input-wrapper{display:flex;align-items:center;gap:.5rem;width:100%;position:relative}.input-wrapper input[readonly]{cursor:pointer;padding-right:48px;border-radius:30px}.input-icon{cursor:pointer;color:#0000008a;position:absolute;right:10px}.input-clear-icon{cursor:pointer;color:#0000008a;position:absolute;right:36px}.preset-list{display:flex;flex-direction:column;gap:.5rem;padding:0;margin:0 0 6rem}.preset-btn{justify-content:flex-start;text-align:left;padding-left:8px}.preset-btn .p-button-label{display:inline-block}.preset-btn:not(.p-button-outlined){background-color:transparent;color:#111827}.preset-btn:hover{background-color:#f3f6f9}.preset-btn.active,.preset-btn.p-button.active,.preset-btn.custom-active,.preset-btn.p-button.custom-active{background-color:#e6f4ea!important;border-color:#63b77e!important;color:#063f23!important;font-weight:600}.reset-link{text-align:center;cursor:pointer}.atomix-date-range-overlay .overlay-left .reset-link{display:inline-block;margin-top:1rem;color:#2196f3;cursor:pointer}.overlay-right{flex:1}.overlay-inner.inline{flex-direction:row}:host ::ng-deep .p-column-filter-menu .overlay-inner.inline{display:flex!important;flex-direction:row!important;flex-wrap:nowrap!important}:host ::ng-deep .p-overlaypanel .overlay-inner.inline{display:flex!important;flex-direction:row!important}.overlay-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:.5rem}.atomix-overlay-calendar ::ng-deep .p-datepicker{width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "component", type: i4.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "component", type: i5.OverlayPanel, selector: "p-overlayPanel", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
574
+ _getCalendarElements() {
575
+ const calEls = [];
576
+ const overlayCal = document.querySelector('.atomix-overlay-calendar .p-datepicker');
577
+ const inlineCal = document.querySelector('.inline-calendar .p-datepicker');
578
+ if (overlayCal)
579
+ calEls.push(overlayCal);
580
+ if (inlineCal)
581
+ calEls.push(inlineCal);
582
+ try {
583
+ const panel = this.overlayPanel;
584
+ if (panel && panel.el && panel.el.nativeElement) {
585
+ const el = panel.el.nativeElement.querySelector('.p-datepicker');
586
+ if (el)
587
+ calEls.push(el);
588
+ }
589
+ }
590
+ catch (e) { }
591
+ // remove duplicates
592
+ return Array.from(new Set(calEls));
593
+ }
594
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AtomixDaterangeCalendarComponent, deps: [{ token: i1.DatePipe }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
595
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AtomixDaterangeCalendarComponent, selector: "atomix-daterange-calendar", inputs: { placeholder: "placeholder", styleClass: "styleClass", selectionMode: "selectionMode", inputStyleClass: "inputStyleClass", inline: "inline", disabled: "disabled", selectedDate: "selectedDate", maxDate: "maxDate", minDate: "minDate", defaultPreset: "defaultPreset" }, outputs: { dateRangeChange: "dateRangeChange" }, viewQueries: [{ propertyName: "overlayPanel", first: true, predicate: ["overlayPanel"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div>\n <ng-container *ngIf=\"!inline; else inlineBlock\">\n <div [ngClass]=\"styleClass\" class=\"input-wrapper\">\n <input\n pInputText\n type=\"text\"\n [ngClass]=\"inputStyleClass\"\n [placeholder]=\"placeholder\"\n [value]=\"getDateRangeLabel()\"\n readonly\n [disabled]=\"disabled\"\n (click)=\"overlayPanel?.toggle($event)\"\n (keydown)=\"onInputKeyDown($event)\"\n />\n <i class=\"pi pi-calendar input-icon\" title=\"Open calendar\" (click)=\"overlayPanel?.toggle($event)\"></i>\n <i *ngIf=\"hasSelection\" class=\"pi pi-times input-clear-icon\" title=\"Clear\" tabindex=\"0\" (click)=\"clearAndStop($event)\" (keydown.enter)=\"clearAndStop($event)\" (keydown.space)=\"clearAndStop($event)\"></i>\n\n </div>\n\n <p-overlayPanel #overlayPanel [dismissable]=\"true\" appendTo=\"body\" styleClass=\"atomix-date-range-overlay\" (onShow)=\"onOverlayShow()\" (onHide)=\"onOverlayHide()\">\n <div class=\"overlay-inner\">\n <div class=\"overlay-left\">\n <div class=\"preset-list\">\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('today')\" [ngClass]=\"{ 'active': selectedPreset === 'today' }\" label=\"Today\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('yesterday')\" [ngClass]=\"{ 'active': selectedPreset === 'yesterday' }\" label=\"Yesterday\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last7days')\" [ngClass]=\"{ 'active': selectedPreset === 'last7days' }\" label=\"Last 7 days\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last30days')\" [ngClass]=\"{ 'active': selectedPreset === 'last30days' }\" label=\"Last 30 days\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last3months')\" [ngClass]=\"{ 'active': selectedPreset === 'last3months' }\" label=\"Last 3 months\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last6months')\" [ngClass]=\"{ 'active': selectedPreset === 'last6months' }\" label=\"Last 6 months\"></button>\n <a class=\"reset-link\" (click)=\"resetAndClose()\">Reset</a>\n </div>\n </div>\n <div class=\"overlay-right\">\n <p-calendar [(ngModel)]=\"modelDate\" [selectionMode]=\"'range'\" [inline]=\"true\" [dateFormat]=\"'mm/dd/yyyy'\" [showOtherMonths]=\"true\" [locale]=\"enLocale\" [showIcon]=\"false\" [styleClass]=\"'atomix-overlay-calendar'\" (ngModelChange)=\"onModelChange($event)\" (onMonthChange)=\"onCalendarViewChanged($event)\" (onYearChange)=\"onCalendarViewChanged($event)\" [disabled]=\"disabled\" [maxDate]=\"maxDate\" [minDate]=\"minDate\"></p-calendar>\n </div>\n </div>\n </p-overlayPanel>\n </ng-container>\n\n <ng-template #inlineBlock>\n <div [ngClass]=\"styleClass\" class=\"input-wrapper\">\n <input\n pInputText\n type=\"text\"\n [ngClass]=\"inputStyleClass\"\n [placeholder]=\"placeholder\"\n [value]=\"getDateRangeLabel()\"\n readonly\n [disabled]=\"disabled\"\n (keydown)=\"onInputKeyDown($event)\"\n />\n <i class=\"pi pi-calendar input-icon\" title=\"Open calendar\"></i>\n <i *ngIf=\"hasSelection\" class=\"pi pi-times input-clear-icon\" title=\"Clear\" tabindex=\"0\" (click)=\"clearAndStop($event)\" (keydown.enter)=\"clearAndStop($event)\" (keydown.space)=\"clearAndStop($event)\"></i>\n </div>\n <div class=\"overlay-inner inline-calendar flex\">\n <div class=\"overlay-left\">\n <div class=\"preset-list\">\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('today')\" [ngClass]=\"{ 'active': selectedPreset === 'today' }\" label=\"Today\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('yesterday')\" [ngClass]=\"{ 'active': selectedPreset === 'yesterday' }\" label=\"Yesterday\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last7days')\" [ngClass]=\"{ 'active': selectedPreset === 'last7days' }\" label=\"Last 7 days\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last30days')\" [ngClass]=\"{ 'active': selectedPreset === 'last30days' }\" label=\"Last 30 days\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last3months')\" [ngClass]=\"{ 'active': selectedPreset === 'last3months' }\" label=\"Last 3 months\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last6months')\" [ngClass]=\"{ 'active': selectedPreset === 'last6months' }\" label=\"Last 6 months\"></button>\n <a class=\"reset-link\" (click)=\"resetAndClose()\">Reset</a>\n </div>\n </div>\n <div class=\"overlay-right\">\n <p-calendar [(ngModel)]=\"modelDate\" [selectionMode]=\"'range'\" [inline]=\"true\" [dateFormat]=\"'mm/dd/yyyy'\" [showOtherMonths]=\"true\" [locale]=\"enLocale\" [showIcon]=\"false\" [styleClass]=\"'atomix-overlay-calendar'\" (ngModelChange)=\"onModelChange($event)\" (onMonthChange)=\"onCalendarViewChanged($event)\" (onYearChange)=\"onCalendarViewChanged($event)\" [disabled]=\"disabled\" [maxDate]=\"maxDate\" [minDate]=\"minDate\"></p-calendar>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: ["::ng-deep .p-calendar button{background-color:transparent!important}::ng-deep .p-overlaypanel .p-overlaypanel-content{margin-top:0!important}::ng-deep .p-datepicker{border:none!important;border-radius:8px}::ng-deep .p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-month{color:#63b77e;transition:background-color .2s,color .2s,box-shadow .2s;font-weight:600;padding:.5rem}::ng-deep .p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-year,::ng-deep .p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-month{color:#63b77e;transition:background-color .2s,color .2s,box-shadow .2s;font-weight:600;padding:.5rem}::ng-deep .p-datepicker .p-monthpicker .p-monthpicker-month.p-highlight{color:#fff;background:#63c984}::ng-deep .p-datepicker .p-yearpicker .p-yearpicker-year.p-highlight{color:#fff;background:#63b77e}::ng-deep .p-datepicker table th{border-bottom:1px solid rgba(0,0,0,.12);color:#000000de;font-weight:400;font-size:.875rem}::ng-deep .p-datepicker table td>span.p-highlight{color:#fff;background:#63c984}::ng-deep .p-datepicker table td{padding:.2rem 0}::ng-deep .p-datepicker table td>span{width:2.8rem;height:2.8rem;border-radius:0%;transition:none}::ng-deep .p-datepicker table td.p-datepicker-today>span{box-shadow:inset 0 0 0 2px #00000061}::ng-deep .p-datepicker table td>span.p-highlight.start-range{border-top-left-radius:10px;border-bottom-left-radius:10px}::ng-deep .p-datepicker table td>span.p-highlight.end-range{border-top-right-radius:10px;border-bottom-right-radius:10px}::ng-deep .p-datepicker table td>span.p-highlight.between-range{background:#00c37dad!important}::ng-deep .inline-calendar .p-datepicker table td>span{width:2.4rem;height:2.4rem}::ng-deep .inline-calendar{border-bottom:1px solid #e5e5e5}::ng-deep .atomix-date-range-overlay{border-radius:8px}.overlay-inner{display:flex;gap:1rem;align-items:flex-start;flex-wrap:nowrap}.overlay-left{padding:.75rem .75rem 4rem;text-align:center;border-right:1px solid #e5e5e5}.inline-calendar .overlay-left{padding-bottom:2rem}.input-wrapper{display:flex;align-items:center;gap:.5rem;position:relative}.input-wrapper input[readonly]{cursor:pointer;padding-right:40px!important;border-radius:30px}.input-wrapper input{color:#000000de}.input-wrapper input::placeholder{color:#0009}.input-icon{cursor:pointer;color:#0000008a;position:absolute;right:10px}.input-clear-icon{cursor:pointer;color:#0000008a;position:absolute;right:27px}.preset-list{display:flex;flex-direction:column;gap:0}.preset-btn{justify-content:flex-start;text-align:left;padding-left:8px}.inline-calendar .preset-btn{padding:.3rem .8rem!important}.inline-calendar{gap:0}.preset-btn .p-button-label{display:inline-block}.preset-btn:not(.p-button-outlined){background-color:transparent;color:#111827}.preset-btn:hover{background-color:#f3f6f9}.preset-btn.active,.preset-btn.p-button.active,.preset-btn.custom-active,.preset-btn.p-button.custom-active{background-color:#63b77e!important;color:#fff!important;font-weight:700;line-height:17px;border-radius:12px}.reset-link{text-align:left;cursor:pointer;margin-top:25px;padding:.3rem 1.4rem!important;color:#63b77e;font-weight:600}.atomix-date-range-overlay .overlay-left .reset-link{display:inline-block;margin-top:1rem;color:#2196f3;cursor:pointer}.overlay-right{flex:1}.overlay-inner.inline{flex-direction:row}:host ::ng-deep .p-column-filter-menu .overlay-inner.inline{display:flex!important;flex-direction:row!important;flex-wrap:nowrap!important}:host ::ng-deep .p-overlaypanel .overlay-inner.inline{display:flex!important;flex-direction:row!important}.overlay-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:.5rem}.atomix-overlay-calendar ::ng-deep .p-datepicker{width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "component", type: i4.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "component", type: i5.OverlayPanel, selector: "p-overlayPanel", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
266
596
  }
267
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AtomixDaterangeCalendarComponent, decorators: [{
597
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AtomixDaterangeCalendarComponent, decorators: [{
268
598
  type: Component,
269
- args: [{ selector: 'atomix-daterange-calendar', template: "<div>\n <div class=\"input-wrapper\">\n <input\n pInputText\n type=\"text\"\n [ngClass]=\"inputStyleClass\"\n [placeholder]=\"placeholder\"\n [value]=\"getDateRangeLabel()\"\n readonly\n [disabled]=\"disabled\"\n (click)=\"op.toggle($event)\"\n (keydown)=\"onInputKeyDown($event)\"\n />\n <i *ngIf=\"hasSelection\" class=\"pi pi-times input-clear-icon\" title=\"Clear\" tabindex=\"0\" (click)=\"clearAndStop($event)\" (keydown.enter)=\"clearAndStop($event)\" (keydown.space)=\"clearAndStop($event)\"></i>\n <i class=\"pi pi-calendar input-icon\" title=\"Open calendar\" (click)=\"op.toggle($event)\"></i>\n </div>\n <p-overlayPanel #op [dismissable]=\"true\" appendTo=\"body\" styleClass=\"atomix-date-range-overlay\">\n <div class=\"overlay-inner\">\n <div class=\"overlay-left\">\n <div class=\"preset-list\">\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('today')\" [ngClass]=\"{ 'active': selectedPreset === 'today' }\" label=\"Today\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('yesterday')\" [ngClass]=\"{ 'active': selectedPreset === 'yesterday' }\" label=\"Yesterday\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('lastWeek')\" [ngClass]=\"{ 'active': selectedPreset === 'lastWeek' }\" label=\"Last week\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('lastMonth')\" [ngClass]=\"{ 'active': selectedPreset === 'lastMonth' }\" label=\"Last month\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('lastQuarter')\" [ngClass]=\"{ 'active': selectedPreset === 'lastQuarter' }\" label=\"Last quarter\"></button>\n <!-- <button pButton pRipple type=\"button\" class=\"preset-btn p-button-outlined\" (click)=\"toggleCustomRange()\" [ngClass]=\"{ 'custom-active': customRangeMode }\" label=\"Custom range\"></button> -->\n </div>\n <a class=\"reset-link\" (click)=\"resetAndClose()\">Reset</a>\n </div>\n <div class=\"overlay-right\">\n <p-calendar [(ngModel)]=\"selectedDate\" [selectionMode]=\"'range'\" [inline]=\"true\" [dateFormat]=\"'mm/dd/yyyy'\" [showOtherMonths]=\"true\" [locale]=\"enLocale\" [showIcon]=\"false\" [styleClass]=\"'atomix-overlay-calendar'\" (ngModelChange)=\"onDateRangeChange($event)\" [disabled]=\"disabled\" [maxDate]=\"maxDate\" [minDate]=\"minDate\"></p-calendar>\n <!-- <div class=\"overlay-actions\" *ngIf=\"!inline\">\n <button pButton pRipple type=\"button\" class=\"p-button-help p-button-sm\" (click)=\"applyCustomRange()\">Apply</button>\n <button pButton pRipple type=\"button\" class=\"p-button-text p-button-sm\" (click)=\"resetAndClose()\">Cancel</button>\n </div> -->\n </div>\n </div>\n </p-overlayPanel>\n</div>\n", styles: ["::ng-deep .p-calendar{button{background-color:transparent!important}}.overlay-inner{display:flex;gap:1rem;align-items:flex-start;flex-wrap:nowrap}.overlay-left{padding-right:.75rem;display:flex;flex-direction:column;gap:.5rem}.input-wrapper{display:flex;align-items:center;gap:.5rem;width:100%;position:relative}.input-wrapper input[readonly]{cursor:pointer;padding-right:48px;border-radius:30px}.input-icon{cursor:pointer;color:#0000008a;position:absolute;right:10px}.input-clear-icon{cursor:pointer;color:#0000008a;position:absolute;right:36px}.preset-list{display:flex;flex-direction:column;gap:.5rem;padding:0;margin:0 0 6rem}.preset-btn{justify-content:flex-start;text-align:left;padding-left:8px}.preset-btn .p-button-label{display:inline-block}.preset-btn:not(.p-button-outlined){background-color:transparent;color:#111827}.preset-btn:hover{background-color:#f3f6f9}.preset-btn.active,.preset-btn.p-button.active,.preset-btn.custom-active,.preset-btn.p-button.custom-active{background-color:#e6f4ea!important;border-color:#63b77e!important;color:#063f23!important;font-weight:600}.reset-link{text-align:center;cursor:pointer}.atomix-date-range-overlay .overlay-left .reset-link{display:inline-block;margin-top:1rem;color:#2196f3;cursor:pointer}.overlay-right{flex:1}.overlay-inner.inline{flex-direction:row}:host ::ng-deep .p-column-filter-menu .overlay-inner.inline{display:flex!important;flex-direction:row!important;flex-wrap:nowrap!important}:host ::ng-deep .p-overlaypanel .overlay-inner.inline{display:flex!important;flex-direction:row!important}.overlay-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:.5rem}.atomix-overlay-calendar ::ng-deep .p-datepicker{width:100%}\n"] }]
270
- }], ctorParameters: () => [{ type: i1.DatePipe }], propDecorators: { placeholder: [{
599
+ args: [{ selector: 'atomix-daterange-calendar', template: "<div>\n <ng-container *ngIf=\"!inline; else inlineBlock\">\n <div [ngClass]=\"styleClass\" class=\"input-wrapper\">\n <input\n pInputText\n type=\"text\"\n [ngClass]=\"inputStyleClass\"\n [placeholder]=\"placeholder\"\n [value]=\"getDateRangeLabel()\"\n readonly\n [disabled]=\"disabled\"\n (click)=\"overlayPanel?.toggle($event)\"\n (keydown)=\"onInputKeyDown($event)\"\n />\n <i class=\"pi pi-calendar input-icon\" title=\"Open calendar\" (click)=\"overlayPanel?.toggle($event)\"></i>\n <i *ngIf=\"hasSelection\" class=\"pi pi-times input-clear-icon\" title=\"Clear\" tabindex=\"0\" (click)=\"clearAndStop($event)\" (keydown.enter)=\"clearAndStop($event)\" (keydown.space)=\"clearAndStop($event)\"></i>\n\n </div>\n\n <p-overlayPanel #overlayPanel [dismissable]=\"true\" appendTo=\"body\" styleClass=\"atomix-date-range-overlay\" (onShow)=\"onOverlayShow()\" (onHide)=\"onOverlayHide()\">\n <div class=\"overlay-inner\">\n <div class=\"overlay-left\">\n <div class=\"preset-list\">\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('today')\" [ngClass]=\"{ 'active': selectedPreset === 'today' }\" label=\"Today\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('yesterday')\" [ngClass]=\"{ 'active': selectedPreset === 'yesterday' }\" label=\"Yesterday\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last7days')\" [ngClass]=\"{ 'active': selectedPreset === 'last7days' }\" label=\"Last 7 days\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last30days')\" [ngClass]=\"{ 'active': selectedPreset === 'last30days' }\" label=\"Last 30 days\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last3months')\" [ngClass]=\"{ 'active': selectedPreset === 'last3months' }\" label=\"Last 3 months\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last6months')\" [ngClass]=\"{ 'active': selectedPreset === 'last6months' }\" label=\"Last 6 months\"></button>\n <a class=\"reset-link\" (click)=\"resetAndClose()\">Reset</a>\n </div>\n </div>\n <div class=\"overlay-right\">\n <p-calendar [(ngModel)]=\"modelDate\" [selectionMode]=\"'range'\" [inline]=\"true\" [dateFormat]=\"'mm/dd/yyyy'\" [showOtherMonths]=\"true\" [locale]=\"enLocale\" [showIcon]=\"false\" [styleClass]=\"'atomix-overlay-calendar'\" (ngModelChange)=\"onModelChange($event)\" (onMonthChange)=\"onCalendarViewChanged($event)\" (onYearChange)=\"onCalendarViewChanged($event)\" [disabled]=\"disabled\" [maxDate]=\"maxDate\" [minDate]=\"minDate\"></p-calendar>\n </div>\n </div>\n </p-overlayPanel>\n </ng-container>\n\n <ng-template #inlineBlock>\n <div [ngClass]=\"styleClass\" class=\"input-wrapper\">\n <input\n pInputText\n type=\"text\"\n [ngClass]=\"inputStyleClass\"\n [placeholder]=\"placeholder\"\n [value]=\"getDateRangeLabel()\"\n readonly\n [disabled]=\"disabled\"\n (keydown)=\"onInputKeyDown($event)\"\n />\n <i class=\"pi pi-calendar input-icon\" title=\"Open calendar\"></i>\n <i *ngIf=\"hasSelection\" class=\"pi pi-times input-clear-icon\" title=\"Clear\" tabindex=\"0\" (click)=\"clearAndStop($event)\" (keydown.enter)=\"clearAndStop($event)\" (keydown.space)=\"clearAndStop($event)\"></i>\n </div>\n <div class=\"overlay-inner inline-calendar flex\">\n <div class=\"overlay-left\">\n <div class=\"preset-list\">\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('today')\" [ngClass]=\"{ 'active': selectedPreset === 'today' }\" label=\"Today\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('yesterday')\" [ngClass]=\"{ 'active': selectedPreset === 'yesterday' }\" label=\"Yesterday\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last7days')\" [ngClass]=\"{ 'active': selectedPreset === 'last7days' }\" label=\"Last 7 days\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last30days')\" [ngClass]=\"{ 'active': selectedPreset === 'last30days' }\" label=\"Last 30 days\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last3months')\" [ngClass]=\"{ 'active': selectedPreset === 'last3months' }\" label=\"Last 3 months\"></button>\n <button pButton pRipple type=\"button\" class=\"preset-btn\" (click)=\"applyPreset('last6months')\" [ngClass]=\"{ 'active': selectedPreset === 'last6months' }\" label=\"Last 6 months\"></button>\n <a class=\"reset-link\" (click)=\"resetAndClose()\">Reset</a>\n </div>\n </div>\n <div class=\"overlay-right\">\n <p-calendar [(ngModel)]=\"modelDate\" [selectionMode]=\"'range'\" [inline]=\"true\" [dateFormat]=\"'mm/dd/yyyy'\" [showOtherMonths]=\"true\" [locale]=\"enLocale\" [showIcon]=\"false\" [styleClass]=\"'atomix-overlay-calendar'\" (ngModelChange)=\"onModelChange($event)\" (onMonthChange)=\"onCalendarViewChanged($event)\" (onYearChange)=\"onCalendarViewChanged($event)\" [disabled]=\"disabled\" [maxDate]=\"maxDate\" [minDate]=\"minDate\"></p-calendar>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: ["::ng-deep .p-calendar button{background-color:transparent!important}::ng-deep .p-overlaypanel .p-overlaypanel-content{margin-top:0!important}::ng-deep .p-datepicker{border:none!important;border-radius:8px}::ng-deep .p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-month{color:#63b77e;transition:background-color .2s,color .2s,box-shadow .2s;font-weight:600;padding:.5rem}::ng-deep .p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-year,::ng-deep .p-datepicker .p-datepicker-header .p-datepicker-title .p-datepicker-month{color:#63b77e;transition:background-color .2s,color .2s,box-shadow .2s;font-weight:600;padding:.5rem}::ng-deep .p-datepicker .p-monthpicker .p-monthpicker-month.p-highlight{color:#fff;background:#63c984}::ng-deep .p-datepicker .p-yearpicker .p-yearpicker-year.p-highlight{color:#fff;background:#63b77e}::ng-deep .p-datepicker table th{border-bottom:1px solid rgba(0,0,0,.12);color:#000000de;font-weight:400;font-size:.875rem}::ng-deep .p-datepicker table td>span.p-highlight{color:#fff;background:#63c984}::ng-deep .p-datepicker table td{padding:.2rem 0}::ng-deep .p-datepicker table td>span{width:2.8rem;height:2.8rem;border-radius:0%;transition:none}::ng-deep .p-datepicker table td.p-datepicker-today>span{box-shadow:inset 0 0 0 2px #00000061}::ng-deep .p-datepicker table td>span.p-highlight.start-range{border-top-left-radius:10px;border-bottom-left-radius:10px}::ng-deep .p-datepicker table td>span.p-highlight.end-range{border-top-right-radius:10px;border-bottom-right-radius:10px}::ng-deep .p-datepicker table td>span.p-highlight.between-range{background:#00c37dad!important}::ng-deep .inline-calendar .p-datepicker table td>span{width:2.4rem;height:2.4rem}::ng-deep .inline-calendar{border-bottom:1px solid #e5e5e5}::ng-deep .atomix-date-range-overlay{border-radius:8px}.overlay-inner{display:flex;gap:1rem;align-items:flex-start;flex-wrap:nowrap}.overlay-left{padding:.75rem .75rem 4rem;text-align:center;border-right:1px solid #e5e5e5}.inline-calendar .overlay-left{padding-bottom:2rem}.input-wrapper{display:flex;align-items:center;gap:.5rem;position:relative}.input-wrapper input[readonly]{cursor:pointer;padding-right:40px!important;border-radius:30px}.input-wrapper input{color:#000000de}.input-wrapper input::placeholder{color:#0009}.input-icon{cursor:pointer;color:#0000008a;position:absolute;right:10px}.input-clear-icon{cursor:pointer;color:#0000008a;position:absolute;right:27px}.preset-list{display:flex;flex-direction:column;gap:0}.preset-btn{justify-content:flex-start;text-align:left;padding-left:8px}.inline-calendar .preset-btn{padding:.3rem .8rem!important}.inline-calendar{gap:0}.preset-btn .p-button-label{display:inline-block}.preset-btn:not(.p-button-outlined){background-color:transparent;color:#111827}.preset-btn:hover{background-color:#f3f6f9}.preset-btn.active,.preset-btn.p-button.active,.preset-btn.custom-active,.preset-btn.p-button.custom-active{background-color:#63b77e!important;color:#fff!important;font-weight:700;line-height:17px;border-radius:12px}.reset-link{text-align:left;cursor:pointer;margin-top:25px;padding:.3rem 1.4rem!important;color:#63b77e;font-weight:600}.atomix-date-range-overlay .overlay-left .reset-link{display:inline-block;margin-top:1rem;color:#2196f3;cursor:pointer}.overlay-right{flex:1}.overlay-inner.inline{flex-direction:row}:host ::ng-deep .p-column-filter-menu .overlay-inner.inline{display:flex!important;flex-direction:row!important;flex-wrap:nowrap!important}:host ::ng-deep .p-overlaypanel .overlay-inner.inline{display:flex!important;flex-direction:row!important}.overlay-actions{display:flex;gap:.5rem;justify-content:flex-end;margin-top:.5rem}.atomix-overlay-calendar ::ng-deep .p-datepicker{width:100%}\n"] }]
600
+ }], ctorParameters: () => [{ type: i1.DatePipe }, { type: i0.Renderer2 }], propDecorators: { placeholder: [{
271
601
  type: Input
272
602
  }], styleClass: [{
273
603
  type: Input
@@ -275,6 +605,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
275
605
  type: Input
276
606
  }], inputStyleClass: [{
277
607
  type: Input
608
+ }], inline: [{
609
+ type: Input
278
610
  }], disabled: [{
279
611
  type: Input
280
612
  }], selectedDate: [{
@@ -283,10 +615,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
283
615
  type: Input
284
616
  }], minDate: [{
285
617
  type: Input
618
+ }], defaultPreset: [{
619
+ type: Input
286
620
  }], overlayPanel: [{
287
621
  type: ViewChild,
288
- args: ['op']
622
+ args: ['overlayPanel']
289
623
  }], dateRangeChange: [{
290
624
  type: Output
291
625
  }] } });
292
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbWl4LWRhdGVyYW5nZS1jYWxlbmRhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9wcmltZWtpdC9zcmMvbGliL2xpYi9hdG9taXgtZGF0ZXJhbmdlLWNhbGVuZGFyL2F0b21peC1kYXRlcmFuZ2UtY2FsZW5kYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcHJpbWVraXQvc3JjL2xpYi9saWIvYXRvbWl4LWRhdGVyYW5nZS1jYWxlbmRhci9hdG9taXgtZGF0ZXJhbmdlLWNhbGVuZGFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUE0QixNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7QUFTNUcsTUFBTSxPQUFPLGdDQUFnQztJQTREdkI7SUEzRFgsV0FBVyxHQUFXLEVBQUUsQ0FBQztJQUN6QixVQUFVLEdBQVcsRUFBRSxDQUFDO0lBQ3hCLGFBQWEsR0FBWSxPQUFPLENBQUM7SUFDakMsZUFBZSxHQUFXLEVBQUUsQ0FBQztJQUM3QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLFlBQVksR0FBa0IsSUFBSSxDQUFDO0lBQ25DLE9BQU8sQ0FBUTtJQUNmLE9BQU8sQ0FBUTtJQUV4QixlQUFlLEdBQVksS0FBSyxDQUFDO0lBQ2pDLGNBQWMsR0FBa0IsSUFBSSxDQUFDLENBQUMscUZBQXFGO0lBQzFHLFlBQVksQ0FBZ0I7SUFDbkMsZUFBZSxHQUFHLElBQUksWUFBWSxFQUFpQixDQUFDO0lBRTlELFFBQVEsR0FBRztRQUNULGNBQWMsRUFBRSxDQUFDO1FBQ2pCLFFBQVEsRUFBRTtZQUNSLFFBQVE7WUFDUixRQUFRO1lBQ1IsU0FBUztZQUNULFdBQVc7WUFDWCxVQUFVO1lBQ1YsUUFBUTtZQUNSLFVBQVU7U0FDWDtRQUNELGFBQWEsRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQztRQUNoRSxXQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUM7UUFDdkQsVUFBVSxFQUFFO1lBQ1YsU0FBUztZQUNULFVBQVU7WUFDVixPQUFPO1lBQ1AsT0FBTztZQUNQLEtBQUs7WUFDTCxNQUFNO1lBQ04sTUFBTTtZQUNOLFFBQVE7WUFDUixXQUFXO1lBQ1gsU0FBUztZQUNULFVBQVU7WUFDVixVQUFVO1NBQ1g7UUFDRCxlQUFlLEVBQUU7WUFDZixLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7U0FDTjtRQUNELEtBQUssRUFBRSxPQUFPO1FBQ2QsS0FBSyxFQUFFLE9BQU87S0FDZixDQUFDO0lBRUYsWUFBb0IsUUFBa0I7UUFBbEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtJQUFHLENBQUM7SUFFMUMsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDNUIsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLFlBQTZCLENBQUM7WUFDbEUsSUFBSSxHQUFHLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RFLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNqRCxJQUFJLENBQUMsY0FBYyxHQUFHLE1BQU0sSUFBSSxRQUFRLENBQUM7WUFDM0MsQ0FBQztpQkFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDN0IsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsY0FBYyxDQUFDLEtBQW9CO1FBQ2pDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxPQUFPLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUM7Z0JBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsS0FBWSxDQUFDLENBQUM7WUFBQyxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUM7WUFDN0QsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3pCLENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBWSxDQUFDLEtBQVk7UUFDdkIsMkRBQTJEO1FBQzNELElBQUksQ0FBQztZQUFDLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUFDLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUEsQ0FBQztRQUM3QyxJQUFJLENBQUM7WUFBQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFBQyxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUM7UUFDNUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxPQUFPLE9BQU8sQ0FDWixJQUFJLENBQUMsWUFBWTtZQUNmLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztZQUMvQixJQUFJLENBQUMsWUFBdUIsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUMxQyxDQUFDLENBQUUsSUFBSSxDQUFDLFlBQXVCLENBQUMsQ0FBQyxDQUFDO1lBQ2xDLENBQUMsQ0FBRSxJQUFJLENBQUMsWUFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FDckMsQ0FBQztJQUNKLENBQUM7SUFFTyxhQUFhLENBQUMsQ0FBTztRQUMzQixPQUFPLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVPLFVBQVUsQ0FBQyxDQUFPLEVBQUUsQ0FBTztRQUNqQyxPQUFPLENBQ0wsQ0FBQyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsQ0FBQyxXQUFXLEVBQUU7WUFDbkMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQyxRQUFRLEVBQUU7WUFDN0IsQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FDNUIsQ0FBQztJQUNKLENBQUM7SUFFTyxZQUFZLENBQUMsUUFBYyxFQUFFLE1BQVk7UUFDL0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLFFBQVE7UUFDUixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQztZQUFFLE9BQU8sT0FBTyxDQUFDO1FBQ2pGLFlBQVk7UUFDWixNQUFNLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQixDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzQixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUFFLE9BQU8sV0FBVyxDQUFDO1FBQzdFLG1FQUFtRTtRQUNuRSxNQUFNLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QixLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLE9BQU8sR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQztZQUFFLE9BQU8sVUFBVSxDQUFDO1FBQ3RGLFlBQVk7UUFDWixNQUFNLHNCQUFzQixHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbEYsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQzVELGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QixNQUFNLG1CQUFtQixHQUFHLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxFQUFFLGtCQUFrQixDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pHLElBQ0UsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsbUJBQW1CLENBQUM7WUFDM0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsa0JBQWtCLENBQUM7WUFFeEMsT0FBTyxXQUFXLENBQUM7UUFDckIsY0FBYztRQUNkLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUMvQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLG1CQUFtQixHQUFHLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sY0FBYyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxtQkFBbUIsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakYsTUFBTSxxQkFBcUIsR0FBRyxtQkFBbUIsR0FBRyxDQUFDLENBQUM7UUFDdEQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUscUJBQXFCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakYsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQztZQUFFLE9BQU8sYUFBYSxDQUFDO1FBQzNHLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGNBQWM7UUFDWixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7SUFDL0IsQ0FBQztJQUVELGFBQWE7UUFDWCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdEIsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDdEIsSUFBSSxDQUFDO2dCQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7WUFBQyxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUM7UUFDaEQsQ0FBQztJQUNILENBQUM7SUFFRCxpQkFBaUI7UUFDZixJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUM3QyxJQUFJLElBQUksQ0FBQyxlQUFlO1lBQUUsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUM7SUFDM0QsQ0FBQztJQUVELGdCQUFnQjtRQUNkLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUM7Z0JBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUFDLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUEsQ0FBQztRQUNoRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDN0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUM7SUFDakMsQ0FBQztJQUVELGlCQUFpQjtRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUMsV0FBVyxJQUFJLG1CQUFtQixDQUFDO1FBQzVHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQXNCLENBQUM7UUFDakQsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPLG1CQUFtQixDQUFDO1FBQy9DLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxZQUFZLENBQUMsQ0FBQztRQUM5RCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDNUQsT0FBTyxHQUFHLFFBQVEsTUFBTSxNQUFNLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsV0FBVyxDQUFDLE1BQWdFO1FBQzFFLE1BQU0sS0FBSyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDekIsSUFBSSxLQUFLLEdBQWdCLElBQUksQ0FBQztRQUM5QixJQUFJLEdBQUcsR0FBZ0IsSUFBSSxDQUFDO1FBQzVCLFFBQVEsTUFBTSxFQUFFLENBQUM7WUFDZixLQUFLLE9BQU87Z0JBQ1YsS0FBSyxHQUFHLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUMvRSxNQUFNO1lBQ1IsS0FBSyxXQUFXO2dCQUNkLE1BQU0sQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMxQixDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDM0IsS0FBSyxHQUFHLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRSxNQUFNO1lBQ1IsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUNoQixNQUFNLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDOUIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ25DLE1BQU0sT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNoQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDckMsS0FBSyxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsRUFBRSxPQUFPLENBQUMsUUFBUSxFQUFFLEVBQUUsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQy9FLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUN2RSxNQUFNO1lBQ1IsQ0FBQztZQUNELEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDakIsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNsRixNQUFNLGtCQUFrQixHQUFHLElBQUksSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7Z0JBQzVELGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDOUIsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLEVBQUUsRUFBRSxrQkFBa0IsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDekcsS0FBSyxHQUFHLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxFQUFFLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUN2RixHQUFHLEdBQUcsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsV0FBVyxFQUFFLEVBQUUsa0JBQWtCLENBQUMsUUFBUSxFQUFFLEVBQUUsa0JBQWtCLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDOUcsTUFBTTtZQUNSLENBQUM7WUFDRCxLQUFLLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RDLE1BQU0sbUJBQW1CLEdBQUcsT0FBTyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzVDLE1BQU0sY0FBYyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxtQkFBbUIsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pGLE1BQU0scUJBQXFCLEdBQUcsbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO2dCQUN0RCxNQUFNLGdCQUFnQixHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxxQkFBcUIsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDakYsS0FBSyxHQUFHLGdCQUFnQixDQUFDO2dCQUN6QixHQUFHLEdBQUcsY0FBYyxDQUFDO2dCQUNyQixNQUFNO1lBQ1IsQ0FBQztZQUNEO2dCQUNFLE1BQU07UUFDVixDQUFDO1FBQ0QsSUFBSSxLQUFLLElBQUksR0FBRyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNqQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUM7WUFDN0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksQ0FBQztZQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFBQyxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUM7SUFDakQsQ0FBQztJQUVELGlCQUFpQixDQUFDLFNBQXdCO1FBQ3hDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3JDLElBQUksU0FBUyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BFLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQy9CLENBQUM7YUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDdEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDM0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDL0IsQ0FBQztJQUNILENBQUM7d0dBdlBVLGdDQUFnQzs0RkFBaEMsZ0NBQWdDLDZjQ1Q3QyxpK0ZBdUNBOzs0RkQ5QmEsZ0NBQWdDO2tCQUw1QyxTQUFTOytCQUNFLDJCQUEyQjs2RUFLNUIsV0FBVztzQkFBbkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFJVyxZQUFZO3NCQUE1QixTQUFTO3VCQUFDLElBQUk7Z0JBQ0wsZUFBZTtzQkFBeEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0LCBWaWV3Q2hpbGQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT3ZlcmxheVBhbmVsIH0gZnJvbSAncHJpbWVuZy9vdmVybGF5cGFuZWwnO1xuaW1wb3J0IHsgRGF0ZVBpcGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhdG9taXgtZGF0ZXJhbmdlLWNhbGVuZGFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2F0b21peC1kYXRlcmFuZ2UtY2FsZW5kYXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9hdG9taXgtZGF0ZXJhbmdlLWNhbGVuZGFyLmNvbXBvbmVudC5jc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgQXRvbWl4RGF0ZXJhbmdlQ2FsZW5kYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBASW5wdXQoKSBwbGFjZWhvbGRlcjogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIHN0eWxlQ2xhc3M6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBzZWxlY3Rpb25Nb2RlOiAncmFuZ2UnID0gJ3JhbmdlJztcbiAgQElucHV0KCkgaW5wdXRTdHlsZUNsYXNzOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgc2VsZWN0ZWREYXRlOiBEYXRlW10gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgbWF4RGF0ZSE6IERhdGU7XG4gIEBJbnB1dCgpIG1pbkRhdGUhOiBEYXRlO1xuXG4gIGN1c3RvbVJhbmdlTW9kZTogYm9vbGVhbiA9IGZhbHNlO1xuICBzZWxlY3RlZFByZXNldDogc3RyaW5nIHwgbnVsbCA9IG51bGw7IC8vICd0b2RheScgfCAneWVzdGVyZGF5JyB8ICdsYXN0V2VlaycgfCAnbGFzdE1vbnRoJyB8ICdsYXN0UXVhcnRlcicgfCAnY3VzdG9tJyB8IG51bGxcbiAgQFZpZXdDaGlsZCgnb3AnKSBvdmVybGF5UGFuZWwhOiBPdmVybGF5UGFuZWw7XG4gIEBPdXRwdXQoKSBkYXRlUmFuZ2VDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPERhdGVbXSB8IG51bGw+KCk7XG5cbiAgZW5Mb2NhbGUgPSB7XG4gICAgZmlyc3REYXlPZldlZWs6IDAsXG4gICAgZGF5TmFtZXM6IFtcbiAgICAgICdTdW5kYXknLFxuICAgICAgJ01vbmRheScsXG4gICAgICAnVHVlc2RheScsXG4gICAgICAnV2VkbmVzZGF5JyxcbiAgICAgICdUaHVyc2RheScsXG4gICAgICAnRnJpZGF5JyxcbiAgICAgICdTYXR1cmRheScsXG4gICAgXSxcbiAgICBkYXlOYW1lc1Nob3J0OiBbJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddLFxuICAgIGRheU5hbWVzTWluOiBbJ1N1JywgJ01vJywgJ1R1JywgJ1dlJywgJ1RoJywgJ0ZyJywgJ1NhJ10sXG4gICAgbW9udGhOYW1lczogW1xuICAgICAgJ0phbnVhcnknLFxuICAgICAgJ0ZlYnJ1YXJ5JyxcbiAgICAgICdNYXJjaCcsXG4gICAgICAnQXByaWwnLFxuICAgICAgJ01heScsXG4gICAgICAnSnVuZScsXG4gICAgICAnSnVseScsXG4gICAgICAnQXVndXN0JyxcbiAgICAgICdTZXB0ZW1iZXInLFxuICAgICAgJ09jdG9iZXInLFxuICAgICAgJ05vdmVtYmVyJyxcbiAgICAgICdEZWNlbWJlcicsXG4gICAgXSxcbiAgICBtb250aE5hbWVzU2hvcnQ6IFtcbiAgICAgICdKYW4nLFxuICAgICAgJ0ZlYicsXG4gICAgICAnTWFyJyxcbiAgICAgICdBcHInLFxuICAgICAgJ01heScsXG4gICAgICAnSnVuJyxcbiAgICAgICdKdWwnLFxuICAgICAgJ0F1ZycsXG4gICAgICAnU2VwJyxcbiAgICAgICdPY3QnLFxuICAgICAgJ05vdicsXG4gICAgICAnRGVjJyxcbiAgICBdLFxuICAgIHRvZGF5OiAnVG9kYXknLFxuICAgIGNsZWFyOiAnQ2xlYXInLFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgZGF0ZVBpcGU6IERhdGVQaXBlKSB7fVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snc2VsZWN0ZWREYXRlJ10pIHtcbiAgICAgIGNvbnN0IHNlbCA9IGNoYW5nZXNbJ3NlbGVjdGVkRGF0ZSddLmN1cnJlbnRWYWx1ZSBhcyBEYXRlW10gfCBudWxsO1xuICAgICAgaWYgKHNlbCAmJiBBcnJheS5pc0FycmF5KHNlbCkgJiYgc2VsLmxlbmd0aCA9PT0gMiAmJiBzZWxbMF0gJiYgc2VsWzFdKSB7XG4gICAgICAgIGNvbnN0IHByZXNldCA9IHRoaXMuZGV0ZWN0UHJlc2V0KHNlbFswXSwgc2VsWzFdKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFByZXNldCA9IHByZXNldCA/PyAnY3VzdG9tJztcbiAgICAgIH0gZWxzZSBpZiAoc2VsID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFByZXNldCA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25JbnB1dEtleURvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRW50ZXInIHx8IGV2ZW50LmtleSA9PT0gJyAnKSB7XG4gICAgICB0cnkgeyB0aGlzLm92ZXJsYXlQYW5lbD8udG9nZ2xlKGV2ZW50IGFzIGFueSk7IH0gY2F0Y2ggKGUpIHt9XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIGNsZWFyQW5kU3RvcChldmVudDogRXZlbnQpIHtcbiAgICAvLyBQcmV2ZW50IHRvZ2dsZSBmcm9tIGhhcHBlbmluZyB3aGVuIGNsZWFyIGljb24gaXMgY2xpY2tlZFxuICAgIHRyeSB7IGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyB9IGNhdGNoIChlKSB7fVxuICAgIHRyeSB7IGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IH0gY2F0Y2ggKGUpIHt9XG4gICAgdGhpcy5jbGVhckRhdGVSYW5nZSgpO1xuICB9XG5cbiAgZ2V0IGhhc1NlbGVjdGlvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQm9vbGVhbihcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlICYmXG4gICAgICAgIEFycmF5LmlzQXJyYXkodGhpcy5zZWxlY3RlZERhdGUpICYmXG4gICAgICAgICh0aGlzLnNlbGVjdGVkRGF0ZSBhcyBEYXRlW10pLmxlbmd0aCA9PT0gMiAmJlxuICAgICAgICAhISh0aGlzLnNlbGVjdGVkRGF0ZSBhcyBEYXRlW10pWzBdICYmXG4gICAgICAgICEhKHRoaXMuc2VsZWN0ZWREYXRlIGFzIERhdGVbXSlbMV1cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBub3JtYWxpemVEYXRlKGQ6IERhdGUpOiBEYXRlIHtcbiAgICByZXR1cm4gbmV3IERhdGUoZC5nZXRGdWxsWWVhcigpLCBkLmdldE1vbnRoKCksIGQuZ2V0RGF0ZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNTYW1lRGF0ZShhOiBEYXRlLCBiOiBEYXRlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGEuZ2V0RnVsbFllYXIoKSA9PT0gYi5nZXRGdWxsWWVhcigpICYmXG4gICAgICBhLmdldE1vbnRoKCkgPT09IGIuZ2V0TW9udGgoKSAmJlxuICAgICAgYS5nZXREYXRlKCkgPT09IGIuZ2V0RGF0ZSgpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZGV0ZWN0UHJlc2V0KHN0YXJ0UmF3OiBEYXRlLCBlbmRSYXc6IERhdGUpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMubm9ybWFsaXplRGF0ZShzdGFydFJhdyk7XG4gICAgY29uc3QgZW5kID0gdGhpcy5ub3JtYWxpemVEYXRlKGVuZFJhdyk7XG4gICAgY29uc3QgdG9kYXkgPSB0aGlzLm5vcm1hbGl6ZURhdGUobmV3IERhdGUoKSk7XG4gICAgLy8gdG9kYXlcbiAgICBpZiAodGhpcy5pc1NhbWVEYXRlKHN0YXJ0LCB0b2RheSkgJiYgdGhpcy5pc1NhbWVEYXRlKGVuZCwgdG9kYXkpKSByZXR1cm4gJ3RvZGF5JztcbiAgICAvLyB5ZXN0ZXJkYXlcbiAgICBjb25zdCB5ID0gbmV3IERhdGUodG9kYXkpO1xuICAgIHkuc2V0RGF0ZSh5LmdldERhdGUoKSAtIDEpO1xuICAgIGlmICh0aGlzLmlzU2FtZURhdGUoc3RhcnQsIHkpICYmIHRoaXMuaXNTYW1lRGF0ZShlbmQsIHkpKSByZXR1cm4gJ3llc3RlcmRheSc7XG4gICAgLy8gbGFzdFdlZWsgKGxhc3QgNyBkYXlzIHdoZXJlIGVuZCA9IHllc3RlcmRheSBhbmQgc3RhcnQgPSBlbmQgLSA2KVxuICAgIGNvbnN0IGx3RW5kID0gbmV3IERhdGUodG9kYXkpO1xuICAgIGx3RW5kLnNldERhdGUobHdFbmQuZ2V0RGF0ZSgpIC0gMSk7XG4gICAgY29uc3QgbHdTdGFydCA9IG5ldyBEYXRlKGx3RW5kKTtcbiAgICBsd1N0YXJ0LnNldERhdGUobHdFbmQuZ2V0RGF0ZSgpIC0gNik7XG4gICAgaWYgKHRoaXMuaXNTYW1lRGF0ZShzdGFydCwgbHdTdGFydCkgJiYgdGhpcy5pc1NhbWVEYXRlKGVuZCwgbHdFbmQpKSByZXR1cm4gJ2xhc3RXZWVrJztcbiAgICAvLyBsYXN0TW9udGhcbiAgICBjb25zdCBmaXJzdERheU9mQ3VycmVudE1vbnRoID0gbmV3IERhdGUodG9kYXkuZ2V0RnVsbFllYXIoKSwgdG9kYXkuZ2V0TW9udGgoKSwgMSk7XG4gICAgY29uc3QgbGFzdERheU9mUHJldk1vbnRoID0gbmV3IERhdGUoZmlyc3REYXlPZkN1cnJlbnRNb250aCk7XG4gICAgbGFzdERheU9mUHJldk1vbnRoLnNldERhdGUoMCk7XG4gICAgY29uc3QgZmlyc3REYXlPZlByZXZNb250aCA9IG5ldyBEYXRlKGxhc3REYXlPZlByZXZNb250aC5nZXRGdWxsWWVhcigpLCBsYXN0RGF5T2ZQcmV2TW9udGguZ2V0TW9udGgoKSwgMSk7XG4gICAgaWYgKFxuICAgICAgdGhpcy5pc1NhbWVEYXRlKHN0YXJ0LCBmaXJzdERheU9mUHJldk1vbnRoKSAmJlxuICAgICAgdGhpcy5pc1NhbWVEYXRlKGVuZCwgbGFzdERheU9mUHJldk1vbnRoKVxuICAgIClcbiAgICAgIHJldHVybiAnbGFzdE1vbnRoJztcbiAgICAvLyBsYXN0UXVhcnRlclxuICAgIGNvbnN0IG1vbnRoID0gdG9kYXkuZ2V0TW9udGgoKTtcbiAgICBjb25zdCBxdWFydGVyID0gTWF0aC5mbG9vcihtb250aCAvIDMpO1xuICAgIGNvbnN0IHByZXZRdWFydGVyRW5kTW9udGggPSBxdWFydGVyICogMyAtIDE7XG4gICAgY29uc3QgcHJldlF1YXJ0ZXJFbmQgPSBuZXcgRGF0ZSh0b2RheS5nZXRGdWxsWWVhcigpLCBwcmV2UXVhcnRlckVuZE1vbnRoICsgMSwgMCk7XG4gICAgY29uc3QgcHJldlF1YXJ0ZXJTdGFydE1vbnRoID0gcHJldlF1YXJ0ZXJFbmRNb250aCAtIDI7XG4gICAgY29uc3QgcHJldlF1YXJ0ZXJTdGFydCA9IG5ldyBEYXRlKHRvZGF5LmdldEZ1bGxZZWFyKCksIHByZXZRdWFydGVyU3RhcnRNb250aCwgMSk7XG4gICAgaWYgKHRoaXMuaXNTYW1lRGF0ZShzdGFydCwgcHJldlF1YXJ0ZXJTdGFydCkgJiYgdGhpcy5pc1NhbWVEYXRlKGVuZCwgcHJldlF1YXJ0ZXJFbmQpKSByZXR1cm4gJ2xhc3RRdWFydGVyJztcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNsZWFyRGF0ZVJhbmdlKCkge1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbnVsbDtcbiAgICB0aGlzLmRhdGVSYW5nZUNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWREYXRlKTtcbiAgICB0aGlzLnNlbGVjdGVkUHJlc2V0ID0gbnVsbDtcbiAgICB0aGlzLmN1c3RvbVJhbmdlTW9kZSA9IGZhbHNlO1xuICB9XG5cbiAgcmVzZXRBbmRDbG9zZSgpIHtcbiAgICB0aGlzLmNsZWFyRGF0ZVJhbmdlKCk7XG4gICAgaWYgKHRoaXMub3ZlcmxheVBhbmVsKSB7XG4gICAgICB0cnkgeyB0aGlzLm92ZXJsYXlQYW5lbC5oaWRlKCk7IH0gY2F0Y2ggKGUpIHt9XG4gICAgfVxuICB9XG5cbiAgdG9nZ2xlQ3VzdG9tUmFuZ2UoKSB7XG4gICAgdGhpcy5jdXN0b21SYW5nZU1vZGUgPSAhdGhpcy5jdXN0b21SYW5nZU1vZGU7XG4gICAgaWYgKHRoaXMuY3VzdG9tUmFuZ2VNb2RlKSB0aGlzLnNlbGVjdGVkUHJlc2V0ID0gJ2N1c3RvbSc7XG4gIH1cblxuICBhcHBseUN1c3RvbVJhbmdlKCkge1xuICAgIHRoaXMuZGF0ZVJhbmdlQ2hhbmdlLmVtaXQodGhpcy5zZWxlY3RlZERhdGUpO1xuICAgIGlmICh0aGlzLm92ZXJsYXlQYW5lbCkge1xuICAgICAgdHJ5IHsgdGhpcy5vdmVybGF5UGFuZWwuaGlkZSgpOyB9IGNhdGNoIChlKSB7fVxuICAgIH1cbiAgICB0aGlzLmN1c3RvbVJhbmdlTW9kZSA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0ZWRQcmVzZXQgPSAnY3VzdG9tJztcbiAgfVxuXG4gIGdldERhdGVSYW5nZUxhYmVsKCkge1xuICAgIGlmICghdGhpcy5zZWxlY3RlZERhdGUgfHwgIUFycmF5LmlzQXJyYXkodGhpcy5zZWxlY3RlZERhdGUpKSByZXR1cm4gdGhpcy5wbGFjZWhvbGRlciB8fCAnU2VsZWN0IGRhdGUgcmFuZ2UnO1xuICAgIGNvbnN0IFtzdGFydCwgZW5kXSA9IHRoaXMuc2VsZWN0ZWREYXRlIGFzIERhdGVbXTtcbiAgICBpZiAoIXN0YXJ0IHx8ICFlbmQpIHJldHVybiAnU2VsZWN0IGRhdGUgcmFuZ2UnO1xuICAgIGNvbnN0IHN0YXJ0U3RyID0gdGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0oc3RhcnQsICdNTS9kZC95eXl5Jyk7XG4gICAgY29uc3QgZW5kU3RyID0gdGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0oZW5kLCAnTU0vZGQveXl5eScpO1xuICByZXR1cm4gYCR7c3RhcnRTdHJ9IOKAkyAke2VuZFN0cn1gO1xuICB9XG5cbiAgYXBwbHlQcmVzZXQocHJlc2V0OiAndG9kYXknfCd5ZXN0ZXJkYXknfCdsYXN0V2Vlayd8J2xhc3RNb250aCd8J2xhc3RRdWFydGVyJykge1xuICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICBsZXQgc3RhcnQ6IERhdGUgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgZW5kOiBEYXRlIHwgbnVsbCA9IG51bGw7XG4gICAgc3dpdGNoIChwcmVzZXQpIHtcbiAgICAgIGNhc2UgJ3RvZGF5JzpcbiAgICAgICAgc3RhcnQgPSBlbmQgPSBuZXcgRGF0ZSh0b2RheS5nZXRGdWxsWWVhcigpLCB0b2RheS5nZXRNb250aCgpLCB0b2RheS5nZXREYXRlKCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3llc3RlcmRheSc6XG4gICAgICAgIGNvbnN0IHkgPSBuZXcgRGF0ZSh0b2RheSk7XG4gICAgICAgIHkuc2V0RGF0ZSh5LmdldERhdGUoKSAtIDEpO1xuICAgICAgICBzdGFydCA9IGVuZCA9IG5ldyBEYXRlKHkuZ2V0RnVsbFllYXIoKSwgeS5nZXRNb250aCgpLCB5LmdldERhdGUoKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbGFzdFdlZWsnOiB7XG4gICAgICAgIGNvbnN0IGx3RW5kID0gbmV3IERhdGUodG9kYXkpO1xuICAgICAgICBsd0VuZC5zZXREYXRlKGx3RW5kLmdldERhdGUoKSAtIDEpO1xuICAgICAgICBjb25zdCBsd1N0YXJ0ID0gbmV3IERhdGUobHdFbmQpO1xuICAgICAgICBsd1N0YXJ0LnNldERhdGUobHdFbmQuZ2V0RGF0ZSgpIC0gNik7XG4gICAgICAgIHN0YXJ0ID0gbmV3IERhdGUobHdTdGFydC5nZXRGdWxsWWVhcigpLCBsd1N0YXJ0LmdldE1vbnRoKCksIGx3U3RhcnQuZ2V0RGF0ZSgpKTtcbiAgICAgICAgZW5kID0gbmV3IERhdGUobHdFbmQuZ2V0RnVsbFllYXIoKSwgbHdFbmQuZ2V0TW9udGgoKSwgbHdFbmQuZ2V0RGF0ZSgpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdsYXN0TW9udGgnOiB7XG4gICAgICAgIGNvbnN0IGZpcnN0RGF5T2ZDdXJyZW50TW9udGggPSBuZXcgRGF0ZSh0b2RheS5nZXRGdWxsWWVhcigpLCB0b2RheS5nZXRNb250aCgpLCAxKTtcbiAgICAgICAgY29uc3QgbGFzdERheU9mUHJldk1vbnRoID0gbmV3IERhdGUoZmlyc3REYXlPZkN1cnJlbnRNb250aCk7XG4gICAgICAgIGxhc3REYXlPZlByZXZNb250aC5zZXREYXRlKDApO1xuICAgICAgICBjb25zdCBmaXJzdERheU9mUHJldk1vbnRoID0gbmV3IERhdGUobGFzdERheU9mUHJldk1vbnRoLmdldEZ1bGxZZWFyKCksIGxhc3REYXlPZlByZXZNb250aC5nZXRNb250aCgpLCAxKTtcbiAgICAgICAgc3RhcnQgPSBuZXcgRGF0ZShmaXJzdERheU9mUHJldk1vbnRoLmdldEZ1bGxZZWFyKCksIGZpcnN0RGF5T2ZQcmV2TW9udGguZ2V0TW9udGgoKSwgMSk7XG4gICAgICAgIGVuZCA9IG5ldyBEYXRlKGxhc3REYXlPZlByZXZNb250aC5nZXRGdWxsWWVhcigpLCBsYXN0RGF5T2ZQcmV2TW9udGguZ2V0TW9udGgoKSwgbGFzdERheU9mUHJldk1vbnRoLmdldERhdGUoKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnbGFzdFF1YXJ0ZXInOiB7XG4gICAgICAgIGNvbnN0IG1vbnRoID0gdG9kYXkuZ2V0TW9udGgoKTtcbiAgICAgICAgY29uc3QgcXVhcnRlciA9IE1hdGguZmxvb3IobW9udGggLyAzKTtcbiAgICAgICAgY29uc3QgcHJldlF1YXJ0ZXJFbmRNb250aCA9IHF1YXJ0ZXIgKiAzIC0gMTtcbiAgICAgICAgY29uc3QgcHJldlF1YXJ0ZXJFbmQgPSBuZXcgRGF0ZSh0b2RheS5nZXRGdWxsWWVhcigpLCBwcmV2UXVhcnRlckVuZE1vbnRoICsgMSwgMCk7XG4gICAgICAgIGNvbnN0IHByZXZRdWFydGVyU3RhcnRNb250aCA9IHByZXZRdWFydGVyRW5kTW9udGggLSAyO1xuICAgICAgICBjb25zdCBwcmV2UXVhcnRlclN0YXJ0ID0gbmV3IERhdGUodG9kYXkuZ2V0RnVsbFllYXIoKSwgcHJldlF1YXJ0ZXJTdGFydE1vbnRoLCAxKTtcbiAgICAgICAgc3RhcnQgPSBwcmV2UXVhcnRlclN0YXJ0O1xuICAgICAgICBlbmQgPSBwcmV2UXVhcnRlckVuZDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKHN0YXJ0ICYmIGVuZCkge1xuICAgICAgdGhpcy5zZWxlY3RlZERhdGUgPSBbc3RhcnQsIGVuZF07XG4gICAgICB0aGlzLmRhdGVSYW5nZUNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWREYXRlKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQcmVzZXQgPSBwcmVzZXQ7XG4gICAgICB0aGlzLmN1c3RvbVJhbmdlTW9kZSA9IGZhbHNlO1xuICAgIH1cbiAgICB0cnkgeyB0aGlzLm92ZXJsYXlQYW5lbD8uaGlkZSgpOyB9IGNhdGNoIChlKSB7fVxuICB9XG5cbiAgb25EYXRlUmFuZ2VDaGFuZ2UoZGF0ZVJhbmdlOiBEYXRlW10gfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5kYXRlUmFuZ2VDaGFuZ2UuZW1pdChkYXRlUmFuZ2UpO1xuICAgIGlmIChkYXRlUmFuZ2UgJiYgQXJyYXkuaXNBcnJheShkYXRlUmFuZ2UpKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkUHJlc2V0ID0gdGhpcy5kZXRlY3RQcmVzZXQoZGF0ZVJhbmdlWzBdLCBkYXRlUmFuZ2VbMV0pO1xuICAgICAgdGhpcy5jdXN0b21SYW5nZU1vZGUgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKCFkYXRlUmFuZ2UpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQcmVzZXQgPSBudWxsO1xuICAgICAgdGhpcy5jdXN0b21SYW5nZU1vZGUgPSBmYWxzZTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXY+XG4gICAgPGRpdiBjbGFzcz1cImlucHV0LXdyYXBwZXJcIj5cbiAgICAgIDxpbnB1dFxuICAgICAgICBwSW5wdXRUZXh0XG4gICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgW25nQ2xhc3NdPVwiaW5wdXRTdHlsZUNsYXNzXCJcbiAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgICAgW3ZhbHVlXT1cImdldERhdGVSYW5nZUxhYmVsKClcIlxuICByZWFkb25seVxuICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAoY2xpY2spPVwib3AudG9nZ2xlKCRldmVudClcIlxuICAgICAgICAoa2V5ZG93bik9XCJvbklucHV0S2V5RG93bigkZXZlbnQpXCJcbiAgLz5cbiAgPGkgKm5nSWY9XCJoYXNTZWxlY3Rpb25cIiBjbGFzcz1cInBpIHBpLXRpbWVzIGlucHV0LWNsZWFyLWljb25cIiB0aXRsZT1cIkNsZWFyXCIgdGFiaW5kZXg9XCIwXCIgKGNsaWNrKT1cImNsZWFyQW5kU3RvcCgkZXZlbnQpXCIgKGtleWRvd24uZW50ZXIpPVwiY2xlYXJBbmRTdG9wKCRldmVudClcIiAoa2V5ZG93bi5zcGFjZSk9XCJjbGVhckFuZFN0b3AoJGV2ZW50KVwiPjwvaT5cbiAgPGkgY2xhc3M9XCJwaSBwaS1jYWxlbmRhciBpbnB1dC1pY29uXCIgdGl0bGU9XCJPcGVuIGNhbGVuZGFyXCIgKGNsaWNrKT1cIm9wLnRvZ2dsZSgkZXZlbnQpXCI+PC9pPlxuICAgIDwvZGl2PlxuICAgIDxwLW92ZXJsYXlQYW5lbCAjb3AgW2Rpc21pc3NhYmxlXT1cInRydWVcIiBhcHBlbmRUbz1cImJvZHlcIiBzdHlsZUNsYXNzPVwiYXRvbWl4LWRhdGUtcmFuZ2Utb3ZlcmxheVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm92ZXJsYXktaW5uZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm92ZXJsYXktbGVmdFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJwcmVzZXQtbGlzdFwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHBSaXBwbGUgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0blwiIChjbGljayk9XCJhcHBseVByZXNldCgndG9kYXknKVwiIFtuZ0NsYXNzXT1cInsgJ2FjdGl2ZSc6IHNlbGVjdGVkUHJlc2V0ID09PSAndG9kYXknIH1cIiBsYWJlbD1cIlRvZGF5XCI+PC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gcFJpcHBsZSB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuXCIgKGNsaWNrKT1cImFwcGx5UHJlc2V0KCd5ZXN0ZXJkYXknKVwiIFtuZ0NsYXNzXT1cInsgJ2FjdGl2ZSc6IHNlbGVjdGVkUHJlc2V0ID09PSAneWVzdGVyZGF5JyB9XCIgbGFiZWw9XCJZZXN0ZXJkYXlcIj48L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBwUmlwcGxlIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG5cIiAoY2xpY2spPVwiYXBwbHlQcmVzZXQoJ2xhc3RXZWVrJylcIiBbbmdDbGFzc109XCJ7ICdhY3RpdmUnOiBzZWxlY3RlZFByZXNldCA9PT0gJ2xhc3RXZWVrJyB9XCIgbGFiZWw9XCJMYXN0IHdlZWtcIj48L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBwUmlwcGxlIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG5cIiAoY2xpY2spPVwiYXBwbHlQcmVzZXQoJ2xhc3RNb250aCcpXCIgW25nQ2xhc3NdPVwieyAnYWN0aXZlJzogc2VsZWN0ZWRQcmVzZXQgPT09ICdsYXN0TW9udGgnIH1cIiBsYWJlbD1cIkxhc3QgbW9udGhcIj48L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBwUmlwcGxlIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG5cIiAoY2xpY2spPVwiYXBwbHlQcmVzZXQoJ2xhc3RRdWFydGVyJylcIiBbbmdDbGFzc109XCJ7ICdhY3RpdmUnOiBzZWxlY3RlZFByZXNldCA9PT0gJ2xhc3RRdWFydGVyJyB9XCIgbGFiZWw9XCJMYXN0IHF1YXJ0ZXJcIj48L2J1dHRvbj5cbiAgICAgICAgICAgIDwhLS0gPGJ1dHRvbiBwQnV0dG9uIHBSaXBwbGUgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0biBwLWJ1dHRvbi1vdXRsaW5lZFwiIChjbGljayk9XCJ0b2dnbGVDdXN0b21SYW5nZSgpXCIgW25nQ2xhc3NdPVwieyAnY3VzdG9tLWFjdGl2ZSc6IGN1c3RvbVJhbmdlTW9kZSB9XCIgbGFiZWw9XCJDdXN0b20gcmFuZ2VcIj48L2J1dHRvbj4gLS0+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGEgY2xhc3M9XCJyZXNldC1saW5rXCIgKGNsaWNrKT1cInJlc2V0QW5kQ2xvc2UoKVwiPlJlc2V0PC9hPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm92ZXJsYXktcmlnaHRcIj5cbiAgICAgICAgICA8cC1jYWxlbmRhciBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRGF0ZVwiIFtzZWxlY3Rpb25Nb2RlXT1cIidyYW5nZSdcIiBbaW5saW5lXT1cInRydWVcIiBbZGF0ZUZvcm1hdF09XCInbW0vZGQveXl5eSdcIiBbc2hvd090aGVyTW9udGhzXT1cInRydWVcIiBbbG9jYWxlXT1cImVuTG9jYWxlXCIgW3Nob3dJY29uXT1cImZhbHNlXCIgW3N0eWxlQ2xhc3NdPVwiJ2F0b21peC1vdmVybGF5LWNhbGVuZGFyJ1wiIChuZ01vZGVsQ2hhbmdlKT1cIm9uRGF0ZVJhbmdlQ2hhbmdlKCRldmVudClcIiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiBbbWF4RGF0ZV09XCJtYXhEYXRlXCIgW21pbkRhdGVdPVwibWluRGF0ZVwiPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgICA8IS0tIDxkaXYgY2xhc3M9XCJvdmVybGF5LWFjdGlvbnNcIiAqbmdJZj1cIiFpbmxpbmVcIj5cbiAgICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBwUmlwcGxlIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInAtYnV0dG9uLWhlbHAgcC1idXR0b24tc21cIiAoY2xpY2spPVwiYXBwbHlDdXN0b21SYW5nZSgpXCI+QXBwbHk8L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBwUmlwcGxlIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInAtYnV0dG9uLXRleHQgcC1idXR0b24tc21cIiAoY2xpY2spPVwicmVzZXRBbmRDbG9zZSgpXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+IC0tPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvcC1vdmVybGF5UGFuZWw+XG48L2Rpdj5cbiJdfQ==
626
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRvbWl4LWRhdGVyYW5nZS1jYWxlbmRhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9wcmltZWtpdC9zcmMvbGliL2xpYi9hdG9taXgtZGF0ZXJhbmdlLWNhbGVuZGFyL2F0b21peC1kYXRlcmFuZ2UtY2FsZW5kYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcHJpbWVraXQvc3JjL2xpYi9saWIvYXRvbWl4LWRhdGVyYW5nZS1jYWxlbmRhci9hdG9taXgtZGF0ZXJhbmdlLWNhbGVuZGFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUEwRCxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7QUFTMUksTUFBTSxPQUFPLGdDQUFnQztJQTBFdkI7SUFBNEI7SUF6RXZDLFdBQVcsR0FBVyxFQUFFLENBQUM7SUFDekIsVUFBVSxHQUFXLEVBQUUsQ0FBQztJQUN4QixhQUFhLEdBQVksT0FBTyxDQUFDO0lBQ2pDLGVBQWUsR0FBVyxFQUFFLENBQUM7SUFDN0IsTUFBTSxHQUFZLEtBQUssQ0FBQztJQUN4QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLFlBQVksR0FBa0IsSUFBSSxDQUFDO0lBQ25DLE9BQU8sQ0FBUTtJQUNmLE9BQU8sQ0FBUTtJQUNmLGFBQWEsR0FBOEYsSUFBSSxDQUFDO0lBRXpILGVBQWUsR0FBWSxLQUFLLENBQUM7SUFDakMsY0FBYyxHQUFrQixJQUFJLENBQUMsQ0FBQyx1R0FBdUc7SUFDbEgsWUFBWSxDQUFnQjtJQUM3QyxlQUFlLEdBQUcsSUFBSSxZQUFZLEVBQWlCLENBQUM7SUFFOUQsdUdBQXVHO0lBQ3ZHLFNBQVMsR0FBa0IsSUFBSSxDQUFDO0lBRWhDLFFBQVEsR0FBRztRQUNULGNBQWMsRUFBRSxDQUFDO1FBQ2pCLFFBQVEsRUFBRTtZQUNSLFFBQVE7WUFDUixRQUFRO1lBQ1IsU0FBUztZQUNULFdBQVc7WUFDWCxVQUFVO1lBQ1YsUUFBUTtZQUNSLFVBQVU7U0FDWDtRQUNELGFBQWEsRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQztRQUNoRSxXQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUM7UUFDdkQsVUFBVSxFQUFFO1lBQ1YsU0FBUztZQUNULFVBQVU7WUFDVixPQUFPO1lBQ1AsT0FBTztZQUNQLEtBQUs7WUFDTCxNQUFNO1lBQ04sTUFBTTtZQUNOLFFBQVE7WUFDUixXQUFXO1lBQ1gsU0FBUztZQUNULFVBQVU7WUFDVixVQUFVO1NBQ1g7UUFDRCxlQUFlLEVBQUU7WUFDZixLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7WUFDTCxLQUFLO1lBQ0wsS0FBSztZQUNMLEtBQUs7U0FDTjtRQUNELEtBQUssRUFBRSxPQUFPO1FBQ2QsS0FBSyxFQUFFLE9BQU87S0FDZixDQUFDO0lBRUYsd0NBQXdDO0lBQ2hDLG1CQUFtQixHQUFrQixJQUFJLENBQUM7SUFDMUMscUJBQXFCLEdBQWtCLElBQUksQ0FBQztJQUM1QyxrQkFBa0IsR0FBdUIsRUFBRSxDQUFDO0lBQzVDLGlCQUFpQixHQUFjLEVBQUUsQ0FBQztJQUNsQyxnQkFBZ0IsR0FBdUIsRUFBRSxDQUFDO0lBQzFDLHVCQUF1QixHQUFjLEVBQUUsQ0FBQztJQUN4QyxZQUFZLEdBQWtCLElBQUksQ0FBQyxDQUFDLDJCQUEyQjtJQUV2RSxZQUFvQixRQUFrQixFQUFVLFFBQW1CO1FBQS9DLGFBQVEsR0FBUixRQUFRLENBQVU7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFXO0lBQUcsQ0FBQztJQUV2RSxRQUFRO1FBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFDRCw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDbkUsd0RBQXdEO1FBQ3hELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN2Qiw2Q0FBNkM7UUFDN0MsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7UUFDakMsQ0FBQztJQUNILENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztZQUM1QixNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUMsWUFBNkIsQ0FBQztZQUNsRSxJQUFJLEdBQUcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDdEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pELElBQUksQ0FBQyxjQUFjLEdBQUcsTUFBTSxJQUFJLFFBQVEsQ0FBQztnQkFDekMsa0RBQWtEO2dCQUNsRCxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUM1QixDQUFDO2lCQUFNLElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztnQkFDM0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7WUFDeEIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsY0FBYyxDQUFDLEtBQW9CO1FBQ2pDLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxPQUFPLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUMvQyxJQUFJLENBQUM7Z0JBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsS0FBWSxDQUFDLENBQUM7WUFBQyxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUM7WUFDN0QsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3pCLENBQUM7SUFDSCxDQUFDO0lBRUQsYUFBYTtRQUNYLG1FQUFtRTtRQUNuRSxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUMxRCxJQUFJLENBQUMsbUJBQW1CLEdBQUksSUFBSSxDQUFDLFlBQXVCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEksQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQ2xDLENBQUM7UUFDRCxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUNqRCw2RUFBNkU7UUFDN0UsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDbkUscUVBQXFFO1FBQ3JFLElBQUksSUFBSSxDQUFDLFlBQVksSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM1RixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdFLElBQUksQ0FBQyxjQUFjLEdBQUcsTUFBTSxJQUFJLFFBQVEsQ0FBQztRQUMzQyxDQUFDO2FBQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUM3QixDQUFDO1FBQ0gsbURBQW1EO1FBQ25ELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUNyQiw2REFBNkQ7UUFDN0QsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7SUFDakMsQ0FBQztJQUVELGFBQWE7UUFDWCwyRkFBMkY7UUFDM0YsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM3QixNQUFNLGNBQWMsR0FBRyxPQUFPLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0csSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztZQUM3QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztZQUNqRCx1Q0FBdUM7WUFDdkMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDckUsQ0FBQztRQUNELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7UUFDaEMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUMvQix1REFBdUQ7UUFDdkQsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3JCLGlCQUFpQjtRQUNqQixJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsYUFBYSxDQUFDLFNBQXdCO1FBQ3BDLDBGQUEwRjtRQUMxRixvRkFBb0Y7UUFDcEYsNkVBQTZFO1FBQzdFLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNuRCxJQUFJLFNBQVMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNwRyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BFLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1lBQzdCLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDO1lBQ25DLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM3Qyw0Q0FBNEM7WUFDNUMsSUFBSSxDQUFDO2dCQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFBQyxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUM7UUFDakQsQ0FBQzthQUFNLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN0QixvQkFBb0I7WUFDcEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDM0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7WUFDN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7WUFDekIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEMsQ0FBQzthQUFNLENBQUM7WUFDTiwyRkFBMkY7WUFDM0YsOERBQThEO1lBQzlELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1lBQzNCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQy9CLENBQUM7UUFDSCwyRUFBMkU7UUFDM0UsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCx3REFBd0Q7SUFDeEQscUJBQXFCLENBQUMsS0FBVztRQUMvQiwwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLHFGQUFxRjtRQUNyRixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDO2dCQUNILElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO2dCQUM5QixJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztZQUNqQyxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakIsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ1QsQ0FBQztJQUVELElBQUksWUFBWTtRQUNkLE9BQU8sT0FBTyxDQUNaLElBQUksQ0FBQyxZQUFZO1lBQ2YsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDO1lBQy9CLElBQUksQ0FBQyxZQUF1QixDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQzFDLENBQUMsQ0FBRSxJQUFJLENBQUMsWUFBdUIsQ0FBQyxDQUFDLENBQUM7WUFDbEMsQ0FBQyxDQUFFLElBQUksQ0FBQyxZQUF1QixDQUFDLENBQUMsQ0FBQyxDQUNyQyxDQUFDO0lBQ0osQ0FBQztJQUVPLGFBQWEsQ0FBQyxDQUFPO1FBQzNCLE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBRU8sVUFBVSxDQUFDLENBQU8sRUFBRSxDQUFPO1FBQ2pDLE9BQU8sQ0FDTCxDQUFDLENBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQyxDQUFDLFdBQVcsRUFBRTtZQUNuQyxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRTtZQUM3QixDQUFDLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUM1QixDQUFDO0lBQ0osQ0FBQztJQUVPLFlBQVksQ0FBQyxRQUFjLEVBQUUsTUFBWTtRQUMvQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzNDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7UUFDN0MsUUFBUTtRQUNSLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO1lBQUUsT0FBTyxPQUFPLENBQUM7UUFDakYsWUFBWTtRQUNaLE1BQU0sQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzNCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQUUsT0FBTyxXQUFXLENBQUM7UUFDN0UsMEVBQTBFO1FBQzFFLE1BQU0sS0FBSyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLE1BQU0sT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO1lBQUUsT0FBTyxXQUFXLENBQUM7UUFDdkYsNkVBQTZFO1FBQzdFLE1BQU0sTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9CLE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLFFBQVEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO1lBQUUsT0FBTyxZQUFZLENBQUM7UUFDMUYscUZBQXFGO1FBQ3JGLE1BQU0sTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9CLE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO1lBQUUsT0FBTyxhQUFhLENBQUM7UUFDM0YscUZBQXFGO1FBQ3JGLE1BQU0sTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9CLE1BQU0sUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO1lBQUUsT0FBTyxhQUFhLENBQUM7UUFDM0YsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsY0FBYztRQUNaLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN4QixDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUM7Z0JBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUFDLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUEsQ0FBQztRQUNoRCxDQUFDO0lBQ0gsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFZO1FBQ3ZCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVELGlCQUFpQjtRQUNmLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDO1FBQzdDLElBQUksSUFBSSxDQUFDLGVBQWU7WUFBRSxJQUFJLENBQUMsY0FBYyxHQUFHLFFBQVEsQ0FBQztJQUMzRCxDQUFDO0lBRUQsZ0JBQWdCO1FBQ2QsOERBQThEO1FBQzlELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ2hFLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QyxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUM7Z0JBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUFDLENBQUM7WUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUEsQ0FBQztRQUNoRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDN0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUM7SUFDakMsQ0FBQztJQUVDLGlCQUFpQjtRQUNqQiwyRUFBMkU7UUFDM0UsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQ3RELElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQztZQUFFLE9BQU8sRUFBRSxDQUFDO1FBRXZELE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEdBQUcsU0FBNEIsQ0FBQztRQUMxQyxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUM7UUFFL0Isd0VBQXdFO1FBQ3hFLElBQUksS0FBSyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDbEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQzlELE9BQU8sR0FBRyxRQUFRLElBQUksS0FBSyxHQUFHLENBQUM7UUFDakMsQ0FBQztRQUVELHFEQUFxRDtRQUNyRCxJQUFJLEtBQUssSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNqQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDOUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFDO1lBQzFELE9BQU8sR0FBRyxRQUFRLElBQUksS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzFDLENBQUM7UUFFRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCxXQUFXLENBQUMsTUFBZ0Y7UUFDMUYsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN6QixJQUFJLEtBQUssR0FBZ0IsSUFBSSxDQUFDO1FBQzlCLElBQUksR0FBRyxHQUFnQixJQUFJLENBQUM7UUFDNUIsUUFBUSxNQUFNLEVBQUUsQ0FBQztZQUNmLEtBQUssT0FBTztnQkFDVixLQUFLLEdBQUcsR0FBRyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQy9FLE1BQU07WUFDUixLQUFLLFdBQVc7Z0JBQ2QsTUFBTSxDQUFDLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzFCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUMzQixLQUFLLEdBQUcsR0FBRyxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQ25FLE1BQU07WUFDUixLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pCLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUN2RSxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3RCLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNqQyxNQUFNO1lBQ1IsQ0FBQztZQUNELEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQztnQkFDbEIsR0FBRyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQ3ZFLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDdEIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7Z0JBQ2xDLE1BQU07WUFDUixDQUFDO1lBQ0QsS0FBSyxhQUFhLENBQUMsQ0FBQyxDQUFDO2dCQUNuQixHQUFHLEdBQUcsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDdkUsS0FBSyxHQUFHLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN0QixLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDbkMsTUFBTTtZQUNSLENBQUM7WUFDRCxLQUFLLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxFQUFFLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUN2RSxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3RCLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxNQUFNO1lBQ1IsQ0FBQztZQUNEO2dCQUNFLE1BQU07UUFDVixDQUFDO1FBQ0QsSUFBSSxLQUFLLElBQUksR0FBRyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUNqQyxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzlCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM3QyxJQUFJLENBQUMsY0FBYyxHQUFHLE1BQU0sQ0FBQztZQUM3QixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUMvQixDQUFDO1FBQ0QsSUFBSSxDQUFDO1lBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUFDLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUEsQ0FBQztRQUNqRCw2REFBNkQ7UUFDN0QsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxTQUF3QjtRQUN4QyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyQyxJQUFJLFNBQVMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDMUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwRSxJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUMvQixDQUFDO2FBQU0sSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1lBQzNCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQy9CLENBQUM7UUFDSCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsNkZBQTZGO0lBQ3JGLDJCQUEyQjtRQUNqQyxJQUFJLENBQUM7WUFDSCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBRXJELGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQWMsRUFBRSxFQUFFO2dCQUMxQywyQ0FBMkM7Z0JBQzNDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDckQsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO29CQUN4QixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUM7b0JBQy9DLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztvQkFDN0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxDQUFDO2dCQUNuRCxDQUFDLENBQUMsQ0FBQztnQkFFVCxzREFBc0Q7Z0JBQ3RELHVFQUF1RTtnQkFDdkUsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxLQUFLLENBQUM7Z0JBQzFELE1BQU0sZUFBZSxHQUFJLFNBQXFCLENBQUMsYUFBYSxDQUFDLDhEQUE4RCxDQUFDLENBQUM7Z0JBQzdILE1BQU0sY0FBYyxHQUFJLFNBQXFCLENBQUMsYUFBYSxDQUFDLDZEQUE2RCxDQUFDLENBQUM7Z0JBQzNILE1BQU0sY0FBYyxHQUFHLGVBQWUsSUFBSSxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDM0osTUFBTSxhQUFhLEdBQUcsY0FBYyxJQUFJLGNBQWMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7Z0JBQ3JILE1BQU0sS0FBSyxHQUEyRCxFQUFFLENBQUM7Z0JBQ3pFLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO2dCQUM5RCxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7b0JBQ3JCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUF1QixDQUFDO29CQUNwRCxpRkFBaUY7b0JBQ2pGLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7b0JBQzlDLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRTt3QkFBRSxRQUFRLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDN0QsSUFBSSxRQUFRLEVBQUUsQ0FBQzt3QkFDYixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO3dCQUM5RCxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzs0QkFDdkQsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDOzRCQUN4QixNQUFNLEVBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQzs0QkFDakMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQzs0QkFDN0IsT0FBTzt3QkFDVCxDQUFDO29CQUNILENBQUM7b0JBQ0QsK0ZBQStGO29CQUMvRixNQUFNLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ2hELE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7b0JBQ2xDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7d0JBQ3RCLDhDQUE4Qzt3QkFDOUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsRUFBRSxDQUFDOzRCQUNwRCxNQUFNLEVBQUUsR0FBRyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsY0FBYyxFQUFFLEdBQUcsQ0FBQyxDQUFDOzRCQUN4RCxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDOzRCQUM3QixPQUFPO3dCQUNULENBQUM7b0JBQ0gsQ0FBQztvQkFDRCx3REFBd0Q7Z0JBQzFELENBQUMsQ0FBQyxDQUFDO2dCQUVULElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO29CQUFFLE9BQU87Z0JBRXpCLDJDQUEyQztnQkFDM0MsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO2dCQUN0RCxNQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBRXJELHVEQUF1RDtnQkFDdkQsTUFBTSxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO2dCQUMxTCxNQUFNLFNBQVMsR0FBRyxLQUFLLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUM7Z0JBQzNGLE1BQU0sT0FBTyxHQUFHLEtBQUssSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztnQkFFakYsMkVBQTJFO2dCQUMzRSxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2xDLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDaEMsS0FBSyxNQUFNLEVBQUUsSUFBSSxLQUFLLEVBQUUsQ0FBQztvQkFDdkIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDMUIsSUFBSSxLQUFLLEtBQUssS0FBSyxJQUFJLENBQUMsS0FBSyxLQUFLLEVBQUUsQ0FBQzt3QkFDbkMsMENBQTBDO3dCQUMxQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxDQUFDO3dCQUMvQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO29CQUMvQyxDQUFDO3lCQUFNLElBQUksQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO3dCQUN2QixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxDQUFDO29CQUNqRCxDQUFDO3lCQUFNLElBQUksQ0FBQyxLQUFLLEtBQUssRUFBRSxDQUFDO3dCQUN2QixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO29CQUMvQyxDQUFDO3lCQUFNLElBQUksQ0FBQyxHQUFHLEtBQUssSUFBSSxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUM7d0JBQ2xDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUM7b0JBQ25ELENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxxRUFBcUU7UUFDdkUsQ0FBQztJQUNILENBQUM7SUFFTyxPQUFPLENBQUMsQ0FBTztRQUNyQixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDMUIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2pELE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxJQUFXO1FBQ3BDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDNUIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzdCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRO1FBQ3ZDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN6QixNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxpQkFBaUI7UUFDdkQsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLGFBQWE7UUFDbkcsTUFBTSxTQUFTLEdBQUcsQ0FBQyxlQUFlLFdBQVcsSUFBSSxFQUFFLGVBQWUsU0FBUyxJQUFJLENBQUMsQ0FBQztRQUNqRixLQUFLLE1BQU0sR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQzVCLE1BQU0sY0FBYyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsNEJBQTRCLEdBQUcsRUFBRSxDQUF1QixDQUFDO1lBQ3ZHLElBQUksY0FBYztnQkFBRSxPQUFPLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUF1QixJQUFJLGNBQWMsQ0FBQztRQUNsRyxDQUFDO1FBQ0QsS0FBSyxNQUFNLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUM1QixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBdUIsQ0FBQztZQUNoRSxJQUFJLEtBQUs7Z0JBQUUsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBdUIsSUFBSSxLQUFLLENBQUM7UUFDdkUsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFFTyx1QkFBdUI7UUFDN0IsaUNBQWlDO1FBQ2pDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQztZQUNQLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQztnQkFDSCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBbUIsQ0FBQztnQkFDdkMsSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLEVBQUUsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO29CQUNoRCxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7b0JBQ2pFLElBQUksRUFBRTt3QkFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQWEsQ0FBQyxDQUFDO2dCQUNyQyxDQUFDO1lBQ0gsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQSxDQUFDO1lBRWQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO2dCQUNwQixNQUFNLEdBQUcsR0FBRyxJQUFJLGdCQUFnQixDQUFDLEdBQUcsRUFBRTtvQkFDcEMsZ0RBQWdEO29CQUNoRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3pCLENBQUMsQ0FBQyxDQUFDO2dCQUNILHVGQUF1RjtnQkFDdkYsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2xHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2xDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ2hDLDBHQUEwRztnQkFDMUcsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQztnQkFDaEMsSUFBSSxNQUFNLElBQUksSUFBSSxDQUFDLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO29CQUNsRSxNQUFNLFNBQVMsR0FBRyxJQUFJLGdCQUFnQixDQUFDLEdBQUcsRUFBRTt3QkFDMUMsNERBQTREO3dCQUM1RCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7d0JBQ3ZCLG1EQUFtRDt3QkFDbkQsVUFBVSxDQUFDLEdBQUcsRUFBRTs0QkFDZCxJQUFJLENBQUM7Z0NBQ0gsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0NBQzlCLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDOzRCQUNqQyxDQUFDOzRCQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO3dCQUNqQixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxrRUFBa0U7b0JBQzdFLENBQUMsQ0FBQyxDQUFDO29CQUNILFNBQVMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztvQkFDL0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDdEMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDNUMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxTQUFTO1FBQ1gsQ0FBQztJQUNILENBQUM7SUFFTyxzQkFBc0I7UUFDNUIsSUFBSSxDQUFDO1lBQ0gsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDM0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDM0QsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsaUJBQWlCLEdBQUcsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFDM0IsSUFBSSxDQUFDLHVCQUF1QixHQUFHLEVBQUUsQ0FBQztJQUNwQyxDQUFDO0lBRU8sZUFBZTtRQUNyQixJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSTtZQUFFLE9BQU8sQ0FBQyxvQkFBb0I7UUFDM0QsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMscUJBQXFCLENBQUMsR0FBRyxFQUFFO1lBQ3BELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1lBQ3pCLElBQUksQ0FBQywyQkFBMkIsRUFBRSxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLHNCQUFzQjtRQUM1QixJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxFQUFFLENBQUM7WUFDOUIsTUFBTSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO0lBQ0gsQ0FBQztJQUVPLG9CQUFvQjtRQUMxQixNQUFNLE1BQU0sR0FBYyxFQUFFLENBQUM7UUFDN0IsTUFBTSxVQUFVLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQ3BGLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztRQUMzRSxJQUFJLFVBQVU7WUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3hDLElBQUksU0FBUztZQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQW1CLENBQUM7WUFDdkMsSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLEVBQUUsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUNoRCxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ2pFLElBQUksRUFBRTtvQkFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQWEsQ0FBQyxDQUFDO1lBQ3JDLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDZixvQkFBb0I7UUFDcEIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDckMsQ0FBQzt3R0Fsa0JVLGdDQUFnQzs0RkFBaEMsZ0NBQWdDLHlnQkNUN0MsbWdMQXdFQTs7NEZEL0RhLGdDQUFnQztrQkFMNUMsU0FBUzsrQkFDRSwyQkFBMkI7cUdBSzVCLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBSXFCLFlBQVk7c0JBQXRDLFNBQVM7dUJBQUMsY0FBYztnQkFDZixlQUFlO3NCQUF4QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQsIFZpZXdDaGlsZCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSwgUmVuZGVyZXIyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPdmVybGF5UGFuZWwgfSBmcm9tICdwcmltZW5nL292ZXJsYXlwYW5lbCc7XG5pbXBvcnQgeyBEYXRlUGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2F0b21peC1kYXRlcmFuZ2UtY2FsZW5kYXInLFxuICB0ZW1wbGF0ZVVybDogJy4vYXRvbWl4LWRhdGVyYW5nZS1jYWxlbmRhci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2F0b21peC1kYXRlcmFuZ2UtY2FsZW5kYXIuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgQXRvbWl4RGF0ZXJhbmdlQ2FsZW5kYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBzdHlsZUNsYXNzOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgc2VsZWN0aW9uTW9kZTogJ3JhbmdlJyA9ICdyYW5nZSc7XG4gIEBJbnB1dCgpIGlucHV0U3R5bGVDbGFzczogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGlubGluZTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBzZWxlY3RlZERhdGU6IERhdGVbXSB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSBtYXhEYXRlITogRGF0ZTtcbiAgQElucHV0KCkgbWluRGF0ZSE6IERhdGU7XG4gIEBJbnB1dCgpIGRlZmF1bHRQcmVzZXQ6ICd0b2RheScgfCAneWVzdGVyZGF5JyB8ICdsYXN0N2RheXMnIHwgJ2xhc3QzMGRheXMnIHwgJ2xhc3QzbW9udGhzJyB8ICdsYXN0Nm1vbnRocycgfCBudWxsID0gbnVsbDtcblxuICBjdXN0b21SYW5nZU1vZGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc2VsZWN0ZWRQcmVzZXQ6IHN0cmluZyB8IG51bGwgPSBudWxsOyAvLyAndG9kYXknIHwgJ3llc3RlcmRheScgfCAnbGFzdDdkYXlzJyB8ICdsYXN0MzBkYXlzJyB8ICdsYXN0M21vbnRocycgfCAnbGFzdDZtb250aHMnIHwgJ2N1c3RvbScgfCBudWxsXG4gIEBWaWV3Q2hpbGQoJ292ZXJsYXlQYW5lbCcpIG92ZXJsYXlQYW5lbD86IE92ZXJsYXlQYW5lbDtcbiAgQE91dHB1dCgpIGRhdGVSYW5nZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZVtdIHwgbnVsbD4oKTtcblxuICAvLyBpbnRlcm5hbCBtb2RlbCBib3VuZCB0byBwLWNhbGVuZGFyIHRvIGF2b2lkIGNoYW5naW5nIGV4dGVybmFsIHNlbGVjdGlvbiBkdXJpbmcgZmlyc3QtY2xpY2sgc2VsZWN0aW9uXG4gIG1vZGVsRGF0ZTogRGF0ZVtdIHwgbnVsbCA9IG51bGw7XG5cbiAgZW5Mb2NhbGUgPSB7XG4gICAgZmlyc3REYXlPZldlZWs6IDAsXG4gICAgZGF5TmFtZXM6IFtcbiAgICAgICdTdW5kYXknLFxuICAgICAgJ01vbmRheScsXG4gICAgICAnVHVlc2RheScsXG4gICAgICAnV2VkbmVzZGF5JyxcbiAgICAgICdUaHVyc2RheScsXG4gICAgICAnRnJpZGF5JyxcbiAgICAgICdTYXR1cmRheScsXG4gICAgXSxcbiAgICBkYXlOYW1lc1Nob3J0OiBbJ1N1bicsICdNb24nLCAnVHVlJywgJ1dlZCcsICdUaHUnLCAnRnJpJywgJ1NhdCddLFxuICAgIGRheU5hbWVzTWluOiBbJ1N1JywgJ01vJywgJ1R1JywgJ1dlJywgJ1RoJywgJ0ZyJywgJ1NhJ10sXG4gICAgbW9udGhOYW1lczogW1xuICAgICAgJ0phbnVhcnknLFxuICAgICAgJ0ZlYnJ1YXJ5JyxcbiAgICAgICdNYXJjaCcsXG4gICAgICAnQXByaWwnLFxuICAgICAgJ01heScsXG4gICAgICAnSnVuZScsXG4gICAgICAnSnVseScsXG4gICAgICAnQXVndXN0JyxcbiAgICAgICdTZXB0ZW1iZXInLFxuICAgICAgJ09jdG9iZXInLFxuICAgICAgJ05vdmVtYmVyJyxcbiAgICAgICdEZWNlbWJlcicsXG4gICAgXSxcbiAgICBtb250aE5hbWVzU2hvcnQ6IFtcbiAgICAgICdKYW4nLFxuICAgICAgJ0ZlYicsXG4gICAgICAnTWFyJyxcbiAgICAgICdBcHInLFxuICAgICAgJ01heScsXG4gICAgICAnSnVuJyxcbiAgICAgICdKdWwnLFxuICAgICAgJ0F1ZycsXG4gICAgICAnU2VwJyxcbiAgICAgICdPY3QnLFxuICAgICAgJ05vdicsXG4gICAgICAnRGVjJyxcbiAgICBdLFxuICAgIHRvZGF5OiAnVG9kYXknLFxuICAgIGNsZWFyOiAnQ2xlYXInLFxuICB9O1xuXG4gIC8vIHRlbXBvcmFyeSBzdG9yYWdlIGZvciBvdmVybGF5IHNlc3Npb25cbiAgcHJpdmF0ZSBfb3ZlcmxheUluaXRpYWxEYXRlOiBEYXRlW10gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfb3ZlcmxheUluaXRpYWxQcmVzZXQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9jYWxlbmRhck9ic2VydmVyczogTXV0YXRpb25PYnNlcnZlcltdID0gW107XG4gIHByaXZhdGUgX29ic2VydmVkRWxlbWVudHM6IEVsZW1lbnRbXSA9IFtdO1xuICBwcml2YXRlIF9wYXJlbnRPYnNlcnZlcnM6IE11dGF0aW9uT2JzZXJ2ZXJbXSA9IFtdO1xuICBwcml2YXRlIF9vYnNlcnZlZFBhcmVudEVsZW1lbnRzOiBFbGVtZW50W10gPSBbXTtcbiAgcHJpdmF0ZSBfdXBkYXRlUmFmSWQ6IG51bWJlciB8IG51bGwgPSBudWxsOyAvLyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgaWRcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGVQaXBlOiBEYXRlUGlwZSwgcHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zZWxlY3RlZERhdGUgJiYgdGhpcy5kZWZhdWx0UHJlc2V0KSB7XG4gICAgICB0aGlzLmFwcGx5UHJlc2V0KHRoaXMuZGVmYXVsdFByZXNldCk7XG4gICAgfVxuICAgIC8vIGluaXRpYWxpemUgaW50ZXJuYWwgbW9kZWxcbiAgICB0aGlzLm1vZGVsRGF0ZSA9IHRoaXMuc2VsZWN0ZWREYXRlID8gWy4uLnRoaXMuc2VsZWN0ZWREYXRlXSA6IG51bGw7XG4gICAgLy8gaW5pdGlhbCBjbGFzcyB1cGRhdGUgaWYgdGhlcmUgaXMgYSBwcmUtc2VsZWN0ZWQgcmFuZ2VcbiAgICB0aGlzLl9zY2hlZHVsZVVwZGF0ZSgpO1xuICAgIC8vIHN0YXJ0IG9ic2VydmVycyBpZiBpbmxpbmUgY2FsZW5kYXIgaXMgdXNlZFxuICAgIGlmICh0aGlzLmlubGluZSkge1xuICAgICAgdGhpcy5fc3RhcnRDYWxlbmRhck9ic2VydmVycygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlc1snc2VsZWN0ZWREYXRlJ10pIHtcbiAgICAgIGNvbnN0IHNlbCA9IGNoYW5nZXNbJ3NlbGVjdGVkRGF0ZSddLmN1cnJlbnRWYWx1ZSBhcyBEYXRlW10gfCBudWxsO1xuICAgICAgaWYgKHNlbCAmJiBBcnJheS5pc0FycmF5KHNlbCkgJiYgc2VsLmxlbmd0aCA9PT0gMiAmJiBzZWxbMF0gJiYgc2VsWzFdKSB7XG4gICAgICAgIGNvbnN0IHByZXNldCA9IHRoaXMuZGV0ZWN0UHJlc2V0KHNlbFswXSwgc2VsWzFdKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFByZXNldCA9IHByZXNldCA/PyAnY3VzdG9tJztcbiAgICAgICAgLy8gc3luYyBpbnRlcm5hbCBtb2RlbCB3aGVuIGV4dGVybmFsIHZhbHVlIGNoYW5nZXNcbiAgICAgICAgdGhpcy5tb2RlbERhdGUgPSBbLi4uc2VsXTtcbiAgICAgIH0gZWxzZSBpZiAoc2VsID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFByZXNldCA9IG51bGw7XG4gICAgICAgIHRoaXMubW9kZWxEYXRlID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbklucHV0S2V5RG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdFbnRlcicgfHwgZXZlbnQua2V5ID09PSAnICcpIHtcbiAgICAgIHRyeSB7IHRoaXMub3ZlcmxheVBhbmVsPy50b2dnbGUoZXZlbnQgYXMgYW55KTsgfSBjYXRjaCAoZSkge31cbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgb25PdmVybGF5U2hvdygpOiB2b2lkIHtcbiAgICAvLyBzdG9yZSBhIGRlZXAgY29weSBvZiBjdXJyZW50IHNlbGVjdGlvbi9wcmVzZXQgd2hlbiBvdmVybGF5IG9wZW5zXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWREYXRlICYmIEFycmF5LmlzQXJyYXkodGhpcy5zZWxlY3RlZERhdGUpKSB7XG4gICAgICB0aGlzLl9vdmVybGF5SW5pdGlhbERhdGUgPSAodGhpcy5zZWxlY3RlZERhdGUgYXMgRGF0ZVtdKS5tYXAoZCA9PiAoZCA/IG5ldyBEYXRlKGQuZ2V0RnVsbFllYXIoKSwgZC5nZXRNb250aCgpLCBkLmdldERhdGUoKSkgOiBkKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX292ZXJsYXlJbml0aWFsRGF0ZSA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuX292ZXJsYXlJbml0aWFsUHJlc2V0ID0gdGhpcy5zZWxlY3RlZFByZXNldDtcbiAgICAvLyBlbnN1cmUgY2FsZW5kYXIgbW9kZWwgc2hvd3MgdGhlIGN1cnJlbnRseSBjb21taXR0ZWQgc2VsZWN0aW9uIHdoZW4gb3BlbmluZ1xuICAgIHRoaXMubW9kZWxEYXRlID0gdGhpcy5zZWxlY3RlZERhdGUgPyBbLi4udGhpcy5zZWxlY3RlZERhdGVdIDogbnVsbDtcbiAgICAvLyBlbnN1cmUgcHJlc2V0IGJ1dHRvbnMgcmVmbGVjdCBjdXJyZW50IHNlbGVjdGlvbiB3aGVuIG92ZXJsYXkgb3BlbnNcbiAgICBpZiAodGhpcy5zZWxlY3RlZERhdGUgJiYgQXJyYXkuaXNBcnJheSh0aGlzLnNlbGVjdGVkRGF0ZSkgJiYgdGhpcy5zZWxlY3RlZERhdGUubGVuZ3RoID09PSAyKSB7XG4gICAgICBjb25zdCBwcmVzZXQgPSB0aGlzLmRldGVjdFByZXNldCh0aGlzLnNlbGVjdGVkRGF0ZVswXSwgdGhpcy5zZWxlY3RlZERhdGVbMV0pO1xuICAgICAgdGhpcy5zZWxlY3RlZFByZXNldCA9IHByZXNldCA/PyAnY3VzdG9tJztcbiAgICB9IGVsc2UgaWYgKCF0aGlzLnNlbGVjdGVkRGF0ZSkge1xuICAgICAgdGhpcy5zZWxlY3RlZFByZXNldCA9IG51bGw7XG4gICAgfVxuICAvLyBhZGQgc3RhcnQvZW5kIGNsYXNzZXMgdG8gcmFuZ2UgY2VsbHMgZm9yIHN0eWxpbmdcbiAgdGhpcy5fc2NoZWR1bGVVcGRhdGUoKTtcbiAgICAvLyBvYnNlcnZlIERPTSBjaGFuZ2VzIChQcmltZU5HIG1heSByZS1yZW5kZXIgaW5zaWRlIG92ZXJsYXkpXG4gICAgdGhpcy5fc3RhcnRDYWxlbmRhck9ic2VydmVycygpO1xuICB9XG5cbiAgb25PdmVybGF5SGlkZSgpOiB2b2lkIHtcbiAgICAvLyBpZiBpbnRlcm5hbCBjYWxlbmRhciBtb2RlbCBoYXMgYW4gaW5jb21wbGV0ZSBzZWxlY3Rpb24gKHBhcnRpYWwgcmFuZ2UpIHJldmVydCB0byBpbml0aWFsXG4gICAgY29uc3QgbW9kZWwgPSB0aGlzLm1vZGVsRGF0ZTtcbiAgICBjb25zdCBpc1BhcnRpYWxNb2RlbCA9IEJvb2xlYW4obW9kZWwgJiYgQXJyYXkuaXNBcnJheShtb2RlbCkgJiYgbW9kZWwubGVuZ3RoID4gMCAmJiBtb2RlbFswXSAmJiAhbW9kZWxbMV0pO1xuICAgIGlmIChpc1BhcnRpYWxNb2RlbCkge1xuICAgICAgdGhpcy5zZWxlY3RlZERhdGUgPSB0aGlzLl9vdmVybGF5SW5pdGlhbERhdGU7XG4gICAgICB0aGlzLnNlbGVjdGVkUHJlc2V0ID0gdGhpcy5fb3ZlcmxheUluaXRpYWxQcmVzZXQ7XG4gICAgICAvLyByZXNldCBpbnRlcm5hbCBtb2RlbCB0byBzeW5jZWQgdmFsdWVcbiAgICAgIHRoaXMubW9kZWxEYXRlID0gdGhpcy5zZWxlY3RlZERhdGUgPyBbLi4udGhpcy5zZWxlY3RlZERhdGVdIDogbnVsbDtcbiAgICB9XG4gICAgdGhpcy5fb3ZlcmxheUluaXRpYWxEYXRlID0gbnVsbDtcbiAgICB0aGlzLl9vdmVybGF5SW5pdGlhbFByZXNldCA9IG51bGw7XG4gICAgdGhpcy5jdXN0b21SYW5nZU1vZGUgPSBmYWxzZTtcbiAgLy8gY2xlYW51cCBhbnkgc3RhcnQvZW5kIGNsYXNzZXMgdG8gYXZvaWQgc3RhbGUgY2xhc3Nlc1xuICB0aGlzLl9zY2hlZHVsZVVwZGF0ZSgpO1xuICAgIC8vIHN0b3Agb2JzZXJ2aW5nXG4gICAgdGhpcy5fc3RvcENhbGVuZGFyT2JzZXJ2ZXJzKCk7XG4gIH1cblxuICBvbk1vZGVsQ2hhbmdlKGRhdGVSYW5nZTogRGF0ZVtdIHwgbnVsbCkge1xuICAgIC8vIFdoZW4gdXNlciBjbGlja3MgYSBmaXJzdCBkYXRlLCBQcmltZU5HIG1heSBlbWl0IGFuIGFycmF5IHdpdGggMSB2YWx1ZS4gV2UgZG9uJ3Qgd2FudCB0b1xuICAgIC8vIHVwZGF0ZSB0aGUgZXh0ZXJuYWwgc2VsZWN0ZWREYXRlIHVudGlsIHRoZSByYW5nZSBpcyBjb21wbGV0ZWQgKHR3byBkYXRlcykgc28gdGhhdFxuICAgIC8vIHRoZSBjYWxlbmRhciBkb2VzIG5vdCBqdW1wIGJhY2sgdG8gYSBwcmV2aW91c2x5IHNlbGVjdGVkIGVuZCBkYXRlJ3MgbW9udGguXG4gICAgdGhpcy5tb2RlbERhdGUgPSBkYXRlUmFuZ2UgPyBbLi4uZGF0ZVJhbmdlXSA6IG51bGw7XG4gICAgaWYgKGRhdGVSYW5nZSAmJiBBcnJheS5pc0FycmF5KGRhdGVSYW5nZSkgJiYgZGF0ZVJhbmdlLmxlbmd0aCA9PT0gMiAmJiBkYXRlUmFuZ2VbMF0gJiYgZGF0ZVJhbmdlWzFdKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkUHJlc2V0ID0gdGhpcy5kZXRlY3RQcmVzZXQoZGF0ZVJhbmdlWzBdLCBkYXRlUmFuZ2VbMV0pO1xuICAgICAgdGhpcy5jdXN0b21SYW5nZU1vZGUgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gWy4uLmRhdGVSYW5nZV07XG4gICAgICB0aGlzLmRhdGVSYW5nZUNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWREYXRlKTtcbiAgICAgIC8vIGNsb3NlIG92ZXJsYXkgbGlrZSB3aGVuIGFwcGx5aW5nIGEgcHJlc2V0XG4gICAgICB0cnkgeyB0aGlzLm92ZXJsYXlQYW5lbD8uaGlkZSgpOyB9IGNhdGNoIChlKSB7fVxuICAgIH0gZWxzZSBpZiAoIWRhdGVSYW5nZSkge1xuICAgICAgLy8gY2xlYXJlZCBzZWxlY3Rpb25cbiAgICAgIHRoaXMuc2VsZWN0ZWRQcmVzZXQgPSBudWxsO1xuICAgICAgdGhpcy5jdXN0b21SYW5nZU1vZGUgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbnVsbDtcbiAgICAgIHRoaXMuZGF0ZVJhbmdlQ2hhbmdlLmVtaXQobnVsbCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHNpbmdsZSBkYXRlIHNlbGVjdGluZyAocGFydGlhbCByYW5nZSkgLSBkbyBub3QgZW1pdCBjaGFuZ2UgeWV0OyBqdXN0IGtlZXAgaW50ZXJuYWwgbW9kZWxcbiAgICAgIC8vIHNvIHRoZSBjYWxlbmRhcidzIHZpZXcgcmVtYWlucyB3aGVyZSB0aGUgdXNlciBuYXZpZ2F0ZWQgdG8uXG4gICAgICB0aGlzLnNlbGVjdGVkUHJlc2V0ID0gbnVsbDtcbiAgICAgIHRoaXMuY3VzdG9tUmFuZ2VNb2RlID0gZmFsc2U7XG4gICAgfVxuICAvLyB1cGRhdGUgc3RhcnQvZW5kIGNsYXNzZXMgd2hpbGUgdXNlciBpcyBzZWxlY3Rpbmcgb3Igd2hlbiByYW5nZSBjb21wbGV0ZXNcbiAgdGhpcy5fc2NoZWR1bGVVcGRhdGUoKTtcbiAgfVxuXG4gIC8vIENhbGxlZCB3aGVuIHRoZSBjYWxlbmRhcidzIHZpc2libGUgbW9udGgveWVhciBjaGFuZ2VzXG4gIG9uQ2FsZW5kYXJWaWV3Q2hhbmdlZChldmVudD86IGFueSk6IHZvaWQge1xuICAgIC8vIFJlYXBwbHkgY2xhc3NlcyBhZnRlciBQcmltZU5HIHJlLXJlbmRlclxuICAgIHRoaXMuX3NjaGVkdWxlVXBkYXRlKCk7XG4gICAgLy8gUmVhdHRhY2ggb2JzZXJ2ZXJzIGFmdGVyIGEgc21hbGwgZGVsYXkgc2luY2UgUHJpbWVORyB3aWxsIGxpa2VseSByZXBsYWNlIERPTSBub2Rlc1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5fc3RvcENhbGVuZGFyT2JzZXJ2ZXJzKCk7XG4gICAgICAgIHRoaXMuX3N0YXJ0Q2FsZW5kYXJPYnNlcnZlcnMoKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHsgfVxuICAgIH0sIDQwKTtcbiAgfVxuXG4gIGdldCBoYXNTZWxlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIEJvb2xlYW4oXG4gICAgICB0aGlzLnNlbGVjdGVkRGF0ZSAmJlxuICAgICAgICBBcnJheS5pc0FycmF5KHRoaXMuc2VsZWN0ZWREYXRlKSAmJlxuICAgICAgICAodGhpcy5zZWxlY3RlZERhdGUgYXMgRGF0ZVtdKS5sZW5ndGggPT09IDIgJiZcbiAgICAgICAgISEodGhpcy5zZWxlY3RlZERhdGUgYXMgRGF0ZVtdKVswXSAmJlxuICAgICAgICAhISh0aGlzLnNlbGVjdGVkRGF0ZSBhcyBEYXRlW10pWzFdXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplRGF0ZShkOiBEYXRlKTogRGF0ZSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGQuZ2V0RnVsbFllYXIoKSwgZC5nZXRNb250aCgpLCBkLmdldERhdGUoKSk7XG4gIH1cblxuICBwcml2YXRlIGlzU2FtZURhdGUoYTogRGF0ZSwgYjogRGF0ZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBhLmdldEZ1bGxZZWFyKCkgPT09IGIuZ2V0RnVsbFllYXIoKSAmJlxuICAgICAgYS5nZXRNb250aCgpID09PSBiLmdldE1vbnRoKCkgJiZcbiAgICAgIGEuZ2V0RGF0ZSgpID09PSBiLmdldERhdGUoKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGRldGVjdFByZXNldChzdGFydFJhdzogRGF0ZSwgZW5kUmF3OiBEYXRlKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLm5vcm1hbGl6ZURhdGUoc3RhcnRSYXcpO1xuICAgIGNvbnN0IGVuZCA9IHRoaXMubm9ybWFsaXplRGF0ZShlbmRSYXcpO1xuICAgIGNvbnN0IHRvZGF5ID0gdGhpcy5ub3JtYWxpemVEYXRlKG5ldyBEYXRlKCkpO1xuICAgIC8vIHRvZGF5XG4gICAgaWYgKHRoaXMuaXNTYW1lRGF0ZShzdGFydCwgdG9kYXkpICYmIHRoaXMuaXNTYW1lRGF0ZShlbmQsIHRvZGF5KSkgcmV0dXJuICd0b2RheSc7XG4gICAgLy8geWVzdGVyZGF5XG4gICAgY29uc3QgeSA9IG5ldyBEYXRlKHRvZGF5KTtcbiAgICB5LnNldERhdGUoeS5nZXREYXRlKCkgLSAxKTtcbiAgICBpZiAodGhpcy5pc1NhbWVEYXRlKHN0YXJ0LCB5KSAmJiB0aGlzLmlzU2FtZURhdGUoZW5kLCB5KSkgcmV0dXJuICd5ZXN0ZXJkYXknO1xuICAgIC8vIGxhc3Q3ZGF5cyAobGFzdCA3IGRheXMgaW5jbHVkaW5nIHRvZGF5OiBzdGFydCA9IHRvZGF5IC0gNiwgZW5kID0gdG9kYXkpXG4gICAgY29uc3QgbDdFbmQgPSBuZXcgRGF0ZSh0b2RheSk7XG4gICAgY29uc3QgbDdTdGFydCA9IG5ldyBEYXRlKHRvZGF5KTtcbiAgICBsN1N0YXJ0LnNldERhdGUodG9kYXkuZ2V0RGF0ZSgpIC0gNik7XG4gICAgaWYgKHRoaXMuaXNTYW1lRGF0ZShzdGFydCwgbDdTdGFydCkgJiYgdGhpcy5pc1NhbWVEYXRlKGVuZCwgbDdFbmQpKSByZXR1cm4gJ2xhc3Q3ZGF5cyc7XG4gICAgLy8gbGFzdDMwZGF5cyAobGFzdCAzMCBkYXlzIGluY2x1ZGluZyB0b2RheTogc3RhcnQgPSB0b2RheSAtIDI5LCBlbmQgPSB0b2RheSlcbiAgICBjb25zdCBsMzBFbmQgPSBuZXcgRGF0ZSh0b2RheSk7XG4gICAgY29uc3QgbDMwU3RhcnQgPSBuZXcgRGF0ZSh0b2RheSk7XG4gICAgbDMwU3RhcnQuc2V0RGF0ZSh0b2RheS5nZXREYXRlKCkgLSAyOSk7XG4gICAgaWYgKHRoaXMuaXNTYW1lRGF0ZShzdGFydCwgbDMwU3RhcnQpICYmIHRoaXMuaXNTYW1lRGF0ZShlbmQsIGwzMEVuZCkpIHJldHVybiAnbGFzdDMwZGF5cyc7XG4gICAgLy8gbGFzdDNtb250aHMgKGxhc3QgMyBtb250aHMgaW5jbHVkaW5nIHRvZGF5OiBzdGFydCA9IHRvZGF5IC0gMyBtb250aHMsIGVuZCA9IHRvZGF5KVxuICAgIGNvbnN0IGwzbUVuZCA9IG5ldyBEYXRlKHRvZGF5KTtcbiAgICBjb25zdCBsM21TdGFydCA9IG5ldyBEYXRlKHRvZGF5KTtcbiAgICBsM21TdGFydC5zZXRNb250aCh0b2RheS5nZXRNb250aCgpIC0gMyk7XG4gICAgaWYgKHRoaXMuaXNTYW1lRGF0ZShzdGFydCwgbDNtU3RhcnQpICYmIHRoaXMuaXNTYW1lRGF0ZShlbmQsIGwzbUVuZCkpIHJldHVybiAnbGFzdDNtb250aHMnO1xuICAgIC8vIGxhc3Q2bW9udGhzIChsYXN0IDYgbW9udGhzIGluY2x1ZGluZyB0b2RheTogc3RhcnQgPSB0b2RheSAtIDYgbW9udGhzLCBlbmQgPSB0b2RheSlcbiAgICBjb25zdCBsNm1FbmQgPSBuZXcgRGF0ZSh0b2RheSk7XG4gICAgY29uc3QgbDZtU3RhcnQgPSBuZXcgRGF0ZSh0b2RheSk7XG4gICAgbDZtU3RhcnQuc2V0TW9udGgodG9kYXkuZ2V0TW9udGgoKSAtIDYpO1xuICAgIGlmICh0aGlzLmlzU2FtZURhdGUoc3RhcnQsIGw2bVN0YXJ0KSAmJiB0aGlzLmlzU2FtZURhdGUoZW5kLCBsNm1FbmQpKSByZXR1cm4gJ2xhc3Q2bW9udGhzJztcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNsZWFyRGF0ZVJhbmdlKCkge1xuICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gbnVsbDtcbiAgICB0aGlzLmRhdGVSYW5nZUNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWREYXRlKTtcbiAgICB0aGlzLnNlbGVjdGVkUHJlc2V0ID0gbnVsbDtcbiAgICB0aGlzLmN1c3RvbVJhbmdlTW9kZSA9IGZhbHNlO1xuICAgIHRoaXMubW9kZWxEYXRlID0gbnVsbDtcbiAgfVxuXG4gIHJlc2V0QW5kQ2xvc2UoKSB7XG4gICAgdGhpcy5jbGVhckRhdGVSYW5nZSgpO1xuICAgIGlmICh0aGlzLm92ZXJsYXlQYW5lbCkge1xuICAgICAgdHJ5IHsgdGhpcy5vdmVybGF5UGFuZWwuaGlkZSgpOyB9IGNhdGNoIChlKSB7fVxuICAgIH1cbiAgfVxuXG4gIGNsZWFyQW5kU3RvcChldmVudDogRXZlbnQpIHtcbiAgICB0aGlzLmNsZWFyRGF0ZVJhbmdlKCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICB0b2dnbGVDdXN0b21SYW5nZSgpIHtcbiAgICB0aGlzLmN1c3RvbVJhbmdlTW9kZSA9ICF0aGlzLmN1c3RvbVJhbmdlTW9kZTtcbiAgICBpZiAodGhpcy5jdXN0b21SYW5nZU1vZGUpIHRoaXMuc2VsZWN0ZWRQcmVzZXQgPSAnY3VzdG9tJztcbiAgfVxuXG4gIGFwcGx5Q3VzdG9tUmFuZ2UoKSB7XG4gICAgLy8gZW5zdXJlIGV4dGVybmFsIHNlbGVjdGVkRGF0ZSBpcyBpbiBzeW5jIHdpdGggaW50ZXJuYWwgbW9kZWxcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IHRoaXMubW9kZWxEYXRlID8gWy4uLnRoaXMubW9kZWxEYXRlXSA6IG51bGw7XG4gICAgdGhpcy5kYXRlUmFuZ2VDaGFuZ2UuZW1pdCh0aGlzLnNlbGVjdGVkRGF0ZSk7XG4gICAgaWYgKHRoaXMub3ZlcmxheVBhbmVsKSB7XG4gICAgICB0cnkgeyB0aGlzLm92ZXJsYXlQYW5lbC5oaWRlKCk7IH0gY2F0Y2ggKGUpIHt9XG4gICAgfVxuICAgIHRoaXMuY3VzdG9tUmFuZ2VNb2RlID0gZmFsc2U7XG4gICAgdGhpcy5zZWxlY3RlZFByZXNldCA9ICdjdXN0b20nO1xuICB9XG5cbiAgICBnZXREYXRlUmFuZ2VMYWJlbCgpIHtcbiAgICAvLyBDaGVjayB0aGUgaW50ZXJuYWwgbW9kZWwgZmlyc3QgdG8gc2hvdyByZWFsLXRpbWUgdXBkYXRlcyB3aGlsZSBzZWxlY3RpbmdcbiAgICBjb25zdCBkYXRlQXJyYXkgPSB0aGlzLm1vZGVsRGF0ZSB8fCB0aGlzLnNlbGVjdGVkRGF0ZTtcbiAgICBpZiAoIWRhdGVBcnJheSB8fCAhQXJyYXkuaXNBcnJheShkYXRlQXJyYXkpKSByZXR1cm4gJyc7XG4gICAgXG4gICAgY29uc3QgW3N0YXJ0LCBlbmRdID0gZGF0ZUFycmF5IGFzIChEYXRlIHwgbnVsbClbXTtcbiAgICAgICAgICAgIGNvbnN0IGFycm93ID0gJ1xcdTI3OTQnO1xuXG4gICAgLy8gU2hvdyBqdXN0IHRoZSBmaXJzdCBkYXRlIHdpdGggYW4gYXJyb3cgaWYgb25seSBmaXJzdCBkYXRlIGlzIHNlbGVjdGVkXG4gICAgaWYgKHN0YXJ0ICYmICFlbmQpIHtcbiAgICAgIGNvbnN0IHN0YXJ0U3RyID0gdGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0oc3RhcnQsICdNTS9kZC95eXl5Jyk7XG4gICAgICByZXR1cm4gYCR7c3RhcnRTdHJ9ICR7YXJyb3d9IGA7XG4gICAgfVxuICAgIFxuICAgIC8vIFNob3cgdGhlIGNvbXBsZXRlIHJhbmdlIGlmIGJvdGggZGF0ZXMgYXJlIHNlbGVjdGVkXG4gICAgaWYgKHN0YXJ0ICYmIGVuZCkge1xuICAgICAgY29uc3Qgc3RhcnRTdHIgPSB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybShzdGFydCwgJ01NL2RkL3l5eXknKTtcbiAgICAgIGNvbnN0IGVuZFN0ciA9IHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKGVuZCwgJ01NL2RkL3l5eXknKTtcbiAgICAgIHJldHVybiBgJHtzdGFydFN0cn0gJHthcnJvd30gJHtlbmRTdHJ9YDtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgYXBwbHlQcmVzZXQocHJlc2V0OiAndG9kYXknfCd5ZXN0ZXJkYXknfCdsYXN0N2RheXMnfCdsYXN0MzBkYXlzJ3wnbGFzdDNtb250aHMnfCdsYXN0Nm1vbnRocycpIHtcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgbGV0IHN0YXJ0OiBEYXRlIHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGVuZDogRGF0ZSB8IG51bGwgPSBudWxsO1xuICAgIHN3aXRjaCAocHJlc2V0KSB7XG4gICAgICBjYXNlICd0b2RheSc6XG4gICAgICAgIHN0YXJ0ID0gZW5kID0gbmV3IERhdGUodG9kYXkuZ2V0RnVsbFllYXIoKSwgdG9kYXkuZ2V0TW9udGgoKSwgdG9kYXkuZ2V0RGF0ZSgpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd5ZXN0ZXJkYXknOlxuICAgICAgICBjb25zdCB5ID0gbmV3IERhdGUodG9kYXkpO1xuICAgICAgICB5LnNldERhdGUoeS5nZXREYXRlKCkgLSAxKTtcbiAgICAgICAgc3RhcnQgPSBlbmQgPSBuZXcgRGF0ZSh5LmdldEZ1bGxZZWFyKCksIHkuZ2V0TW9udGgoKSwgeS5nZXREYXRlKCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2xhc3Q3ZGF5cyc6IHtcbiAgICAgICAgZW5kID0gbmV3IERhdGUodG9kYXkuZ2V0RnVsbFllYXIoKSwgdG9kYXkuZ2V0TW9udGgoKSwgdG9kYXkuZ2V0RGF0ZSgpKTtcbiAgICAgICAgc3RhcnQgPSBuZXcgRGF0ZShlbmQpO1xuICAgICAgICBzdGFydC5zZXREYXRlKGVuZC5nZXREYXRlKCkgLSA2KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdsYXN0MzBkYXlzJzoge1xuICAgICAgICBlbmQgPSBuZXcgRGF0ZSh0b2RheS5nZXRGdWxsWWVhcigpLCB0b2RheS5nZXRNb250aCgpLCB0b2RheS5nZXREYXRlKCkpO1xuICAgICAgICBzdGFydCA9IG5ldyBEYXRlKGVuZCk7XG4gICAgICAgIHN0YXJ0LnNldERhdGUoZW5kLmdldERhdGUoKSAtIDI5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdsYXN0M21vbnRocyc6IHtcbiAgICAgICAgZW5kID0gbmV3IERhdGUodG9kYXkuZ2V0RnVsbFllYXIoKSwgdG9kYXkuZ2V0TW9udGgoKSwgdG9kYXkuZ2V0RGF0ZSgpKTtcbiAgICAgICAgc3RhcnQgPSBuZXcgRGF0ZShlbmQpO1xuICAgICAgICBzdGFydC5zZXRNb250aChlbmQuZ2V0TW9udGgoKSAtIDMpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2xhc3Q2bW9udGhzJzoge1xuICAgICAgICBlbmQgPSBuZXcgRGF0ZSh0b2RheS5nZXRGdWxsWWVhcigpLCB0b2RheS5nZXRNb250aCgpLCB0b2RheS5nZXREYXRlKCkpO1xuICAgICAgICBzdGFydCA9IG5ldyBEYXRlKGVuZCk7XG4gICAgICAgIHN0YXJ0LnNldE1vbnRoKGVuZC5nZXRNb250aCgpIC0gNik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGlmIChzdGFydCAmJiBlbmQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gW3N0YXJ0LCBlbmRdO1xuICAgICAgdGhpcy5tb2RlbERhdGUgPSBbc3RhcnQsIGVuZF07XG4gICAgICB0aGlzLmRhdGVSYW5nZUNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWREYXRlKTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQcmVzZXQgPSBwcmVzZXQ7XG4gICAgICB0aGlzLmN1c3RvbVJhbmdlTW9kZSA9IGZhbHNlO1xuICAgIH1cbiAgICB0cnkgeyB0aGlzLm92ZXJsYXlQYW5lbD8uaGlkZSgpOyB9IGNhdGNoIChlKSB7fVxuICAvLyBlbnN1cmUgd2UgdXBkYXRlIHN0YXJ0L2VuZCBjbGFzc2VzIGFmdGVyIGFwcGx5aW5nIGEgcHJlc2V0XG4gIHRoaXMuX3NjaGVkdWxlVXBkYXRlKCk7XG4gIH1cblxuICBvbkRhdGVSYW5nZUNoYW5nZShkYXRlUmFuZ2U6IERhdGVbXSB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGVSYW5nZUNoYW5nZS5lbWl0KGRhdGVSYW5nZSk7XG4gICAgaWYgKGRhdGVSYW5nZSAmJiBBcnJheS5pc0FycmF5KGRhdGVSYW5nZSkpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQcmVzZXQgPSB0aGlzLmRldGVjdFByZXNldChkYXRlUmFuZ2VbMF0sIGRhdGVSYW5nZVsxXSk7XG4gICAgICB0aGlzLmN1c3RvbVJhbmdlTW9kZSA9IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoIWRhdGVSYW5nZSkge1xuICAgICAgdGhpcy5zZWxlY3RlZFByZXNldCA9IG51bGw7XG4gICAgICB0aGlzLmN1c3RvbVJhbmdlTW9kZSA9IGZhbHNlO1xuICAgIH1cbiAgdGhpcy5fc2NoZWR1bGVVcGRhdGUoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuX3N0b3BDYWxlbmRhck9ic2VydmVycygpO1xuICAgIHRoaXMuX2NhbmNlbFNjaGVkdWxlZFVwZGF0ZSgpO1xuICB9XG5cbiAgLy8gV2FsayB0aGUgcmVuZGVyZWQgY2FsZW5kYXIgRE9NKHMpIChvdmVybGF5ICsgaW5saW5lKSBhbmQgYWRkIHN0YXJ0LXJhbmdlL2VuZC1yYW5nZSBjbGFzc2VzXG4gIHByaXZhdGUgX3VwZGF0ZVN0YXJ0RW5kUmFuZ2VDbGFzc2VzKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjYWxlbmRhckVsZW1lbnRzID0gdGhpcy5fZ2V0Q2FsZW5kYXJFbGVtZW50cygpO1xuXG4gICAgICBjYWxlbmRhckVsZW1lbnRzLmZvckVhY2goKGNhbEVsOiBFbGVtZW50KSA9PiB7XG4gICAgICAgIC8vIFJlbW92ZSBleGlzdGluZyBjbGFzc2VzIGZyb20gc3BhbnMgZmlyc3RcbiAgICAgICAgY29uc3QgYWxsU3BhbnMgPSBjYWxFbC5xdWVyeVNlbGVjdG9yQWxsKCd0ZCA+IHNwYW4nKTtcbiAgICAgICAgYWxsU3BhbnMuZm9yRWFjaCgoc3BhbikgPT4ge1xuICAgICAgICAgIHRoaXMucmVuZGVyZXIucmVtb3ZlQ2xhc3Moc3BhbiwgJ3N0YXJ0LXJhbmdlJyk7XG4gICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhzcGFuLCAnZW5kLXJhbmdlJyk7XG4gICAgICAgICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDbGFzcyhzcGFuLCAnYmV0d2Vlbi1yYW5nZScpO1xuICAgICAgICB9KTtcblxuICAvLyBDb2xsZWN0IHNwYW4vZGF0ZSBwYWlycywgcHJlZmVyIGRhdGEtZGF0ZSBhdHRyaWJ1dGVcbiAgLy8gQ2FjaGUgaGVhZGVyIG1vbnRoL3llYXIgZm9yIHRoaXMgY2FsZW5kYXIgdG8gYXZvaWQgcXVlcnlpbmcgcGVyLXNwYW5cbiAgY29uc3QgcGFuZWxOb2RlID0gY2FsRWwuY2xvc2VzdCgnLnAtZGF0ZXBpY2tlcicpIHx8IGNhbEVsO1xuICBjb25zdCBoZWFkZXJNb250aE5vZGUgPSAocGFuZWxOb2RlIGFzIEVsZW1lbnQpLnF1ZXJ5U2VsZWN0b3IoJy5wLWRhdGVwaWNrZXItaGVhZGVyIC5wLWRhdGVwaWNrZXItdGl0bGUgLnAtZGF0ZXBpY2tlci1tb250aCcpO1xuICBjb25zdCBoZWFkZXJZZWFyTm9kZSA9IChwYW5lbE5vZGUgYXMgRWxlbWVudCkucXVlcnlTZWxlY3RvcignLnAtZGF0ZXBpY2tlci1oZWFkZXIgLnAtZGF0ZXBpY2tlci10aXRsZSAucC1kYXRlcGlja2VyLXllYXInKTtcbiAgY29uc3QgaGVhZGVyTW9udGhJZHggPSBoZWFkZXJNb250aE5vZGUgJiYgaGVhZGVyTW9udGhOb2RlLnRleHRDb250ZW50ID8gKHRoaXMuZW5Mb2NhbGUubW9udGhOYW1lcyB8fCBbXSkuaW5kZXhPZihoZWFkZXJNb250aE5vZGUudGV4dENvbnRlbnQudHJpbSgpKSA6IE5hTjtcbiAgY29uc3QgaGVhZGVyWWVhclZhbCA9IGhlYWRlclllYXJOb2RlICYmIGhlYWRlclllYXJOb2RlLnRleHRDb250ZW50ID8gcGFyc2VJbnQoaGVhZGVyWWVhck5vZGUudGV4dENvbnRlbnQudHJpbSgpLCAxMCkgOiBOYU47XG4gICAgICAgIGNvbnN0IGl0ZW1zOiB7IGR0OiBEYXRlOyBzcGFuOiBFbGVtZW50OyB0ZD86IEhUTUxFbGVtZW50IHwgbnVsbCB9W10gPSBbXTtcbiAgICAgICAgY29uc3Qgc3BhbnMgPSBjYWxFbC5xdWVyeVNlbGVjdG9yQWxsKCd0ZCA+IHNwYW4ucC1oaWdobGlnaHQnKTtcbiAgICAgICAgc3BhbnMuZm9yRWFjaCgoc3BhbikgPT4ge1xuICAgICAgICAgIGNvbnN0IHRkID0gc3Bhbi5jbG9zZXN0KCd0ZCcpIGFzIEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICAgICAgICAvLyBUcnkgdG8gcmVhZCBkYXRhLWRhdGUgYXR0cmlidXRlLCB3aGljaCBzb21lIFByaW1lTkcgdmVyc2lvbnMgcmVuZGVyIG9uIHNwYW4vdGRcbiAgICAgICAgICBsZXQgZGF0YURhdGUgPSBzcGFuLmdldEF0dHJpYnV0ZSgnZGF0YS1kYXRlJyk7XG4gICAgICAgICAgaWYgKCFkYXRhRGF0ZSAmJiB0ZCkgZGF0YURhdGUgPSB0ZC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZGF0ZScpO1xuICAgICAgICAgIGlmIChkYXRhRGF0ZSkge1xuICAgICAgICAgICAgY29uc3QgcGFydHMgPSBkYXRhRGF0ZS5zcGxpdCgnLScpLm1hcCgocCkgPT4gcGFyc2VJbnQocCwgMTApKTtcbiAgICAgICAgICAgIGlmIChwYXJ0cy5sZW5ndGggPj0gMyAmJiBwYXJ0cy5ldmVyeSgobikgPT4gIWlzTmFOKG4pKSkge1xuICAgICAgICAgICAgICBjb25zdCBbeSwgbSwgZF0gPSBwYXJ0cztcbiAgICAgICAgICAgICAgY29uc3QgZHQgPSBuZXcgRGF0ZSh5LCBtIC0gMSwgZCk7XG4gICAgICAgICAgICAgIGl0ZW1zLnB1c2goeyBkdCwgdGQsIHNwYW4gfSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gRmFsbGJhY2s6IHBhcnNlIGRheSBudW1iZXIgYW5kIGluZmVyIG1vbnRoL3llYXIgZnJvbSBuZWFyYnkgaGVhZGVyIGluIHRoZSBzYW1lIC5wLWRhdGVwaWNrZXJcbiAgICAgICAgICBjb25zdCBkYXlUZXh0ID0gKHNwYW4udGV4dENvbnRlbnQgfHwgJycpLnRyaW0oKTtcbiAgICAgICAgICBjb25zdCBkYXkgPSBwYXJzZUludChkYXlUZXh0LCAxMCk7XG4gICAgICAgICAgaWYgKCFpc05hTihkYXkpICYmIHRkKSB7XG4gICAgICAgICAgICAvLyBVc2UgY2FjaGVkIGhlYWRlciBtb250aC95ZWFyIHdoZW4gYXZhaWxhYmxlXG4gICAgICAgICAgICBpZiAoIWlzTmFOKGhlYWRlck1vbnRoSWR4KSAmJiAhaXNOYU4oaGVhZGVyWWVhclZhbCkpIHtcbiAgICAgICAgICAgICAgY29uc3QgZHQgPSBuZXcgRGF0ZShoZWFkZXJZZWFyVmFsLCBoZWFkZXJNb250aElkeCwgZGF5KTtcbiAgICAgICAgICAgICAgaXRlbXMucHVzaCh7IGR0LCB0ZCwgc3BhbiB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBsYXN0IHJlc29ydDogaWdub3JlIHNwYW4gaWYgZGF0ZSBjYW5ub3QgYmUgZGV0ZXJtaW5lZFxuICAgICAgICB9KTtcblxuICBpZiAoaXRlbXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgICAgLy8gU29ydCBpdGVtcyB0byBmaW5kIG1pbi9tYXggKHN0YXJ0ICYgZW5kKVxuICAgICAgICBpdGVtcy5zb3J0KChhLCBiKSA9PiBhLmR0LmdldFRpbWUoKSAtIGIuZHQuZ2V0VGltZSgpKTtcbiAgICAgICAgY29uc3QgZGV0ZWN0ZWRTdGFydCA9IGl0ZW1zWzBdLmR0O1xuICAgICAgICBjb25zdCBkZXRlY3RlZEVuZCA9IGl0ZW1zW2l0ZW1zLmxlbmd0aCAtIDFdLmR0O1xuXG4gIC8vIFByZWZlcnJlZCByYW5nZSBpcyBtb2RlbERhdGUvc2VsZWN0ZWREYXRlIGlmIHByZXNlbnRcbiAgY29uc3QgcmFuZ2UgPSAodGhpcy5zZWxlY3RlZERhdGUgJiYgdGhpcy5zZWxlY3RlZERhdGUubGVuZ3RoID09PSAyKSA/IHRoaXMuc2VsZWN0ZWREYXRlIDogKHRoaXMubW9kZWxEYXRlICYmIHRoaXMubW9kZWxEYXRlLmxlbmd0aCA9PT0gMiA/IHRoaXMubW9kZWxEYXRlIDogW2RldGVjdGVkU3RhcnQsIGRldGVjdGVkRW5kXSk7XG4gIGNvbnN0IHN0YXJ0RGF0ZSA9IHJhbmdlICYmIHJhbmdlWzBdID8gdGhpcy5ub3JtYWxpemVEYXRlKHJhbmdlWzBdIGFzIERhdGUpIDogZGV0ZWN0ZWRTdGFydDtcbiAgY29uc3QgZW5kRGF0ZSA9IHJhbmdlICYmIHJhbmdlWzFdID8gdGhpcy5ub3JtYWxpemVEYXRlKHJhbmdlWzFdIGFzIERhdGUpIDogZGV0ZWN0ZWRFbmQ7XG5cbiAgICAgICAgLy8gRm9yIGVhY2ggaXRlbSwgYWRkIHN0YXJ0LXJhbmdlLGVuZC1yYW5nZSwgb3IgYmV0d2Vlbi1yYW5nZSBiYXNlZCBvbiBkYXRlXG4gICAgICAgIGNvbnN0IHNUaW1lID0gc3RhcnREYXRlLmdldFRpbWUoKTtcbiAgICAgICAgY29uc3QgZVRpbWUgPSBlbmREYXRlLmdldFRpbWUoKTtcbiAgICAgICAgZm9yIChjb25zdCBpdCBvZiBpdGVtcykge1xuICAgICAgICAgIGNvbnN0IHQgPSBpdC5kdC5nZXRUaW1lKCk7XG4gICAgICAgICAgaWYgKHNUaW1lID09PSBlVGltZSAmJiB0ID09PSBzVGltZSkge1xuICAgICAgICAgICAgLy8gc2luZ2xlLWRheSByYW5nZSwgbWFyayBib3RoIHN0YXJ0ICYgZW5kXG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKGl0LnNwYW4sICdzdGFydC1yYW5nZScpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhpdC5zcGFuLCAnZW5kLXJhbmdlJyk7XG4gICAgICAgICAgfSBlbHNlIGlmICh0ID09PSBzVGltZSkge1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5hZGRDbGFzcyhpdC5zcGFuLCAnc3RhcnQtcmFuZ2UnKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHQgPT09IGVUaW1lKSB7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcmVyLmFkZENsYXNzKGl0LnNwYW4sICdlbmQtcmFuZ2UnKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHQgPiBzVGltZSAmJiB0IDwgZVRpbWUpIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuYWRkQ2xhc3MoaXQuc3BhbiwgJ2JldHdlZW4tcmFuZ2UnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGlnbm9yZSBET00gZXJyb3JzIChlLmcuLCBzZXJ2ZXItc2lkZSByZW5kZXJpbmcgLyBtaXNzaW5nIGVsZW1lbnRzKVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXNvRGF0ZShkOiBEYXRlKTogc3RyaW5nIHtcbiAgICBjb25zdCB5ID0gZC5nZXRGdWxsWWVhcigpO1xuICAgIGNvbnN0IG0gPSBTdHJpbmcoZC5nZXRNb250aCgpICsgMSkucGFkU3RhcnQoMiwgJzAnKTtcbiAgICBjb25zdCBkYXkgPSBTdHJpbmcoZC5nZXREYXRlKCkpLnBhZFN0YXJ0KDIsICcwJyk7XG4gICAgcmV0dXJuIGAke3l9LSR7bX0tJHtkYXl9YDtcbiAgfVxuXG4gIHByaXZhdGUgX2ZpbmRFbGVtZW50QnlEYXRlKGRhdGU/OiBEYXRlKTogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQge1xuICAgIGlmICghZGF0ZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCB5ID0gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgIGNvbnN0IG0gPSBkYXRlLmdldE1vbnRoKCkgKyAxOyAvLyAxLi4xMlxuICAgIGNvbnN0IGQgPSBkYXRlLmdldERhdGUoKTtcbiAgICBjb25zdCBpc29VbnBhZGRlZCA9IGAke3l9LSR7bX0tJHtkfWA7IC8vIGUuZy4gMjAyNS0xMS0xXG4gICAgY29uc3QgaXNvUGFkZGVkID0gYCR7eX0tJHtTdHJpbmcobSkucGFkU3RhcnQoMiwgJzAnKX0tJHtTdHJpbmcoZCkucGFkU3RhcnQoMiwgJzAnKX1gOyAvLyAyMDI1LTExLTAxXG4gICAgY29uc3Qgc2VsZWN0b3JzID0gW2BbZGF0YS1kYXRlPVwiJHtpc29VbnBhZGRlZH1cIl1gLCBgW2RhdGEtZGF0ZT1cIiR7aXNvUGFkZGVkfVwiXWBdO1xuICAgIGZvciAoY29uc3Qgc2VsIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgZm91bmRJbk92ZXJsYXkgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGAuYXRvbWl4LW92ZXJsYXktY2FsZW5kYXIgJHtzZWx9YCkgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgICAgaWYgKGZvdW5kSW5PdmVybGF5KSByZXR1cm4gZm91bmRJbk92ZXJsYXkuY2xvc2VzdCgndGQnKSBhcyBIVE1MRWxlbWVudCB8IG51bGwgfHwgZm91bmRJbk92ZXJsYXk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc2VsIG9mIHNlbGVjdG9ycykge1xuICAgICAgY29uc3QgZm91bmQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHNlbCkgYXMgSFRNTEVsZW1lbnQgfCBudWxsO1xuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmQuY2xvc2VzdCgndGQnKSBhcyBIVE1MRWxlbWVudCB8IG51bGwgfHwgZm91bmQ7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIF9zdGFydENhbGVuZGFyT2JzZXJ2ZXJzKCk6IHZvaWQge1xuICAgIC8vIHN0b3AgZmlyc3QgdG8gYXZvaWQgZHVwbGljYXRlc1xuICAgIHRoaXMuX3N0b3BDYWxlbmRhck9ic2VydmVycygpO1xuICAgIHRyeSB7XG4gIGNvbnN0IGNhbEVscyA9IHRoaXMuX2dldENhbGVuZGFyRWxlbWVudHMoKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBhbmVsID0gdGhpcy5vdmVybGF5UGFuZWwgYXMgYW55O1xuICAgICAgICBpZiAocGFuZWwgJiYgcGFuZWwuZWwgJiYgcGFuZWwuZWwubmF0aXZlRWxlbWVudCkge1xuICAgICAgICAgIGNvbnN0IGVsID0gcGFuZWwuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcucC1kYXRlcGlja2VyJyk7XG4gICAgICAgICAgaWYgKGVsKSBjYWxFbHMucHVzaChlbCBhcyBFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge31cblxuICAgICAgY2FsRWxzLmZvckVhY2goKGVsKSA9PiB7XG4gICAgICAgIGNvbnN0IG9icyA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgICAvLyBSZWFwcGx5IGNsYXNzZXMgYWZ0ZXIgRE9NIGNoYW5nZXMgKGRlYm91bmNlZClcbiAgICAgICAgICB0aGlzLl9zY2hlZHVsZVVwZGF0ZSgpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gV2F0Y2ggY2hpbGRMaXN0LCBzdWJ0cmVlIGFuZCBjbGFzcyBhdHRyaWJ1dGUgY2hhbmdlcyAoc3BhbiBjbGFzcyB0b2dnbGVzIGFyZSBjb21tb24pXG4gICAgICAgIG9icy5vYnNlcnZlKGVsLCB7IGNoaWxkTGlzdDogdHJ1ZSwgc3VidHJlZTogdHJ1ZSwgYXR0cmlidXRlczogdHJ1ZSwgYXR0cmlidXRlRmlsdGVyOiBbJ2NsYXNzJ10gfSk7XG4gICAgICAgIHRoaXMuX2NhbGVuZGFyT2JzZXJ2ZXJzLnB1c2gob2JzKTtcbiAgICAgICAgdGhpcy5fb2JzZXJ2ZWRFbGVtZW50cy5wdXNoKGVsKTtcbiAgICAgICAgLy8gQWxzbyBvYnNlcnZlIHBhcmVudCAtIGlmIFByaW1lTkcgcmVwbGFjZXMgdGhlIC5wLWRhdGVwaWNrZXIgZWxlbWVudCwgcGFyZW50IGNoaWxkTGlzdCBjaGFuZ2VzIHdpbGwgZmlyZVxuICAgICAgICBjb25zdCBwYXJlbnQgPSBlbC5wYXJlbnRFbGVtZW50O1xuICAgICAgICBpZiAocGFyZW50ICYmIHRoaXMuX29ic2VydmVkUGFyZW50RWxlbWVudHMuaW5kZXhPZihwYXJlbnQpID09PSAtMSkge1xuICAgICAgICAgIGNvbnN0IHBhcmVudE9icyA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKCgpID0+IHtcbiAgICAgICAgICAgIC8vIHJlYXR0YWNoIG9ic2VydmVycyBzaW5jZSB0aGUgY2FsRWwgbWF5IGhhdmUgYmVlbiByZXBsYWNlZFxuICAgICAgICAgICAgdGhpcy5fc2NoZWR1bGVVcGRhdGUoKTtcbiAgICAgICAgICAgIC8vIGRldGFjaCBhbmQgcmUtYXR0YWNoIG9ic2VydmVycyBhZnRlciBET00gc2V0dGxlc1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RvcENhbGVuZGFyT2JzZXJ2ZXJzKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhcnRDYWxlbmRhck9ic2VydmVycygpO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IH1cbiAgICAgICAgICAgIH0sIDEwMCk7IC8vIHNsaWdodGx5IGxhcmdlciBkZWxheSB0byBsZXQgUHJpbWVORyBmaW5pc2ggdGhlIG1vbnRoIHJlbmRlcmluZ1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHBhcmVudE9icy5vYnNlcnZlKHBhcmVudCwgeyBjaGlsZExpc3Q6IHRydWUsIHN1YnRyZWU6IGZhbHNlIH0pO1xuICAgICAgICAgIHRoaXMuX3BhcmVudE9ic2VydmVycy5wdXNoKHBhcmVudE9icyk7XG4gICAgICAgICAgdGhpcy5fb2JzZXJ2ZWRQYXJlbnRFbGVtZW50cy5wdXNoKHBhcmVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIGlnbm9yZVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3N0b3BDYWxlbmRhck9ic2VydmVycygpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5fY2FsZW5kYXJPYnNlcnZlcnMuZm9yRWFjaCgob2JzKSA9PiBvYnMuZGlzY29ubmVjdCgpKTtcbiAgICAgIHRoaXMuX3BhcmVudE9ic2VydmVycy5mb3JFYWNoKChvYnMpID0+IG9icy5kaXNjb25uZWN0KCkpO1xuICAgIH0gY2F0Y2ggKGUpIHsgfVxuICAgIHRoaXMuX2NhbGVuZGFyT2JzZXJ2ZXJzID0gW107XG4gICAgdGhpcy5fb2JzZXJ2ZWRFbGVtZW50cyA9IFtdO1xuICAgIHRoaXMuX3BhcmVudE9ic2VydmVycyA9IFtdO1xuICAgIHRoaXMuX29ic2VydmVkUGFyZW50RWxlbWVudHMgPSBbXTtcbiAgfVxuXG4gIHByaXZhdGUgX3NjaGVkdWxlVXBkYXRlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl91cGRhdGVSYWZJZCAhPSBudWxsKSByZXR1cm47IC8vIGFscmVhZHkgc2NoZWR1bGVkXG4gICAgdGhpcy5fdXBkYXRlUmFmSWQgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIHRoaXMuX3VwZGF0ZVJhZklkID0gbnVsbDtcbiAgICAgIHRoaXMuX3VwZGF0ZVN0YXJ0RW5kUmFuZ2VDbGFzc2VzKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9jYW5jZWxTY2hlZHVsZWRVcGRhdGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3VwZGF0ZVJhZklkICE9IG51bGwpIHtcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLl91cGRhdGVSYWZJZCk7XG4gICAgICB0aGlzLl91cGRhdGVSYWZJZCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0Q2FsZW5kYXJFbGVtZW50cygpOiBFbGVtZW50W10ge1xuICAgIGNvbnN0IGNhbEVsczogRWxlbWVudFtdID0gW107XG4gICAgY29uc3Qgb3ZlcmxheUNhbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5hdG9taXgtb3ZlcmxheS1jYWxlbmRhciAucC1kYXRlcGlja2VyJyk7XG4gICAgY29uc3QgaW5saW5lQ2FsID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmlubGluZS1jYWxlbmRhciAucC1kYXRlcGlja2VyJyk7XG4gICAgaWYgKG92ZXJsYXlDYWwpIGNhbEVscy5wdXNoKG92ZXJsYXlDYWwpO1xuICAgIGlmIChpbmxpbmVDYWwpIGNhbEVscy5wdXNoKGlubGluZUNhbCk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhbmVsID0gdGhpcy5vdmVybGF5UGFuZWwgYXMgYW55O1xuICAgICAgaWYgKHBhbmVsICYmIHBhbmVsLmVsICYmIHBhbmVsLmVsLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgY29uc3QgZWwgPSBwYW5lbC5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5wLWRhdGVwaWNrZXInKTtcbiAgICAgICAgaWYgKGVsKSBjYWxFbHMucHVzaChlbCBhcyBFbGVtZW50KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7IH1cbiAgICAvLyByZW1vdmUgZHVwbGljYXRlc1xuICAgIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoY2FsRWxzKSk7XG4gIH1cbn1cbiIsIjxkaXY+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCIhaW5saW5lOyBlbHNlIGlubGluZUJsb2NrXCI+XG4gICAgPGRpdiBbbmdDbGFzc109XCJzdHlsZUNsYXNzXCIgY2xhc3M9XCJpbnB1dC13cmFwcGVyXCI+XG4gICAgICA8aW5wdXRcbiAgICAgICAgcElucHV0VGV4dFxuICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgIFtuZ0NsYXNzXT1cImlucHV0U3R5bGVDbGFzc1wiXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gIFt2YWx1ZV09XCJnZXREYXRlUmFuZ2VMYWJlbCgpXCJcbiAgICAgICAgcmVhZG9ubHlcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgKGNsaWNrKT1cIm92ZXJsYXlQYW5lbD8udG9nZ2xlKCRldmVudClcIlxuICAgICAgICAoa2V5ZG93bik9XCJvbklucHV0S2V5RG93bigkZXZlbnQpXCJcbiAgICAgIC8+XG4gICAgICA8aSBjbGFzcz1cInBpIHBpLWNhbGVuZGFyIGlucHV0LWljb25cIiB0aXRsZT1cIk9wZW4gY2FsZW5kYXJcIiAoY2xpY2spPVwib3ZlcmxheVBhbmVsPy50b2dnbGUoJGV2ZW50KVwiPjwvaT5cbiAgICAgIDxpICpuZ0lmPVwiaGFzU2VsZWN0aW9uXCIgY2xhc3M9XCJwaSBwaS10aW1lcyBpbnB1dC1jbGVhci1pY29uXCIgdGl0bGU9XCJDbGVhclwiIHRhYmluZGV4PVwiMFwiIChjbGljayk9XCJjbGVhckFuZFN0b3AoJGV2ZW50KVwiIChrZXlkb3duLmVudGVyKT1cImNsZWFyQW5kU3RvcCgkZXZlbnQpXCIgKGtleWRvd24uc3BhY2UpPVwiY2xlYXJBbmRTdG9wKCRldmVudClcIj48L2k+XG5cbiAgICA8L2Rpdj5cblxuICAgIDxwLW92ZXJsYXlQYW5lbCAjb3ZlcmxheVBhbmVsIFtkaXNtaXNzYWJsZV09XCJ0cnVlXCIgYXBwZW5kVG89XCJib2R5XCIgc3R5bGVDbGFzcz1cImF0b21peC1kYXRlLXJhbmdlLW92ZXJsYXlcIiAob25TaG93KT1cIm9uT3ZlcmxheVNob3coKVwiIChvbkhpZGUpPVwib25PdmVybGF5SGlkZSgpXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwib3ZlcmxheS1pbm5lclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwib3ZlcmxheS1sZWZ0XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInByZXNldC1saXN0XCI+XG4gICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gcFJpcHBsZSB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuXCIgKGNsaWNrKT1cImFwcGx5UHJlc2V0KCd0b2RheScpXCIgW25nQ2xhc3NdPVwieyAnYWN0aXZlJzogc2VsZWN0ZWRQcmVzZXQgPT09ICd0b2RheScgfVwiIGxhYmVsPVwiVG9kYXlcIj48L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBwUmlwcGxlIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG5cIiAoY2xpY2spPVwiYXBwbHlQcmVzZXQoJ3llc3RlcmRheScpXCIgW25nQ2xhc3NdPVwieyAnYWN0aXZlJzogc2VsZWN0ZWRQcmVzZXQgPT09ICd5ZXN0ZXJkYXknIH1cIiBsYWJlbD1cIlllc3RlcmRheVwiPjwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHBSaXBwbGUgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0blwiIChjbGljayk9XCJhcHBseVByZXNldCgnbGFzdDdkYXlzJylcIiBbbmdDbGFzc109XCJ7ICdhY3RpdmUnOiBzZWxlY3RlZFByZXNldCA9PT0gJ2xhc3Q3ZGF5cycgfVwiIGxhYmVsPVwiTGFzdCA3IGRheXNcIj48L2J1dHRvbj5cbiAgICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBwUmlwcGxlIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG5cIiAoY2xpY2spPVwiYXBwbHlQcmVzZXQoJ2xhc3QzMGRheXMnKVwiIFtuZ0NsYXNzXT1cInsgJ2FjdGl2ZSc6IHNlbGVjdGVkUHJlc2V0ID09PSAnbGFzdDMwZGF5cycgfVwiIGxhYmVsPVwiTGFzdCAzMCBkYXlzXCI+PC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gcFJpcHBsZSB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuXCIgKGNsaWNrKT1cImFwcGx5UHJlc2V0KCdsYXN0M21vbnRocycpXCIgW25nQ2xhc3NdPVwieyAnYWN0aXZlJzogc2VsZWN0ZWRQcmVzZXQgPT09ICdsYXN0M21vbnRocycgfVwiIGxhYmVsPVwiTGFzdCAzIG1vbnRoc1wiPjwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHBSaXBwbGUgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0blwiIChjbGljayk9XCJhcHBseVByZXNldCgnbGFzdDZtb250aHMnKVwiIFtuZ0NsYXNzXT1cInsgJ2FjdGl2ZSc6IHNlbGVjdGVkUHJlc2V0ID09PSAnbGFzdDZtb250aHMnIH1cIiBsYWJlbD1cIkxhc3QgNiBtb250aHNcIj48L2J1dHRvbj5cbiAgICAgICAgICAgIDxhIGNsYXNzPVwicmVzZXQtbGlua1wiIChjbGljayk9XCJyZXNldEFuZENsb3NlKClcIj5SZXNldDwvYT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJvdmVybGF5LXJpZ2h0XCI+XG4gICAgICAgICAgPHAtY2FsZW5kYXIgWyhuZ01vZGVsKV09XCJtb2RlbERhdGVcIiBbc2VsZWN0aW9uTW9kZV09XCIncmFuZ2UnXCIgW2lubGluZV09XCJ0cnVlXCIgW2RhdGVGb3JtYXRdPVwiJ21tL2RkL3l5eXknXCIgW3Nob3dPdGhlck1vbnRoc109XCJ0cnVlXCIgW2xvY2FsZV09XCJlbkxvY2FsZVwiIFtzaG93SWNvbl09XCJmYWxzZVwiIFtzdHlsZUNsYXNzXT1cIidhdG9taXgtb3ZlcmxheS1jYWxlbmRhcidcIiAobmdNb2RlbENoYW5nZSk9XCJvbk1vZGVsQ2hhbmdlKCRldmVudClcIiAob25Nb250aENoYW5nZSk9XCJvbkNhbGVuZGFyVmlld0NoYW5nZWQoJGV2ZW50KVwiIChvblllYXJDaGFuZ2UpPVwib25DYWxlbmRhclZpZXdDaGFuZ2VkKCRldmVudClcIiBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIiBbbWF4RGF0ZV09XCJtYXhEYXRlXCIgW21pbkRhdGVdPVwibWluRGF0ZVwiPjwvcC1jYWxlbmRhcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L3Atb3ZlcmxheVBhbmVsPlxuICA8L25nLWNvbnRhaW5lcj5cblxuICA8bmctdGVtcGxhdGUgI2lubGluZUJsb2NrPlxuICAgIDxkaXYgW25nQ2xhc3NdPVwic3R5bGVDbGFzc1wiIGNsYXNzPVwiaW5wdXQtd3JhcHBlclwiPlxuICAgICAgPGlucHV0XG4gICAgICAgIHBJbnB1dFRleHRcbiAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICBbbmdDbGFzc109XCJpbnB1dFN0eWxlQ2xhc3NcIlxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxuICBbdmFsdWVdPVwiZ2V0RGF0ZVJhbmdlTGFiZWwoKVwiXG4gICAgICAgIHJlYWRvbmx5XG4gICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgIChrZXlkb3duKT1cIm9uSW5wdXRLZXlEb3duKCRldmVudClcIlxuICAgICAgLz5cbiAgICAgIDxpIGNsYXNzPVwicGkgcGktY2FsZW5kYXIgaW5wdXQtaWNvblwiIHRpdGxlPVwiT3BlbiBjYWxlbmRhclwiPjwvaT5cbiAgICAgIDxpICpuZ0lmPVwiaGFzU2VsZWN0aW9uXCIgY2xhc3M9XCJwaSBwaS10aW1lcyBpbnB1dC1jbGVhci1pY29uXCIgdGl0bGU9XCJDbGVhclwiIHRhYmluZGV4PVwiMFwiIChjbGljayk9XCJjbGVhckFuZFN0b3AoJGV2ZW50KVwiIChrZXlkb3duLmVudGVyKT1cImNsZWFyQW5kU3RvcCgkZXZlbnQpXCIgKGtleWRvd24uc3BhY2UpPVwiY2xlYXJBbmRTdG9wKCRldmVudClcIj48L2k+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm92ZXJsYXktaW5uZXIgaW5saW5lLWNhbGVuZGFyIGZsZXhcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJvdmVybGF5LWxlZnRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInByZXNldC1saXN0XCI+XG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHBSaXBwbGUgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0blwiIChjbGljayk9XCJhcHBseVByZXNldCgndG9kYXknKVwiIFtuZ0NsYXNzXT1cInsgJ2FjdGl2ZSc6IHNlbGVjdGVkUHJlc2V0ID09PSAndG9kYXknIH1cIiBsYWJlbD1cIlRvZGF5XCI+PC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHBSaXBwbGUgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0blwiIChjbGljayk9XCJhcHBseVByZXNldCgneWVzdGVyZGF5JylcIiBbbmdDbGFzc109XCJ7ICdhY3RpdmUnOiBzZWxlY3RlZFByZXNldCA9PT0gJ3llc3RlcmRheScgfVwiIGxhYmVsPVwiWWVzdGVyZGF5XCI+PC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHBSaXBwbGUgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0blwiIChjbGljayk9XCJhcHBseVByZXNldCgnbGFzdDdkYXlzJylcIiBbbmdDbGFzc109XCJ7ICdhY3RpdmUnOiBzZWxlY3RlZFByZXNldCA9PT0gJ2xhc3Q3ZGF5cycgfVwiIGxhYmVsPVwiTGFzdCA3IGRheXNcIj48L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uIHBCdXR0b24gcFJpcHBsZSB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJwcmVzZXQtYnRuXCIgKGNsaWNrKT1cImFwcGx5UHJlc2V0KCdsYXN0MzBkYXlzJylcIiBbbmdDbGFzc109XCJ7ICdhY3RpdmUnOiBzZWxlY3RlZFByZXNldCA9PT0gJ2xhc3QzMGRheXMnIH1cIiBsYWJlbD1cIkxhc3QgMzAgZGF5c1wiPjwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b24gcEJ1dHRvbiBwUmlwcGxlIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInByZXNldC1idG5cIiAoY2xpY2spPVwiYXBwbHlQcmVzZXQoJ2xhc3QzbW9udGhzJylcIiBbbmdDbGFzc109XCJ7ICdhY3RpdmUnOiBzZWxlY3RlZFByZXNldCA9PT0gJ2xhc3QzbW9udGhzJyB9XCIgbGFiZWw9XCJMYXN0IDMgbW9udGhzXCI+PC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHBSaXBwbGUgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicHJlc2V0LWJ0blwiIChjbGljayk9XCJhcHBseVByZXNldCgnbGFzdDZtb250aHMnKVwiIFtuZ0NsYXNzXT1cInsgJ2FjdGl2ZSc6IHNlbGVjdGVkUHJlc2V0ID09PSAnbGFzdDZtb250aHMnIH1cIiBsYWJlbD1cIkxhc3QgNiBtb250aHNcIj48L2J1dHRvbj5cbiAgICAgICAgICA8YSBjbGFzcz1cInJlc2V0LWxpbmtcIiAoY2xpY2spPVwicmVzZXRBbmRDbG9zZSgpXCI+UmVzZXQ8L2E+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJvdmVybGF5LXJpZ2h0XCI+XG4gIDxwLWNhbGVuZGFyIFsobmdNb2RlbCldPVwibW9kZWxEYXRlXCIgW3NlbGVjdGlvbk1vZGVdPVwiJ3JhbmdlJ1wiIFtpbmxpbmVdPVwidHJ1ZVwiIFtkYXRlRm9ybWF0XT1cIidtbS9kZC95eXl5J1wiIFtzaG93T3RoZXJNb250aHNdPVwidHJ1ZVwiIFtsb2NhbGVdPVwiZW5Mb2NhbGVcIiBbc2hvd0ljb25dPVwiZmFsc2VcIiBbc3R5bGVDbGFzc109XCInYXRvbWl4LW92ZXJsYXktY2FsZW5kYXInXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25Nb2RlbENoYW5nZSgkZXZlbnQpXCIgKG9uTW9udGhDaGFuZ2UpPVwib25DYWxlbmRhclZpZXdDaGFuZ2VkKCRldmVudClcIiAob25ZZWFyQ2hhbmdlKT1cIm9uQ2FsZW5kYXJWaWV3Q2hhbmdlZCgkZXZlbnQpXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgW21heERhdGVdPVwibWF4RGF0ZVwiIFttaW5EYXRlXT1cIm1pbkRhdGVcIj48L3AtY2FsZW5kYXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvZGl2PlxuIl19