ngx-wapp-components 1.31.4 → 1.32.1
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.
- package/esm2020/lib/misc/w-cron-expressions/w-cron-expressions.component.mjs +504 -0
- package/esm2020/lib/shared/enums/cron-expressions/enum.model.mjs +29 -0
- package/esm2020/lib/shared/models/cron-expressions/cron-component-translations.model.mjs +2 -0
- package/esm2020/lib/shared/models/multiselect-option.model.mjs +2 -0
- package/esm2020/lib/wapp-components.module.mjs +10 -5
- package/esm2020/public-api.mjs +4 -1
- package/fesm2015/ngx-wapp-components.mjs +547 -22
- package/fesm2015/ngx-wapp-components.mjs.map +1 -1
- package/fesm2020/ngx-wapp-components.mjs +544 -22
- package/fesm2020/ngx-wapp-components.mjs.map +1 -1
- package/lib/misc/w-cron-expressions/w-cron-expressions.component.d.ts +74 -0
- package/lib/shared/enums/cron-expressions/enum.model.d.ts +25 -0
- package/lib/shared/models/cron-expressions/cron-component-translations.model.d.ts +43 -0
- package/lib/shared/models/multiselect-option.model.d.ts +4 -0
- package/lib/wapp-components.module.d.ts +52 -51
- package/package.json +3 -1
- package/public-api.d.ts +3 -0
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import { FormControl, Validators } from '@angular/forms';
|
|
3
|
+
import { CronFieldType, CronPeriodicityType } from '../../shared/enums/cron-expressions/enum.model';
|
|
4
|
+
import cronstrue from 'cronstrue/i18n';
|
|
5
|
+
import { CronExpressionParser } from 'cron-parser';
|
|
6
|
+
import { WDatePipeFormatType } from '../../shared/models/enums.model';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "@angular/forms";
|
|
9
|
+
import * as i2 from "../../shared/services/form-control.service";
|
|
10
|
+
import * as i3 from "../../shared/pipes/w-date.pipe";
|
|
11
|
+
import * as i4 from "@angular/common";
|
|
12
|
+
import * as i5 from "../../edit/w-edit-input-number/w-edit-input-number.component";
|
|
13
|
+
import * as i6 from "../../edit/w-edit-select/w-edit-select.component";
|
|
14
|
+
import * as i7 from "../../edit/w-edit-multiselect/w-edit-multiselect.component";
|
|
15
|
+
import * as i8 from "../../layout/w-panel/w-panel.component";
|
|
16
|
+
import * as i9 from "../../layout/w-panel-grid/w-panel-grid.component";
|
|
17
|
+
import * as i10 from "../../view/w-view-text/w-view-text.component";
|
|
18
|
+
export class WCronExpressionsComponent {
|
|
19
|
+
constructor(formBuilder, formControlService, wappDate) {
|
|
20
|
+
this.formBuilder = formBuilder;
|
|
21
|
+
this.formControlService = formControlService;
|
|
22
|
+
this.wappDate = wappDate;
|
|
23
|
+
this.monthDays = Array.from({ length: 31 }, (_, i) => ({ value: i + 1 }));
|
|
24
|
+
this.minutes = Array.from({ length: 60 }, (_, i) => i);
|
|
25
|
+
this.hours = Array.from({ length: 24 }, (_, i) => i);
|
|
26
|
+
this.expression = ['*', '*', '*', '*', '*', '*'];
|
|
27
|
+
this.description = '';
|
|
28
|
+
this.occurrences = '';
|
|
29
|
+
this.hasContainer = true;
|
|
30
|
+
this.occurrencesNumber = 5;
|
|
31
|
+
this.translationsObject = {
|
|
32
|
+
periodicities: {
|
|
33
|
+
everyXMinutes: "Repetir cada X minutos",
|
|
34
|
+
everyMinute: "Repetir cada minuto",
|
|
35
|
+
everyXHours: "Repetir cada X horas",
|
|
36
|
+
everyHourOfDay: "Repetir cada hora del día",
|
|
37
|
+
everyXDays: "Repetir cada X días",
|
|
38
|
+
everyWeek: "Repetir cada semana",
|
|
39
|
+
everyMonth: "Repetir cada mes",
|
|
40
|
+
everyXMonths: "Repetir X meses",
|
|
41
|
+
},
|
|
42
|
+
months: {
|
|
43
|
+
january: "Enero (1)",
|
|
44
|
+
february: "Febrero (2)",
|
|
45
|
+
march: "Marzo (3)",
|
|
46
|
+
april: "Abril (4)",
|
|
47
|
+
may: "Mayo (5)",
|
|
48
|
+
june: "Junio (6)",
|
|
49
|
+
july: "Julio (7)",
|
|
50
|
+
august: "Agosto (8)",
|
|
51
|
+
september: "Septiembre (9)",
|
|
52
|
+
october: "Octubre (10)",
|
|
53
|
+
november: "Noviembre (11)",
|
|
54
|
+
december: "Diciembre (12)"
|
|
55
|
+
},
|
|
56
|
+
weekDays: {
|
|
57
|
+
sunday: "Domingo (0)",
|
|
58
|
+
monday: "Lunes (1)",
|
|
59
|
+
tuesday: "Martes (2)",
|
|
60
|
+
wednesday: "Miercoles (3)",
|
|
61
|
+
thursday: "Jueves (4)",
|
|
62
|
+
friday: "Viernes (5)",
|
|
63
|
+
saturday: "Sabado (6)"
|
|
64
|
+
},
|
|
65
|
+
periodicityLabel: "Periodicidad",
|
|
66
|
+
minuteLabel: "Minuto",
|
|
67
|
+
hourLabel: "Hora",
|
|
68
|
+
daysLabel: "Día",
|
|
69
|
+
weekDaysLabel: "Días de la semana",
|
|
70
|
+
monthsLabel: "Meses",
|
|
71
|
+
descriptionLabel: "Descripción",
|
|
72
|
+
occurrencesLabel: "Las siguientes 5 ocurrencias serán: "
|
|
73
|
+
};
|
|
74
|
+
this.cronExpression = new EventEmitter();
|
|
75
|
+
}
|
|
76
|
+
ngOnInit() {
|
|
77
|
+
this.initFormGroup();
|
|
78
|
+
this.initPeriodicities();
|
|
79
|
+
this.initMonths();
|
|
80
|
+
this.initWeekDays();
|
|
81
|
+
if (this.initialValue) {
|
|
82
|
+
this.initParsedValues();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
initFormGroup() {
|
|
86
|
+
if (this.initialValue) {
|
|
87
|
+
const parts = this.initialValue.split(" ");
|
|
88
|
+
this.formGroup = this.formBuilder.group({
|
|
89
|
+
periodicity: new FormControl(),
|
|
90
|
+
minutes: new FormControl(this.hasInitialValue(parts[CronFieldType.Minute]) ?
|
|
91
|
+
this.formatCronNumber(parts[CronFieldType.Minute])
|
|
92
|
+
: 0),
|
|
93
|
+
hours: new FormControl(this.hasInitialValue(parts[CronFieldType.Hour]) ?
|
|
94
|
+
this.formatCronNumber(parts[CronFieldType.Hour])
|
|
95
|
+
: 0),
|
|
96
|
+
weekDays: new FormControl(this.hasInitialValue(parts[CronFieldType.WeekDay]) ?
|
|
97
|
+
parts[CronFieldType.WeekDay].replace(/\//g, '').split(',').map(Number)
|
|
98
|
+
: []),
|
|
99
|
+
monthDay: new FormControl(this.hasInitialValue(parts[CronFieldType.MonthDay]) ?
|
|
100
|
+
this.formatCronNumber(parts[CronFieldType.MonthDay])
|
|
101
|
+
: 1),
|
|
102
|
+
monthDays: new FormControl(this.hasInitialValue(parts[CronFieldType.MonthDay]) ?
|
|
103
|
+
parts[CronFieldType.MonthDay].replace(/[/*]/g, '').split(',').map(Number)
|
|
104
|
+
: []),
|
|
105
|
+
months: new FormControl(this.hasInitialValue(parts[CronFieldType.Month]) ?
|
|
106
|
+
parts[CronFieldType.Month].replace(/\//g, '').split(',').map(Number)
|
|
107
|
+
: 0),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this.formGroup = this.formBuilder.group({
|
|
112
|
+
periodicity: new FormControl(0),
|
|
113
|
+
minutes: new FormControl(0),
|
|
114
|
+
hours: new FormControl(0),
|
|
115
|
+
weekDays: new FormControl([]),
|
|
116
|
+
monthDay: new FormControl(1),
|
|
117
|
+
monthDays: new FormControl([]),
|
|
118
|
+
months: new FormControl(0),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
hasInitialValue(part) {
|
|
123
|
+
if (part == '*' || part == '0') {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
formatCronNumber(cronValue) {
|
|
131
|
+
return +cronValue.replace(/[/*]/g, '');
|
|
132
|
+
}
|
|
133
|
+
initPeriodicities() {
|
|
134
|
+
const translationsMap = {
|
|
135
|
+
[CronPeriodicityType.EveryXMinutes]: this.translationsObject.periodicities.everyXMinutes,
|
|
136
|
+
[CronPeriodicityType.EveryMinute]: this.translationsObject.periodicities.everyMinute,
|
|
137
|
+
[CronPeriodicityType.EveryXHours]: this.translationsObject.periodicities.everyXHours,
|
|
138
|
+
[CronPeriodicityType.EveryHourOfDay]: this.translationsObject.periodicities.everyHourOfDay,
|
|
139
|
+
[CronPeriodicityType.EveryXDays]: this.translationsObject.periodicities.everyXDays,
|
|
140
|
+
[CronPeriodicityType.EveryWeek]: this.translationsObject.periodicities.everyWeek,
|
|
141
|
+
[CronPeriodicityType.EveryMonth]: this.translationsObject.periodicities.everyMonth,
|
|
142
|
+
[CronPeriodicityType.EveryXMonths]: this.translationsObject.periodicities.everyXMonths,
|
|
143
|
+
};
|
|
144
|
+
if (this.periodicitiesDisplayed) {
|
|
145
|
+
this.periodicities = this.periodicitiesDisplayed.map(periodicity => ({
|
|
146
|
+
value: periodicity,
|
|
147
|
+
name: translationsMap[periodicity]
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.periodicities = Object.entries(translationsMap).map(([key, value]) => ({
|
|
152
|
+
value: Number(key),
|
|
153
|
+
name: value
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
if (!this.initialValue) {
|
|
157
|
+
this.periodicitySelected = this.periodicities[0]?.value;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
initParsedValues() {
|
|
161
|
+
this.expression = this.parseCronExpression(this.initialValue);
|
|
162
|
+
this.periodicitySelected = this.getCronPeriodicityType(this.initialValue);
|
|
163
|
+
this.handleZeroHoursArray();
|
|
164
|
+
this.cronToHuman();
|
|
165
|
+
}
|
|
166
|
+
parseCronExpression(cron) {
|
|
167
|
+
const parts = cron.split(" ");
|
|
168
|
+
while (parts.length < 6) {
|
|
169
|
+
parts.push('*');
|
|
170
|
+
}
|
|
171
|
+
return parts;
|
|
172
|
+
}
|
|
173
|
+
initMonths() {
|
|
174
|
+
this.months = [
|
|
175
|
+
{ value: 1, name: this.translationsObject.months.january },
|
|
176
|
+
{ value: 2, name: this.translationsObject.months.february },
|
|
177
|
+
{ value: 3, name: this.translationsObject.months.march },
|
|
178
|
+
{ value: 4, name: this.translationsObject.months.april },
|
|
179
|
+
{ value: 5, name: this.translationsObject.months.may },
|
|
180
|
+
{ value: 6, name: this.translationsObject.months.june },
|
|
181
|
+
{ value: 7, name: this.translationsObject.months.july },
|
|
182
|
+
{ value: 8, name: this.translationsObject.months.august },
|
|
183
|
+
{ value: 9, name: this.translationsObject.months.september },
|
|
184
|
+
{ value: 10, name: this.translationsObject.months.october },
|
|
185
|
+
{ value: 11, name: this.translationsObject.months.november },
|
|
186
|
+
{ value: 12, name: this.translationsObject.months.december },
|
|
187
|
+
];
|
|
188
|
+
}
|
|
189
|
+
initWeekDays() {
|
|
190
|
+
this.weekDays = [
|
|
191
|
+
{ value: 0, name: this.translationsObject.weekDays.sunday },
|
|
192
|
+
{ value: 1, name: this.translationsObject.weekDays.monday },
|
|
193
|
+
{ value: 2, name: this.translationsObject.weekDays.tuesday },
|
|
194
|
+
{ value: 3, name: this.translationsObject.weekDays.wednesday },
|
|
195
|
+
{ value: 4, name: this.translationsObject.weekDays.thursday },
|
|
196
|
+
{ value: 5, name: this.translationsObject.weekDays.friday },
|
|
197
|
+
{ value: 6, name: this.translationsObject.weekDays.saturday },
|
|
198
|
+
];
|
|
199
|
+
}
|
|
200
|
+
allowSeconds() {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
allowMinutes() {
|
|
204
|
+
switch (this.periodicitySelected) {
|
|
205
|
+
case CronPeriodicityType.EveryXMinutes:
|
|
206
|
+
case CronPeriodicityType.EveryMinute:
|
|
207
|
+
case CronPeriodicityType.EveryXHours:
|
|
208
|
+
case CronPeriodicityType.EveryHourOfDay:
|
|
209
|
+
case CronPeriodicityType.EveryXDays:
|
|
210
|
+
case CronPeriodicityType.EveryWeek:
|
|
211
|
+
case CronPeriodicityType.EveryMonth:
|
|
212
|
+
case CronPeriodicityType.EveryXMonths:
|
|
213
|
+
return true;
|
|
214
|
+
default:
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
allowHours() {
|
|
219
|
+
switch (this.periodicitySelected) {
|
|
220
|
+
case CronPeriodicityType.EveryXHours:
|
|
221
|
+
case CronPeriodicityType.EveryHourOfDay:
|
|
222
|
+
case CronPeriodicityType.EveryXDays:
|
|
223
|
+
case CronPeriodicityType.EveryWeek:
|
|
224
|
+
case CronPeriodicityType.EveryMonth:
|
|
225
|
+
case CronPeriodicityType.EveryXMonths:
|
|
226
|
+
return true;
|
|
227
|
+
default:
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
allowWeekDays() {
|
|
232
|
+
switch (this.periodicitySelected) {
|
|
233
|
+
case CronPeriodicityType.EveryWeek:
|
|
234
|
+
return true;
|
|
235
|
+
default:
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
allowMonthDay() {
|
|
240
|
+
switch (this.periodicitySelected) {
|
|
241
|
+
case CronPeriodicityType.EveryXDays:
|
|
242
|
+
return true;
|
|
243
|
+
default:
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
allowMonthDays() {
|
|
248
|
+
switch (this.periodicitySelected) {
|
|
249
|
+
case CronPeriodicityType.EveryXMonths:
|
|
250
|
+
case CronPeriodicityType.EveryMonth:
|
|
251
|
+
return true;
|
|
252
|
+
default:
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
allowMonths() {
|
|
257
|
+
switch (this.periodicitySelected) {
|
|
258
|
+
case CronPeriodicityType.EveryXMonths:
|
|
259
|
+
return true;
|
|
260
|
+
default:
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
isMonthDaysRequired() {
|
|
265
|
+
if (this.periodicitySelected == CronPeriodicityType.EveryXMonths) {
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
onPeriodicitySelected() {
|
|
273
|
+
this.restartExpression();
|
|
274
|
+
this.handleZeroHoursArray();
|
|
275
|
+
this.updateMonthDaysRequirement();
|
|
276
|
+
this.onHoursSelected(this.hourSelected);
|
|
277
|
+
this.onWeekDaysSelected(this.weekDaySelected);
|
|
278
|
+
this.onMonthsSelected(this.monthSelected);
|
|
279
|
+
this.onMonthDaysSelected(this.monthDaysSelected);
|
|
280
|
+
this.onMonthDaySelected(this.monthDaySelected);
|
|
281
|
+
this.onMinuteSelected(this.minuteSelected);
|
|
282
|
+
}
|
|
283
|
+
handleZeroHoursArray() {
|
|
284
|
+
if (this.periodicitySelected == CronPeriodicityType.EveryXHours) {
|
|
285
|
+
this.hours = Array.from({ length: 23 }, (_, i) => i + 1);
|
|
286
|
+
if (this.hourSelected == 0) {
|
|
287
|
+
this.hourSelected = 1;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
this.hours = Array.from({ length: 24 }, (_, i) => i);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
onMinuteSelected(minuteSelected) {
|
|
295
|
+
switch (this.periodicitySelected) {
|
|
296
|
+
case CronPeriodicityType.EveryXMinutes: {
|
|
297
|
+
this.expression[CronFieldType.Second] = `0`;
|
|
298
|
+
this.expression[CronFieldType.Minute] = `*/${minuteSelected}`;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
case CronPeriodicityType.EveryMinute:
|
|
302
|
+
case CronPeriodicityType.EveryHourOfDay:
|
|
303
|
+
case CronPeriodicityType.EveryXHours:
|
|
304
|
+
case CronPeriodicityType.EveryXDays:
|
|
305
|
+
case CronPeriodicityType.EveryWeek:
|
|
306
|
+
case CronPeriodicityType.EveryMonth:
|
|
307
|
+
case CronPeriodicityType.EveryXMonths: {
|
|
308
|
+
this.expression[CronFieldType.Second] = `0`;
|
|
309
|
+
this.expression[CronFieldType.Minute] = `${minuteSelected}`;
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
this.cronToHuman();
|
|
314
|
+
}
|
|
315
|
+
onHoursSelected(hoursSelected) {
|
|
316
|
+
this.expression[CronFieldType.Minute] = `${this.minuteSelected}`;
|
|
317
|
+
switch (this.periodicitySelected) {
|
|
318
|
+
case CronPeriodicityType.EveryXHours:
|
|
319
|
+
this.expression[CronFieldType.Hour] = `*/${hoursSelected}`;
|
|
320
|
+
break;
|
|
321
|
+
case CronPeriodicityType.EveryHourOfDay:
|
|
322
|
+
case CronPeriodicityType.EveryXDays:
|
|
323
|
+
case CronPeriodicityType.EveryWeek:
|
|
324
|
+
case CronPeriodicityType.EveryMonth:
|
|
325
|
+
case CronPeriodicityType.EveryXMonths:
|
|
326
|
+
this.expression[CronFieldType.Hour] = `${hoursSelected}`;
|
|
327
|
+
break;
|
|
328
|
+
}
|
|
329
|
+
this.cronToHuman();
|
|
330
|
+
}
|
|
331
|
+
onWeekDaysSelected(weekDaysSelected) {
|
|
332
|
+
switch (this.periodicitySelected) {
|
|
333
|
+
case CronPeriodicityType.EveryWeek: {
|
|
334
|
+
this.expression[CronFieldType.WeekDay] = `${weekDaysSelected}`;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
this.cronToHuman();
|
|
338
|
+
}
|
|
339
|
+
onMonthDaysSelected(monthDaysSelected) {
|
|
340
|
+
switch (this.periodicitySelected) {
|
|
341
|
+
case CronPeriodicityType.EveryXDays:
|
|
342
|
+
this.expression[CronFieldType.MonthDay] = `*/${this.monthDaySelected}`;
|
|
343
|
+
break;
|
|
344
|
+
case CronPeriodicityType.EveryMonth:
|
|
345
|
+
case CronPeriodicityType.EveryXMonths:
|
|
346
|
+
if (monthDaysSelected instanceof Array && monthDaysSelected.length == 0) {
|
|
347
|
+
this.expression[CronFieldType.MonthDay] = `*`;
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
this.expression[CronFieldType.MonthDay] = `${monthDaysSelected}`;
|
|
351
|
+
}
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
this.cronToHuman();
|
|
355
|
+
}
|
|
356
|
+
onMonthDaySelected(monthDaysSelected) {
|
|
357
|
+
switch (this.periodicitySelected) {
|
|
358
|
+
case CronPeriodicityType.EveryXDays:
|
|
359
|
+
this.expression[CronFieldType.MonthDay] = `*/${monthDaysSelected}`;
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
this.cronToHuman();
|
|
363
|
+
}
|
|
364
|
+
onMonthsSelected(monthsSelected) {
|
|
365
|
+
switch (this.periodicitySelected) {
|
|
366
|
+
case CronPeriodicityType.EveryXMonths: {
|
|
367
|
+
this.expression[CronFieldType.Second] = `0`;
|
|
368
|
+
this.expression[CronFieldType.Month] = `${monthsSelected}`;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
this.cronToHuman();
|
|
372
|
+
}
|
|
373
|
+
cronToHuman() {
|
|
374
|
+
this.description = cronstrue.toString(this.expression.join(' '), { locale: window.navigator.language.slice(0, 2) });
|
|
375
|
+
const options = {
|
|
376
|
+
currentDate: new Date(),
|
|
377
|
+
};
|
|
378
|
+
const interval = CronExpressionParser.parse(this.expression.join(' '), options);
|
|
379
|
+
let dates = interval.take(this.occurrencesNumber).map((date) => new Date(date.toString()));
|
|
380
|
+
this.occurrences = dates.map(d => this.wappDate.transform(d, WDatePipeFormatType.G)).join(", ");
|
|
381
|
+
let cronExpression = this.expression.join(' ');
|
|
382
|
+
if (![CronPeriodicityType.EveryXMinutes, CronPeriodicityType.EveryMinute, CronPeriodicityType.EveryXHours].includes(this.periodicitySelected)) {
|
|
383
|
+
cronExpression = this.localUserCronToUTCCron(this.expression.join(' '));
|
|
384
|
+
}
|
|
385
|
+
this.cronExpression.emit(cronExpression);
|
|
386
|
+
}
|
|
387
|
+
localUserCronToUTCCron(cronExpression) {
|
|
388
|
+
const cronParts = cronExpression.trim().split(' ');
|
|
389
|
+
const userOffset = -(new Date().getTimezoneOffset() / 60);
|
|
390
|
+
const localHour = parseInt(cronParts[2], 10);
|
|
391
|
+
let utcHour = localHour - userOffset;
|
|
392
|
+
let dayAdjustment = 0;
|
|
393
|
+
if (utcHour >= 24) {
|
|
394
|
+
utcHour -= 24;
|
|
395
|
+
dayAdjustment = 1;
|
|
396
|
+
}
|
|
397
|
+
else if (utcHour < 0) {
|
|
398
|
+
utcHour += 24;
|
|
399
|
+
dayAdjustment = -1;
|
|
400
|
+
}
|
|
401
|
+
cronParts[2] = utcHour.toString();
|
|
402
|
+
return cronParts.join(' ');
|
|
403
|
+
}
|
|
404
|
+
formatArrayValues(array) {
|
|
405
|
+
return array?.map(a => a.value).join(',');
|
|
406
|
+
}
|
|
407
|
+
restartExpression() {
|
|
408
|
+
this.expression = ['*', '*', '*', '*', '*', '*'];
|
|
409
|
+
}
|
|
410
|
+
getCronPeriodicityType(cron) {
|
|
411
|
+
const parts = cron.split(" ");
|
|
412
|
+
if (parts.length !== 6) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
const [second, minute, hour, dayOfMonth, month, dayOfWeek] = parts;
|
|
416
|
+
if (minute.startsWith("*/") && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
|
|
417
|
+
return CronPeriodicityType.EveryXMinutes;
|
|
418
|
+
}
|
|
419
|
+
if (minute !== "*" && hour === "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
|
|
420
|
+
return CronPeriodicityType.EveryMinute;
|
|
421
|
+
}
|
|
422
|
+
if (hour.startsWith("*/") && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
|
|
423
|
+
return CronPeriodicityType.EveryXHours;
|
|
424
|
+
}
|
|
425
|
+
if (minute !== "*" && hour !== "*" && dayOfMonth === "*" && month === "*" && dayOfWeek === "*") {
|
|
426
|
+
return CronPeriodicityType.EveryHourOfDay;
|
|
427
|
+
}
|
|
428
|
+
if (dayOfMonth.startsWith("*/") && month === "*" && dayOfWeek === "*") {
|
|
429
|
+
return CronPeriodicityType.EveryXDays;
|
|
430
|
+
}
|
|
431
|
+
if (dayOfWeek !== "*" && dayOfMonth === "*" && month === "*") {
|
|
432
|
+
return CronPeriodicityType.EveryWeek;
|
|
433
|
+
}
|
|
434
|
+
if (dayOfMonth !== "*" && month == "*") {
|
|
435
|
+
return CronPeriodicityType.EveryMonth;
|
|
436
|
+
}
|
|
437
|
+
if (month !== "*") {
|
|
438
|
+
return CronPeriodicityType.EveryXMonths;
|
|
439
|
+
}
|
|
440
|
+
return null;
|
|
441
|
+
}
|
|
442
|
+
updateMonthDaysRequirement() {
|
|
443
|
+
if (this.periodicitySelected == CronPeriodicityType.EveryXMonths) {
|
|
444
|
+
this.formGroup.controls['monthDays'].removeValidators([Validators.required]);
|
|
445
|
+
this.formGroup.controls['monthDays'].updateValueAndValidity();
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
this.formGroup.controls['monthDays'].addValidators([Validators.required]);
|
|
449
|
+
this.formGroup.controls['monthDays'].updateValueAndValidity();
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
set periodicitySelected(value) {
|
|
453
|
+
this.formGroup?.patchValue({ periodicity: value });
|
|
454
|
+
}
|
|
455
|
+
get periodicitySelected() {
|
|
456
|
+
return this.formGroup.get('periodicity').value;
|
|
457
|
+
}
|
|
458
|
+
get minuteSelected() {
|
|
459
|
+
return this.formGroup.get('minutes').value;
|
|
460
|
+
}
|
|
461
|
+
set hourSelected(value) {
|
|
462
|
+
this.formGroup?.patchValue({ hours: value });
|
|
463
|
+
}
|
|
464
|
+
get hourSelected() {
|
|
465
|
+
return this.formGroup.get('hours').value;
|
|
466
|
+
}
|
|
467
|
+
get weekDaySelected() {
|
|
468
|
+
return this.formGroup.get('weekDays').value;
|
|
469
|
+
}
|
|
470
|
+
get monthDaySelected() {
|
|
471
|
+
return this.formGroup.get('monthDay').value;
|
|
472
|
+
}
|
|
473
|
+
get monthDaysSelected() {
|
|
474
|
+
return this.formGroup.get('monthDays').value;
|
|
475
|
+
}
|
|
476
|
+
get monthSelected() {
|
|
477
|
+
return this.formGroup.get('months').value;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
WCronExpressionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WCronExpressionsComponent, deps: [{ token: i1.FormBuilder }, { token: i2.FormControlService }, { token: i3.WDatePipe }], target: i0.ɵɵFactoryTarget.Component });
|
|
481
|
+
WCronExpressionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.7", type: WCronExpressionsComponent, selector: "w-cron-expressions", inputs: { initialValue: "initialValue", periodicitiesDisplayed: "periodicitiesDisplayed", hasContainer: "hasContainer", occurrencesNumber: "occurrencesNumber", translationsObject: "translationsObject" }, outputs: { cronExpression: "cronExpression" }, ngImport: i0, template: "<w-panel *ngIf=\"hasContainer; else cronComponent\">\r\n <ng-container *ngTemplateOutlet=\"cronComponent\"></ng-container>\r\n</w-panel>\r\n\r\n<ng-template #cronComponent>\r\n <form [formGroup]=\"formGroup\" class=\"col-12\">\r\n <w-panel-grid class=\"col-12\">\r\n <w-edit-select class=\"col-12\"\r\n [label]=\"translationsObject.periodicityLabel\"\r\n [required]=\"true\"\r\n [options]=\"periodicities\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'name'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('periodicity'))\"\r\n (onChange)=\"onPeriodicitySelected()\">\r\n </w-edit-select>\r\n <w-edit-multiselect *ngIf=\"allowMonths()\"\r\n class=\"col-12\"\r\n [label]=\"translationsObject.monthsLabel\"\r\n [required]=\"true\"\r\n [options]=\"months\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'name'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('months'))\"\r\n (onChange)=\"onMonthsSelected($event)\">\r\n </w-edit-multiselect>\r\n <w-edit-multiselect *ngIf=\"allowMonthDays()\"\r\n class=\"col-12\"\r\n [label]=\"translationsObject.daysLabel\"\r\n [required]=\"isMonthDaysRequired()\"\r\n [options]=\"monthDays\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'value'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('monthDays'))\"\r\n (onChange)=\"onMonthDaysSelected($event)\">\r\n </w-edit-multiselect>\r\n <w-edit-select *ngIf=\"allowMonthDay()\"\r\n class=\"col-12\"\r\n [label]=\"translationsObject.daysLabel\"\r\n [required]=\"true\"\r\n [options]=\"monthDays\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'value'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('monthDay'))\"\r\n (onChange)=\"onMonthDaysSelected($event)\">\r\n </w-edit-select>\r\n <w-edit-multiselect *ngIf=\"allowWeekDays()\"\r\n class=\"col-12\"\r\n [label]=\"translationsObject.weekDaysLabel\"\r\n [required]=\"true\"\r\n [options]=\"weekDays\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'name'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('weekDays'))\"\r\n (onChange)=\"onWeekDaysSelected($event)\">\r\n </w-edit-multiselect>\r\n <w-edit-select *ngIf=\"allowHours()\"\r\n class=\"col-6\" \r\n [label]=\"translationsObject.hourLabel\"\r\n [required]=\"true\"\r\n [options]=\"hours\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('hours'))\"\r\n (onChange)=\"onHoursSelected($event)\">\r\n </w-edit-select>\r\n <w-edit-select *ngIf=\"allowMinutes()\"\r\n [ngClass]=\"{'col-6': allowHours(), 'col-12': !allowHours()}\" \r\n [label]=\"translationsObject.minuteLabel\"\r\n [required]=\"true\"\r\n [options]=\"minutes\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('minutes'))\"\r\n (onChange)=\"onMinuteSelected($event)\">\r\n </w-edit-select>\r\n <w-edit-input-number *ngIf=\"allowSeconds()\"\r\n class=\"col-6\"\r\n [label]=\"'Segundos'\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n [max]=\"59\">\r\n </w-edit-input-number>\r\n <w-view-text class=\"col-12\"\r\n [label]=\"translationsObject.descriptionLabel\"\r\n [value]=\"description\"\r\n [layout]=\"'vertical'\">\r\n </w-view-text>\r\n <w-view-text class=\"col-12\"\r\n [label]=\"translationsObject.occurrencesLabel\"\r\n [value]=\"occurrences\"\r\n [layout]=\"'vertical'\">\r\n </w-view-text>\r\n </w-panel-grid>\r\n </form>\r\n</ng-template>", styles: [""], dependencies: [{ kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i5.WEditInputNumberComponent, selector: "w-edit-input-number", inputs: ["label", "showLabel", "placeholder", "successMessage", "mode", "minFractionDigits", "maxFractionDigits", "required", "requiredErrorDescription", "disabled", "pattern", "patternErrorDescription", "min", "minErrorDescription", "max", "maxErrorDescription", "prefix", "suffix", "autofocus", "size", "formControl", "removePaddingTop", "tooltip", "tooltipPosition"] }, { kind: "component", type: i6.WEditSelectComponent, selector: "w-edit-select", inputs: ["label", "showLabel", "placeholder", "disabled", "loading", "required", "size", "options", "filter", "optionLabel", "optionValue", "appendTo", "showClear", "formControl", "requiredErrorDescription", "removePaddingTop", "tooltip", "tooltipPosition"], outputs: ["onChange", "onClear"] }, { kind: "component", type: i7.WEditMultiselectComponent, selector: "w-edit-multiselect", inputs: ["label", "showLabel", "placeholder", "filter", "filterPlaceholder", "disabled", "optionDisabled", "showPanelDisabled", "readonly", "required", "size", "options", "optionLabel", "optionValue", "appendTo", "showClear", "showToggleAll", "formControl", "requiredErrorDescription", "removePaddingTop", "tooltip", "tooltipPosition"], outputs: ["onChange"] }, { kind: "component", type: i8.WPanelComponent, selector: "w-panel", inputs: ["width", "title", "subtitle", "activeGrid", "reduced", "justifyContent", "activeOverflow", "heightOverflow", "maxHeightOverflow", "backgroundColor", "activeMaxHeight", "activeMenu", "menuOptions", "wPanelStyleClass", "wPanelContentStyleClass"] }, { kind: "component", type: i9.WPanelGridComponent, selector: "w-panel-grid" }, { kind: "component", type: i10.WViewTextComponent, selector: "w-view-text", inputs: ["label", "value", "tooltip", "tooltipPosition", "layout", "displayAsList"] }] });
|
|
482
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.7", ngImport: i0, type: WCronExpressionsComponent, decorators: [{
|
|
483
|
+
type: Component,
|
|
484
|
+
args: [{ selector: 'w-cron-expressions', template: "<w-panel *ngIf=\"hasContainer; else cronComponent\">\r\n <ng-container *ngTemplateOutlet=\"cronComponent\"></ng-container>\r\n</w-panel>\r\n\r\n<ng-template #cronComponent>\r\n <form [formGroup]=\"formGroup\" class=\"col-12\">\r\n <w-panel-grid class=\"col-12\">\r\n <w-edit-select class=\"col-12\"\r\n [label]=\"translationsObject.periodicityLabel\"\r\n [required]=\"true\"\r\n [options]=\"periodicities\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'name'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('periodicity'))\"\r\n (onChange)=\"onPeriodicitySelected()\">\r\n </w-edit-select>\r\n <w-edit-multiselect *ngIf=\"allowMonths()\"\r\n class=\"col-12\"\r\n [label]=\"translationsObject.monthsLabel\"\r\n [required]=\"true\"\r\n [options]=\"months\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'name'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('months'))\"\r\n (onChange)=\"onMonthsSelected($event)\">\r\n </w-edit-multiselect>\r\n <w-edit-multiselect *ngIf=\"allowMonthDays()\"\r\n class=\"col-12\"\r\n [label]=\"translationsObject.daysLabel\"\r\n [required]=\"isMonthDaysRequired()\"\r\n [options]=\"monthDays\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'value'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('monthDays'))\"\r\n (onChange)=\"onMonthDaysSelected($event)\">\r\n </w-edit-multiselect>\r\n <w-edit-select *ngIf=\"allowMonthDay()\"\r\n class=\"col-12\"\r\n [label]=\"translationsObject.daysLabel\"\r\n [required]=\"true\"\r\n [options]=\"monthDays\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'value'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('monthDay'))\"\r\n (onChange)=\"onMonthDaysSelected($event)\">\r\n </w-edit-select>\r\n <w-edit-multiselect *ngIf=\"allowWeekDays()\"\r\n class=\"col-12\"\r\n [label]=\"translationsObject.weekDaysLabel\"\r\n [required]=\"true\"\r\n [options]=\"weekDays\"\r\n [optionValue]=\"'value'\"\r\n [optionLabel]=\"'name'\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('weekDays'))\"\r\n (onChange)=\"onWeekDaysSelected($event)\">\r\n </w-edit-multiselect>\r\n <w-edit-select *ngIf=\"allowHours()\"\r\n class=\"col-6\" \r\n [label]=\"translationsObject.hourLabel\"\r\n [required]=\"true\"\r\n [options]=\"hours\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('hours'))\"\r\n (onChange)=\"onHoursSelected($event)\">\r\n </w-edit-select>\r\n <w-edit-select *ngIf=\"allowMinutes()\"\r\n [ngClass]=\"{'col-6': allowHours(), 'col-12': !allowHours()}\" \r\n [label]=\"translationsObject.minuteLabel\"\r\n [required]=\"true\"\r\n [options]=\"minutes\"\r\n [formControl]=\"formControlService.convertToFormControl(formGroup.get('minutes'))\"\r\n (onChange)=\"onMinuteSelected($event)\">\r\n </w-edit-select>\r\n <w-edit-input-number *ngIf=\"allowSeconds()\"\r\n class=\"col-6\"\r\n [label]=\"'Segundos'\"\r\n [required]=\"true\"\r\n [min]=\"0\"\r\n [max]=\"59\">\r\n </w-edit-input-number>\r\n <w-view-text class=\"col-12\"\r\n [label]=\"translationsObject.descriptionLabel\"\r\n [value]=\"description\"\r\n [layout]=\"'vertical'\">\r\n </w-view-text>\r\n <w-view-text class=\"col-12\"\r\n [label]=\"translationsObject.occurrencesLabel\"\r\n [value]=\"occurrences\"\r\n [layout]=\"'vertical'\">\r\n </w-view-text>\r\n </w-panel-grid>\r\n </form>\r\n</ng-template>" }]
|
|
485
|
+
}], ctorParameters: function () { return [{ type: i1.FormBuilder }, { type: i2.FormControlService }, { type: i3.WDatePipe }]; }, propDecorators: { initialValue: [{
|
|
486
|
+
type: Input,
|
|
487
|
+
args: ['initialValue']
|
|
488
|
+
}], periodicitiesDisplayed: [{
|
|
489
|
+
type: Input,
|
|
490
|
+
args: ['periodicitiesDisplayed']
|
|
491
|
+
}], hasContainer: [{
|
|
492
|
+
type: Input,
|
|
493
|
+
args: ['hasContainer']
|
|
494
|
+
}], occurrencesNumber: [{
|
|
495
|
+
type: Input,
|
|
496
|
+
args: ['occurrencesNumber']
|
|
497
|
+
}], translationsObject: [{
|
|
498
|
+
type: Input,
|
|
499
|
+
args: ['translationsObject']
|
|
500
|
+
}], cronExpression: [{
|
|
501
|
+
type: Output,
|
|
502
|
+
args: ['cronExpression']
|
|
503
|
+
}] } });
|
|
504
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidy1jcm9uLWV4cHJlc3Npb25zLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3dhcHAtY29tcG9uZW50cy9zcmMvbGliL21pc2Mvdy1jcm9uLWV4cHJlc3Npb25zL3ctY3Jvbi1leHByZXNzaW9ucy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93YXBwLWNvbXBvbmVudHMvc3JjL2xpYi9taXNjL3ctY3Jvbi1leHByZXNzaW9ucy93LWNyb24tZXhwcmVzc2lvbnMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQWUsV0FBVyxFQUFhLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpGLE9BQU8sRUFBRSxhQUFhLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUdwRyxPQUFRLFNBQVMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFbkQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0saUNBQWlDLENBQUM7Ozs7Ozs7Ozs7OztBQU90RSxNQUFNLE9BQU8seUJBQXlCO0lBaUVwQyxZQUNVLFdBQXdCLEVBQ3pCLGtCQUFzQyxFQUNyQyxRQUFtQjtRQUZuQixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN6Qix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3JDLGFBQVEsR0FBUixRQUFRLENBQVc7UUE3RDdCLGNBQVMsR0FBSSxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEtB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USxFQUFFO1lBQzNELEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7U0FDNUQsQ0FBQztJQUNKLENBQUM7SUFFRCxZQUFZO1FBQ1YsSUFBSSxDQUFDLFFBQVEsR0FBRztZQUNkLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUU7WUFDM0QsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRTtZQUMzRCxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFO1lBQzVELEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUU7WUFDOUQsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRTtZQUM3RCxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFO1lBQzNELEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUU7U0FDOUQsQ0FBQztJQUNKLENBQUM7SUFFRCxZQUFZO1FBQ1YsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsWUFBWTtRQUNWLFFBQU8sSUFBSSxDQUFDLG1CQUFtQixFQUFDO1lBQzlCLEtBQUssbUJBQW1CLENBQUMsYUFBYSxDQUFDO1lBQ3ZDLEtBQUssbUJBQW1CLENBQUMsV0FBVyxDQUFDO1lBQ3JD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LENBQUM7SUFDN0MsQ0FBQzs7c0hBOWhCVSx5QkFBeUI7MEdBQXpCLHlCQUF5QixxVENoQnRDLHc1S0EyRmM7MkZEM0VELHlCQUF5QjtrQkFMckMsU0FBUzsrQkFDRSxvQkFBb0I7MkpBbUJQLFlBQVk7c0JBQWxDLEtBQUs7dUJBQUMsY0FBYztnQkFDWSxzQkFBc0I7c0JBQXRELEtBQUs7dUJBQUMsd0JBQXdCO2dCQUNSLFlBQVk7c0JBQWxDLEtBQUs7dUJBQUMsY0FBYztnQkFDTyxpQkFBaUI7c0JBQTVDLEtBQUs7dUJBQUMsbUJBQW1CO2dCQUNHLGtCQUFrQjtzQkFBOUMsS0FBSzt1QkFBQyxvQkFBb0I7Z0JBNENELGNBQWM7c0JBQXZDLE1BQU07dUJBQUMsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7IE11bHRpU2VsZWN0T3B0aW9uIH0gZnJvbSAnLi4vLi4vc2hhcmVkL21vZGVscy9tdWx0aXNlbGVjdC1vcHRpb24ubW9kZWwnO1xyXG5pbXBvcnQgeyBDcm9uRmllbGRUeXBlLCBDcm9uUGVyaW9kaWNpdHlUeXBlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2VudW1zL2Nyb24tZXhwcmVzc2lvbnMvZW51bS5tb2RlbCc7XHJcbmltcG9ydCB7IENyb25Db21wb25lbnRUcmFuc2xhdGlvbnMgfSBmcm9tICcuLi8uLi9zaGFyZWQvbW9kZWxzL2Nyb24tZXhwcmVzc2lvbnMvY3Jvbi1jb21wb25lbnQtdHJhbnNsYXRpb25zLm1vZGVsJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2xTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3NlcnZpY2VzL2Zvcm0tY29udHJvbC5zZXJ2aWNlJztcclxuaW1wb3J0ICBjcm9uc3RydWUgZnJvbSAnY3JvbnN0cnVlL2kxOG4nO1xyXG5pbXBvcnQgeyBDcm9uRXhwcmVzc2lvblBhcnNlciB9IGZyb20gJ2Nyb24tcGFyc2VyJztcclxuaW1wb3J0IHsgV0RhdGVQaXBlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3BpcGVzL3ctZGF0ZS5waXBlJztcclxuaW1wb3J0IHsgV0RhdGVQaXBlRm9ybWF0VHlwZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9tb2RlbHMvZW51bXMubW9kZWwnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICd3LWNyb24tZXhwcmVzc2lvbnMnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi93LWNyb24tZXhwcmVzc2lvbnMuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3ctY3Jvbi1leHByZXNzaW9ucy5jb21wb25lbnQuY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFdDcm9uRXhwcmVzc2lvbnNDb21wb25lbnQge1xyXG4gIGZvcm1Hcm91cCE6IEZvcm1Hcm91cDtcclxuXHJcbiAgcGVyaW9kaWNpdGllcyE6IE11bHRpU2VsZWN0T3B0aW9uW107XHJcbiAgbW9udGhzITogTXVsdGlTZWxlY3RPcHRpb25bXTtcclxuICB3ZWVrRGF5cyE6IE11bHRpU2VsZWN0T3B0aW9uW107XHJcblxyXG4gIG1vbnRoRGF5cyA9ICBBcnJheS5mcm9tKHsgbGVuZ3RoOiAzMSB9LCAoXywgaSkgPT4gKHsgdmFsdWU6IGkgKyAxIH0pKTtcclxuICBtaW51dGVzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogNjAgfSwgKF8sIGkpID0+IGkpO1xyXG4gIGhvdXJzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogMjQgfSwgKF8sIGkpID0+IGkpO1xyXG5cclxuICBleHByZXNzaW9uOiBhbnlbXSA9IFsnKicsJyonLCcqJywnKicsJyonLCcqJ107XHJcbiAgZGVzY3JpcHRpb246IHN0cmluZyA9ICcnO1xyXG4gIG9jY3VycmVuY2VzOiBzdHJpbmc9ICcnO1xyXG5cclxuICBASW5wdXQoJ2luaXRpYWxWYWx1ZScpIGluaXRpYWxWYWx1ZSE6IHN0cmluZztcclxuICBASW5wdXQoJ3BlcmlvZGljaXRpZXNEaXNwbGF5ZWQnKSBwZXJpb2RpY2l0aWVzRGlzcGxheWVkITogQ3JvblBlcmlvZGljaXR5VHlwZVtdO1xyXG4gIEBJbnB1dCgnaGFzQ29udGFpbmVyJykgaGFzQ29udGFpbmVyOiBib29sZWFuID0gdHJ1ZTtcclxuICBASW5wdXQoJ29jY3VycmVuY2VzTnVtYmVyJykgb2NjdXJyZW5jZXNOdW1iZXI6IG51bWJlciA9IDU7XHJcbiAgQElucHV0KCd0cmFuc2xhdGlvbnNPYmplY3QnKSB0cmFuc2xhdGlvbnNPYmplY3Q6IENyb25Db21wb25lbnRUcmFuc2xhdGlvbnMgPSB7XHJcbiAgICBwZXJpb2RpY2l0aWVzOiB7XHJcbiAgICAgIGV2ZXJ5WE1pbnV0ZXM6IFwiUmVwZXRpciBjYWRhIFggbWludXRvc1wiLFxyXG4gICAgICBldmVyeU1pbnV0ZTogXCJSZXBldGlyIGNhZGEgbWludXRvXCIsXHJcbiAgICAgIGV2ZXJ5WEhvdXJzOiBcIlJlcGV0aXIgY2FkYSBYIGhvcmFzXCIsXHJcbiAgICAgIGV2ZXJ5SG91ck9mRGF5OiBcIlJlcGV0aXIgY2FkYSBob3JhIGRlbCBkw61hXCIsXHJcbiAgICAgIGV2ZXJ5WERheXM6IFwiUmVwZXRpciBjYWRhIFggZMOtYXNcIixcclxuICAgICAgZXZlcnlXZWVrOiBcIlJlcGV0aXIgY2FkYSBzZW1hbmFcIixcclxuICAgICAgZXZlcnlNb250aDogXCJSZXBldGlyIGNhZGEgbWVzXCIsXHJcbiAgICAgIGV2ZXJ5WE1vbnRoczogXCJSZXBldGlyIFggbWVzZXNcIixcclxuICAgIH0sXHJcbiAgICBtb250aHM6IHtcclxuICAgICAgamFudWFyeTogXCJFbmVybyAoMSlcIixcclxuICAgICAgZmVicnVhcnk6IFwiRmVicmVybyAoMilcIixcclxuICAgICAgbWFyY2g6IFwiTWFyem8gKDMpXCIsXHJcbiAgICAgIGFwcmlsOiBcIkFicmlsICg0KVwiLFxyXG4gICAgICBtYXk6IFwiTWF5byAoNSlcIixcclxuICAgICAganVuZTogXCJKdW5pbyAoNilcIixcclxuICAgICAganVseTogXCJKdWxpbyAoNylcIixcclxuICAgICAgYXVndXN0OiBcIkFnb3N0byAoOClcIixcclxuICAgICAgc2VwdGVtYmVyOiBcIlNlcHRpZW1icmUgKDkpXCIsXHJcbiAgICAgIG9jdG9iZXI6IFwiT2N0dWJyZSAoMTApXCIsXHJcbiAgICAgIG5vdmVtYmVyOiBcIk5vdmllbWJyZSAoMTEpXCIsXHJcbiAgICAgIGRlY2VtYmVyOiBcIkRpY2llbWJyZSAoMTIpXCJcclxuICAgIH0sXHJcbiAgICB3ZWVrRGF5czoge1xyXG4gICAgICBzdW5kYXk6IFwiRG9taW5nbyAoMClcIixcclxuICAgICAgbW9uZGF5OiBcIkx1bmVzICgxKVwiLFxyXG4gICAgICB0dWVzZGF5OiBcIk1hcnRlcyAoMilcIixcclxuICAgICAgd2VkbmVzZGF5OiBcIk1pZXJjb2xlcyAoMylcIixcclxuICAgICAgdGh1cnNkYXk6IFwiSnVldmVzICg0KVwiLFxyXG4gICAgICBmcmlkYXk6IFwiVmllcm5lcyAoNSlcIixcclxuICAgICAgc2F0dXJkYXk6IFwiU2FiYWRvICg2KVwiXHJcbiAgICB9LFxyXG4gICAgcGVyaW9kaWNpdHlMYWJlbDogXCJQZXJpb2RpY2lkYWRcIixcclxuICAgIG1pbnV0ZUxhYmVsOiBcIk1pbnV0b1wiLFxyXG4gICAgaG91ckxhYmVsOiBcIkhvcmFcIixcclxuICAgIGRheXNMYWJlbDogXCJEw61hXCIsXHJcbiAgICB3ZWVrRGF5c0xhYmVsOiBcIkTDrWFzIGRlIGxhIHNlbWFuYVwiLFxyXG4gICAgbW9udGhzTGFiZWw6IFwiTWVzZXNcIixcclxuICAgIGRlc2NyaXB0aW9uTGFiZWw6IFwiRGVzY3JpcGNpw7NuXCIsXHJcbiAgICBvY2N1cnJlbmNlc0xhYmVsOiBcIkxhcyBzaWd1aWVudGVzIDUgb2N1cnJlbmNpYXMgc2Vyw6FuOiBcIlxyXG4gIH07XHJcblxyXG4gIEBPdXRwdXQoJ2Nyb25FeHByZXNzaW9uJykgY3JvbkV4cHJlc3Npb246IEV2ZW50RW1pdHRlcjxzdHJpbmc+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xyXG4gIFxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBmb3JtQnVpbGRlcjogRm9ybUJ1aWxkZXIsXHJcbiAgICBwdWJsaWMgZm9ybUNvbnRyb2xTZXJ2aWNlOiBGb3JtQ29udHJvbFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHdhcHBEYXRlOiBXRGF0ZVBpcGVcclxuICApIHsgfVxyXG4gIFxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy5pbml0Rm9ybUdyb3VwKCk7XHJcbiAgICB0aGlzLmluaXRQZXJpb2RpY2l0aWVzKCk7XHJcbiAgICB0aGlzLmluaXRNb250aHMoKTtcclxuICAgIHRoaXMuaW5pdFdlZWtEYXlzKCk7XHJcblxyXG4gICAgaWYodGhpcy5pbml0aWFsVmFsdWUpIHtcclxuICAgICAgdGhpcy5pbml0UGFyc2VkVmFsdWVzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpbml0Rm9ybUdyb3VwKCkge1xyXG4gICAgaWYodGhpcy5pbml0aWFsVmFsdWUpIHtcclxuICAgICAgY29uc3QgcGFydHMgPSB0aGlzLmluaXRpYWxWYWx1ZS5zcGxpdChcIiBcIik7XHJcblxyXG4gICAgICB0aGlzLmZvcm1Hcm91cCA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xyXG4gICAgICAgIHBlcmlvZGljaXR5OiBuZXcgRm9ybUNvbnRyb2woKSxcclxuICAgICAgICBtaW51dGVzOiBuZXcgRm9ybUNvbnRyb2woXHJcbiAgICAgICAgICB0aGlzLmhhc0luaXRpYWxWYWx1ZShcclxuICAgICAgICAgICAgcGFydHNbQ3JvbkZpZWxkVHlwZS5NaW51dGVdKSA/IFxyXG4gICAgICAgICAgICB0aGlzLmZvcm1hdENyb25OdW1iZXIocGFydHNbQ3JvbkZpZWxkVHlwZS5NaW51dGVdKVxyXG4gICAgICAgICAgICA6IDApLFxyXG4gICAgICAgIGhvdXJzOiBuZXcgRm9ybUNvbnRyb2woXHJcbiAgICAgICAgICB0aGlzLmhhc0luaXRpYWxWYWx1ZShcclxuICAgICAgICAgICAgcGFydHNbQ3JvbkZpZWxkVHlwZS5Ib3VyXSkgPyBcclxuICAgICAgICAgICAgdGhpcy5mb3JtYXRDcm9uTnVtYmVyKHBhcnRzW0Nyb25GaWVsZFR5cGUuSG91cl0pXHJcbiAgICAgICAgICAgIDogMCksXHJcbiAgICAgICAgd2Vla0RheXM6IG5ldyBGb3JtQ29udHJvbChcclxuICAgICAgICAgIHRoaXMuaGFzSW5pdGlhbFZhbHVlKFxyXG4gICAgICAgICAgICBwYXJ0c1tDcm9uRmllbGRUeXBlLldlZWtEYXldKSA/IFxyXG4gICAgICAgICAgICBwYXJ0c1tDcm9uRmllbGRUeXBlLldlZWtEYXldLnJlcGxhY2UoL1xcLy9nLCAnJykuc3BsaXQoJywnKS5tYXAoTnVtYmVyKVxyXG4gICAgICAgICAgICA6IFtdKSxcclxuICAgICAgICBtb250aERheTogbmV3IEZvcm1Db250cm9sKFxyXG4gICAgICAgICAgdGhpcy5oYXNJbml0aWFsVmFsdWUoXHJcbiAgICAgICAgICAgIHBhcnRzW0Nyb25GaWVsZFR5cGUuTW9udGhEYXldKSA/IFxyXG4gICAgICAgICAgICB0aGlzLmZvcm1hdENyb25OdW1iZXIocGFydHNbQ3JvbkZpZWxkVHlwZS5Nb250aERheV0pXHJcbiAgICAgICAgICAgIDogMSksXHJcbiAgICAgICAgbW9udGhEYXlzOiBuZXcgRm9ybUNvbnRyb2woXHJcbiAgICAgICAgICB0aGlzLmhhc0luaXRpYWxWYWx1ZShwYXJ0c1tDcm9uRmllbGRUeXBlLk1vbnRoRGF5XSkgPyBcclxuICAgICAgICAgICAgcGFydHNbQ3JvbkZpZWxkVHlwZS5Nb250aERheV0ucmVwbGFjZSgvWy8qXS9nLCAnJykuc3BsaXQoJywnKS5tYXAoTnVtYmVyKVxyXG4gICAgICAgICAgICA6IFtdKSxcclxuICAgICAgICBtb250aHM6IG5ldyBGb3JtQ29udHJvbChcclxuICAgICAgICAgIHRoaXMuaGFzSW5pdGlhbFZhbHVlKHBhcnRzW0Nyb25GaWVsZFR5cGUuTW9udGhdKSA/IFxyXG4gICAgICAgICAgICBwYXJ0c1tDcm9uRmllbGRUeXBlLk1vbnRoXS5yZXBsYWNlKC9cXC8vZywgJycpLnNwbGl0KCcsJykubWFwKE51bWJlcilcclxuICAgICAgICAgICAgOiAwKSxcclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmZvcm1Hcm91cCA9IHRoaXMuZm9ybUJ1aWxkZXIuZ3JvdXAoe1xyXG4gICAgICAgIHBlcmlvZGljaXR5OiBuZXcgRm9ybUNvbnRyb2woMCksXHJcbiAgICAgICAgbWludXRlczogbmV3IEZvcm1Db250cm9sKDApLFxyXG4gICAgICAgIGhvdXJzOiBuZXcgRm9ybUNvbnRyb2woMCksXHJcbiAgICAgICAgd2Vla0RheXM6IG5ldyBGb3JtQ29udHJvbChbXSksXHJcbiAgICAgICAgbW9udGhEYXk6IG5ldyBGb3JtQ29udHJvbCgxKSxcclxuICAgICAgICBtb250aERheXM6IG5ldyBGb3JtQ29udHJvbChbXSksXHJcbiAgICAgICAgbW9udGhzOiBuZXcgRm9ybUNvbnRyb2woMCksXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaGFzSW5pdGlhbFZhbHVlKHBhcnQ6IHN0cmluZykge1xyXG4gICAgaWYocGFydCA9PSAnKicgfHwgcGFydCA9PSAnMCcpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBmb3JtYXRDcm9uTnVtYmVyKGNyb25WYWx1ZTogc3RyaW5nKSB7XHJcbiAgICByZXR1cm4gK2Nyb25WYWx1ZS5yZXBsYWNlKC9bLypdL2csICcnKTtcclxuICB9XHJcblxyXG4gIGluaXRQZXJpb2RpY2l0aWVzKCkge1xyXG4gICAgY29uc3QgdHJhbnNsYXRpb25zTWFwID0ge1xyXG4gICAgICBbQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVhNaW51dGVzXTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3QucGVyaW9kaWNpdGllcy5ldmVyeVhNaW51dGVzLFxyXG4gICAgICBbQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeU1pbnV0ZV06IHRoaXMudHJhbnNsYXRpb25zT2JqZWN0LnBlcmlvZGljaXRpZXMuZXZlcnlNaW51dGUsXHJcbiAgICAgIFtDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WEhvdXJzXTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3QucGVyaW9kaWNpdGllcy5ldmVyeVhIb3VycyxcclxuICAgICAgW0Nyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlIb3VyT2ZEYXldOiB0aGlzLnRyYW5zbGF0aW9uc09iamVjdC5wZXJpb2RpY2l0aWVzLmV2ZXJ5SG91ck9mRGF5LFxyXG4gICAgICBbQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVhEYXlzXTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3QucGVyaW9kaWNpdGllcy5ldmVyeVhEYXlzLFxyXG4gICAgICBbQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVdlZWtdOiB0aGlzLnRyYW5zbGF0aW9uc09iamVjdC5wZXJpb2RpY2l0aWVzLmV2ZXJ5V2VlayxcclxuICAgICAgW0Nyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlNb250aF06IHRoaXMudHJhbnNsYXRpb25zT2JqZWN0LnBlcmlvZGljaXRpZXMuZXZlcnlNb250aCxcclxuICAgICAgW0Nyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTW9udGhzXTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3QucGVyaW9kaWNpdGllcy5ldmVyeVhNb250aHMsXHJcbiAgICB9O1xyXG5cclxuICAgIGlmICh0aGlzLnBlcmlvZGljaXRpZXNEaXNwbGF5ZWQpIHtcclxuICAgICAgdGhpcy5wZXJpb2RpY2l0aWVzID0gdGhpcy5wZXJpb2RpY2l0aWVzRGlzcGxheWVkLm1hcChwZXJpb2RpY2l0eSA9PiAoe1xyXG4gICAgICAgIHZhbHVlOiBwZXJpb2RpY2l0eSxcclxuICAgICAgICBuYW1lOiB0cmFuc2xhdGlvbnNNYXBbcGVyaW9kaWNpdHldXHJcbiAgICAgIH0pKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucGVyaW9kaWNpdGllcyA9IE9iamVjdC5lbnRyaWVzKHRyYW5zbGF0aW9uc01hcCkubWFwKChba2V5LCB2YWx1ZV0pID0+ICh7XHJcbiAgICAgICAgdmFsdWU6IE51bWJlcihrZXkpLCBcclxuICAgICAgICBuYW1lOiB2YWx1ZVxyXG4gICAgICB9KSk7XHJcbiAgICB9XHJcbiAgICBpZighdGhpcy5pbml0aWFsVmFsdWUpIHtcclxuICAgICAgdGhpcy5wZXJpb2RpY2l0eVNlbGVjdGVkID0gdGhpcy5wZXJpb2RpY2l0aWVzWzBdPy52YWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGluaXRQYXJzZWRWYWx1ZXMoKSB7XHJcbiAgICB0aGlzLmV4cHJlc3Npb24gPSB0aGlzLnBhcnNlQ3JvbkV4cHJlc3Npb24odGhpcy5pbml0aWFsVmFsdWUpO1xyXG4gICAgXHJcbiAgICB0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQgPSB0aGlzLmdldENyb25QZXJpb2RpY2l0eVR5cGUodGhpcy5pbml0aWFsVmFsdWUpITtcclxuICAgIHRoaXMuaGFuZGxlWmVyb0hvdXJzQXJyYXkoKTtcclxuICAgIHRoaXMuY3JvblRvSHVtYW4oKTtcclxuICB9XHJcblxyXG4gIHBhcnNlQ3JvbkV4cHJlc3Npb24oY3Jvbjogc3RyaW5nKTogYW55W10ge1xyXG4gICAgY29uc3QgcGFydHMgPSBjcm9uLnNwbGl0KFwiIFwiKTtcclxuICAgIFxyXG4gICAgd2hpbGUgKHBhcnRzLmxlbmd0aCA8IDYpIHtcclxuICAgICAgcGFydHMucHVzaCgnKicpO1xyXG4gICAgfVxyXG4gIFxyXG4gICAgcmV0dXJuIHBhcnRzO1xyXG4gIH1cclxuXHJcbiAgaW5pdE1vbnRocygpIHtcclxuICAgIHRoaXMubW9udGhzID0gW1xyXG4gICAgICB7IHZhbHVlOiAxLCBuYW1lOiB0aGlzLnRyYW5zbGF0aW9uc09iamVjdC5tb250aHMuamFudWFyeSB9LCBcclxuICAgICAgeyB2YWx1ZTogMiwgbmFtZTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3QubW9udGhzLmZlYnJ1YXJ5IH0sIFxyXG4gICAgICB7IHZhbHVlOiAzLCBuYW1lOiB0aGlzLnRyYW5zbGF0aW9uc09iamVjdC5tb250aHMubWFyY2ggfSwgXHJcbiAgICAgIHsgdmFsdWU6IDQsIG5hbWU6IHRoaXMudHJhbnNsYXRpb25zT2JqZWN0Lm1vbnRocy5hcHJpbCB9LCBcclxuICAgICAgeyB2YWx1ZTogNSwgbmFtZTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3QubW9udGhzLm1heSB9LCBcclxuICAgICAgeyB2YWx1ZTogNiwgbmFtZTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3QubW9udGhzLmp1bmUgfSwgXHJcbiAgICAgIHsgdmFsdWU6IDcsIG5hbWU6IHRoaXMudHJhbnNsYXRpb25zT2JqZWN0Lm1vbnRocy5qdWx5IH0sIFxyXG4gICAgICB7IHZhbHVlOiA4LCBuYW1lOiB0aGlzLnRyYW5zbGF0aW9uc09iamVjdC5tb250aHMuYXVndXN0IH0sIFxyXG4gICAgICB7IHZhbHVlOiA5LCBuYW1lOiB0aGlzLnRyYW5zbGF0aW9uc09iamVjdC5tb250aHMuc2VwdGVtYmVyIH0sIFxyXG4gICAgICB7IHZhbHVlOiAxMCwgbmFtZTp0aGlzLnRyYW5zbGF0aW9uc09iamVjdC5tb250aHMub2N0b2JlciB9LCBcclxuICAgICAgeyB2YWx1ZTogMTEsIG5hbWU6dGhpcy50cmFuc2xhdGlvbnNPYmplY3QubW9udGhzLm5vdmVtYmVyIH0sIFxyXG4gICAgICB7IHZhbHVlOiAxMiwgbmFtZTp0aGlzLnRyYW5zbGF0aW9uc09iamVjdC5tb250aHMuZGVjZW1iZXIgfSwgXHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgaW5pdFdlZWtEYXlzKCkge1xyXG4gICAgdGhpcy53ZWVrRGF5cyA9IFtcclxuICAgICAgeyB2YWx1ZTogMCwgbmFtZTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3Qud2Vla0RheXMuc3VuZGF5IH0sIFxyXG4gICAgICB7IHZhbHVlOiAxLCBuYW1lOiB0aGlzLnRyYW5zbGF0aW9uc09iamVjdC53ZWVrRGF5cy5tb25kYXkgfSwgXHJcbiAgICAgIHsgdmFsdWU6IDIsIG5hbWU6IHRoaXMudHJhbnNsYXRpb25zT2JqZWN0LndlZWtEYXlzLnR1ZXNkYXkgfSwgXHJcbiAgICAgIHsgdmFsdWU6IDMsIG5hbWU6IHRoaXMudHJhbnNsYXRpb25zT2JqZWN0LndlZWtEYXlzLndlZG5lc2RheSB9LCBcclxuICAgICAgeyB2YWx1ZTogNCwgbmFtZTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3Qud2Vla0RheXMudGh1cnNkYXkgfSwgXHJcbiAgICAgIHsgdmFsdWU6IDUsIG5hbWU6IHRoaXMudHJhbnNsYXRpb25zT2JqZWN0LndlZWtEYXlzLmZyaWRheSB9LCBcclxuICAgICAgeyB2YWx1ZTogNiwgbmFtZTogdGhpcy50cmFuc2xhdGlvbnNPYmplY3Qud2Vla0RheXMuc2F0dXJkYXkgfSwgXHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgYWxsb3dTZWNvbmRzKCkge1xyXG4gICAgcmV0dXJuIGZhbHNlOyBcclxuICB9XHJcblxyXG4gIGFsbG93TWludXRlcygpIHtcclxuICAgIHN3aXRjaCh0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQpe1xyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTWludXRlczpcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5TWludXRlOlxyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYSG91cnM6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeUhvdXJPZkRheTpcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WERheXM6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVdlZWs6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeU1vbnRoOlxyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTW9udGhzOiBcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgZGVmYXVsdDogXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYWxsb3dIb3VycygpIHtcclxuICAgIHN3aXRjaCh0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQpe1xyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYSG91cnM6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeUhvdXJPZkRheTpcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WERheXM6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVdlZWs6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeU1vbnRoOlxyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTW9udGhzOiBcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgZGVmYXVsdDogXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYWxsb3dXZWVrRGF5cygpIHtcclxuICAgIHN3aXRjaCh0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQpe1xyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlXZWVrOlxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICBkZWZhdWx0OiBcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhbGxvd01vbnRoRGF5KCkge1xyXG4gICAgc3dpdGNoKHRoaXMucGVyaW9kaWNpdHlTZWxlY3RlZCl7XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVhEYXlzOiBcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgZGVmYXVsdDogXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgYWxsb3dNb250aERheXMoKSB7XHJcbiAgICBzd2l0Y2godGhpcy5wZXJpb2RpY2l0eVNlbGVjdGVkKXtcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WE1vbnRoczogXHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeU1vbnRoOlxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICBkZWZhdWx0OiBcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBhbGxvd01vbnRocygpIHtcclxuICAgIHN3aXRjaCh0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQpe1xyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTW9udGhzOiBcclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgZGVmYXVsdDogXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaXNNb250aERheXNSZXF1aXJlZCgpIHtcclxuICAgIGlmKHRoaXMucGVyaW9kaWNpdHlTZWxlY3RlZCA9PSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WE1vbnRocykge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9IGVsc2UgeyBcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvblBlcmlvZGljaXR5U2VsZWN0ZWQoKSB7XHJcbiAgICB0aGlzLnJlc3RhcnRFeHByZXNzaW9uKCk7XHJcbiAgICB0aGlzLmhhbmRsZVplcm9Ib3Vyc0FycmF5KCk7XHJcbiAgICB0aGlzLnVwZGF0ZU1vbnRoRGF5c1JlcXVpcmVtZW50KCk7XHJcbiAgICB0aGlzLm9uSG91cnNTZWxlY3RlZCh0aGlzLmhvdXJTZWxlY3RlZCk7XHJcbiAgICB0aGlzLm9uV2Vla0RheXNTZWxlY3RlZCh0aGlzLndlZWtEYXlTZWxlY3RlZCk7XHJcbiAgICB0aGlzLm9uTW9udGhzU2VsZWN0ZWQodGhpcy5tb250aFNlbGVjdGVkKTtcclxuICAgIHRoaXMub25Nb250aERheXNTZWxlY3RlZCh0aGlzLm1vbnRoRGF5c1NlbGVjdGVkKTtcclxuICAgIHRoaXMub25Nb250aERheVNlbGVjdGVkKHRoaXMubW9udGhEYXlTZWxlY3RlZCk7XHJcbiAgICB0aGlzLm9uTWludXRlU2VsZWN0ZWQodGhpcy5taW51dGVTZWxlY3RlZCk7XHJcbiAgfVxyXG5cclxuICBoYW5kbGVaZXJvSG91cnNBcnJheSgpIHtcclxuICAgIGlmICh0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQgPT0gQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVhIb3Vycykge1xyXG4gICAgICB0aGlzLmhvdXJzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogMjMgfSwgKF8sIGkpID0+IGkgKyAxKTtcclxuICAgICAgaWYodGhpcy5ob3VyU2VsZWN0ZWQgPT0gMCkge1xyXG4gICAgICAgIHRoaXMuaG91clNlbGVjdGVkID0gMTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5ob3VycyA9IEFycmF5LmZyb20oeyBsZW5ndGg6IDI0IH0sIChfLCBpKSA9PiBpKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uTWludXRlU2VsZWN0ZWQobWludXRlU2VsZWN0ZWQ6IG51bWJlcikge1xyXG4gICAgc3dpdGNoKHRoaXMucGVyaW9kaWNpdHlTZWxlY3RlZCl7XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVhNaW51dGVzOiB7XHJcbiAgICAgICAgdGhpcy5leHByZXNzaW9uW0Nyb25GaWVsZFR5cGUuU2Vjb25kXSA9IGAwYDtcclxuICAgICAgICB0aGlzLmV4cHJlc3Npb25bQ3JvbkZpZWxkVHlwZS5NaW51dGVdID0gYCovJHttaW51dGVTZWxlY3RlZH1gO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeU1pbnV0ZTpcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5SG91ck9mRGF5OlxyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYSG91cnM6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVhEYXlzOlxyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlXZWVrOlxyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlNb250aDpcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WE1vbnRoczoge1xyXG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbltDcm9uRmllbGRUeXBlLlNlY29uZF0gPSBgMGA7XHJcbiAgICAgICAgdGhpcy5leHByZXNzaW9uW0Nyb25GaWVsZFR5cGUuTWludXRlXSA9IGAke21pbnV0ZVNlbGVjdGVkfWA7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRoaXMuY3JvblRvSHVtYW4oKTtcclxuICB9XHJcblxyXG4gIG9uSG91cnNTZWxlY3RlZChob3Vyc1NlbGVjdGVkOiBudW1iZXIpIHtcclxuICAgIHRoaXMuZXhwcmVzc2lvbltDcm9uRmllbGRUeXBlLk1pbnV0ZV0gPSBgJHt0aGlzLm1pbnV0ZVNlbGVjdGVkfWA7XHJcbiAgICBzd2l0Y2godGhpcy5wZXJpb2RpY2l0eVNlbGVjdGVkKXtcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WEhvdXJzOlxyXG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbltDcm9uRmllbGRUeXBlLkhvdXJdID0gYCovJHtob3Vyc1NlbGVjdGVkfWA7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeUhvdXJPZkRheTpcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WERheXM6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVdlZWs6XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeU1vbnRoOlxyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTW9udGhzOiBcclxuICAgICAgICB0aGlzLmV4cHJlc3Npb25bQ3JvbkZpZWxkVHlwZS5Ib3VyXSA9IGAke2hvdXJzU2VsZWN0ZWR9YDtcclxuICAgICAgICBicmVhaztcclxuICAgIH1cclxuICAgIHRoaXMuY3JvblRvSHVtYW4oKTtcclxuICB9XHJcblxyXG4gIG9uV2Vla0RheXNTZWxlY3RlZCh3ZWVrRGF5c1NlbGVjdGVkOiBudW1iZXJbXSkge1xyXG4gICAgc3dpdGNoKHRoaXMucGVyaW9kaWNpdHlTZWxlY3RlZCl7XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVdlZWs6IHtcclxuICAgICAgICB0aGlzLmV4cHJlc3Npb25bQ3JvbkZpZWxkVHlwZS5XZWVrRGF5XSA9IGAke3dlZWtEYXlzU2VsZWN0ZWR9YDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgdGhpcy5jcm9uVG9IdW1hbigpO1xyXG4gIH1cclxuXHJcbiAgb25Nb250aERheXNTZWxlY3RlZChtb250aERheXNTZWxlY3RlZDogYW55KSB7XHJcbiAgICBzd2l0Y2godGhpcy5wZXJpb2RpY2l0eVNlbGVjdGVkKXtcclxuICAgICAgY2FzZSBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WERheXM6XHJcbiAgICAgICAgICB0aGlzLmV4cHJlc3Npb25bQ3JvbkZpZWxkVHlwZS5Nb250aERheV0gPSBgKi8ke3RoaXMubW9udGhEYXlTZWxlY3RlZH1gO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeU1vbnRoOlxyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTW9udGhzOiBcclxuICAgICAgICBpZihtb250aERheXNTZWxlY3RlZCBpbnN0YW5jZW9mIEFycmF5ICYmIG1vbnRoRGF5c1NlbGVjdGVkLmxlbmd0aCA9PSAwKSB7XHJcbiAgICAgICAgICB0aGlzLmV4cHJlc3Npb25bQ3JvbkZpZWxkVHlwZS5Nb250aERheV0gPSBgKmA7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuZXhwcmVzc2lvbltDcm9uRmllbGRUeXBlLk1vbnRoRGF5XSA9IGAke21vbnRoRGF5c1NlbGVjdGVkfWA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgdGhpcy5jcm9uVG9IdW1hbigpO1xyXG4gIH1cclxuXHJcbiAgb25Nb250aERheVNlbGVjdGVkKG1vbnRoRGF5c1NlbGVjdGVkOiBhbnkpIHtcclxuICAgIHN3aXRjaCh0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQpe1xyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYRGF5czpcclxuICAgICAgICAgIHRoaXMuZXhwcmVzc2lvbltDcm9uRmllbGRUeXBlLk1vbnRoRGF5XSA9IGAqLyR7bW9udGhEYXlzU2VsZWN0ZWR9YDtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgfVxyXG4gICAgdGhpcy5jcm9uVG9IdW1hbigpO1xyXG4gIH1cclxuXHJcbiAgb25Nb250aHNTZWxlY3RlZChtb250aHNTZWxlY3RlZDogbnVtYmVyW10pIHtcclxuICAgIHN3aXRjaCh0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQpe1xyXG4gICAgICBjYXNlIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTW9udGhzOiB7XHJcbiAgICAgICAgdGhpcy5leHByZXNzaW9uW0Nyb25GaWVsZFR5cGUuU2Vjb25kXSA9IGAwYDtcclxuICAgICAgICB0aGlzLmV4cHJlc3Npb25bQ3JvbkZpZWxkVHlwZS5Nb250aF0gPSBgJHttb250aHNTZWxlY3RlZH1gO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLmNyb25Ub0h1bWFuKCk7XHJcbiAgfVxyXG5cclxuICBjcm9uVG9IdW1hbigpIHtcclxuICAgIHRoaXMuZGVzY3JpcHRpb24gPSBjcm9uc3RydWUudG9TdHJpbmcodGhpcy5leHByZXNzaW9uLmpvaW4oJyAnKSwge2xvY2FsZTogd2luZG93Lm5hdmlnYXRvci5sYW5ndWFnZS5zbGljZSgwLDIpIH0pO1xyXG4gICAgXHJcbiAgICBjb25zdCBvcHRpb25zID0ge1xyXG4gICAgICBjdXJyZW50RGF0ZTogbmV3IERhdGUoKSxcclxuICAgIH07XHJcbiAgICBcclxuICAgIGNvbnN0IGludGVydmFsID0gQ3JvbkV4cHJlc3Npb25QYXJzZXIucGFyc2UodGhpcy5leHByZXNzaW9uLmpvaW4oJyAnKSwgb3B0aW9ucyk7XHJcblxyXG4gICAgbGV0IGRhdGVzID0gaW50ZXJ2YWwudGFrZSh0aGlzLm9jY3VycmVuY2VzTnVtYmVyKS5tYXAoKGRhdGUpID0+IG5ldyBEYXRlKGRhdGUudG9TdHJpbmcoKSkpO1xyXG4gICAgdGhpcy5vY2N1cnJlbmNlcyA9IGRhdGVzLm1hcChkID0+IHRoaXMud2FwcERhdGUudHJhbnNmb3JtKGQsIFdEYXRlUGlwZUZvcm1hdFR5cGUuRykpLmpvaW4oXCIsIFwiKTtcclxuXHJcbiAgICBsZXQgY3JvbkV4cHJlc3Npb246IHN0cmluZyA9IHRoaXMuZXhwcmVzc2lvbi5qb2luKCcgJyk7XHJcblxyXG4gICAgaWYoIVtDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WE1pbnV0ZXMsIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlNaW51dGUsIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYSG91cnNdLmluY2x1ZGVzKHRoaXMucGVyaW9kaWNpdHlTZWxlY3RlZCkpIHtcclxuICAgICAgY3JvbkV4cHJlc3Npb24gPSB0aGlzLmxvY2FsVXNlckNyb25Ub1VUQ0Nyb24odGhpcy5leHByZXNzaW9uLmpvaW4oJyAnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jcm9uRXhwcmVzc2lvbi5lbWl0KGNyb25FeHByZXNzaW9uKTtcclxuICB9XHJcblxyXG4gIGxvY2FsVXNlckNyb25Ub1VUQ0Nyb24oY3JvbkV4cHJlc3Npb246IHN0cmluZykge1xyXG4gICAgXHJcbiAgICBjb25zdCBjcm9uUGFydHMgPSBjcm9uRXhwcmVzc2lvbi50cmltKCkuc3BsaXQoJyAnKTtcclxuICAgIGNvbnN0IHVzZXJPZmZzZXQgPSAtKG5ldyBEYXRlKCkuZ2V0VGltZXpvbmVPZmZzZXQoKSAvIDYwKTtcclxuICAgIGNvbnN0IGxvY2FsSG91ciA9IHBhcnNlSW50KGNyb25QYXJ0c1syXSwgMTApO1xyXG5cclxuICAgIGxldCB1dGNIb3VyID0gbG9jYWxIb3VyIC0gdXNlck9mZnNldDtcclxuICAgIGxldCBkYXlBZGp1c3RtZW50ID0gMDtcclxuICBcclxuICAgIGlmICh1dGNIb3VyID49IDI0KSB7XHJcbiAgICAgIHV0Y0hvdXIgLT0gMjQ7XHJcbiAgICAgIGRheUFkanVzdG1lbnQgPSAxO1xyXG4gICAgfSBlbHNlIGlmICh1dGNIb3VyIDwgMCkge1xyXG4gICAgICB1dGNIb3VyICs9IDI0O1xyXG4gICAgICBkYXlBZGp1c3RtZW50ID0gLTE7XHJcbiAgICB9XHJcbiAgXHJcbiAgICBjcm9uUGFydHNbMl0gPSB1dGNIb3VyLnRvU3RyaW5nKCk7XHJcbiAgXHJcbiAgICByZXR1cm4gY3JvblBhcnRzLmpvaW4oJyAnKTtcclxuICB9XHJcblxyXG4gIGZvcm1hdEFycmF5VmFsdWVzKGFycmF5OiBhbnlbXSkge1xyXG4gICAgcmV0dXJuIGFycmF5Py5tYXAoYSA9PiBhLnZhbHVlKS5qb2luKCcsJyk7XHJcbiAgfVxyXG5cclxuICByZXN0YXJ0RXhwcmVzc2lvbigpIHtcclxuICAgIHRoaXMuZXhwcmVzc2lvbiA9IFsnKicsJyonLCcqJywnKicsJyonLCcqJ107XHJcbiAgfVxyXG5cclxuICBnZXRDcm9uUGVyaW9kaWNpdHlUeXBlKGNyb246IHN0cmluZyk6IENyb25QZXJpb2RpY2l0eVR5cGUgfCBudWxsIHtcclxuICAgIGNvbnN0IHBhcnRzID0gY3Jvbi5zcGxpdChcIiBcIik7XHJcbiAgXHJcbiAgICBpZiAocGFydHMubGVuZ3RoICE9PSA2KSB7XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gIFxyXG4gICAgY29uc3QgW3NlY29uZCwgbWludXRlLCBob3VyLCBkYXlPZk1vbnRoLCBtb250aCwgZGF5T2ZXZWVrXSA9IHBhcnRzO1xyXG5cclxuICAgIGlmIChtaW51dGUuc3RhcnRzV2l0aChcIiovXCIpICYmIGhvdXIgPT09IFwiKlwiICYmIGRheU9mTW9udGggPT09IFwiKlwiICYmIG1vbnRoID09PSBcIipcIiAmJiBkYXlPZldlZWsgPT09IFwiKlwiKSB7XHJcbiAgICAgIHJldHVybiBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WE1pbnV0ZXM7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG1pbnV0ZSAhPT0gXCIqXCIgJiYgaG91ciA9PT0gXCIqXCIgJiYgZGF5T2ZNb250aCA9PT0gXCIqXCIgJiYgbW9udGggPT09IFwiKlwiICYmIGRheU9mV2VlayA9PT0gXCIqXCIpIHtcclxuICAgICAgcmV0dXJuIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlNaW51dGU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGhvdXIuc3RhcnRzV2l0aChcIiovXCIpICYmIGRheU9mTW9udGggPT09IFwiKlwiICYmIG1vbnRoID09PSBcIipcIiAmJiBkYXlPZldlZWsgPT09IFwiKlwiKSB7XHJcbiAgICAgIHJldHVybiBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5WEhvdXJzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChtaW51dGUgIT09IFwiKlwiICYmIGhvdXIgIT09IFwiKlwiICYmIGRheU9mTW9udGggPT09IFwiKlwiICYmIG1vbnRoID09PSBcIipcIiAmJiBkYXlPZldlZWsgPT09IFwiKlwiKSB7XHJcbiAgICAgIHJldHVybiBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5SG91ck9mRGF5O1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkYXlPZk1vbnRoLnN0YXJ0c1dpdGgoXCIqL1wiKSAmJiBtb250aCA9PT0gXCIqXCIgJiYgZGF5T2ZXZWVrID09PSBcIipcIikge1xyXG4gICAgICByZXR1cm4gQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVhEYXlzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkYXlPZldlZWsgIT09IFwiKlwiICYmIGRheU9mTW9udGggPT09IFwiKlwiICYmIG1vbnRoID09PSBcIipcIikge1xyXG4gICAgICByZXR1cm4gQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVdlZWs7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGRheU9mTW9udGggIT09IFwiKlwiICYmIG1vbnRoID09IFwiKlwiKSB7XHJcbiAgICAgIHJldHVybiBDcm9uUGVyaW9kaWNpdHlUeXBlLkV2ZXJ5TW9udGg7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGlmIChtb250aCAhPT0gXCIqXCIpIHtcclxuICAgICAgcmV0dXJuIENyb25QZXJpb2RpY2l0eVR5cGUuRXZlcnlYTW9udGhzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlTW9udGhEYXlzUmVxdWlyZW1lbnQoKSB7XHJcbiAgICBpZih0aGlzLnBlcmlvZGljaXR5U2VsZWN0ZWQgPT0gQ3JvblBlcmlvZGljaXR5VHlwZS5FdmVyeVhNb250aHMpIHtcclxuICAgICAgdGhpcy5mb3JtR3JvdXAuY29udHJvbHNbJ21vbnRoRGF5cyddLnJlbW92ZVZhbGlkYXRvcnMoW1ZhbGlkYXRvcnMucmVxdWlyZWRdKTtcclxuICAgICAgdGhpcy5mb3JtR3JvdXAuY29udHJvbHNbJ21vbnRoRGF5cyddLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcclxuICAgIH0gZWxzZSB7IFxyXG4gICAgICB0aGlzLmZvcm1Hcm91cC5jb250cm9sc1snbW9udGhEYXlzJ10uYWRkVmFsaWRhdG9ycyhbVmFsaWRhdG9ycy5yZXF1aXJlZF0pO1xyXG4gICAgICB0aGlzLmZvcm1Hcm91cC5jb250cm9sc1snbW9udGhEYXlzJ10udXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2V0IHBlcmlvZGljaXR5U2VsZWN0ZWQodmFsdWU6IG51bWJlcikge1xyXG4gICAgdGhpcy5mb3JtR3JvdXA/LnBhdGNoVmFsdWUoe3BlcmlvZGljaXR5OiB2YWx1ZX0pO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHBlcmlvZGljaXR5U2VsZWN0ZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb3JtR3JvdXAuZ2V0KCdwZXJpb2RpY2l0eScpIS52YWx1ZTtcclxuICB9XHJcblxyXG4gIGdldCBtaW51dGVTZWxlY3RlZCgpIHtcclxuICAgIHJldHVybiB0aGlzLmZvcm1Hcm91cC5nZXQoJ21pbnV0ZXMnKSEudmFsdWU7XHJcbiAgfVxyXG5cclxuICBzZXQgaG91clNlbGVjdGVkKHZhbHVlOiBudW1iZXIpIHtcclxuICAgIHRoaXMuZm9ybUdyb3VwPy5wYXRjaFZhbHVlKHtob3VyczogdmFsdWV9KTtcclxuICB9XHJcblxyXG4gIGdldCBob3VyU2VsZWN0ZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb3JtR3JvdXAuZ2V0KCdob3VycycpIS52YWx1ZTtcclxuICB9XHJcblxyXG4gIGdldCB3ZWVrRGF5U2VsZWN0ZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb3JtR3JvdXAuZ2V0KCd3ZWVrRGF5cycpIS52YWx1ZTtcclxuICB9XHJcblxyXG4gIGdldCBtb250aERheVNlbGVjdGVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuZm9ybUdyb3VwLmdldCgnbW9udGhEYXknKSEudmFsdWU7XHJcbiAgfVxyXG5cclxuICBnZXQgbW9udGhEYXlzU2VsZWN0ZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb3JtR3JvdXAuZ2V0KCdtb250aERheXMnKSEudmFsdWU7XHJcbiAgfVxyXG5cclxuICBnZXQgbW9udGhTZWxlY3RlZCgpIHtcclxuICAgIHJldHVybiB0aGlzLmZvcm1Hcm91cC5nZXQoJ21vbnRocycpIS52YWx1ZTtcclxuICB9XHJcbn1cclxuIiwiPHctcGFuZWwgKm5nSWY9XCJoYXNDb250YWluZXI7IGVsc2UgY3JvbkNvbXBvbmVudFwiPlxyXG4gICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNyb25Db21wb25lbnRcIj48L25nLWNvbnRhaW5lcj5cclxuPC93LXBhbmVsPlxyXG5cclxuPG5nLXRlbXBsYXRlICNjcm9uQ29tcG9uZW50PlxyXG4gICAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtR3JvdXBcIiBjbGFzcz1cImNvbC0xMlwiPlxyXG4gICAgICAgIDx3LXBhbmVsLWdyaWQgY2xhc3M9XCJjb2wtMTJcIj5cclxuICAgICAgICAgICAgPHctZWRpdC1zZWxlY3QgY2xhc3M9XCJjb2wtMTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJ0cmFuc2xhdGlvbnNPYmplY3QucGVyaW9kaWNpdHlMYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cInBlcmlvZGljaXRpZXNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25WYWx1ZV09XCIndmFsdWUnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uTGFiZWxdPVwiJ25hbWUnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZm9ybUNvbnRyb2xTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1Db250cm9sKGZvcm1Hcm91cC5nZXQoJ3BlcmlvZGljaXR5JykpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwib25QZXJpb2RpY2l0eVNlbGVjdGVkKClcIj5cclxuICAgICAgICAgICAgPC93LWVkaXQtc2VsZWN0PlxyXG4gICAgICAgICAgICA8dy1lZGl0LW11bHRpc2VsZWN0ICpuZ0lmPVwiYWxsb3dNb250aHMoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtMTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJ0cmFuc2xhdGlvbnNPYmplY3QubW9udGhzTGFiZWxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uc109XCJtb250aHNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25WYWx1ZV09XCIndmFsdWUnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uTGFiZWxdPVwiJ25hbWUnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZm9ybUNvbnRyb2xTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1Db250cm9sKGZvcm1Hcm91cC5nZXQoJ21vbnRocycpKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uTW9udGhzU2VsZWN0ZWQoJGV2ZW50KVwiPlxyXG4gICAgICAgICAgICA8L3ctZWRpdC1tdWx0aXNlbGVjdD5cclxuICAgICAgICAgICAgPHctZWRpdC1tdWx0aXNlbGVjdCAqbmdJZj1cImFsbG93TW9udGhEYXlzKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLTEyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbGFiZWxdPVwidHJhbnNsYXRpb25zT2JqZWN0LmRheXNMYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cImlzTW9udGhEYXlzUmVxdWlyZWQoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwibW9udGhEYXlzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uVmFsdWVdPVwiJ3ZhbHVlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbkxhYmVsXT1cIid2YWx1ZSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFNlcnZpY2UuY29udmVydFRvRm9ybUNvbnRyb2woZm9ybUdyb3VwLmdldCgnbW9udGhEYXlzJykpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwib25Nb250aERheXNTZWxlY3RlZCgkZXZlbnQpXCI+XHJcbiAgICAgICAgICAgIDwvdy1lZGl0LW11bHRpc2VsZWN0PlxyXG4gICAgICAgICAgICA8dy1lZGl0LXNlbGVjdCAqbmdJZj1cImFsbG93TW9udGhEYXkoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtMTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJ0cmFuc2xhdGlvbnNPYmplY3QuZGF5c0xhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwibW9udGhEYXlzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uVmFsdWVdPVwiJ3ZhbHVlJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbkxhYmVsXT1cIid2YWx1ZSdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFNlcnZpY2UuY29udmVydFRvRm9ybUNvbnRyb2woZm9ybUdyb3VwLmdldCgnbW9udGhEYXknKSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvbkNoYW5nZSk9XCJvbk1vbnRoRGF5c1NlbGVjdGVkKCRldmVudClcIj5cclxuICAgICAgICAgICAgPC93LWVkaXQtc2VsZWN0PlxyXG4gICAgICAgICAgICA8dy1lZGl0LW11bHRpc2VsZWN0ICpuZ0lmPVwiYWxsb3dXZWVrRGF5cygpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC0xMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cInRyYW5zbGF0aW9uc09iamVjdC53ZWVrRGF5c0xhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwid2Vla0RheXNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25WYWx1ZV09XCIndmFsdWUnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3B0aW9uTGFiZWxdPVwiJ25hbWUnXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZm9ybUNvbnRyb2xTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1Db250cm9sKGZvcm1Hcm91cC5nZXQoJ3dlZWtEYXlzJykpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAob25DaGFuZ2UpPVwib25XZWVrRGF5c1NlbGVjdGVkKCRldmVudClcIj5cclxuICAgICAgICAgICAgPC93LWVkaXQtbXVsdGlzZWxlY3Q+XHJcbiAgICAgICAgICAgIDx3LWVkaXQtc2VsZWN0ICpuZ0lmPVwiYWxsb3dIb3VycygpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29sLTZcIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJ0cmFuc2xhdGlvbnNPYmplY3QuaG91ckxhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zXT1cImhvdXJzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFNlcnZpY2UuY29udmVydFRvRm9ybUNvbnRyb2woZm9ybUdyb3VwLmdldCgnaG91cnMnKSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uSG91cnNTZWxlY3RlZCgkZXZlbnQpXCI+XHJcbiAgICAgICAgICAgIDwvdy1lZGl0LXNlbGVjdD5cclxuICAgICAgICAgICAgPHctZWRpdC1zZWxlY3QgKm5nSWY9XCJhbGxvd01pbnV0ZXMoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7J2NvbC02JzogYWxsb3dIb3VycygpLCAnY29sLTEyJzogIWFsbG93SG91cnMoKX1cIiBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJ0cmFuc2xhdGlvbnNPYmplY3QubWludXRlTGFiZWxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cInRydWVcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNdPVwibWludXRlc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiZm9ybUNvbnRyb2xTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1Db250cm9sKGZvcm1Hcm91cC5nZXQoJ21pbnV0ZXMnKSlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uTWludXRlU2VsZWN0ZWQoJGV2ZW50KVwiPlxyXG4gICAgICAgICAgICA8L3ctZWRpdC1zZWxlY3Q+XHJcbiAgICAgICAgICAgIDx3LWVkaXQtaW5wdXQtbnVtYmVyICpuZ0lmPVwiYWxsb3dTZWNvbmRzKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNvbC02XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cIidTZWd1bmRvcydcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5dPVwiMFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhdPVwiNTlcIj5cclxuICAgICAgICAgICAgPC93LWVkaXQtaW5wdXQtbnVtYmVyPlxyXG4gICAgICAgICAgICA8dy12aWV3LXRleHQgY2xhc3M9XCJjb2wtMTJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cInRyYW5zbGF0aW9uc09iamVjdC5kZXNjcmlwdGlvbkxhYmVsXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJkZXNjcmlwdGlvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbGF5b3V0XT1cIid2ZXJ0aWNhbCdcIj5cclxuICAgICAgICAgICAgPC93LXZpZXctdGV4dD5cclxuICAgICAgICAgICAgPHctdmlldy10ZXh0IGNsYXNzPVwiY29sLTEyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtsYWJlbF09XCJ0cmFuc2xhdGlvbnNPYmplY3Qub2NjdXJyZW5jZXNMYWJlbFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwib2NjdXJyZW5jZXNcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2xheW91dF09XCIndmVydGljYWwnXCI+XHJcbiAgICAgICAgICAgIDwvdy12aWV3LXRleHQ+XHJcbiAgICAgICAgPC93LXBhbmVsLWdyaWQ+XHJcbiAgICA8L2Zvcm0+XHJcbjwvbmctdGVtcGxhdGU+Il19
|