nxt-pick-datetime 17.0.1 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +53 -53
  2. package/assets/picker.scss +673 -673
  3. package/fesm2022/nxt-pick-datetime-moment-adapter.mjs +23 -26
  4. package/fesm2022/nxt-pick-datetime-moment-adapter.mjs.map +1 -1
  5. package/fesm2022/nxt-pick-datetime-native-adapter.mjs +22 -24
  6. package/fesm2022/nxt-pick-datetime-native-adapter.mjs.map +1 -1
  7. package/fesm2022/nxt-pick-datetime.mjs +77 -75
  8. package/fesm2022/nxt-pick-datetime.mjs.map +1 -1
  9. package/lib/class/date-time.class.d.ts +1 -1
  10. package/moment-adapter/moment-adapter.module.d.ts +2 -0
  11. package/moment-adapter/public-api.d.ts +1 -1
  12. package/native-adapter/native-adapter.module.d.ts +2 -0
  13. package/native-adapter/public-api.d.ts +1 -1
  14. package/package.json +10 -15
  15. package/esm2022/lib/class/date-time-adapter.class.mjs +0 -97
  16. package/esm2022/lib/class/date-time-format.class.mjs +0 -4
  17. package/esm2022/lib/class/date-time.class.mjs +0 -95
  18. package/esm2022/lib/class/dialog-config.class.mjs +0 -47
  19. package/esm2022/lib/class/dialog-ref.class.mjs +0 -119
  20. package/esm2022/lib/date-time/calendar/calendar.component.mjs +0 -346
  21. package/esm2022/lib/date-time/calendar-body/calendar-body.component.mjs +0 -151
  22. package/esm2022/lib/date-time/calendar-month-view/calendar-month-view.component.mjs +0 -429
  23. package/esm2022/lib/date-time/calendar-multi-year-view/calendar-multi-year-view.component.mjs +0 -358
  24. package/esm2022/lib/date-time/calendar-year-view/calendar-year-view.component.mjs +0 -362
  25. package/esm2022/lib/date-time/date-time-inline/date-time-inline.component.mjs +0 -275
  26. package/esm2022/lib/date-time/date-time-picker/date-time-picker.component.mjs +0 -541
  27. package/esm2022/lib/date-time/date-time-picker-container/date-time-picker-container.animations.mjs +0 -19
  28. package/esm2022/lib/date-time/date-time-picker-container/date-time-picker-container.component.mjs +0 -389
  29. package/esm2022/lib/date-time/date-time-picker-input.directive.mjs +0 -618
  30. package/esm2022/lib/date-time/date-time-picker-intl.service.mjs +0 -61
  31. package/esm2022/lib/date-time/date-time-picker-trigger.directive.mjs +0 -70
  32. package/esm2022/lib/date-time/date-time.module.mjs +0 -96
  33. package/esm2022/lib/date-time/number-fixed-len.pipe.mjs +0 -22
  34. package/esm2022/lib/date-time/timer/timer.component.mjs +0 -299
  35. package/esm2022/lib/date-time/timer-box/timer-box.component.mjs +0 -95
  36. package/esm2022/lib/dialog/dialog-container/dialog-container.component.mjs +0 -248
  37. package/esm2022/lib/dialog/dialog.module.mjs +0 -42
  38. package/esm2022/lib/dialog/dialog.service.mjs +0 -251
  39. package/esm2022/lib/utils/object.mjs +0 -24
  40. package/esm2022/moment-adapter/date-time-adapter.class.mjs +0 -220
  41. package/esm2022/moment-adapter/date-time-format.class.mjs +0 -13
  42. package/esm2022/moment-adapter/moment-adapter.module.mjs +0 -37
  43. package/esm2022/moment-adapter/nxt-pick-datetime-moment-adapter.mjs +0 -5
  44. package/esm2022/moment-adapter/public-api.mjs +0 -3
  45. package/esm2022/native-adapter/date-time-adapter.class.mjs +0 -366
  46. package/esm2022/native-adapter/date-time-format.class.mjs +0 -13
  47. package/esm2022/native-adapter/native-adapter.module.mjs +0 -37
  48. package/esm2022/native-adapter/nxt-pick-datetime-native-adapter.mjs +0 -5
  49. package/esm2022/native-adapter/public-api.mjs +0 -2
  50. package/esm2022/nxt-pick-datetime.mjs +0 -5
  51. package/esm2022/public-api.mjs +0 -14
@@ -1,362 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, EventEmitter, HostBinding, Inject, Input, Output, ViewChild } from '@angular/core';
2
- import { NXT_DATE_TIME_FORMATS } from '../../class/date-time-format.class';
3
- import { CalendarCell, CalendarBodyComponent } from '../calendar-body/calendar-body.component';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "../../class/date-time-adapter.class";
6
- import * as i2 from "../calendar-body/calendar-body.component";
7
- /** @internal */
8
- const MONTHS_PER_YEAR = 12;
9
- /** @internal */
10
- const MONTHS_PER_ROW = 3;
11
- export class YearViewComponent {
12
- get selectMode() {
13
- return this._selectMode;
14
- }
15
- set selectMode(val) {
16
- this._selectMode = val;
17
- if (this.initiated) {
18
- this.generateMonthList();
19
- this.cdRef.markForCheck();
20
- }
21
- }
22
- get selected() {
23
- return this._selected;
24
- }
25
- set selected(value) {
26
- value = this.dateTimeAdapter.deserialize(value);
27
- this._selected = this.getValidDate(value);
28
- this.setSelectedMonths();
29
- }
30
- get selecteds() {
31
- return this._selecteds;
32
- }
33
- set selecteds(values) {
34
- this._selecteds = [];
35
- values.forEach(val => {
36
- const value = this.dateTimeAdapter.deserialize(val);
37
- this._selecteds.push(this.getValidDate(value));
38
- });
39
- this.setSelectedMonths();
40
- }
41
- get pickerMoment() {
42
- return this._pickerMoment;
43
- }
44
- set pickerMoment(value) {
45
- const oldMoment = this._pickerMoment;
46
- value = this.dateTimeAdapter.deserialize(value);
47
- this._pickerMoment =
48
- this.getValidDate(value) || this.dateTimeAdapter.now();
49
- if (!this.hasSameYear(oldMoment, this._pickerMoment) &&
50
- this.initiated) {
51
- this.generateMonthList();
52
- }
53
- }
54
- get dateTimeFilter() {
55
- return this._dateTimeFilter;
56
- }
57
- set dateTimeFilter(filter) {
58
- this._dateTimeFilter = filter;
59
- if (this.initiated) {
60
- this.generateMonthList();
61
- }
62
- }
63
- get min() {
64
- return this._minDate;
65
- }
66
- set min(value) {
67
- value = this.dateTimeAdapter.deserialize(value);
68
- this._minDate = this.getValidDate(value);
69
- if (this.initiated) {
70
- this.generateMonthList();
71
- }
72
- }
73
- get max() {
74
- return this._maxDate;
75
- }
76
- set max(value) {
77
- value = this.dateTimeAdapter.deserialize(value);
78
- this._maxDate = this.getValidDate(value);
79
- if (this.initiated) {
80
- this.generateMonthList();
81
- }
82
- }
83
- get months() {
84
- return this._months;
85
- }
86
- get activeCell() {
87
- if (this._pickerMoment) {
88
- return this.dateTimeAdapter.getMonth(this._pickerMoment);
89
- }
90
- return;
91
- }
92
- get isInSingleMode() {
93
- return this.selectMode === 'single';
94
- }
95
- get isInRangeMode() {
96
- return (this.selectMode === 'range' ||
97
- this.selectMode === 'rangeFrom' ||
98
- this.selectMode === 'rangeTo');
99
- }
100
- /** @internal */
101
- get calendarView() {
102
- return true;
103
- }
104
- constructor(cdRef, dateTimeAdapter, dateTimeFormats) {
105
- this.cdRef = cdRef;
106
- this.dateTimeAdapter = dateTimeAdapter;
107
- this.dateTimeFormats = dateTimeFormats;
108
- /**
109
- * The select mode of the picker;
110
- */
111
- this._selectMode = 'single';
112
- this._selecteds = new Array();
113
- this.initiated = false;
114
- /**
115
- * Callback to invoke when a new month is selected
116
- */
117
- this.change = new EventEmitter();
118
- /**
119
- * Emits the selected year
120
- *
121
- * This doesn't imply a change on the selected date.
122
- */
123
- this.monthSelected = new EventEmitter();
124
- /** Emits when any date is activated */
125
- this.pickerMomentChange = new EventEmitter();
126
- /** Emits when use keyboard enter to select a calendar cell */
127
- this.keyboardEnter = new EventEmitter();
128
- this.monthNames = this.dateTimeAdapter.getMonthNames('short');
129
- }
130
- ngOnInit() {
131
- this.localeSub = this.dateTimeAdapter.localeChanges.subscribe(() => {
132
- this.generateMonthList();
133
- this.cdRef.markForCheck();
134
- });
135
- }
136
- ngAfterContentInit() {
137
- this.generateMonthList();
138
- this.initiated = true;
139
- }
140
- ngOnDestroy() {
141
- this.localeSub?.unsubscribe();
142
- this.localeSub = undefined;
143
- }
144
- /**
145
- * Handle a calendarCell selected
146
- */
147
- selectCalendarCell(cell) {
148
- this.selectMonth(cell.value);
149
- }
150
- /**
151
- * Handle a new month selected
152
- */
153
- selectMonth(month) {
154
- const firstDateOfMonth = this.dateTimeAdapter.createDate(this.dateTimeAdapter.getYear(this.pickerMoment), month, 1);
155
- this.monthSelected.emit(firstDateOfMonth);
156
- const daysInMonth = this.dateTimeAdapter.getNumDaysInMonth(firstDateOfMonth);
157
- const result = this.dateTimeAdapter.createDate(this.dateTimeAdapter.getYear(this.pickerMoment), month, Math.min(daysInMonth, this.dateTimeAdapter.getDate(this.pickerMoment)), this.dateTimeAdapter.getHours(this.pickerMoment), this.dateTimeAdapter.getMinutes(this.pickerMoment), this.dateTimeAdapter.getSeconds(this.pickerMoment));
158
- this.change.emit(result);
159
- }
160
- /**
161
- * Handle keydown event on calendar body
162
- */
163
- handleCalendarKeydown(event) {
164
- let moment;
165
- switch (event.code.toLowerCase()) {
166
- // minus 1 month
167
- case 'arrowleft':
168
- moment = this.dateTimeAdapter.addCalendarMonths(this.pickerMoment, -1);
169
- this.pickerMomentChange.emit(moment);
170
- break;
171
- // add 1 month
172
- case 'arrowright':
173
- moment = this.dateTimeAdapter.addCalendarMonths(this.pickerMoment, 1);
174
- this.pickerMomentChange.emit(moment);
175
- break;
176
- // minus 3 months
177
- case 'arrowup':
178
- moment = this.dateTimeAdapter.addCalendarMonths(this.pickerMoment, -3);
179
- this.pickerMomentChange.emit(moment);
180
- break;
181
- // add 3 months
182
- case 'arrowdown':
183
- moment = this.dateTimeAdapter.addCalendarMonths(this.pickerMoment, 3);
184
- this.pickerMomentChange.emit(moment);
185
- break;
186
- // move to first month of current year
187
- case 'home':
188
- moment = this.dateTimeAdapter.addCalendarMonths(this.pickerMoment, -this.dateTimeAdapter.getMonth(this.pickerMoment));
189
- this.pickerMomentChange.emit(moment);
190
- break;
191
- // move to last month of current year
192
- case 'end':
193
- moment = this.dateTimeAdapter.addCalendarMonths(this.pickerMoment, 11 - this.dateTimeAdapter.getMonth(this.pickerMoment));
194
- this.pickerMomentChange.emit(moment);
195
- break;
196
- // minus 1 year (or 10 year)
197
- case 'pageup':
198
- moment = this.dateTimeAdapter.addCalendarYears(this.pickerMoment, event.altKey ? -10 : -1);
199
- this.pickerMomentChange.emit(moment);
200
- break;
201
- // add 1 year (or 10 year)
202
- case 'pagedown':
203
- moment = this.dateTimeAdapter.addCalendarYears(this.pickerMoment, event.altKey ? 10 : 1);
204
- this.pickerMomentChange.emit(moment);
205
- break;
206
- // Select current month
207
- case 'enter':
208
- this.selectMonth(this.dateTimeAdapter.getMonth(this.pickerMoment));
209
- this.keyboardEnter.emit();
210
- break;
211
- default:
212
- return;
213
- }
214
- this.focusActiveCell();
215
- event.preventDefault();
216
- }
217
- /**
218
- * Generate the calendar month list
219
- */
220
- generateMonthList() {
221
- if (!this.pickerMoment) {
222
- return;
223
- }
224
- this.setSelectedMonths();
225
- this.todayMonth = this.getMonthInCurrentYear(this.dateTimeAdapter.now());
226
- this._months = [];
227
- for (let i = 0; i < MONTHS_PER_YEAR / MONTHS_PER_ROW; i++) {
228
- const row = [];
229
- for (let j = 0; j < MONTHS_PER_ROW; j++) {
230
- const month = j + i * MONTHS_PER_ROW;
231
- const monthCell = this.createMonthCell(month);
232
- row.push(monthCell);
233
- }
234
- this._months.push(row);
235
- }
236
- return;
237
- }
238
- /**
239
- * Creates an CalendarCell for the given month.
240
- */
241
- createMonthCell(month) {
242
- const startDateOfMonth = this.dateTimeAdapter.createDate(this.dateTimeAdapter.getYear(this.pickerMoment), month, 1);
243
- const ariaLabel = this.dateTimeAdapter.format(startDateOfMonth, this.dateTimeFormats.monthYearA11yLabel);
244
- const cellClass = 'nxt-dt-month-' + month;
245
- return new CalendarCell(month, this.monthNames[month], ariaLabel, this.isMonthEnabled(month), false, cellClass);
246
- }
247
- /**
248
- * Check if the given month is enable
249
- */
250
- isMonthEnabled(month) {
251
- const firstDateOfMonth = this.dateTimeAdapter.createDate(this.dateTimeAdapter.getYear(this.pickerMoment), month, 1);
252
- // If any date in the month is selectable,
253
- // we count the month as enable
254
- for (let date = firstDateOfMonth; this.dateTimeAdapter.getMonth(date) === month; date = this.dateTimeAdapter.addCalendarDays(date, 1)) {
255
- if (!!date &&
256
- (!this.dateTimeFilter || this.dateTimeFilter(date, 'month')) &&
257
- (!this.min ||
258
- this.dateTimeAdapter.compare(date, this.min) >= 0) &&
259
- (!this.max ||
260
- this.dateTimeAdapter.compare(date, this.max) <= 0)) {
261
- return true;
262
- }
263
- }
264
- return false;
265
- }
266
- /**
267
- * Gets the month in this year that the given Date falls on.
268
- * Returns undefined if the given Date is in another year.
269
- */
270
- getMonthInCurrentYear(date) {
271
- if (this.getValidDate(date) && this.getValidDate(this._pickerMoment)) {
272
- const result = this.dateTimeAdapter.compareYear(date, this._pickerMoment);
273
- // < 0 : the given date's year is before pickerMoment's year, we return -1 as selected month value.
274
- // > 0 : the given date's year is after pickerMoment's year, we return 12 as selected month value.
275
- // 0 : the give date's year is same as the pickerMoment's year, we return the actual month value.
276
- if (result < 0) {
277
- return -1;
278
- }
279
- else if (result > 0) {
280
- return 12;
281
- }
282
- else {
283
- return this.dateTimeAdapter.getMonth(date);
284
- }
285
- }
286
- return;
287
- }
288
- /**
289
- * Set the selectedMonths value
290
- * In single mode, it has only one value which represent the month the selected date in
291
- * In range mode, it would has two values, one for the month the fromValue in and the other for the month the toValue in
292
- */
293
- setSelectedMonths() {
294
- this.selectedMonths = [];
295
- if (this.isInSingleMode && this.selected) {
296
- this.selectedMonths[0] = this.getMonthInCurrentYear(this.selected);
297
- }
298
- if (this.isInRangeMode && this.selecteds) {
299
- this.selectedMonths[0] = this.getMonthInCurrentYear(this.selecteds[0]);
300
- this.selectedMonths[1] = this.getMonthInCurrentYear(this.selecteds[1]);
301
- }
302
- }
303
- /**
304
- * Check the given dates are in the same year
305
- */
306
- hasSameYear(dateLeft, dateRight) {
307
- return !!(dateLeft &&
308
- dateRight &&
309
- this.dateTimeAdapter.getYear(dateLeft) ===
310
- this.dateTimeAdapter.getYear(dateRight));
311
- }
312
- /**
313
- * Get a valid date object
314
- */
315
- getValidDate(obj) {
316
- return this.dateTimeAdapter.isDateInstance(obj) &&
317
- this.dateTimeAdapter.isValid(obj)
318
- ? obj
319
- : undefined;
320
- }
321
- focusActiveCell() {
322
- this.calendarBodyElm?.focusActiveCell();
323
- }
324
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: YearViewComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.DateTimeAdapter }, { token: NXT_DATE_TIME_FORMATS }], target: i0.ɵɵFactoryTarget.Component }); }
325
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.4", type: YearViewComponent, selector: "nxt-date-time-year-view", inputs: { selectMode: "selectMode", selected: "selected", selecteds: "selecteds", pickerMoment: "pickerMoment", dateTimeFilter: "dateTimeFilter", min: "min", max: "max" }, outputs: { change: "change", monthSelected: "monthSelected", pickerMomentChange: "pickerMomentChange", keyboardEnter: "keyboardEnter" }, host: { properties: { "class.nxt-dt-calendar-view": "this.calendarView" } }, viewQueries: [{ propertyName: "calendarBodyElm", first: true, predicate: CalendarBodyComponent, descendants: true, static: true }], ngImport: i0, template: "<table class=\"nxt-dt-calendar-table nxt-dt-calendar-year-table\">\n <thead class=\"nxt-dt-calendar-header\">\n <tr>\n <th class=\"nxt-dt-calendar-table-divider\"\n aria-hidden=\"true\"\n colspan=\"3\"></th>\n </tr>\n </thead>\n <tbody nxtDateTimeCalendarBody\n role=\"grid\"\n [rows]=\"months\"\n [numCols]=\"3\"\n [cellRatio]=\"3 / 7\"\n [activeCell]=\"activeCell ?? 0\"\n [todayValue]=\"todayMonth??undefined\"\n [selectedValues]=\"selectedMonths\"\n [selectMode]=\"selectMode\"\n (keydown)=\"handleCalendarKeydown($event)\"\n (select)=\"selectCalendarCell($event)\">\n </tbody>\n</table>\n", styles: [""], dependencies: [{ kind: "component", type: i2.CalendarBodyComponent, selector: "[nxtDateTimeCalendarBody]", inputs: ["activeCell", "rows", "numCols", "cellRatio", "todayValue", "selectedValues", "selectMode"], outputs: ["select"], exportAs: ["nxtDateTimeCalendarBody"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
326
- }
327
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: YearViewComponent, decorators: [{
328
- type: Component,
329
- args: [{ selector: 'nxt-date-time-year-view', preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<table class=\"nxt-dt-calendar-table nxt-dt-calendar-year-table\">\n <thead class=\"nxt-dt-calendar-header\">\n <tr>\n <th class=\"nxt-dt-calendar-table-divider\"\n aria-hidden=\"true\"\n colspan=\"3\"></th>\n </tr>\n </thead>\n <tbody nxtDateTimeCalendarBody\n role=\"grid\"\n [rows]=\"months\"\n [numCols]=\"3\"\n [cellRatio]=\"3 / 7\"\n [activeCell]=\"activeCell ?? 0\"\n [todayValue]=\"todayMonth??undefined\"\n [selectedValues]=\"selectedMonths\"\n [selectMode]=\"selectMode\"\n (keydown)=\"handleCalendarKeydown($event)\"\n (select)=\"selectCalendarCell($event)\">\n </tbody>\n</table>\n" }]
330
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.DateTimeAdapter }, { type: undefined, decorators: [{
331
- type: Inject,
332
- args: [NXT_DATE_TIME_FORMATS]
333
- }] }], propDecorators: { selectMode: [{
334
- type: Input
335
- }], selected: [{
336
- type: Input
337
- }], selecteds: [{
338
- type: Input
339
- }], pickerMoment: [{
340
- type: Input
341
- }], dateTimeFilter: [{
342
- type: Input
343
- }], min: [{
344
- type: Input
345
- }], max: [{
346
- type: Input
347
- }], change: [{
348
- type: Output
349
- }], monthSelected: [{
350
- type: Output
351
- }], pickerMomentChange: [{
352
- type: Output
353
- }], keyboardEnter: [{
354
- type: Output
355
- }], calendarBodyElm: [{
356
- type: ViewChild,
357
- args: [CalendarBodyComponent, { static: true }]
358
- }], calendarView: [{
359
- type: HostBinding,
360
- args: ['class.nxt-dt-calendar-view']
361
- }] } });
362
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIteWVhci12aWV3LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3BpY2stZGF0ZXRpbWUvc3JjL2xpYi9kYXRlLXRpbWUvY2FsZW5kYXIteWVhci12aWV3L2NhbGVuZGFyLXllYXItdmlldy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9waWNrLWRhdGV0aW1lL3NyYy9saWIvZGF0ZS10aW1lL2NhbGVuZGFyLXllYXItdmlldy9jYWxlbmRhci15ZWFyLXZpZXcuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQix1QkFBdUIsRUFBcUIsU0FBUyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUd2TCxPQUFPLEVBQW1CLHFCQUFxQixFQUFFLE1BQU0sb0NBQW9DLENBQUE7QUFFM0YsT0FBTyxFQUFFLFlBQVksRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBDQUEwQyxDQUFBOzs7O0FBRTlGLGdCQUFnQjtBQUNoQixNQUFNLGVBQWUsR0FBRyxFQUFFLENBQUE7QUFFMUIsZ0JBQWdCO0FBQ2hCLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQTtBQVN4QixNQUFNLE9BQU8saUJBQWlCO0lBSzFCLElBQ0ksVUFBVTtRQUNWLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQTtJQUMzQixDQUFDO0lBRUQsSUFBSSxVQUFVLENBQUMsR0FBZTtRQUMxQixJQUFJLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQTtRQUN0QixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUE7WUFDeEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQTtTQUM1QjtJQUNMLENBQUM7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LENBQUMsR0FBUTtRQUN6QixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQztZQUMzQyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDakMsQ0FBQyxDQUFDLEdBQUc7WUFDTCxDQUFDLENBQUMsU0FBUyxDQUFBO0lBQ25CLENBQUM7SUFFTyxlQUFlO1FBQ25CLElBQUksQ0FBQyxlQUFlLEVBQUUsZUFBZSxFQUFFLENBQUE7SUFDM0MsQ0FBQzs4R0EvZVEsaUJBQWlCLGtGQTJMZCxxQkFBcUI7a0dBM0x4QixpQkFBaUIsa2ZBK0tmLHFCQUFxQiw4RENuTXBDLDR0QkFxQkE7OzJGRERhLGlCQUFpQjtrQkFQN0IsU0FBUzsrQkFDSSx5QkFBeUIsdUJBR2QsS0FBSyxtQkFDVCx1QkFBdUIsQ0FBQyxNQUFNOzswQkE2TDFDLE1BQU07MkJBQUMscUJBQXFCO3lDQXJMN0IsVUFBVTtzQkFEYixLQUFLO2dCQWdCRixRQUFRO3NCQURYLEtBQUs7Z0JBYUYsU0FBUztzQkFEWixLQUFLO2dCQWlCRixZQUFZO3NCQURmLEtBQUs7Z0JBd0JGLGNBQWM7c0JBRGpCLEtBQUs7Z0JBZUYsR0FBRztzQkFETixLQUFLO2dCQWdCRixHQUFHO3NCQUROLEtBQUs7Z0JBd0RHLE1BQU07c0JBRmQsTUFBTTtnQkFVRSxhQUFhO3NCQURyQixNQUFNO2dCQUtFLGtCQUFrQjtzQkFEMUIsTUFBTTtnQkFLRSxhQUFhO3NCQURyQixNQUFNO2dCQUtDLGVBQWU7c0JBRHRCLFNBQVM7dUJBQUMscUJBQXFCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUs5QyxZQUFZO3NCQURmLFdBQVc7dUJBQUMsNEJBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJDb250ZW50SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSG9zdEJpbmRpbmcsIEluamVjdCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJ1xuaW1wb3J0IHsgRGF0ZVRpbWVBZGFwdGVyIH0gZnJvbSAnLi4vLi4vY2xhc3MvZGF0ZS10aW1lLWFkYXB0ZXIuY2xhc3MnXG5pbXBvcnQgeyBEYXRlVGltZUZvcm1hdHMsIE5YVF9EQVRFX1RJTUVfRk9STUFUUyB9IGZyb20gJy4uLy4uL2NsYXNzL2RhdGUtdGltZS1mb3JtYXQuY2xhc3MnXG5pbXBvcnQgeyBEYXRlRmlsdGVyLCBTZWxlY3RNb2RlIH0gZnJvbSAnLi4vLi4vY2xhc3MvZGF0ZS10aW1lLmNsYXNzJ1xuaW1wb3J0IHsgQ2FsZW5kYXJDZWxsLCBDYWxlbmRhckJvZHlDb21wb25lbnQgfSBmcm9tICcuLi9jYWxlbmRhci1ib2R5L2NhbGVuZGFyLWJvZHkuY29tcG9uZW50J1xuXG4vKiogQGludGVybmFsICovXG5jb25zdCBNT05USFNfUEVSX1lFQVIgPSAxMlxuXG4vKiogQGludGVybmFsICovXG5jb25zdCBNT05USFNfUEVSX1JPVyA9IDNcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdueHQtZGF0ZS10aW1lLXllYXItdmlldycsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLXllYXItdmlldy5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vY2FsZW5kYXIteWVhci12aWV3LmNvbXBvbmVudC5zY3NzJ10sXG4gICAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgWWVhclZpZXdDb21wb25lbnQ8VD4gaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gICAgLyoqXG4gICAgICogVGhlIHNlbGVjdCBtb2RlIG9mIHRoZSBwaWNrZXI7XG4gICAgICovXG4gICAgcHJpdmF0ZSBfc2VsZWN0TW9kZTogU2VsZWN0TW9kZSA9ICdzaW5nbGUnXG4gICAgQElucHV0KClcbiAgICBnZXQgc2VsZWN0TW9kZSgpOiBTZWxlY3RNb2RlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlbGVjdE1vZGVcbiAgICB9XG5cbiAgICBzZXQgc2VsZWN0TW9kZSh2YWw6IFNlbGVjdE1vZGUpIHtcbiAgICAgICAgdGhpcy5fc2VsZWN0TW9kZSA9IHZhbFxuICAgICAgICBpZiAodGhpcy5pbml0aWF0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVNb250aExpc3QoKVxuICAgICAgICAgICAgdGhpcy5jZFJlZi5tYXJrRm9yQ2hlY2soKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZGF0ZSAqL1xuICAgIHByaXZhdGUgX3NlbGVjdGVkPzogVFxuICAgIEBJbnB1dCgpXG4gICAgZ2V0IHNlbGVjdGVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRcbiAgICB9XG5cbiAgICBzZXQgc2VsZWN0ZWQodmFsdWU6IFQgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5kZXNlcmlhbGl6ZSh2YWx1ZSlcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWQgPSB0aGlzLmdldFZhbGlkRGF0ZSh2YWx1ZSlcbiAgICAgICAgdGhpcy5zZXRTZWxlY3RlZE1vbnRocygpXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfc2VsZWN0ZWRzID0gbmV3IEFycmF5PFQgfCB1bmRlZmluZWQ+KClcbiAgICBASW5wdXQoKVxuICAgIGdldCBzZWxlY3RlZHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZWxlY3RlZHNcbiAgICB9XG5cbiAgICBzZXQgc2VsZWN0ZWRzKHZhbHVlczogQXJyYXk8VCB8IHVuZGVmaW5lZD4pIHtcbiAgICAgICAgdGhpcy5fc2VsZWN0ZWRzID0gW11cbiAgICAgICAgdmFsdWVzLmZvckVhY2godmFsID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuZGVzZXJpYWxpemUodmFsKVxuICAgICAgICAgICAgdGhpcy5fc2VsZWN0ZWRzIS5wdXNoKHRoaXMuZ2V0VmFsaWREYXRlKHZhbHVlKSlcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLnNldFNlbGVjdGVkTW9udGhzKClcbiAgICB9XG5cbiAgICBwcml2YXRlIF9waWNrZXJNb21lbnQ/OiBUXG4gICAgQElucHV0KClcbiAgICBnZXQgcGlja2VyTW9tZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGlja2VyTW9tZW50XG4gICAgfVxuXG4gICAgc2V0IHBpY2tlck1vbWVudCh2YWx1ZTogVCB8IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBvbGRNb21lbnQgPSB0aGlzLl9waWNrZXJNb21lbnRcbiAgICAgICAgdmFsdWUgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5kZXNlcmlhbGl6ZSh2YWx1ZSlcbiAgICAgICAgdGhpcy5fcGlja2VyTW9tZW50ID1cbiAgICAgICAgICAgIHRoaXMuZ2V0VmFsaWREYXRlKHZhbHVlKSB8fCB0aGlzLmRhdGVUaW1lQWRhcHRlci5ub3coKVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLmhhc1NhbWVZZWFyKG9sZE1vbWVudCwgdGhpcy5fcGlja2VyTW9tZW50KSAmJlxuICAgICAgICAgICAgdGhpcy5pbml0aWF0ZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlTW9udGhMaXN0KClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgZnVuY3Rpb24gdXNlZCB0byBmaWx0ZXIgd2hpY2ggZGF0ZXMgYXJlIHNlbGVjdGFibGVcbiAgICAgKi9cbiAgICBwcml2YXRlIF9kYXRlVGltZUZpbHRlcj86IERhdGVGaWx0ZXI8VD5cbiAgICBASW5wdXQoKVxuICAgIGdldCBkYXRlVGltZUZpbHRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RhdGVUaW1lRmlsdGVyXG4gICAgfVxuXG4gICAgc2V0IGRhdGVUaW1lRmlsdGVyKGZpbHRlcjogRGF0ZUZpbHRlcjxUPiB8IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9kYXRlVGltZUZpbHRlciA9IGZpbHRlclxuICAgICAgICBpZiAodGhpcy5pbml0aWF0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVNb250aExpc3QoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFRoZSBtaW5pbXVtIHNlbGVjdGFibGUgZGF0ZSAqL1xuICAgIHByaXZhdGUgX21pbkRhdGU/OiBUXG4gICAgQElucHV0KClcbiAgICBnZXQgbWluKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWluRGF0ZVxuICAgIH1cblxuICAgIHNldCBtaW4odmFsdWU6IFQgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5kZXNlcmlhbGl6ZSh2YWx1ZSlcbiAgICAgICAgdGhpcy5fbWluRGF0ZSA9IHRoaXMuZ2V0VmFsaWREYXRlKHZhbHVlKVxuICAgICAgICBpZiAodGhpcy5pbml0aWF0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVNb250aExpc3QoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFRoZSBtYXhpbXVtIHNlbGVjdGFibGUgZGF0ZSAqL1xuICAgIHByaXZhdGUgX21heERhdGU/OiBUXG4gICAgQElucHV0KClcbiAgICBnZXQgbWF4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWF4RGF0ZVxuICAgIH1cblxuICAgIHNldCBtYXgodmFsdWU6IFQgfCB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsdWUgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5kZXNlcmlhbGl6ZSh2YWx1ZSlcbiAgICAgICAgdGhpcy5fbWF4RGF0ZSA9IHRoaXMuZ2V0VmFsaWREYXRlKHZhbHVlKVxuICAgICAgICBpZiAodGhpcy5pbml0aWF0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVNb250aExpc3QoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZWFkb25seSBtb250aE5hbWVzOiBzdHJpbmdbXVxuXG4gICAgcHJpdmF0ZSBfbW9udGhzPzogQ2FsZW5kYXJDZWxsW11bXVxuICAgIGdldCBtb250aHMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tb250aHNcbiAgICB9XG5cbiAgICBnZXQgYWN0aXZlQ2VsbCgpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICAgICAgICBpZiAodGhpcy5fcGlja2VyTW9tZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0TW9udGgodGhpcy5fcGlja2VyTW9tZW50KVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGdldCBpc0luU2luZ2xlTW9kZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0TW9kZSA9PT0gJ3NpbmdsZSdcbiAgICB9XG5cbiAgICBnZXQgaXNJblJhbmdlTW9kZSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0TW9kZSA9PT0gJ3JhbmdlJyB8fFxuICAgICAgICAgICAgdGhpcy5zZWxlY3RNb2RlID09PSAncmFuZ2VGcm9tJyB8fFxuICAgICAgICAgICAgdGhpcy5zZWxlY3RNb2RlID09PSAncmFuZ2VUbydcbiAgICAgICAgKVxuICAgIH1cblxuICAgIHByaXZhdGUgbG9jYWxlU3ViPzogU3Vic2NyaXB0aW9uXG5cbiAgICBwcml2YXRlIGluaXRpYXRlZCA9IGZhbHNlXG5cbiAgICB0b2RheU1vbnRoPzogbnVtYmVyXG5cbiAgICAvKipcbiAgICAgKiBBbiBhcnJheSB0byBob2xkIGFsbCBzZWxlY3RlZERhdGVzJyBtb250aCB2YWx1ZVxuICAgICAqIHRoZSB2YWx1ZSBpcyB0aGUgbW9udGggbnVtYmVyIGluIGN1cnJlbnQgeWVhclxuICAgICAqL1xuICAgIHNlbGVjdGVkTW9udGhzPzogQXJyYXk8bnVtYmVyIHwgdW5kZWZpbmVkPlxuXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgdG8gaW52b2tlIHdoZW4gYSBuZXcgbW9udGggaXMgc2VsZWN0ZWRcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLW91dHB1dC1uYXRpdmVcbiAgICByZWFkb25seSBjaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFQ+KClcblxuICAgIC8qKlxuICAgICAqIEVtaXRzIHRoZSBzZWxlY3RlZCB5ZWFyXG4gICAgICpcbiAgICAgKiBUaGlzIGRvZXNuJ3QgaW1wbHkgYSBjaGFuZ2Ugb24gdGhlIHNlbGVjdGVkIGRhdGUuXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcmVhZG9ubHkgbW9udGhTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8VD4oKVxuXG4gICAgLyoqIEVtaXRzIHdoZW4gYW55IGRhdGUgaXMgYWN0aXZhdGVkICovXG4gICAgQE91dHB1dCgpXG4gICAgcmVhZG9ubHkgcGlja2VyTW9tZW50Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxUPigpXG5cbiAgICAvKiogRW1pdHMgd2hlbiB1c2Uga2V5Ym9hcmQgZW50ZXIgdG8gc2VsZWN0IGEgY2FsZW5kYXIgY2VsbCAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHJlYWRvbmx5IGtleWJvYXJkRW50ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KClcblxuICAgIC8qKiBUaGUgYm9keSBvZiBjYWxlbmRhciB0YWJsZSAqL1xuICAgIEBWaWV3Q2hpbGQoQ2FsZW5kYXJCb2R5Q29tcG9uZW50LCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHByaXZhdGUgY2FsZW5kYXJCb2R5RWxtPzogQ2FsZW5kYXJCb2R5Q29tcG9uZW50XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5ueHQtZHQtY2FsZW5kYXItdmlldycpXG4gICAgZ2V0IGNhbGVuZGFyVmlldygpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZGF0ZVRpbWVBZGFwdGVyOiBEYXRlVGltZUFkYXB0ZXI8VD4sXG4gICAgICAgIEBJbmplY3QoTlhUX0RBVEVfVElNRV9GT1JNQVRTKVxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGRhdGVUaW1lRm9ybWF0czogRGF0ZVRpbWVGb3JtYXRzXG4gICAgKSB7XG4gICAgICAgIHRoaXMubW9udGhOYW1lcyA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmdldE1vbnRoTmFtZXMoJ3Nob3J0JylcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpIHtcbiAgICAgICAgdGhpcy5sb2NhbGVTdWIgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5sb2NhbGVDaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlTW9udGhMaXN0KClcbiAgICAgICAgICAgIHRoaXMuY2RSZWYubWFya0ZvckNoZWNrKClcbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZ2VuZXJhdGVNb250aExpc3QoKVxuICAgICAgICB0aGlzLmluaXRpYXRlZCA9IHRydWVcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5sb2NhbGVTdWI/LnVuc3Vic2NyaWJlKClcbiAgICAgICAgdGhpcy5sb2NhbGVTdWIgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgYSBjYWxlbmRhckNlbGwgc2VsZWN0ZWRcbiAgICAgKi9cbiAgICBzZWxlY3RDYWxlbmRhckNlbGwoY2VsbDogQ2FsZW5kYXJDZWxsKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VsZWN0TW9udGgoY2VsbC52YWx1ZSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGUgYSBuZXcgbW9udGggc2VsZWN0ZWRcbiAgICAgKi9cbiAgICBwcml2YXRlIHNlbGVjdE1vbnRoKG1vbnRoOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZmlyc3REYXRlT2ZNb250aCA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmNyZWF0ZURhdGUoXG4gICAgICAgICAgICB0aGlzLmRhdGVUaW1lQWRhcHRlci5nZXRZZWFyKHRoaXMucGlja2VyTW9tZW50KSxcbiAgICAgICAgICAgIG1vbnRoLFxuICAgICAgICAgICAgMVxuICAgICAgICApXG5cbiAgICAgICAgdGhpcy5tb250aFNlbGVjdGVkLmVtaXQoZmlyc3REYXRlT2ZNb250aClcblxuICAgICAgICBjb25zdCBkYXlzSW5Nb250aCA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmdldE51bURheXNJbk1vbnRoKFxuICAgICAgICAgICAgZmlyc3REYXRlT2ZNb250aFxuICAgICAgICApXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmNyZWF0ZURhdGUoXG4gICAgICAgICAgICB0aGlzLmRhdGVUaW1lQWRhcHRlci5nZXRZZWFyKHRoaXMucGlja2VyTW9tZW50KSxcbiAgICAgICAgICAgIG1vbnRoLFxuICAgICAgICAgICAgTWF0aC5taW4oXG4gICAgICAgICAgICAgICAgZGF5c0luTW9udGgsXG4gICAgICAgICAgICAgICAgdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0RGF0ZSh0aGlzLnBpY2tlck1vbWVudClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB0aGlzLmRhdGVUaW1lQWRhcHRlci5nZXRIb3Vycyh0aGlzLnBpY2tlck1vbWVudCksXG4gICAgICAgICAgICB0aGlzLmRhdGVUaW1lQWRhcHRlci5nZXRNaW51dGVzKHRoaXMucGlja2VyTW9tZW50KSxcbiAgICAgICAgICAgIHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmdldFNlY29uZHModGhpcy5waWNrZXJNb21lbnQpXG4gICAgICAgIClcblxuICAgICAgICB0aGlzLmNoYW5nZS5lbWl0KHJlc3VsdClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGUga2V5ZG93biBldmVudCBvbiBjYWxlbmRhciBib2R5XG4gICAgICovXG4gICAgaGFuZGxlQ2FsZW5kYXJLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgICAgIGxldCBtb21lbnRcbiAgICAgICAgc3dpdGNoIChldmVudC5jb2RlLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgICAgIC8vIG1pbnVzIDEgbW9udGhcbiAgICAgICAgICAgIGNhc2UgJ2Fycm93bGVmdCc6XG4gICAgICAgICAgICAgICAgbW9tZW50ID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuYWRkQ2FsZW5kYXJNb250aHMoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGlja2VyTW9tZW50LFxuICAgICAgICAgICAgICAgICAgICAtMVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB0aGlzLnBpY2tlck1vbWVudENoYW5nZS5lbWl0KG1vbWVudClcbiAgICAgICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgICAvLyBhZGQgMSBtb250aFxuICAgICAgICAgICAgY2FzZSAnYXJyb3dyaWdodCc6XG4gICAgICAgICAgICAgICAgbW9tZW50ID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuYWRkQ2FsZW5kYXJNb250aHMoXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGlja2VyTW9tZW50LFxuICAgICAgICAgICAgICAgICAgICAxXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIHRoaXMucGlja2VyTW9tZW50Q2hhbmdlLmVtaXQobW9tZW50KVxuICAgICAgICAgICAgICAgIGJyZWFrXG5cbiAgICAgICAgICAgIC8vIG1pbnVzIDMgbW9udGhzXG4gICAgICAgICAgICBjYXNlICdhcnJvd3VwJzpcbiAgICAgICAgICAgICAgICBtb21lbnQgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5hZGRDYWxlbmRhck1vbnRocyhcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5waWNrZXJNb21lbnQsXG4gICAgICAgICAgICAgICAgICAgIC0zXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIHRoaXMucGlja2VyTW9tZW50Q2hhbmdlLmVtaXQobW9tZW50KVxuICAgICAgICAgICAgICAgIGJyZWFrXG5cbiAgICAgICAgICAgIC8vIGFkZCAzIG1vbnRoc1xuICAgICAgICAgICAgY2FzZSAnYXJyb3dkb3duJzpcbiAgICAgICAgICAgICAgICBtb21lbnQgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5hZGRDYWxlbmRhck1vbnRocyhcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5waWNrZXJNb21lbnQsXG4gICAgICAgICAgICAgICAgICAgIDNcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgdGhpcy5waWNrZXJNb21lbnRDaGFuZ2UuZW1pdChtb21lbnQpXG4gICAgICAgICAgICAgICAgYnJlYWtcblxuICAgICAgICAgICAgLy8gbW92ZSB0byBmaXJzdCBtb250aCBvZiBjdXJyZW50IHllYXJcbiAgICAgICAgICAgIGNhc2UgJ2hvbWUnOlxuICAgICAgICAgICAgICAgIG1vbWVudCA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmFkZENhbGVuZGFyTW9udGhzKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBpY2tlck1vbWVudCxcbiAgICAgICAgICAgICAgICAgICAgLXRoaXMuZGF0ZVRpbWVBZGFwdGVyLmdldE1vbnRoKHRoaXMucGlja2VyTW9tZW50KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB0aGlzLnBpY2tlck1vbWVudENoYW5nZS5lbWl0KG1vbWVudClcbiAgICAgICAgICAgICAgICBicmVha1xuXG4gICAgICAgICAgICAvLyBtb3ZlIHRvIGxhc3QgbW9udGggb2YgY3VycmVudCB5ZWFyXG4gICAgICAgICAgICBjYXNlICdlbmQnOlxuICAgICAgICAgICAgICAgIG1vbWVudCA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmFkZENhbGVuZGFyTW9udGhzKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBpY2tlck1vbWVudCxcbiAgICAgICAgICAgICAgICAgICAgMTEgLSB0aGlzLmRhdGVUaW1lQWRhcHRlci5nZXRNb250aCh0aGlzLnBpY2tlck1vbWVudClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgdGhpcy5waWNrZXJNb21lbnRDaGFuZ2UuZW1pdChtb21lbnQpXG4gICAgICAgICAgICAgICAgYnJlYWtcblxuICAgICAgICAgICAgLy8gbWludXMgMSB5ZWFyIChvciAxMCB5ZWFyKVxuICAgICAgICAgICAgY2FzZSAncGFnZXVwJzpcbiAgICAgICAgICAgICAgICBtb21lbnQgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5hZGRDYWxlbmRhclllYXJzKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBpY2tlck1vbWVudCxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuYWx0S2V5ID8gLTEwIDogLTFcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgdGhpcy5waWNrZXJNb21lbnRDaGFuZ2UuZW1pdChtb21lbnQpXG4gICAgICAgICAgICAgICAgYnJlYWtcblxuICAgICAgICAgICAgLy8gYWRkIDEgeWVhciAob3IgMTAgeWVhcilcbiAgICAgICAgICAgIGNhc2UgJ3BhZ2Vkb3duJzpcbiAgICAgICAgICAgICAgICBtb21lbnQgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5hZGRDYWxlbmRhclllYXJzKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBpY2tlck1vbWVudCxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQuYWx0S2V5ID8gMTAgOiAxXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIHRoaXMucGlja2VyTW9tZW50Q2hhbmdlLmVtaXQobW9tZW50KVxuICAgICAgICAgICAgICAgIGJyZWFrXG5cbiAgICAgICAgICAgIC8vIFNlbGVjdCBjdXJyZW50IG1vbnRoXG4gICAgICAgICAgICBjYXNlICdlbnRlcic6XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RNb250aChcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0TW9udGgodGhpcy5waWNrZXJNb21lbnQpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIHRoaXMua2V5Ym9hcmRFbnRlci5lbWl0KClcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm9jdXNBY3RpdmVDZWxsKClcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdlbmVyYXRlIHRoZSBjYWxlbmRhciBtb250aCBsaXN0XG4gICAgICovXG4gICAgcHJpdmF0ZSBnZW5lcmF0ZU1vbnRoTGlzdCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLnBpY2tlck1vbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFNlbGVjdGVkTW9udGhzKClcbiAgICAgICAgdGhpcy50b2RheU1vbnRoID0gdGhpcy5nZXRNb250aEluQ3VycmVudFllYXIoXG4gICAgICAgICAgICB0aGlzLmRhdGVUaW1lQWRhcHRlci5ub3coKVxuICAgICAgICApXG5cbiAgICAgICAgdGhpcy5fbW9udGhzID0gW11cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBNT05USFNfUEVSX1lFQVIgLyBNT05USFNfUEVSX1JPVzsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCByb3cgPSBbXVxuXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IE1PTlRIU19QRVJfUk9XOyBqKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtb250aCA9IGogKyBpICogTU9OVEhTX1BFUl9ST1dcbiAgICAgICAgICAgICAgICBjb25zdCBtb250aENlbGwgPSB0aGlzLmNyZWF0ZU1vbnRoQ2VsbChtb250aClcbiAgICAgICAgICAgICAgICByb3cucHVzaChtb250aENlbGwpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX21vbnRocy5wdXNoKHJvdylcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gQ2FsZW5kYXJDZWxsIGZvciB0aGUgZ2l2ZW4gbW9udGguXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVNb250aENlbGwobW9udGg6IG51bWJlcik6IENhbGVuZGFyQ2VsbCB7XG4gICAgICAgIGNvbnN0IHN0YXJ0RGF0ZU9mTW9udGggPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5jcmVhdGVEYXRlKFxuICAgICAgICAgICAgdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0WWVhcih0aGlzLnBpY2tlck1vbWVudCksXG4gICAgICAgICAgICBtb250aCxcbiAgICAgICAgICAgIDFcbiAgICAgICAgKVxuICAgICAgICBjb25zdCBhcmlhTGFiZWwgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5mb3JtYXQoXG4gICAgICAgICAgICBzdGFydERhdGVPZk1vbnRoLFxuICAgICAgICAgICAgdGhpcy5kYXRlVGltZUZvcm1hdHMubW9udGhZZWFyQTExeUxhYmVsXG4gICAgICAgIClcbiAgICAgICAgY29uc3QgY2VsbENsYXNzID0gJ254dC1kdC1tb250aC0nICsgbW9udGhcbiAgICAgICAgcmV0dXJuIG5ldyBDYWxlbmRhckNlbGwoXG4gICAgICAgICAgICBtb250aCxcbiAgICAgICAgICAgIHRoaXMubW9udGhOYW1lc1ttb250aF0sXG4gICAgICAgICAgICBhcmlhTGFiZWwsXG4gICAgICAgICAgICB0aGlzLmlzTW9udGhFbmFibGVkKG1vbnRoKSxcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgY2VsbENsYXNzXG4gICAgICAgIClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiB0aGUgZ2l2ZW4gbW9udGggaXMgZW5hYmxlXG4gICAgICovXG4gICAgcHJpdmF0ZSBpc01vbnRoRW5hYmxlZChtb250aDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGZpcnN0RGF0ZU9mTW9udGggPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5jcmVhdGVEYXRlKFxuICAgICAgICAgICAgdGhpcy5kYXRlVGltZUFkYXB0ZXIuZ2V0WWVhcih0aGlzLnBpY2tlck1vbWVudCksXG4gICAgICAgICAgICBtb250aCxcbiAgICAgICAgICAgIDFcbiAgICAgICAgKVxuXG4gICAgICAgIC8vIElmIGFueSBkYXRlIGluIHRoZSBtb250aCBpcyBzZWxlY3RhYmxlLFxuICAgICAgICAvLyB3ZSBjb3VudCB0aGUgbW9udGggYXMgZW5hYmxlXG4gICAgICAgIGZvciAoXG4gICAgICAgICAgICBsZXQgZGF0ZSA9IGZpcnN0RGF0ZU9mTW9udGg7XG4gICAgICAgICAgICB0aGlzLmRhdGVUaW1lQWRhcHRlci5nZXRNb250aChkYXRlKSA9PT0gbW9udGg7XG4gICAgICAgICAgICBkYXRlID0gdGhpcy5kYXRlVGltZUFkYXB0ZXIuYWRkQ2FsZW5kYXJEYXlzKGRhdGUsIDEpXG4gICAgICAgICkge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICEhZGF0ZSAmJlxuICAgICAgICAgICAgICAgICghdGhpcy5kYXRlVGltZUZpbHRlciB8fCB0aGlzLmRhdGVUaW1lRmlsdGVyKGRhdGUsICdtb250aCcpKSAmJlxuICAgICAgICAgICAgICAgICghdGhpcy5taW4gfHxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRlVGltZUFkYXB0ZXIuY29tcGFyZShkYXRlLCB0aGlzLm1pbikgPj0gMCkgJiZcbiAgICAgICAgICAgICAgICAoIXRoaXMubWF4IHx8XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmNvbXBhcmUoZGF0ZSwgdGhpcy5tYXgpIDw9IDApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgbW9udGggaW4gdGhpcyB5ZWFyIHRoYXQgdGhlIGdpdmVuIERhdGUgZmFsbHMgb24uXG4gICAgICogUmV0dXJucyB1bmRlZmluZWQgaWYgdGhlIGdpdmVuIERhdGUgaXMgaW4gYW5vdGhlciB5ZWFyLlxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0TW9udGhJbkN1cnJlbnRZZWFyKGRhdGU/OiBUKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgaWYgKHRoaXMuZ2V0VmFsaWREYXRlKGRhdGUpICYmIHRoaXMuZ2V0VmFsaWREYXRlKHRoaXMuX3BpY2tlck1vbWVudCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmNvbXBhcmVZZWFyKFxuICAgICAgICAgICAgICAgIGRhdGUsXG4gICAgICAgICAgICAgICAgdGhpcy5fcGlja2VyTW9tZW50XG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgIC8vIDwgMCA6IHRoZSBnaXZlbiBkYXRlJ3MgeWVhciBpcyBiZWZvcmUgcGlja2VyTW9tZW50J3MgeWVhciwgd2UgcmV0dXJuIC0xIGFzIHNlbGVjdGVkIG1vbnRoIHZhbHVlLlxuICAgICAgICAgICAgLy8gPiAwIDogdGhlIGdpdmVuIGRhdGUncyB5ZWFyIGlzIGFmdGVyIHBpY2tlck1vbWVudCdzIHllYXIsIHdlIHJldHVybiAxMiBhcyBzZWxlY3RlZCBtb250aCB2YWx1ZS5cbiAgICAgICAgICAgIC8vIDAgOiB0aGUgZ2l2ZSBkYXRlJ3MgeWVhciBpcyBzYW1lIGFzIHRoZSBwaWNrZXJNb21lbnQncyB5ZWFyLCB3ZSByZXR1cm4gdGhlIGFjdHVhbCBtb250aCB2YWx1ZS5cbiAgICAgICAgICAgIGlmIChyZXN1bHQgPCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdCA+IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gMTJcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmdldE1vbnRoKGRhdGUpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSBzZWxlY3RlZE1vbnRocyB2YWx1ZVxuICAgICAqIEluIHNpbmdsZSBtb2RlLCBpdCBoYXMgb25seSBvbmUgdmFsdWUgd2hpY2ggcmVwcmVzZW50IHRoZSBtb250aCB0aGUgc2VsZWN0ZWQgZGF0ZSBpblxuICAgICAqIEluIHJhbmdlIG1vZGUsIGl0IHdvdWxkIGhhcyB0d28gdmFsdWVzLCBvbmUgZm9yIHRoZSBtb250aCB0aGUgZnJvbVZhbHVlIGluIGFuZCB0aGUgb3RoZXIgZm9yIHRoZSBtb250aCB0aGUgdG9WYWx1ZSBpblxuICAgICAqL1xuICAgIHByaXZhdGUgc2V0U2VsZWN0ZWRNb250aHMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRNb250aHMgPSBbXVxuICAgICAgICBpZiAodGhpcy5pc0luU2luZ2xlTW9kZSAmJiB0aGlzLnNlbGVjdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkTW9udGhzWzBdID0gdGhpcy5nZXRNb250aEluQ3VycmVudFllYXIodGhpcy5zZWxlY3RlZClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmlzSW5SYW5nZU1vZGUgJiYgdGhpcy5zZWxlY3RlZHMpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNb250aHNbMF0gPSB0aGlzLmdldE1vbnRoSW5DdXJyZW50WWVhcihcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkc1swXVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZE1vbnRoc1sxXSA9IHRoaXMuZ2V0TW9udGhJbkN1cnJlbnRZZWFyKFxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRzWzFdXG4gICAgICAgICAgICApXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayB0aGUgZ2l2ZW4gZGF0ZXMgYXJlIGluIHRoZSBzYW1lIHllYXJcbiAgICAgKi9cbiAgICBwcml2YXRlIGhhc1NhbWVZZWFyKGRhdGVMZWZ0PzogVCwgZGF0ZVJpZ2h0PzogVCkge1xuICAgICAgICByZXR1cm4gISEoXG4gICAgICAgICAgICBkYXRlTGVmdCAmJlxuICAgICAgICAgICAgZGF0ZVJpZ2h0ICYmXG4gICAgICAgICAgICB0aGlzLmRhdGVUaW1lQWRhcHRlci5nZXRZZWFyKGRhdGVMZWZ0KSA9PT1cbiAgICAgICAgICAgIHRoaXMuZGF0ZVRpbWVBZGFwdGVyLmdldFllYXIoZGF0ZVJpZ2h0KVxuICAgICAgICApXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgdmFsaWQgZGF0ZSBvYmplY3RcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldFZhbGlkRGF0ZShvYmo6IGFueSk6IFQgfCB1bmRlZmluZWQge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRlVGltZUFkYXB0ZXIuaXNEYXRlSW5zdGFuY2Uob2JqKSAmJlxuICAgICAgICAgICAgdGhpcy5kYXRlVGltZUFkYXB0ZXIuaXNWYWxpZChvYmopXG4gICAgICAgICAgICA/IG9ialxuICAgICAgICAgICAgOiB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBwcml2YXRlIGZvY3VzQWN0aXZlQ2VsbCgpIHtcbiAgICAgICAgdGhpcy5jYWxlbmRhckJvZHlFbG0/LmZvY3VzQWN0aXZlQ2VsbCgpXG4gICAgfVxufVxuIiwiPHRhYmxlIGNsYXNzPVwibnh0LWR0LWNhbGVuZGFyLXRhYmxlIG54dC1kdC1jYWxlbmRhci15ZWFyLXRhYmxlXCI+XG4gICAgPHRoZWFkIGNsYXNzPVwibnh0LWR0LWNhbGVuZGFyLWhlYWRlclwiPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgICA8dGggY2xhc3M9XCJueHQtZHQtY2FsZW5kYXItdGFibGUtZGl2aWRlclwiXG4gICAgICAgICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICBjb2xzcGFuPVwiM1wiPjwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgPC90aGVhZD5cbiAgICA8dGJvZHkgbnh0RGF0ZVRpbWVDYWxlbmRhckJvZHlcbiAgICAgICAgcm9sZT1cImdyaWRcIlxuICAgICAgICBbcm93c109XCJtb250aHNcIlxuICAgICAgICBbbnVtQ29sc109XCIzXCJcbiAgICAgICAgW2NlbGxSYXRpb109XCIzIC8gN1wiXG4gICAgICAgIFthY3RpdmVDZWxsXT1cImFjdGl2ZUNlbGwgPz8gMFwiXG4gICAgICAgIFt0b2RheVZhbHVlXT1cInRvZGF5TW9udGg/P3VuZGVmaW5lZFwiXG4gICAgICAgIFtzZWxlY3RlZFZhbHVlc109XCJzZWxlY3RlZE1vbnRoc1wiXG4gICAgICAgIFtzZWxlY3RNb2RlXT1cInNlbGVjdE1vZGVcIlxuICAgICAgICAoa2V5ZG93bik9XCJoYW5kbGVDYWxlbmRhcktleWRvd24oJGV2ZW50KVwiXG4gICAgICAgIChzZWxlY3QpPVwic2VsZWN0Q2FsZW5kYXJDZWxsKCRldmVudClcIj5cbiAgICA8L3Rib2R5PlxuPC90YWJsZT5cbiJdfQ==