@snabcentr/client-ui 3.52.1 → 3.52.2
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/catalog/catalog-filters/collapsible/sc-catalog-filter-collapsible.component.d.ts +47 -0
- package/catalog/catalog-filters/index.d.ts +1 -0
- package/catalog/catalog-filters/sc-catalog-filters.component.d.ts +87 -19
- package/esm2022/catalog/catalog-filters/collapsible/sc-catalog-filter-collapsible.component.mjs +59 -0
- package/esm2022/catalog/catalog-filters/index.mjs +2 -1
- package/esm2022/catalog/catalog-filters/sc-catalog-filters.component.mjs +246 -58
- package/fesm2022/snabcentr-client-ui.mjs +296 -55
- package/fesm2022/snabcentr-client-ui.mjs.map +1 -1
- package/package.json +2 -2
- package/release_notes.tmp +2 -2
- package/styles/tailwind/tailwind.scss +17 -4
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
/* eslint-disable class-methods-use-this */
|
|
2
|
-
import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, DestroyRef, inject, input, output } from '@angular/core';
|
|
3
3
|
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
|
4
|
-
import { FormControl, FormGroup,
|
|
4
|
+
import { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
5
5
|
import { SC_CATEGORY_INFO, ScCatalogFilterService, ScIdOrSlugPipe, } from '@snabcentr/client-core';
|
|
6
6
|
import { tuiIsPresent } from '@taiga-ui/cdk';
|
|
7
|
-
import { TuiTextfield } from '@taiga-ui/core';
|
|
8
|
-
import {
|
|
9
|
-
import { TuiCheckbox, TuiInputRange, TuiRadio } from '@taiga-ui/kit';
|
|
7
|
+
import { TuiButton, TuiLabel, TuiNumberFormat, TuiTextfield } from '@taiga-ui/core';
|
|
8
|
+
import { TuiCheckbox, TuiInputNumber, TuiRange } from '@taiga-ui/kit';
|
|
10
9
|
import { isNil } from 'lodash-es';
|
|
11
|
-
import { catchError, EMPTY, filter, map, share, switchMap, tap } from 'rxjs';
|
|
10
|
+
import { catchError, debounceTime, EMPTY, filter, map, merge, share, Subscription, switchMap, tap } from 'rxjs';
|
|
11
|
+
import { ScSelectOnFocusinDirective } from '../../directives/select-on-focusin/sc-select-on-focusin.directive';
|
|
12
|
+
import { ScCatalogFilterCollapsibleComponent } from './collapsible/sc-catalog-filter-collapsible.component';
|
|
12
13
|
import { SC_CATALOG_PRODUCTS_FILTERS } from './tokens/sc-catalog-products-filters';
|
|
13
14
|
import { SC_CATALOG_SHOW_PRODUCTS_RECURSIVELY } from './tokens/sc-catalog-show-products-recursively';
|
|
14
15
|
import * as i0 from "@angular/core";
|
|
15
16
|
import * as i1 from "@angular/forms";
|
|
16
|
-
import * as i2 from "@taiga-ui/
|
|
17
|
-
import * as i3 from "@taiga-ui/
|
|
18
|
-
import * as i4 from "@taiga-ui/
|
|
17
|
+
import * as i2 from "@taiga-ui/core/components/label";
|
|
18
|
+
import * as i3 from "@taiga-ui/core";
|
|
19
|
+
import * as i4 from "@taiga-ui/kit";
|
|
19
20
|
/**
|
|
20
21
|
* Компонент вывода фильтров каталога.
|
|
21
22
|
*/
|
|
@@ -25,9 +26,9 @@ export class ScCatalogFiltersComponent {
|
|
|
25
26
|
*/
|
|
26
27
|
constructor() {
|
|
27
28
|
/**
|
|
28
|
-
*
|
|
29
|
+
* Подписки синхронизации контролов формы (range slider, single-select checkbox).
|
|
29
30
|
*/
|
|
30
|
-
this.
|
|
31
|
+
this.formSyncs = new Subscription();
|
|
31
32
|
/**
|
|
32
33
|
* Сервис для работы с фильтрами каталога.
|
|
33
34
|
*/
|
|
@@ -45,16 +46,31 @@ export class ScCatalogFiltersComponent {
|
|
|
45
46
|
*/
|
|
46
47
|
this.isRecursively = inject(SC_CATALOG_SHOW_PRODUCTS_RECURSIVELY);
|
|
47
48
|
/**
|
|
48
|
-
*
|
|
49
|
+
* Показывать ли кнопку «Показать результаты».
|
|
49
50
|
*/
|
|
50
|
-
this.
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
this.showResultsButton = input(false);
|
|
52
|
+
/**
|
|
53
|
+
* Событие нажатия на кнопку сброса всех фильтров.
|
|
54
|
+
*/
|
|
55
|
+
this.resetFilters = output();
|
|
56
|
+
/**
|
|
57
|
+
* Событие нажатия на кнопку показа результатов.
|
|
58
|
+
*/
|
|
59
|
+
this.showResults = output();
|
|
53
60
|
/**
|
|
54
61
|
* FormGroup для фильтров.
|
|
55
62
|
*/
|
|
56
63
|
this.form = new FormGroup({});
|
|
57
|
-
|
|
64
|
+
/**
|
|
65
|
+
* {@link Observable} фильтров категории.
|
|
66
|
+
*/
|
|
67
|
+
this.filters = toSignal(inject(SC_CATEGORY_INFO).pipe(catchError(() => EMPTY), filter(tuiIsPresent), switchMap((category) => this.catalogFilterService.getFilters$(this.idOrSlugPipe.transform(category), this.isRecursively)), filter(tuiIsPresent), map((filters) => filters.filter((item) => item.type !== 'range' || item.min !== item.max)), tap((filters) => {
|
|
68
|
+
this.updateFormControls(filters);
|
|
69
|
+
}), share()));
|
|
70
|
+
inject(DestroyRef).onDestroy(() => {
|
|
71
|
+
this.formSyncs.unsubscribe();
|
|
72
|
+
});
|
|
73
|
+
this.form.valueChanges.pipe(debounceTime(0), takeUntilDestroyed()).subscribe((filters) => {
|
|
58
74
|
this.catalogProductsFilters$.next(this.buildPropertyFilters(filters));
|
|
59
75
|
});
|
|
60
76
|
}
|
|
@@ -64,17 +80,28 @@ export class ScCatalogFiltersComponent {
|
|
|
64
80
|
* @param filters Массив фильтров для создания контролов.
|
|
65
81
|
*/
|
|
66
82
|
updateFormControls(filters) {
|
|
83
|
+
this.formSyncs.unsubscribe();
|
|
84
|
+
this.formSyncs = new Subscription();
|
|
67
85
|
Object.keys(this.form.controls).forEach((key) => {
|
|
68
86
|
this.form.removeControl(key, { emitEvent: false });
|
|
69
87
|
});
|
|
70
88
|
filters.forEach((item) => {
|
|
71
89
|
switch (item.type) {
|
|
72
|
-
case 'checkbox':
|
|
73
|
-
|
|
90
|
+
case 'checkbox': {
|
|
91
|
+
const checkboxControl = this.createCheckboxFormControl(item);
|
|
92
|
+
this.form.addControl(item.id, checkboxControl, { emitEvent: false });
|
|
93
|
+
// Single-select для !isMultiple: при выборе одного остальные снимаются.
|
|
94
|
+
if (!item.isMultiple && item.values.length > 1) {
|
|
95
|
+
this.formSyncs.add(this.syncSingleSelectCheckbox(checkboxControl));
|
|
96
|
+
}
|
|
74
97
|
break;
|
|
75
|
-
|
|
76
|
-
|
|
98
|
+
}
|
|
99
|
+
case 'range': {
|
|
100
|
+
const rangeControl = this.createRangeFormControl(item);
|
|
101
|
+
this.form.addControl(item.id, rangeControl, { emitEvent: false });
|
|
102
|
+
this.formSyncs.add(this.syncRangeFromToAndSlider(rangeControl));
|
|
77
103
|
break;
|
|
104
|
+
}
|
|
78
105
|
case 'toggle':
|
|
79
106
|
this.form.addControl(item.id, this.createToggleFormControl(item), { emitEvent: false });
|
|
80
107
|
break;
|
|
@@ -98,7 +125,7 @@ export class ScCatalogFiltersComponent {
|
|
|
98
125
|
}
|
|
99
126
|
switch (filterItem.type) {
|
|
100
127
|
case 'checkbox':
|
|
101
|
-
this.processCheckboxFilter(result, filterItem
|
|
128
|
+
this.processCheckboxFilter(result, filterItem, controlValue);
|
|
102
129
|
break;
|
|
103
130
|
case 'range':
|
|
104
131
|
this.processRangeFilter(result, filterItem.id, controlValue);
|
|
@@ -110,34 +137,111 @@ export class ScCatalogFiltersComponent {
|
|
|
110
137
|
break;
|
|
111
138
|
}
|
|
112
139
|
});
|
|
140
|
+
console.log(result);
|
|
113
141
|
return result;
|
|
114
142
|
}
|
|
115
143
|
/**
|
|
116
|
-
*
|
|
144
|
+
* Создаёт FormGroup для checkbox: на каждый {@code value.id} — булевый контрол.
|
|
117
145
|
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
146
|
+
* Единый формат и для одного, и для множества значений: шаблон рендерит их одинаково.
|
|
147
|
+
* Различие в API-выводе для одиночного значения (boolean вместо массива) обрабатывается в {@link processCheckboxFilter}.
|
|
120
148
|
*
|
|
121
149
|
* @param checkboxFilter Фильтр типа checkbox.
|
|
122
150
|
*/
|
|
123
151
|
createCheckboxFormControl(checkboxFilter) {
|
|
124
|
-
|
|
125
|
-
return new FormControl(null);
|
|
126
|
-
}
|
|
152
|
+
const isSelected = (id) => checkboxFilter.selectedValues?.includes(id) ?? false;
|
|
127
153
|
const controls = {};
|
|
128
154
|
checkboxFilter.values.forEach((value) => {
|
|
129
|
-
controls[value.id] = new FormControl(
|
|
155
|
+
controls[value.id] = new FormControl(isSelected(value.id), { nonNullable: true });
|
|
130
156
|
});
|
|
131
157
|
return new FormGroup(controls);
|
|
132
158
|
}
|
|
133
159
|
/**
|
|
134
|
-
*
|
|
160
|
+
* Создаёт {@link FormGroup} для range: {@code from}, {@code to}, {@code slider} (кортеж для {@link TuiRange}).
|
|
135
161
|
*
|
|
136
162
|
* @param rangeFilter Фильтр типа range.
|
|
137
163
|
*/
|
|
138
164
|
createRangeFormControl(rangeFilter) {
|
|
139
|
-
|
|
140
|
-
|
|
165
|
+
const fromValue = Number(rangeFilter.selectedMin ?? rangeFilter.min);
|
|
166
|
+
const toValue = Number(rangeFilter.selectedMax ?? rangeFilter.max);
|
|
167
|
+
return new FormGroup({
|
|
168
|
+
from: new FormControl(fromValue, { nonNullable: true }),
|
|
169
|
+
to: new FormControl(toValue, { nonNullable: true }),
|
|
170
|
+
slider: new FormControl([fromValue, toValue], { nonNullable: true }),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Реализует single-select поведение для FormGroup с булевыми контролами:
|
|
175
|
+
* при появлении нового true остальные контролы группы сбрасываются в false.
|
|
176
|
+
*
|
|
177
|
+
* Сохраняет последнее «стабильное» состояние и сравнивает следующее значение с ним —
|
|
178
|
+
* новый true (отсутствовал в prev) считается выбранным, остальные сбрасываются через setValue.
|
|
179
|
+
*
|
|
180
|
+
* @param group FormGroup checkbox-фильтра (id → boolean).
|
|
181
|
+
*/
|
|
182
|
+
syncSingleSelectCheckbox(group) {
|
|
183
|
+
let previousState = group.getRawValue();
|
|
184
|
+
return group.valueChanges.subscribe((value) => {
|
|
185
|
+
const current = value;
|
|
186
|
+
const newlyChecked = Object.entries(current).find(([id, isChecked]) => {
|
|
187
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
188
|
+
return isChecked && !previousState[id];
|
|
189
|
+
})?.[0];
|
|
190
|
+
if (!newlyChecked) {
|
|
191
|
+
previousState = { ...current };
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const next = {};
|
|
195
|
+
Object.keys(group.controls).forEach((id) => {
|
|
196
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
197
|
+
next[id] = id === newlyChecked;
|
|
198
|
+
});
|
|
199
|
+
previousState = next;
|
|
200
|
+
group.setValue(next);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Связывает поля «от»/«до» с контролом слайдера.
|
|
205
|
+
*
|
|
206
|
+
* @param group FormGroup range-фильтра.
|
|
207
|
+
*/
|
|
208
|
+
syncRangeFromToAndSlider(group) {
|
|
209
|
+
const from = group.get('from');
|
|
210
|
+
const to = group.get('to');
|
|
211
|
+
const slider = group.get('slider');
|
|
212
|
+
if (!from || !to || !slider) {
|
|
213
|
+
return new Subscription();
|
|
214
|
+
}
|
|
215
|
+
const sub = new Subscription();
|
|
216
|
+
// Инпуты → слайдер; если «от» > «до», поднимаем «до» до «от».
|
|
217
|
+
const applySliderFromInputs = () => {
|
|
218
|
+
const low = Number(from.value);
|
|
219
|
+
let high = Number(to.value);
|
|
220
|
+
if (low > high) {
|
|
221
|
+
high = low;
|
|
222
|
+
to.setValue(high, { emitEvent: false });
|
|
223
|
+
}
|
|
224
|
+
const currentPair = slider.value;
|
|
225
|
+
if (currentPair[0] !== low || currentPair[1] !== high) {
|
|
226
|
+
slider.setValue([low, high], { emitEvent: false });
|
|
227
|
+
slider.markAsDirty();
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
sub.add(merge(from.valueChanges, to.valueChanges).subscribe(applySliderFromInputs));
|
|
231
|
+
sub.add(slider.valueChanges.subscribe((value) => {
|
|
232
|
+
const [low, high] = value;
|
|
233
|
+
if (from.value !== low) {
|
|
234
|
+
from.setValue(low, { emitEvent: false });
|
|
235
|
+
from.markAsDirty();
|
|
236
|
+
}
|
|
237
|
+
if (to.value !== high) {
|
|
238
|
+
to.setValue(high, { emitEvent: false });
|
|
239
|
+
to.markAsDirty();
|
|
240
|
+
}
|
|
241
|
+
}));
|
|
242
|
+
// Совпасть с полями при первом показе (уже совпадает при создании, но на всякий случай).
|
|
243
|
+
applySliderFromInputs();
|
|
244
|
+
return sub;
|
|
141
245
|
}
|
|
142
246
|
/**
|
|
143
247
|
* Создает FormControl для toggle.
|
|
@@ -148,45 +252,36 @@ export class ScCatalogFiltersComponent {
|
|
|
148
252
|
return new FormControl(toggleFilter.selectedValue ?? false, { nonNullable: true });
|
|
149
253
|
}
|
|
150
254
|
/**
|
|
151
|
-
* Обрабатывает checkbox
|
|
255
|
+
* Обрабатывает checkbox: FormGroup → string[] выбранных id; для единственного значения — boolean (как toggle).
|
|
152
256
|
*
|
|
153
257
|
* @param result Объект результата для заполнения.
|
|
154
|
-
* @param
|
|
155
|
-
* @param controlValue Значение контрола
|
|
258
|
+
* @param checkboxFilter Метафильтр checkbox.
|
|
259
|
+
* @param controlValue Значение контрола формы (запись id → boolean).
|
|
156
260
|
*/
|
|
157
|
-
processCheckboxFilter(result,
|
|
158
|
-
// Для isMultiple === false: FormControl<string | null> -> string[] из одного выбранного ID.
|
|
159
|
-
if (typeof controlValue === 'string') {
|
|
160
|
-
if (controlValue) {
|
|
161
|
-
// eslint-disable-next-line security/detect-object-injection, no-param-reassign
|
|
162
|
-
result[filterId] = [controlValue];
|
|
163
|
-
}
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
// Для checkbox: FormGroup с FormControl<boolean> -> string[] (массив ID выбранных значений).
|
|
261
|
+
processCheckboxFilter(result, checkboxFilter, controlValue) {
|
|
167
262
|
const selectedIds = Object.entries(controlValue)
|
|
168
263
|
.filter(([, isSelected]) => isSelected)
|
|
169
264
|
.map(([id]) => id);
|
|
170
|
-
if (selectedIds.length
|
|
171
|
-
|
|
172
|
-
result[filterId] = selectedIds;
|
|
265
|
+
if (selectedIds.length === 0) {
|
|
266
|
+
return;
|
|
173
267
|
}
|
|
268
|
+
// eslint-disable-next-line security/detect-object-injection, no-param-reassign
|
|
269
|
+
result[checkboxFilter.id] = selectedIds;
|
|
174
270
|
}
|
|
175
271
|
/**
|
|
176
272
|
* Обрабатывает range фильтр.
|
|
177
273
|
*
|
|
178
274
|
* @param result Объект результата для заполнения.
|
|
179
275
|
* @param filterId Идентификатор фильтра.
|
|
180
|
-
* @param
|
|
181
|
-
* @param
|
|
182
|
-
* @param
|
|
276
|
+
* @param range Значение контрола формы (объект с границами).
|
|
277
|
+
* @param range.from Начальное значение диапазона.
|
|
278
|
+
* @param range.to Конечное значение диапазона.
|
|
183
279
|
*/
|
|
184
|
-
processRangeFilter(result, filterId,
|
|
185
|
-
// Для range: FormControl<[number, number]> -> { from?: string; to?: string; }
|
|
280
|
+
processRangeFilter(result, filterId, range) {
|
|
186
281
|
// eslint-disable-next-line security/detect-object-injection, no-param-reassign
|
|
187
282
|
result[filterId] = {
|
|
188
|
-
from: String(from),
|
|
189
|
-
to: String(to),
|
|
283
|
+
from: String(range.from),
|
|
284
|
+
to: String(range.to),
|
|
190
285
|
};
|
|
191
286
|
}
|
|
192
287
|
/**
|
|
@@ -197,17 +292,110 @@ export class ScCatalogFiltersComponent {
|
|
|
197
292
|
* @param controlValue Значение контрола формы.
|
|
198
293
|
*/
|
|
199
294
|
processToggleFilter(result, filterId, controlValue) {
|
|
200
|
-
// Для toggle: FormControl<boolean> -> boolean
|
|
201
295
|
if (controlValue) {
|
|
202
296
|
// eslint-disable-next-line security/detect-object-injection, no-param-reassign
|
|
203
297
|
result[filterId] = controlValue;
|
|
204
298
|
}
|
|
205
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Сбрасывает поле «от» диапазона к минимальному значению фильтра.
|
|
302
|
+
*
|
|
303
|
+
* @param filterId Идентификатор фильтра.
|
|
304
|
+
* @param min Минимальное значение диапазона.
|
|
305
|
+
*/
|
|
306
|
+
resetRangeFrom(filterId, min) {
|
|
307
|
+
this.form.get(filterId)?.get('from')?.reset(+min);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Сбрасывает поле «до» диапазона к максимальному значению фильтра.
|
|
311
|
+
*
|
|
312
|
+
* @param filterId Идентификатор фильтра.
|
|
313
|
+
* @param max Максимальное значение диапазона.
|
|
314
|
+
*/
|
|
315
|
+
resetRangeTo(filterId, max) {
|
|
316
|
+
this.form.get(filterId)?.get('to')?.reset(+max);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Сбрасывает все чекбоксы группы в `false`.
|
|
320
|
+
*
|
|
321
|
+
* @param filterId Идентификатор фильтра (ключ FormGroup в форме).
|
|
322
|
+
*/
|
|
323
|
+
resetCheckboxGroup(filterId) {
|
|
324
|
+
const group = this.form.get(filterId);
|
|
325
|
+
if (!group) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const resetValue = {};
|
|
329
|
+
Object.keys(group.controls).forEach((id) => {
|
|
330
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
331
|
+
resetValue[id] = false;
|
|
332
|
+
});
|
|
333
|
+
group.reset(resetValue);
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Сбрасывает все фильтры и оповещает родителя о нажатии кнопки сброса.
|
|
337
|
+
*/
|
|
338
|
+
onResetFiltersClick() {
|
|
339
|
+
this.resetAllFilters();
|
|
340
|
+
this.resetFilters.emit();
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Оповещает родителя о нажатии кнопки показа результатов.
|
|
344
|
+
*/
|
|
345
|
+
onShowResultsClick() {
|
|
346
|
+
this.showResults.emit();
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Сбрасывает все фильтры к исходным значениям.
|
|
350
|
+
*/
|
|
351
|
+
resetAllFilters() {
|
|
352
|
+
this.filters()?.forEach((filterItem) => {
|
|
353
|
+
const control = this.form.get(filterItem.id);
|
|
354
|
+
if (!control) {
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
switch (filterItem.type) {
|
|
358
|
+
case 'checkbox': {
|
|
359
|
+
const group = control;
|
|
360
|
+
const resetValue = {};
|
|
361
|
+
Object.keys(group.controls).forEach((id) => {
|
|
362
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
363
|
+
resetValue[id] = false;
|
|
364
|
+
});
|
|
365
|
+
group.reset(resetValue);
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
case 'toggle':
|
|
369
|
+
control.reset(false);
|
|
370
|
+
break;
|
|
371
|
+
case 'range': {
|
|
372
|
+
const group = control;
|
|
373
|
+
const min = +filterItem.min;
|
|
374
|
+
const max = +filterItem.max;
|
|
375
|
+
group.reset({ from: min, to: max, slider: [min, max] });
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
default:
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
}
|
|
206
383
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScCatalogFiltersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
207
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScCatalogFiltersComponent, isStandalone: true, selector: "sc-catalog-filters", inputs: { isOpenAccordion: { classPropertyName: "isOpenAccordion", publicName: "isOpenAccordion", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (filters()?.length) {\n <div class=\"bg-tui-base-01 shadow-sc flex flex-col items-center gap-3 rounded-xl\">\n <tui-accordion class=\"accordion\">\n <button\n [tuiAccordion]=\"isOpenAccordion()\"\n appearance=\"primary\"\n >\n \u0424\u0438\u043B\u044C\u0442\u0440\u044B\n </button>\n <tui-expand>\n <form\n [formGroup]=\"form\"\n class=\"flex flex-col gap-4 pb-1\"\n >\n @for (filter of filters(); track filter.id) {\n <div class=\"flex flex-col gap-2\">\n <label class=\"text-body-s font-medium\">{{ filter.label }}</label>\n\n @if (filter.type === 'checkbox') {\n @if (filter.isMultiple === false) {\n <div class=\"flex flex-col gap-2\">\n @for (value of filter.values; track value.id) {\n @let formControl = form.get(filter.id);\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"filter.id\"\n [value]=\"value.id\"\n tuiRadio\n (click)=\"formControl?.setValue(formControl?.value === value.id ? null : value.id)\"\n type=\"radio\"\n />\n <span class=\"text-body-s\">{{ value.label }}</span>\n </label>\n }\n </div>\n } @else {\n <div\n [formGroupName]=\"filter.id\"\n class=\"flex flex-col gap-2\"\n >\n @for (value of filter.values; track value.id) {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"value.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s\">{{ value.label }}</span>\n </label>\n }\n </div>\n }\n }\n\n @if (filter.type === 'range') {\n <tui-input-range\n [formControlName]=\"filter.id\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n />\n }\n\n @if (filter.type === 'toggle') {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"filter.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s\">\u0414\u0430</span>\n </label>\n }\n </div>\n }\n </form>\n </tui-expand>\n </tui-accordion>\n </div>\n}\n", styles: [".accordion [tuiAccordion]{border:none;mask:none}.accordion tui-expand{box-shadow:none}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: TuiCheckbox, selector: "input[type=\"checkbox\"][tuiCheckbox]", inputs: ["size"] }, { kind: "component", type: i2.TuiRadioComponent, selector: "input[type=\"radio\"][tuiRadio]", inputs: ["size"] }, { kind: "component", type: i2.TuiInputRangeComponent, selector: "tui-input-range", inputs: ["min", "max", "step", "segments", "keySteps", "prefix", "postfix", "quantum", "content"] }, { kind: "component", type: i3.TuiAccordionComponent, selector: "tui-accordion", inputs: ["closeOthers", "size"] }, { kind: "directive", type: i3.TuiAccordionDirective, selector: "button[tuiAccordion]", inputs: ["tuiAccordion"], outputs: ["tuiAccordionChange"] }, { kind: "component", type: i4.TuiExpand, selector: "tui-expand", inputs: ["expanded"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
384
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ScCatalogFiltersComponent, isStandalone: true, selector: "sc-catalog-filters", inputs: { showResultsButton: { classPropertyName: "showResultsButton", publicName: "showResultsButton", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { resetFilters: "resetFilters", showResults: "showResults" }, ngImport: i0, template: "@if (filters()?.length) {\n <form\n [formGroup]=\"form\"\n class=\"flex flex-col pb-1\"\n >\n @for (filter of filters(); track filter.id; let isFirst = $first) {\n @if (!isFirst) {\n <hr class=\"my-3 w-full h-px\" />\n }\n\n <div class=\"flex flex-col gap-2\">\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0433\u0440\u0443\u043F\u043F\u044B. \u0414\u043B\u044F toggle \u043F\u043E\u0434\u043F\u0438\u0441\u0438 \u043D\u0435\u0442: \u043C\u0435\u0442\u043A\u0430 \u0438\u0434\u0451\u0442 \u043F\u0440\u044F\u043C\u043E \u0440\u044F\u0434\u043E\u043C \u0441 \u0441\u0430\u043C\u0438\u043C checkbox. -->\n @if (filter.type !== 'toggle') {\n <label class=\"text-body-s-bold\">{{ filter.label }}</label>\n }\n\n <!-- Checkbox: FormGroup(value.id \u2192 boolean) \u0434\u043B\u044F \u043B\u044E\u0431\u043E\u0433\u043E \u0447\u0438\u0441\u043B\u0430 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439.\n \u0420\u0430\u0437\u0432\u0438\u043B\u043A\u0430 \u043E\u0434\u043D\u043E/\u043C\u043D\u043E\u0433\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u0432\u044B\u043D\u0435\u0441\u0435\u043D\u0430 \u0432 TS (\u0441\u043C. processCheckboxFilter).\n ng-template \u0432\u043D\u0443\u0442\u0440\u0438 formGroupName: \u0438\u043D\u0430\u0447\u0435 reactive forms \u043D\u0435 \u043D\u0430\u0439\u0434\u0451\u0442 ControlContainer \u043F\u0440\u0438 \u043F\u0440\u043E\u0435\u043A\u0446\u0438\u0438 \u0432 \u0434\u043E\u0447\u0435\u0440\u043D\u0438\u0439 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442. -->\n @if (filter.type === 'checkbox') {\n <div\n class=\"flex flex-col gap-2\"\n [formGroupName]=\"filter.id\"\n >\n <sc-catalog-filter-collapsible\n [itemsCount]=\"filter.values.length\"\n [showReset]=\"form.get(filter.id)?.dirty ?? false\"\n (resetGroup)=\"resetCheckboxGroup(filter.id)\"\n >\n <ng-template>\n <div class=\"flex flex-col gap-2\">\n @for (value of filter.values; track value.id) {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"value.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s\">{{ value.label }}</span>\n </label>\n }\n </div>\n </ng-template>\n </sc-catalog-filter-collapsible>\n </div>\n\n <!-- Toggle: \u043E\u0434\u0438\u043D boolean \u043D\u0430 \u043A\u043E\u0440\u043D\u0435 \u0444\u043E\u0440\u043C\u044B, \u043F\u043E\u0434\u043F\u0438\u0441\u044C = filter.label -->\n } @else if (filter.type === 'toggle') {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"filter.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s-bold\">{{ filter.label }}</span>\n </label>\n\n <!-- Range: FormGroup(from, to, slider) \u0441 \u0434\u0432\u0443\u0441\u0442\u043E\u0440\u043E\u043D\u043D\u0435\u0439 \u0441\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0430\u0446\u0438\u0435\u0439 -->\n } @else if (filter.type === 'range') {\n <div\n [formGroupName]=\"filter.id\"\n class=\"flex flex-col gap-3\"\n >\n <div class=\"flex gap-3 px-1\">\n <label\n tuiLabel\n class=\"min-w-0 flex-1\"\n >\n \u041E\u0442\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n scSelectOnFocusin\n tuiInputNumber\n formControlName=\"from\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n autocomplete=\"off\"\n />\n @if (form.get(filter.id)?.get('from')?.dirty) {\n <button\n tuiIconButton\n type=\"button\"\n size=\"xs\"\n appearance=\"icon\"\n iconStart=\"@tui.x\"\n (click)=\"resetRangeFrom(filter.id, filter.min)\"\n ></button>\n }\n </tui-textfield>\n </label>\n <label\n tuiLabel\n class=\"min-w-0 flex-1\"\n >\n \u0414\u043E\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n scSelectOnFocusin\n tuiInputNumber\n formControlName=\"to\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n autocomplete=\"off\"\n />\n @if (form.get(filter.id)?.get('to')?.dirty) {\n <button\n tuiIconButton\n type=\"button\"\n size=\"xs\"\n appearance=\"icon\"\n iconStart=\"@tui.x\"\n (click)=\"resetRangeTo(filter.id, filter.max)\"\n ></button>\n }\n </tui-textfield>\n </label>\n </div>\n\n <tui-range\n size=\"m\"\n formControlName=\"slider\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n [style.--tui-thickness.rem]=\"0.25\"\n />\n </div>\n }\n </div>\n }\n <button\n tuiButton\n appearance=\"secondary\"\n type=\"button\"\n class=\"mt-2\"\n (click)=\"onResetFiltersClick()\"\n >\n \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C \u0444\u0438\u043B\u044C\u0442\u0440\u044B\n </button>\n @if (showResultsButton()) {\n <button\n tuiButton\n appearance=\"primary\"\n type=\"button\"\n class=\"mt-2\"\n (click)=\"onShowResultsClick()\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B\n </button>\n }\n </form>\n}\n", styles: [".accordion [tuiAccordion]{border:none;mask:none}.accordion tui-expand{box-shadow:none}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i2.TuiLabel, selector: "label[tuiLabel]" }, { kind: "component", type: i3.TuiTextfieldComponent, selector: "tui-textfield:not([multi])" }, { kind: "directive", type: i3.TuiTextfieldOptionsDirective, selector: "[tuiTextfieldAppearance],[tuiTextfieldSize],[tuiTextfieldCleaner]", inputs: ["tuiTextfieldAppearance", "tuiTextfieldSize", "tuiTextfieldCleaner"] }, { kind: "directive", type: ScSelectOnFocusinDirective, selector: "tui-input-number, tui-input, tui-input-phone, tui-input-date, tui-input-password, input[tuiInputNumber], input[tuiTextfield], input[tuiInputSlider]" }, { kind: "component", type: ScCatalogFilterCollapsibleComponent, selector: "sc-catalog-filter-collapsible", inputs: ["itemsCount", "showReset"], outputs: ["resetGroup"] }, { kind: "directive", type: TuiNumberFormat, selector: "[tuiNumberFormat]", inputs: ["tuiNumberFormat"] }, { kind: "component", type: TuiCheckbox, selector: "input[type=\"checkbox\"][tuiCheckbox]", inputs: ["size"] }, { kind: "directive", type: i4.TuiInputNumberDirective, selector: "input[tuiInputNumber]", inputs: ["min", "max", "prefix", "postfix"] }, { kind: "component", type: TuiRange, selector: "tui-range", inputs: ["min", "max", "step", "size", "segments", "keySteps", "focusable", "margin", "limit"] }, { kind: "directive", type: TuiButton, selector: "a[tuiButton],button[tuiButton],a[tuiIconButton],button[tuiIconButton]", inputs: ["size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
208
385
|
}
|
|
209
386
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScCatalogFiltersComponent, decorators: [{
|
|
210
387
|
type: Component,
|
|
211
|
-
args: [{ standalone: true, selector: 'sc-catalog-filters', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
388
|
+
args: [{ standalone: true, selector: 'sc-catalog-filters', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
389
|
+
ReactiveFormsModule,
|
|
390
|
+
TuiTextfield,
|
|
391
|
+
ScSelectOnFocusinDirective,
|
|
392
|
+
ScCatalogFilterCollapsibleComponent,
|
|
393
|
+
TuiLabel,
|
|
394
|
+
TuiNumberFormat,
|
|
395
|
+
TuiCheckbox,
|
|
396
|
+
TuiInputNumber,
|
|
397
|
+
TuiRange,
|
|
398
|
+
TuiButton,
|
|
399
|
+
], template: "@if (filters()?.length) {\n <form\n [formGroup]=\"form\"\n class=\"flex flex-col pb-1\"\n >\n @for (filter of filters(); track filter.id; let isFirst = $first) {\n @if (!isFirst) {\n <hr class=\"my-3 w-full h-px\" />\n }\n\n <div class=\"flex flex-col gap-2\">\n <!-- \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0433\u0440\u0443\u043F\u043F\u044B. \u0414\u043B\u044F toggle \u043F\u043E\u0434\u043F\u0438\u0441\u0438 \u043D\u0435\u0442: \u043C\u0435\u0442\u043A\u0430 \u0438\u0434\u0451\u0442 \u043F\u0440\u044F\u043C\u043E \u0440\u044F\u0434\u043E\u043C \u0441 \u0441\u0430\u043C\u0438\u043C checkbox. -->\n @if (filter.type !== 'toggle') {\n <label class=\"text-body-s-bold\">{{ filter.label }}</label>\n }\n\n <!-- Checkbox: FormGroup(value.id \u2192 boolean) \u0434\u043B\u044F \u043B\u044E\u0431\u043E\u0433\u043E \u0447\u0438\u0441\u043B\u0430 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439.\n \u0420\u0430\u0437\u0432\u0438\u043B\u043A\u0430 \u043E\u0434\u043D\u043E/\u043C\u043D\u043E\u0433\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u0432\u044B\u043D\u0435\u0441\u0435\u043D\u0430 \u0432 TS (\u0441\u043C. processCheckboxFilter).\n ng-template \u0432\u043D\u0443\u0442\u0440\u0438 formGroupName: \u0438\u043D\u0430\u0447\u0435 reactive forms \u043D\u0435 \u043D\u0430\u0439\u0434\u0451\u0442 ControlContainer \u043F\u0440\u0438 \u043F\u0440\u043E\u0435\u043A\u0446\u0438\u0438 \u0432 \u0434\u043E\u0447\u0435\u0440\u043D\u0438\u0439 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442. -->\n @if (filter.type === 'checkbox') {\n <div\n class=\"flex flex-col gap-2\"\n [formGroupName]=\"filter.id\"\n >\n <sc-catalog-filter-collapsible\n [itemsCount]=\"filter.values.length\"\n [showReset]=\"form.get(filter.id)?.dirty ?? false\"\n (resetGroup)=\"resetCheckboxGroup(filter.id)\"\n >\n <ng-template>\n <div class=\"flex flex-col gap-2\">\n @for (value of filter.values; track value.id) {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"value.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s\">{{ value.label }}</span>\n </label>\n }\n </div>\n </ng-template>\n </sc-catalog-filter-collapsible>\n </div>\n\n <!-- Toggle: \u043E\u0434\u0438\u043D boolean \u043D\u0430 \u043A\u043E\u0440\u043D\u0435 \u0444\u043E\u0440\u043C\u044B, \u043F\u043E\u0434\u043F\u0438\u0441\u044C = filter.label -->\n } @else if (filter.type === 'toggle') {\n <label class=\"flex items-center gap-2\">\n <input\n [formControlName]=\"filter.id\"\n tuiCheckbox\n type=\"checkbox\"\n />\n <span class=\"text-body-s-bold\">{{ filter.label }}</span>\n </label>\n\n <!-- Range: FormGroup(from, to, slider) \u0441 \u0434\u0432\u0443\u0441\u0442\u043E\u0440\u043E\u043D\u043D\u0435\u0439 \u0441\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u0430\u0446\u0438\u0435\u0439 -->\n } @else if (filter.type === 'range') {\n <div\n [formGroupName]=\"filter.id\"\n class=\"flex flex-col gap-3\"\n >\n <div class=\"flex gap-3 px-1\">\n <label\n tuiLabel\n class=\"min-w-0 flex-1\"\n >\n \u041E\u0442\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n scSelectOnFocusin\n tuiInputNumber\n formControlName=\"from\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n autocomplete=\"off\"\n />\n @if (form.get(filter.id)?.get('from')?.dirty) {\n <button\n tuiIconButton\n type=\"button\"\n size=\"xs\"\n appearance=\"icon\"\n iconStart=\"@tui.x\"\n (click)=\"resetRangeFrom(filter.id, filter.min)\"\n ></button>\n }\n </tui-textfield>\n </label>\n <label\n tuiLabel\n class=\"min-w-0 flex-1\"\n >\n \u0414\u043E\n <tui-textfield [tuiTextfieldCleaner]=\"false\">\n <input\n scSelectOnFocusin\n tuiInputNumber\n formControlName=\"to\"\n [tuiNumberFormat]=\"{ precision: 0 }\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n autocomplete=\"off\"\n />\n @if (form.get(filter.id)?.get('to')?.dirty) {\n <button\n tuiIconButton\n type=\"button\"\n size=\"xs\"\n appearance=\"icon\"\n iconStart=\"@tui.x\"\n (click)=\"resetRangeTo(filter.id, filter.max)\"\n ></button>\n }\n </tui-textfield>\n </label>\n </div>\n\n <tui-range\n size=\"m\"\n formControlName=\"slider\"\n [min]=\"+filter.min\"\n [max]=\"+filter.max\"\n [style.--tui-thickness.rem]=\"0.25\"\n />\n </div>\n }\n </div>\n }\n <button\n tuiButton\n appearance=\"secondary\"\n type=\"button\"\n class=\"mt-2\"\n (click)=\"onResetFiltersClick()\"\n >\n \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C \u0444\u0438\u043B\u044C\u0442\u0440\u044B\n </button>\n @if (showResultsButton()) {\n <button\n tuiButton\n appearance=\"primary\"\n type=\"button\"\n class=\"mt-2\"\n (click)=\"onShowResultsClick()\"\n >\n \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u044B\n </button>\n }\n </form>\n}\n", styles: [".accordion [tuiAccordion]{border:none;mask:none}.accordion tui-expand{box-shadow:none}\n"] }]
|
|
212
400
|
}], ctorParameters: () => [] });
|
|
213
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2MtY2F0YWxvZy1maWx0ZXJzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NsaWVudC11aS9jYXRhbG9nL2NhdGFsb2ctZmlsdGVycy9zYy1jYXRhbG9nLWZpbHRlcnMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2NhdGFsb2cvY2F0YWxvZy1maWx0ZXJzL3NjLWNhdGFsb2ctZmlsdGVycy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFFM0MsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRSxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRixPQUFPLEVBQ0gsZ0JBQWdCLEVBRWhCLHNCQUFzQixFQUV0QixjQUFjLEdBSWpCLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNyRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFN0UsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDbkYsT0FBTyxFQUFFLG9DQUFvQyxFQUFFLE1BQU0sK0NBQStDLENBQUM7Ozs7OztBQUVyRzs7R0FFRztBQVNILE1BQU0sT0FBTyx5QkFBeUI7SUFpRGxDOztPQUVHO0lBQ0g7UUFuREE7O1dBRUc7UUFDYSxvQkFBZSxHQUFHLEtBQUssQ0FBVSxLQUFLLENBQUMsQ0FBQztRQUV4RDs7V0FFRztRQUNjLHlCQUFvQixHQUEyQixNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUUvRjs7V0FFRztRQUNjLGlCQUFZLEdBQW1CLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUV2RTs7V0FFRztRQUNjLDRCQUF1QixHQUFHLE1BQU0sQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO1FBRS9FOztXQUVHO1FBQ2Msa0JBQWEsR0FBRyxNQUFNLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUU5RTs7V0FFRztRQUNnQixZQUFPLEdBQUcsUUFBUSxDQUNqQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxJQUFJLENBQ3pCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFDdkIsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUNwQixTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQ3pILEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxPQUFPLElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFDMUYsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDWixJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckMsQ0FBQyxDQUFDLEVBQ0YsS0FBSyxFQUFFLENBQ1YsQ0FDSixDQUFDO1FBRUY7O1dBRUc7UUFDYSxTQUFJLEdBQUcsSUFBSSxTQUFTLENBRWxDLEVBQUUsQ0FBQyxDQUFDO1FBTUYsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNwRSxJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQzFFLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVEOzs7O09BSUc7SUFDTyxrQkFBa0IsQ0FBQyxPQUEwQjtRQUNuRCxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBVyxFQUFFLEVBQUU7WUFDcEQsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBWSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDckIsUUFBUSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ2hCLEtBQUssVUFBVTtvQkFDWCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO29CQUMxRixNQUFNO2dCQUNWLEtBQUssT0FBTztvQkFDUixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO29CQUN2RixNQUFNO2dCQUNWLEtBQUssUUFBUTtvQkFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO29CQUN4RixNQUFNO2dCQUNWO29CQUNJLE1BQU07WUFDZCxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTyxvQkFBb0IsQ0FBQyxLQUF1SDtRQUNsSixNQUFNLE1BQU0sR0FBc0IsRUFBRSxDQUFDO1FBRXJDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQyxVQUFVLEVBQUUsRUFBRTtZQUNuQyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBOEUsQ0FBQztZQUV2SCxJQUFJLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO2dCQUN0QixPQUFPO1lBQ1gsQ0FBQztZQUVELFFBQVEsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN0QixLQUFLLFVBQVU7b0JBQ1gsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFBRSxFQUFFLFlBQWdELENBQUMsQ0FBQztvQkFDcEcsTUFBTTtnQkFDVixLQUFLLE9BQU87b0JBQ1IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFBRSxFQUFFLFlBQWdDLENBQUMsQ0FBQztvQkFDakYsTUFBTTtnQkFDVixLQUFLLFFBQVE7b0JBQ1QsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxVQUFVLENBQUMsRUFBRSxFQUFFLFlBQXVCLENBQUMsQ0FBQztvQkFDekUsTUFBTTtnQkFDVjtvQkFDSSxNQUFNO1lBQ2QsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxNQUFNLENBQUM7SUFDbEIsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDTyx5QkFBeUIsQ0FBQyxjQUFpQztRQUNqRSxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzdCLE9BQU8sSUFBSSxXQUFXLENBQWdCLElBQUksQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBeUMsRUFBRSxDQUFDO1FBQzFELGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDcEMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLFdBQVcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN2RSxDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7O09BSUc7SUFDTyxzQkFBc0IsQ0FBQyxXQUEwQjtRQUN2RCxxRUFBcUU7UUFDckUsT0FBTyxJQUFJLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsV0FBVyxJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLFdBQVcsSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVKLENBQUM7SUFFRDs7OztPQUlHO0lBQ08sdUJBQXVCLENBQUMsWUFBNEI7UUFDMUQsT0FBTyxJQUFJLFdBQVcsQ0FBQyxZQUFZLENBQUMsYUFBYSxJQUFJLEtBQUssRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZGLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxxQkFBcUIsQ0FBQyxNQUF5QixFQUFFLFFBQWdCLEVBQUUsWUFBOEM7UUFDckgsNEZBQTRGO1FBQzVGLElBQUksT0FBTyxZQUFZLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsSUFBSSxZQUFZLEVBQUUsQ0FBQztnQkFDZiwrRUFBK0U7Z0JBQy9FLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3RDLENBQUM7WUFFRCxPQUFPO1FBQ1gsQ0FBQztRQUVELDZGQUE2RjtRQUM3RixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQzthQUMzQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsVUFBVSxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQzthQUN0QyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUV2QixJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsK0VBQStFO1lBQy9FLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxXQUFXLENBQUM7UUFDbkMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNLLGtCQUFrQixDQUFDLE1BQXlCLEVBQUUsUUFBZ0IsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQW1CO1FBQ2hHLDhFQUE4RTtRQUM5RSwrRUFBK0U7UUFDL0UsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHO1lBQ2YsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUM7WUFDbEIsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUM7U0FDakIsQ0FBQztJQUNOLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxtQkFBbUIsQ0FBQyxNQUF5QixFQUFFLFFBQWdCLEVBQUUsWUFBcUI7UUFDMUYsOENBQThDO1FBQzlDLElBQUksWUFBWSxFQUFFLENBQUM7WUFDZiwrRUFBK0U7WUFDL0UsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLFlBQVksQ0FBQztRQUNwQyxDQUFDO0lBQ0wsQ0FBQzsrR0EzTlEseUJBQXlCO21HQUF6Qix5QkFBeUIsZ1BDcEN0Qywra0lBK0VBLGlKRDdDYyxXQUFXLGdpQ0FBZ0IsV0FBVyw2dUJBQXlDLG1CQUFtQjs7NEZBRW5HLHlCQUF5QjtrQkFSckMsU0FBUztpQ0FDTSxJQUFJLFlBQ04sb0JBQW9CLG1CQUdiLHVCQUF1QixDQUFDLE1BQU0sV0FDdEMsQ0FBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxtQkFBbUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXMgKi9cblxuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgaW5qZWN0LCBpbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkLCB0b1NpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIEZvcm1zTW9kdWxlLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgICBTQ19DQVRFR09SWV9JTkZPLFxuICAgIFNjQ2F0YWxvZ0ZpbHRlcixcbiAgICBTY0NhdGFsb2dGaWx0ZXJTZXJ2aWNlLFxuICAgIFNjSUNoZWNrYm94RmlsdGVyLFxuICAgIFNjSWRPclNsdWdQaXBlLFxuICAgIFNjUHJvcGVydHlGaWx0ZXJzLFxuICAgIFNjUmFuZ2VGaWx0ZXIsXG4gICAgU2NUb2dnbGVGaWx0ZXIsXG59IGZyb20gJ0BzbmFiY2VudHIvY2xpZW50LWNvcmUnO1xuaW1wb3J0IHsgdHVpSXNQcmVzZW50IH0gZnJvbSAnQHRhaWdhLXVpL2Nkayc7XG5pbXBvcnQgeyBUdWlUZXh0ZmllbGQgfSBmcm9tICdAdGFpZ2EtdWkvY29yZSc7XG5pbXBvcnQgeyBUdWlBY2NvcmRpb24gfSBmcm9tICdAdGFpZ2EtdWkvZXhwZXJpbWVudGFsJztcbmltcG9ydCB7IFR1aUNoZWNrYm94LCBUdWlJbnB1dFJhbmdlLCBUdWlSYWRpbyB9IGZyb20gJ0B0YWlnYS11aS9raXQnO1xuaW1wb3J0IHsgaXNOaWwgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgRU1QVFksIGZpbHRlciwgbWFwLCBzaGFyZSwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgU0NfQ0FUQUxPR19QUk9EVUNUU19GSUxURVJTIH0gZnJvbSAnLi90b2tlbnMvc2MtY2F0YWxvZy1wcm9kdWN0cy1maWx0ZXJzJztcbmltcG9ydCB7IFNDX0NBVEFMT0dfU0hPV19QUk9EVUNUU19SRUNVUlNJVkVMWSB9IGZyb20gJy4vdG9rZW5zL3NjLWNhdGFsb2ctc2hvdy1wcm9kdWN0cy1yZWN1cnNpdmVseSc7XG5cbi8qKlxuICog0JrQvtC80L/QvtC90LXQvdGCINCy0YvQstC+0LTQsCDRhNC40LvRjNGC0YDQvtCyINC60LDRgtCw0LvQvtCz0LAuXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdzYy1jYXRhbG9nLWZpbHRlcnMnLFxuICAgIHN0eWxlVXJsOiAnLi9zYy1jYXRhbG9nLWZpbHRlcnMuY29tcG9uZW50LnNjc3MnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9zYy1jYXRhbG9nLWZpbHRlcnMuY29tcG9uZW50Lmh0bWwnLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAgIGltcG9ydHM6IFtGb3Jtc01vZHVsZSwgVHVpVGV4dGZpZWxkLCBUdWlDaGVja2JveCwgVHVpUmFkaW8sIFR1aUlucHV0UmFuZ2UsIFR1aUFjY29yZGlvbiwgUmVhY3RpdmVGb3Jtc01vZHVsZV0sXG59KVxuZXhwb3J0IGNsYXNzIFNjQ2F0YWxvZ0ZpbHRlcnNDb21wb25lbnQge1xuICAgIC8qKlxuICAgICAqINCh0L7RgdGC0L7Rj9C90LjQtSDQvtGC0LrRgNGL0YLQuNGPIGFjY29yZGlvbi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgaXNPcGVuQWNjb3JkaW9uID0gaW5wdXQ8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gICAgLyoqXG4gICAgICog0KHQtdGA0LLQuNGBINC00LvRjyDRgNCw0LHQvtGC0Ysg0YEg0YTQuNC70YzRgtGA0LDQvNC4INC60LDRgtCw0LvQvtCz0LAuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBjYXRhbG9nRmlsdGVyU2VydmljZTogU2NDYXRhbG9nRmlsdGVyU2VydmljZSA9IGluamVjdChTY0NhdGFsb2dGaWx0ZXJTZXJ2aWNlKTtcblxuICAgIC8qKlxuICAgICAqINCf0LDQudC/LCDQstC+0LfQstGA0LDRidCw0Y7RidC40Lkg0LjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LjQu9C4INGB0LjQvNCy0L7Qu9GM0L3QvtC1INC+0LHQvtC30L3QsNGH0LXQvdC40LUgKHNsdWcpINC40YHRhdC+0LTRjyDQuNC3INC90LDRgdGC0YDQvtC10Log0L7QutGA0YPQttC10L3QuNGPLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaWRPclNsdWdQaXBlOiBTY0lkT3JTbHVnUGlwZSA9IGluamVjdChTY0lkT3JTbHVnUGlwZSk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJqZWN0INC00LvRjyDRhdGA0LDQvdC10L3QuNGPINGE0LjQu9GM0YLRgNC+0LIg0L/RgNC+0LTRg9C60YLQvtCyLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY2F0YWxvZ1Byb2R1Y3RzRmlsdGVycyQgPSBpbmplY3QoU0NfQ0FUQUxPR19QUk9EVUNUU19GSUxURVJTKTtcblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC30L3QsNC6INC90LXQvtCx0YXQvtC00LjQvNC+0YHRgtC4INC+0YLQvtCx0YDQsNC20LDRgtGMINGE0LjQu9GM0YLRgNGLINC00LvRjyDQstC70L7QttC10L3QvdGL0YUg0LrQsNGC0LXQs9C+0YDQuNC5LlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaXNSZWN1cnNpdmVseSA9IGluamVjdChTQ19DQVRBTE9HX1NIT1dfUFJPRFVDVFNfUkVDVVJTSVZFTFkpO1xuXG4gICAgLyoqXG4gICAgICoge0BsaW5rIE9ic2VydmFibGV9INGE0LjQu9GM0YLRgNC+0LIg0LrQsNGC0LXQs9C+0YDQuNC4LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBmaWx0ZXJzID0gdG9TaWduYWwoXG4gICAgICAgIGluamVjdChTQ19DQVRFR09SWV9JTkZPKS5waXBlKFxuICAgICAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBFTVBUWSksXG4gICAgICAgICAgICBmaWx0ZXIodHVpSXNQcmVzZW50KSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoY2F0ZWdvcnkpID0+IHRoaXMuY2F0YWxvZ0ZpbHRlclNlcnZpY2UuZ2V0RmlsdGVycyQodGhpcy5pZE9yU2x1Z1BpcGUudHJhbnNmb3JtKGNhdGVnb3J5KSwgdGhpcy5pc1JlY3Vyc2l2ZWx5KSksXG4gICAgICAgICAgICBtYXAoKGZpbHRlcnMpID0+IGZpbHRlcnMuZmlsdGVyKChpdGVtKSA9PiBpdGVtLnR5cGUgIT09ICdyYW5nZScgfHwgaXRlbS5taW4gIT09IGl0ZW0ubWF4KSksXG4gICAgICAgICAgICB0YXAoKGZpbHRlcnMpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUZvcm1Db250cm9scyhmaWx0ZXJzKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgc2hhcmUoKVxuICAgICAgICApXG4gICAgKTtcblxuICAgIC8qKlxuICAgICAqIEZvcm1Hcm91cCDQtNC70Y8g0YTQuNC70YzRgtGA0L7Qsi5cbiAgICAgKi9cbiAgICBwdWJsaWMgcmVhZG9ubHkgZm9ybSA9IG5ldyBGb3JtR3JvdXA8XG4gICAgICAgIFJlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIHRoaXMuY3JlYXRlQ2hlY2tib3hGb3JtQ29udHJvbD4gfCBSZXR1cm5UeXBlPHR5cGVvZiB0aGlzLmNyZWF0ZVJhbmdlRm9ybUNvbnRyb2w+IHwgUmV0dXJuVHlwZTx0eXBlb2YgdGhpcy5jcmVhdGVUb2dnbGVGb3JtQ29udHJvbD4+XG4gICAgPih7fSk7XG5cbiAgICAvKipcbiAgICAgKiDQmNC90LjRhtC40LDQu9C40LfQuNGA0YPQtdGCINGN0LrQt9C10LzQv9C70Y/RgCDQutC70LDRgdGB0LAge0BsaW5rIFNjQ2F0YWxvZ0ZpbHRlcnNDb21wb25lbnR9LlxuICAgICAqL1xuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5mb3JtLnZhbHVlQ2hhbmdlcy5waXBlKHRha2VVbnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKGZpbHRlcnMpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2F0YWxvZ1Byb2R1Y3RzRmlsdGVycyQubmV4dCh0aGlzLmJ1aWxkUHJvcGVydHlGaWx0ZXJzKGZpbHRlcnMpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7QsdC90L7QstC70Y/QtdGCINGB0L7RgdGC0LDQsiDQutC+0L3RgtGA0L7Qu9C+0LIg0YTQvtGA0LzRiyDQvdCwINC+0YHQvdC+0LLQtSDQv9C10YDQtdC00LDQvdC90YvRhSDRhNC40LvRjNGC0YDQvtCyLlxuICAgICAqXG4gICAgICogQHBhcmFtIGZpbHRlcnMg0JzQsNGB0YHQuNCyINGE0LjQu9GM0YLRgNC+0LIg0LTQu9GPINGB0L7Qt9C00LDQvdC40Y8g0LrQvtC90YLRgNC+0LvQvtCyLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCB1cGRhdGVGb3JtQ29udHJvbHMoZmlsdGVyczogU2NDYXRhbG9nRmlsdGVyW10pOiB2b2lkIHtcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5mb3JtLmNvbnRyb2xzKS5mb3JFYWNoKChrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgdGhpcy5mb3JtLnJlbW92ZUNvbnRyb2woa2V5IGFzIG5ldmVyLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZpbHRlcnMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChpdGVtLnR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjaGVja2JveCc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5hZGRDb250cm9sKGl0ZW0uaWQsIHRoaXMuY3JlYXRlQ2hlY2tib3hGb3JtQ29udHJvbChpdGVtKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdyYW5nZSc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm9ybS5hZGRDb250cm9sKGl0ZW0uaWQsIHRoaXMuY3JlYXRlUmFuZ2VGb3JtQ29udHJvbChpdGVtKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICd0b2dnbGUnOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uYWRkQ29udHJvbChpdGVtLmlkLCB0aGlzLmNyZWF0ZVRvZ2dsZUZvcm1Db250cm9sKGl0ZW0pLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQn9GA0LXQvtCx0YDQsNC30YPQtdGCINC30L3QsNGH0LXQvdC40Y8g0YTQvtGA0LzRiyDQsiDQvtCx0YrQtdC60YIg0YTQuNC70YzRgtGA0L7QsiDRgdCy0L7QudGB0YLQsi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZSDQl9C90LDRh9C10L3QuNGPINGE0L7RgNC80YsuXG4gICAgICogQHJldHVybnMg0J7QsdGK0LXQutGCINGE0LjQu9GM0YLRgNC+0LIg0YHQstC+0LnRgdGC0LIuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGJ1aWxkUHJvcGVydHlGaWx0ZXJzKHZhbHVlOiBQYXJ0aWFsPFJlY29yZDxzdHJpbmcsIGJvb2xlYW4gfCBzdHJpbmcgfCBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiB8IFtudW1iZXIsIG51bWJlcl0+PiB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogU2NQcm9wZXJ0eUZpbHRlcnMge1xuICAgICAgICBjb25zdCByZXN1bHQ6IFNjUHJvcGVydHlGaWx0ZXJzID0ge307XG5cbiAgICAgICAgdGhpcy5maWx0ZXJzKCk/LmZvckVhY2goKGZpbHRlckl0ZW0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRyb2xWYWx1ZSA9IHZhbHVlW2ZpbHRlckl0ZW0uaWRdIGFzIGJvb2xlYW4gfCBzdHJpbmcgfCBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiB8IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAgIGlmIChpc05pbChjb250cm9sVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzd2l0Y2ggKGZpbHRlckl0ZW0udHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NoZWNrYm94JzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ2hlY2tib3hGaWx0ZXIocmVzdWx0LCBmaWx0ZXJJdGVtLmlkLCBjb250cm9sVmFsdWUgYXMgc3RyaW5nIHwgUmVjb3JkPHN0cmluZywgYm9vbGVhbj4pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdyYW5nZSc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc1JhbmdlRmlsdGVyKHJlc3VsdCwgZmlsdGVySXRlbS5pZCwgY29udHJvbFZhbHVlIGFzIFtudW1iZXIsIG51bWJlcl0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICd0b2dnbGUnOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2dnbGVGaWx0ZXIocmVzdWx0LCBmaWx0ZXJJdGVtLmlkLCBjb250cm9sVmFsdWUgYXMgYm9vbGVhbik7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCh0L7Qt9C00LDQtdGCINC60L7QvdGC0YDQvtC7INGE0L7RgNC80Ysg0LTQu9GPINGE0LjQu9GM0YLRgNCwINGC0LjQv9CwIGNoZWNrYm94LlxuICAgICAqXG4gICAgICog0JXRgdC70LggYGlzTXVsdGlwbGUgPT09IGZhbHNlYCDigJQg0LLQvtC30LLRgNCw0YnQsNC10YIge0BsaW5rIEZvcm1Db250cm9sfSDRgdGC0YDQvtC60L7QstC+0LPQviDQuNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgNCwICjQu9C+0LPQuNC60LAgcmFkaW8pLFxuICAgICAqINC40L3QsNGH0LUg4oCUIHtAbGluayBGb3JtR3JvdXB9INC90LXQt9Cw0LLQuNGB0LjQvNGL0YUg0LHRg9C70LXQstGL0YUg0LrQvtC90YLRgNC+0LvQvtCyINC/0L4g0LjQtNC10L3RgtC40YTQuNC60LDRgtC+0YDQsNC8INC30L3QsNGH0LXQvdC40LkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY2hlY2tib3hGaWx0ZXIg0KTQuNC70YzRgtGAINGC0LjQv9CwIGNoZWNrYm94LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjcmVhdGVDaGVja2JveEZvcm1Db250cm9sKGNoZWNrYm94RmlsdGVyOiBTY0lDaGVja2JveEZpbHRlcik6IEZvcm1Hcm91cDxSZWNvcmQ8c3RyaW5nLCBGb3JtQ29udHJvbDxib29sZWFuPj4+IHwgRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD4ge1xuICAgICAgICBpZiAoIWNoZWNrYm94RmlsdGVyLmlzTXVsdGlwbGUpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjb250cm9sczogUmVjb3JkPHN0cmluZywgRm9ybUNvbnRyb2w8Ym9vbGVhbj4+ID0ge307XG4gICAgICAgIGNoZWNrYm94RmlsdGVyLnZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgY29udHJvbHNbdmFsdWUuaWRdID0gbmV3IEZvcm1Db250cm9sKGZhbHNlLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbmV3IEZvcm1Hcm91cChjb250cm9scyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHQvtC30LTQsNC10YIgRm9ybUNvbnRyb2wg0LTQu9GPIHJhbmdlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHJhbmdlRmlsdGVyINCk0LjQu9GM0YLRgCDRgtC40L/QsCByYW5nZS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY3JlYXRlUmFuZ2VGb3JtQ29udHJvbChyYW5nZUZpbHRlcjogU2NSYW5nZUZpbHRlcik6IEZvcm1Db250cm9sPFtudW1iZXIsIG51bWJlcl0+IHtcbiAgICAgICAgLy8gVE9ETzog0JTQvtCx0LDQstC40YLRjCB1cGRhdGVPbjogJ2JsdXInINC/0L7RgdC70LUg0LjRgdC/0YDQsNCy0LvQtdC90LjRjyDQsdCw0LPQsCDQsiB0YWlnYS11aS5cbiAgICAgICAgcmV0dXJuIG5ldyBGb3JtQ29udHJvbChbTnVtYmVyKHJhbmdlRmlsdGVyLnNlbGVjdGVkTWluID8/IHJhbmdlRmlsdGVyLm1pbiksIE51bWJlcihyYW5nZUZpbHRlci5zZWxlY3RlZE1heCA/PyByYW5nZUZpbHRlci5tYXgpXSwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQodC+0LfQtNCw0LXRgiBGb3JtQ29udHJvbCDQtNC70Y8gdG9nZ2xlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHRvZ2dsZUZpbHRlciDQpNC40LvRjNGC0YAg0YLQuNC/0LAgdG9nZ2xlLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjcmVhdGVUb2dnbGVGb3JtQ29udHJvbCh0b2dnbGVGaWx0ZXI6IFNjVG9nZ2xlRmlsdGVyKTogRm9ybUNvbnRyb2w8Ym9vbGVhbj4ge1xuICAgICAgICByZXR1cm4gbmV3IEZvcm1Db250cm9sKHRvZ2dsZUZpbHRlci5zZWxlY3RlZFZhbHVlID8/IGZhbHNlLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCe0LHRgNCw0LHQsNGC0YvQstCw0LXRgiBjaGVja2JveCDRhNC40LvRjNGC0YAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcmVzdWx0INCe0LHRitC10LrRgiDRgNC10LfRg9C70YzRgtCw0YLQsCDQtNC70Y8g0LfQsNC/0L7Qu9C90LXQvdC40Y8uXG4gICAgICogQHBhcmFtIGZpbHRlcklkINCY0LTQtdC90YLQuNGE0LjQutCw0YLQvtGAINGE0LjQu9GM0YLRgNCwLlxuICAgICAqIEBwYXJhbSBjb250cm9sVmFsdWUg0JfQvdCw0YfQtdC90LjQtSDQutC+0L3RgtGA0L7Qu9CwINGE0L7RgNC80YsuXG4gICAgICovXG4gICAgcHJpdmF0ZSBwcm9jZXNzQ2hlY2tib3hGaWx0ZXIocmVzdWx0OiBTY1Byb3BlcnR5RmlsdGVycywgZmlsdGVySWQ6IHN0cmluZywgY29udHJvbFZhbHVlOiBzdHJpbmcgfCBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPik6IHZvaWQge1xuICAgICAgICAvLyDQlNC70Y8gaXNNdWx0aXBsZSA9PT0gZmFsc2U6IEZvcm1Db250cm9sPHN0cmluZyB8IG51bGw+IC0+IHN0cmluZ1tdINC40Lcg0L7QtNC90L7Qs9C+INCy0YvQsdGA0LDQvdC90L7Qs9C+IElELlxuICAgICAgICBpZiAodHlwZW9mIGNvbnRyb2xWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGlmIChjb250cm9sVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc2VjdXJpdHkvZGV0ZWN0LW9iamVjdC1pbmplY3Rpb24sIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgICAgICAgICAgcmVzdWx0W2ZpbHRlcklkXSA9IFtjb250cm9sVmFsdWVdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyDQlNC70Y8gY2hlY2tib3g6IEZvcm1Hcm91cCDRgSBGb3JtQ29udHJvbDxib29sZWFuPiAtPiBzdHJpbmdbXSAo0LzQsNGB0YHQuNCyIElEINCy0YvQsdGA0LDQvdC90YvRhSDQt9C90LDRh9C10L3QuNC5KS5cbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRJZHMgPSBPYmplY3QuZW50cmllcyhjb250cm9sVmFsdWUpXG4gICAgICAgICAgICAuZmlsdGVyKChbLCBpc1NlbGVjdGVkXSkgPT4gaXNTZWxlY3RlZClcbiAgICAgICAgICAgIC5tYXAoKFtpZF0pID0+IGlkKTtcblxuICAgICAgICBpZiAoc2VsZWN0ZWRJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHNlY3VyaXR5L2RldGVjdC1vYmplY3QtaW5qZWN0aW9uLCBuby1wYXJhbS1yZWFzc2lnblxuICAgICAgICAgICAgcmVzdWx0W2ZpbHRlcklkXSA9IHNlbGVjdGVkSWRzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7QsdGA0LDQsdCw0YLRi9Cy0LDQtdGCIHJhbmdlINGE0LjQu9GM0YLRgC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByZXN1bHQg0J7QsdGK0LXQutGCINGA0LXQt9GD0LvRjNGC0LDRgtCwINC00LvRjyDQt9Cw0L/QvtC70L3QtdC90LjRjy5cbiAgICAgKiBAcGFyYW0gZmlsdGVySWQg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0YTQuNC70YzRgtGA0LAuXG4gICAgICogQHBhcmFtIGNvbnRyb2xWYWx1ZSDQl9C90LDRh9C10L3QuNC1INC60L7QvdGC0YDQvtC70LAg0YTQvtGA0LzRiy5cbiAgICAgKiBAcGFyYW0gY29udHJvbFZhbHVlLjAg0J3QsNGH0LDQu9GM0L3QvtC1INC30L3QsNGH0LXQvdC40LUg0LTQuNCw0L/QsNC30L7QvdCwLlxuICAgICAqIEBwYXJhbSBjb250cm9sVmFsdWUuMSDQmtC+0L3QtdGH0L3QvtC1INC30L3QsNGH0LXQvdC40LUg0LTQuNCw0L/QsNC30L7QvdCwLlxuICAgICAqL1xuICAgIHByaXZhdGUgcHJvY2Vzc1JhbmdlRmlsdGVyKHJlc3VsdDogU2NQcm9wZXJ0eUZpbHRlcnMsIGZpbHRlcklkOiBzdHJpbmcsIFtmcm9tLCB0b106IFtudW1iZXIsIG51bWJlcl0pOiB2b2lkIHtcbiAgICAgICAgLy8g0JTQu9GPIHJhbmdlOiBGb3JtQ29udHJvbDxbbnVtYmVyLCBudW1iZXJdPiAtPiB7IGZyb20/OiBzdHJpbmc7IHRvPzogc3RyaW5nOyB9XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzZWN1cml0eS9kZXRlY3Qtb2JqZWN0LWluamVjdGlvbiwgbm8tcGFyYW0tcmVhc3NpZ25cbiAgICAgICAgcmVzdWx0W2ZpbHRlcklkXSA9IHtcbiAgICAgICAgICAgIGZyb206IFN0cmluZyhmcm9tKSxcbiAgICAgICAgICAgIHRvOiBTdHJpbmcodG8pLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCe0LHRgNCw0LHQsNGC0YvQstCw0LXRgiB0b2dnbGUg0YTQuNC70YzRgtGALlxuICAgICAqXG4gICAgICogQHBhcmFtIHJlc3VsdCDQntCx0YrQtdC60YIg0YDQtdC30YPQu9GM0YLQsNGC0LAg0LTQu9GPINC30LDQv9C+0LvQvdC10L3QuNGPLlxuICAgICAqIEBwYXJhbSBmaWx0ZXJJZCDQmNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgCDRhNC40LvRjNGC0YDQsC5cbiAgICAgKiBAcGFyYW0gY29udHJvbFZhbHVlINCX0L3QsNGH0LXQvdC40LUg0LrQvtC90YLRgNC+0LvQsCDRhNC+0YDQvNGLLlxuICAgICAqL1xuICAgIHByaXZhdGUgcHJvY2Vzc1RvZ2dsZUZpbHRlcihyZXN1bHQ6IFNjUHJvcGVydHlGaWx0ZXJzLCBmaWx0ZXJJZDogc3RyaW5nLCBjb250cm9sVmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgLy8g0JTQu9GPIHRvZ2dsZTogRm9ybUNvbnRyb2w8Ym9vbGVhbj4gLT4gYm9vbGVhblxuICAgICAgICBpZiAoY29udHJvbFZhbHVlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc2VjdXJpdHkvZGV0ZWN0LW9iamVjdC1pbmplY3Rpb24sIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgICAgICByZXN1bHRbZmlsdGVySWRdID0gY29udHJvbFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiQGlmIChmaWx0ZXJzKCk/Lmxlbmd0aCkge1xuICAgIDxkaXYgY2xhc3M9XCJiZy10dWktYmFzZS0wMSBzaGFkb3ctc2MgZmxleCBmbGV4LWNvbCBpdGVtcy1jZW50ZXIgZ2FwLTMgcm91bmRlZC14bFwiPlxuICAgICAgICA8dHVpLWFjY29yZGlvbiBjbGFzcz1cImFjY29yZGlvblwiPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIFt0dWlBY2NvcmRpb25dPVwiaXNPcGVuQWNjb3JkaW9uKClcIlxuICAgICAgICAgICAgICAgIGFwcGVhcmFuY2U9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICDQpNC40LvRjNGC0YDRi1xuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8dHVpLWV4cGFuZD5cbiAgICAgICAgICAgICAgICA8Zm9ybVxuICAgICAgICAgICAgICAgICAgICBbZm9ybUdyb3VwXT1cImZvcm1cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTQgcGItMVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICBAZm9yIChmaWx0ZXIgb2YgZmlsdGVycygpOyB0cmFjayBmaWx0ZXIuaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1ib2R5LXMgZm9udC1tZWRpdW1cIj57eyBmaWx0ZXIubGFiZWwgfX08L2xhYmVsPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChmaWx0ZXIudHlwZSA9PT0gJ2NoZWNrYm94Jykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGZpbHRlci5pc011bHRpcGxlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZm9yICh2YWx1ZSBvZiBmaWx0ZXIudmFsdWVzOyB0cmFjayB2YWx1ZS5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAbGV0IGZvcm1Db250cm9sID0gZm9ybS5nZXQoZmlsdGVyLmlkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiZmlsdGVyLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwidmFsdWUuaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR1aVJhZGlvXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImZvcm1Db250cm9sPy5zZXRWYWx1ZShmb3JtQ29udHJvbD8udmFsdWUgPT09IHZhbHVlLmlkID8gbnVsbCA6IHZhbHVlLmlkKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cInJhZGlvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtYm9keS1zXCI+e3sgdmFsdWUubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtR3JvdXBOYW1lXT1cImZpbHRlci5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGdhcC0yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZm9yICh2YWx1ZSBvZiBmaWx0ZXIudmFsdWVzOyB0cmFjayB2YWx1ZS5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJ2YWx1ZS5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHVpQ2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1ib2R5LXNcIj57eyB2YWx1ZS5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZmlsdGVyLnR5cGUgPT09ICdyYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHR1aS1pbnB1dC1yYW5nZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJmaWx0ZXIuaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbl09XCIrZmlsdGVyLm1pblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4XT1cIitmaWx0ZXIubWF4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGZpbHRlci50eXBlID09PSAndG9nZ2xlJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJmaWx0ZXIuaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR1aUNoZWNrYm94XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtYm9keS1zXCI+0JTQsDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICAgIDwvdHVpLWV4cGFuZD5cbiAgICAgICAgPC90dWktYWNjb3JkaW9uPlxuICAgIDwvZGl2PlxufVxuIl19
|
|
401
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2MtY2F0YWxvZy1maWx0ZXJzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NsaWVudC11aS9jYXRhbG9nL2NhdGFsb2ctZmlsdGVycy9zYy1jYXRhbG9nLWZpbHRlcnMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xpZW50LXVpL2NhdGFsb2cvY2F0YWxvZy1maWx0ZXJzL3NjLWNhdGFsb2ctZmlsdGVycy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFFM0MsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFFBQVEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0UsT0FBTyxFQUNILGdCQUFnQixFQUVoQixzQkFBc0IsRUFFdEIsY0FBYyxHQUlqQixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0RSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLFNB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SSxZQUNOLG9CQUFvQixtQkFHYix1QkFBdUIsQ0FBQyxNQUFNLFdBQ3RDO3dCQUNMLG1CQUFtQjt3QkFDbkIsWUFBWTt3QkFDWiwwQkFBMEI7d0JBQzFCLG1DQUFtQzt3QkFDbkMsUUFBUTt3QkFDUixlQUFlO3dCQUNmLFdBQVc7d0JBQ1gsY0FBYzt3QkFDZCxRQUFRO3dCQUNSLFNBQVM7cUJBQ1oiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBjbGFzcy1tZXRob2RzLXVzZS10aGlzICovXG5cbmltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIERlc3Ryb3lSZWYsIGluamVjdCwgaW5wdXQsIG91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkLCB0b1NpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICAgIFNDX0NBVEVHT1JZX0lORk8sXG4gICAgU2NDYXRhbG9nRmlsdGVyLFxuICAgIFNjQ2F0YWxvZ0ZpbHRlclNlcnZpY2UsXG4gICAgU2NJQ2hlY2tib3hGaWx0ZXIsXG4gICAgU2NJZE9yU2x1Z1BpcGUsXG4gICAgU2NQcm9wZXJ0eUZpbHRlcnMsXG4gICAgU2NSYW5nZUZpbHRlcixcbiAgICBTY1RvZ2dsZUZpbHRlcixcbn0gZnJvbSAnQHNuYWJjZW50ci9jbGllbnQtY29yZSc7XG5pbXBvcnQgeyB0dWlJc1ByZXNlbnQgfSBmcm9tICdAdGFpZ2EtdWkvY2RrJztcbmltcG9ydCB7IFR1aUJ1dHRvbiwgVHVpTGFiZWwsIFR1aU51bWJlckZvcm1hdCwgVHVpVGV4dGZpZWxkIH0gZnJvbSAnQHRhaWdhLXVpL2NvcmUnO1xuaW1wb3J0IHsgVHVpQ2hlY2tib3gsIFR1aUlucHV0TnVtYmVyLCBUdWlSYW5nZSB9IGZyb20gJ0B0YWlnYS11aS9raXQnO1xuaW1wb3J0IHsgaXNOaWwgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZGVib3VuY2VUaW1lLCBFTVBUWSwgZmlsdGVyLCBtYXAsIG1lcmdlLCBzaGFyZSwgU3Vic2NyaXB0aW9uLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBTY1NlbGVjdE9uRm9jdXNpbkRpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL2RpcmVjdGl2ZXMvc2VsZWN0LW9uLWZvY3VzaW4vc2Mtc2VsZWN0LW9uLWZvY3VzaW4uZGlyZWN0aXZlJztcbmltcG9ydCB7IFNjQ2F0YWxvZ0ZpbHRlckNvbGxhcHNpYmxlQ29tcG9uZW50IH0gZnJvbSAnLi9jb2xsYXBzaWJsZS9zYy1jYXRhbG9nLWZpbHRlci1jb2xsYXBzaWJsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgU0NfQ0FUQUxPR19QUk9EVUNUU19GSUxURVJTIH0gZnJvbSAnLi90b2tlbnMvc2MtY2F0YWxvZy1wcm9kdWN0cy1maWx0ZXJzJztcbmltcG9ydCB7IFNDX0NBVEFMT0dfU0hPV19QUk9EVUNUU19SRUNVUlNJVkVMWSB9IGZyb20gJy4vdG9rZW5zL3NjLWNhdGFsb2ctc2hvdy1wcm9kdWN0cy1yZWN1cnNpdmVseSc7XG5cbi8qKlxuICog0JrQvtC80L/QvtC90LXQvdGCINCy0YvQstC+0LTQsCDRhNC40LvRjNGC0YDQvtCyINC60LDRgtCw0LvQvtCz0LAuXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdzYy1jYXRhbG9nLWZpbHRlcnMnLFxuICAgIHN0eWxlVXJsOiAnLi9zYy1jYXRhbG9nLWZpbHRlcnMuY29tcG9uZW50LnNjc3MnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9zYy1jYXRhbG9nLWZpbHRlcnMuY29tcG9uZW50Lmh0bWwnLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAgIGltcG9ydHM6IFtcbiAgICAgICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcbiAgICAgICAgVHVpVGV4dGZpZWxkLFxuICAgICAgICBTY1NlbGVjdE9uRm9jdXNpbkRpcmVjdGl2ZSxcbiAgICAgICAgU2NDYXRhbG9nRmlsdGVyQ29sbGFwc2libGVDb21wb25lbnQsXG4gICAgICAgIFR1aUxhYmVsLFxuICAgICAgICBUdWlOdW1iZXJGb3JtYXQsXG4gICAgICAgIFR1aUNoZWNrYm94LFxuICAgICAgICBUdWlJbnB1dE51bWJlcixcbiAgICAgICAgVHVpUmFuZ2UsXG4gICAgICAgIFR1aUJ1dHRvbixcbiAgICBdLFxufSlcbmV4cG9ydCBjbGFzcyBTY0NhdGFsb2dGaWx0ZXJzQ29tcG9uZW50IHtcbiAgICAvKipcbiAgICAgKiDQn9C+0LTQv9C40YHQutC4INGB0LjQvdGF0YDQvtC90LjQt9Cw0YbQuNC4INC60L7QvdGC0YDQvtC70L7QsiDRhNC+0YDQvNGLIChyYW5nZSBzbGlkZXIsIHNpbmdsZS1zZWxlY3QgY2hlY2tib3gpLlxuICAgICAqL1xuICAgIHByaXZhdGUgZm9ybVN5bmNzID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuXG4gICAgLyoqXG4gICAgICog0KHQtdGA0LLQuNGBINC00LvRjyDRgNCw0LHQvtGC0Ysg0YEg0YTQuNC70YzRgtGA0LDQvNC4INC60LDRgtCw0LvQvtCz0LAuXG4gICAgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBjYXRhbG9nRmlsdGVyU2VydmljZTogU2NDYXRhbG9nRmlsdGVyU2VydmljZSA9IGluamVjdChTY0NhdGFsb2dGaWx0ZXJTZXJ2aWNlKTtcblxuICAgIC8qKlxuICAgICAqINCf0LDQudC/LCDQstC+0LfQstGA0LDRidCw0Y7RidC40Lkg0LjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0LjQu9C4INGB0LjQvNCy0L7Qu9GM0L3QvtC1INC+0LHQvtC30L3QsNGH0LXQvdC40LUgKHNsdWcpINC40YHRhdC+0LTRjyDQuNC3INC90LDRgdGC0YDQvtC10Log0L7QutGA0YPQttC10L3QuNGPLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaWRPclNsdWdQaXBlOiBTY0lkT3JTbHVnUGlwZSA9IGluamVjdChTY0lkT3JTbHVnUGlwZSk7XG5cbiAgICAvKipcbiAgICAgKiBTdWJqZWN0INC00LvRjyDRhdGA0LDQvdC10L3QuNGPINGE0LjQu9GM0YLRgNC+0LIg0L/RgNC+0LTRg9C60YLQvtCyLlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgY2F0YWxvZ1Byb2R1Y3RzRmlsdGVycyQgPSBpbmplY3QoU0NfQ0FUQUxPR19QUk9EVUNUU19GSUxURVJTKTtcblxuICAgIC8qKlxuICAgICAqINCf0YDQuNC30L3QsNC6INC90LXQvtCx0YXQvtC00LjQvNC+0YHRgtC4INC+0YLQvtCx0YDQsNC20LDRgtGMINGE0LjQu9GM0YLRgNGLINC00LvRjyDQstC70L7QttC10L3QvdGL0YUg0LrQsNGC0LXQs9C+0YDQuNC5LlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgaXNSZWN1cnNpdmVseSA9IGluamVjdChTQ19DQVRBTE9HX1NIT1dfUFJPRFVDVFNfUkVDVVJTSVZFTFkpO1xuXG4gICAgLyoqXG4gICAgICog0J/QvtC60LDQt9GL0LLQsNGC0Ywg0LvQuCDQutC90L7Qv9C60YMgwqvQn9C+0LrQsNC30LDRgtGMINGA0LXQt9GD0LvRjNGC0LDRgtGLwrsuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHNob3dSZXN1bHRzQnV0dG9uID0gaW5wdXQoZmFsc2UpO1xuXG4gICAgLyoqXG4gICAgICog0KHQvtCx0YvRgtC40LUg0L3QsNC20LDRgtC40Y8g0L3QsCDQutC90L7Qv9C60YMg0YHQsdGA0L7RgdCwINCy0YHQtdGFINGE0LjQu9GM0YLRgNC+0LIuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHJlc2V0RmlsdGVycyA9IG91dHB1dCgpO1xuXG4gICAgLyoqXG4gICAgICog0KHQvtCx0YvRgtC40LUg0L3QsNC20LDRgtC40Y8g0L3QsCDQutC90L7Qv9C60YMg0L/QvtC60LDQt9CwINGA0LXQt9GD0LvRjNGC0LDRgtC+0LIuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IHNob3dSZXN1bHRzID0gb3V0cHV0KCk7XG5cbiAgICAvKipcbiAgICAgKiBGb3JtR3JvdXAg0LTQu9GPINGE0LjQu9GM0YLRgNC+0LIuXG4gICAgICovXG4gICAgcHVibGljIHJlYWRvbmx5IGZvcm0gPSBuZXcgRm9ybUdyb3VwPFxuICAgICAgICBSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiB0aGlzLmNyZWF0ZUNoZWNrYm94Rm9ybUNvbnRyb2w+IHwgUmV0dXJuVHlwZTx0eXBlb2YgdGhpcy5jcmVhdGVSYW5nZUZvcm1Db250cm9sPiB8IFJldHVyblR5cGU8dHlwZW9mIHRoaXMuY3JlYXRlVG9nZ2xlRm9ybUNvbnRyb2w+PlxuICAgID4oe30pO1xuXG4gICAgLyoqXG4gICAgICoge0BsaW5rIE9ic2VydmFibGV9INGE0LjQu9GM0YLRgNC+0LIg0LrQsNGC0LXQs9C+0YDQuNC4LlxuICAgICAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBmaWx0ZXJzID0gdG9TaWduYWwoXG4gICAgICAgIGluamVjdChTQ19DQVRFR09SWV9JTkZPKS5waXBlKFxuICAgICAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBFTVBUWSksXG4gICAgICAgICAgICBmaWx0ZXIodHVpSXNQcmVzZW50KSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoY2F0ZWdvcnkpID0+IHRoaXMuY2F0YWxvZ0ZpbHRlclNlcnZpY2UuZ2V0RmlsdGVycyQodGhpcy5pZE9yU2x1Z1BpcGUudHJhbnNmb3JtKGNhdGVnb3J5KSwgdGhpcy5pc1JlY3Vyc2l2ZWx5KSksXG4gICAgICAgICAgICBmaWx0ZXIodHVpSXNQcmVzZW50KSxcbiAgICAgICAgICAgIG1hcCgoZmlsdGVycykgPT4gZmlsdGVycy5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0udHlwZSAhPT0gJ3JhbmdlJyB8fCBpdGVtLm1pbiAhPT0gaXRlbS5tYXgpKSxcbiAgICAgICAgICAgIHRhcCgoZmlsdGVycykgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRm9ybUNvbnRyb2xzKGZpbHRlcnMpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBzaGFyZSgpXG4gICAgICAgIClcbiAgICApO1xuXG4gICAgLyoqXG4gICAgICog0JjQvdC40YbQuNCw0LvQuNC30LjRgNGD0LXRgiDRjdC60LfQtdC80L/Qu9GP0YAg0LrQu9Cw0YHRgdCwIHtAbGluayBTY0NhdGFsb2dGaWx0ZXJzQ29tcG9uZW50fS5cbiAgICAgKi9cbiAgICBwdWJsaWMgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIGluamVjdChEZXN0cm95UmVmKS5vbkRlc3Ryb3koKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mb3JtU3luY3MudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5mb3JtLnZhbHVlQ2hhbmdlcy5waXBlKGRlYm91bmNlVGltZSgwKSwgdGFrZVVudGlsRGVzdHJveWVkKCkpLnN1YnNjcmliZSgoZmlsdGVycykgPT4ge1xuICAgICAgICAgICAgdGhpcy5jYXRhbG9nUHJvZHVjdHNGaWx0ZXJzJC5uZXh0KHRoaXMuYnVpbGRQcm9wZXJ0eUZpbHRlcnMoZmlsdGVycykpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQntCx0L3QvtCy0LvRj9C10YIg0YHQvtGB0YLQsNCyINC60L7QvdGC0YDQvtC70L7QsiDRhNC+0YDQvNGLINC90LAg0L7RgdC90L7QstC1INC/0LXRgNC10LTQsNC90L3Ri9GFINGE0LjQu9GM0YLRgNC+0LIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZmlsdGVycyDQnNCw0YHRgdC40LIg0YTQuNC70YzRgtGA0L7QsiDQtNC70Y8g0YHQvtC30LTQsNC90LjRjyDQutC+0L3RgtGA0L7Qu9C+0LIuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHVwZGF0ZUZvcm1Db250cm9scyhmaWx0ZXJzOiBTY0NhdGFsb2dGaWx0ZXJbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLmZvcm1TeW5jcy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLmZvcm1TeW5jcyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmZvcm0uY29udHJvbHMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mb3JtLnJlbW92ZUNvbnRyb2woa2V5IGFzIG5ldmVyLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZpbHRlcnMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChpdGVtLnR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjaGVja2JveCc6IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hlY2tib3hDb250cm9sID0gdGhpcy5jcmVhdGVDaGVja2JveEZvcm1Db250cm9sKGl0ZW0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uYWRkQ29udHJvbChpdGVtLmlkLCBjaGVja2JveENvbnRyb2wsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBTaW5nbGUtc2VsZWN0INC00LvRjyAhaXNNdWx0aXBsZTog0L/RgNC4INCy0YvQsdC+0YDQtSDQvtC00L3QvtCz0L4g0L7RgdGC0LDQu9GM0L3Ri9C1INGB0L3QuNC80LDRjtGC0YHRjy5cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpdGVtLmlzTXVsdGlwbGUgJiYgaXRlbS52YWx1ZXMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtU3luY3MuYWRkKHRoaXMuc3luY1NpbmdsZVNlbGVjdENoZWNrYm94KGNoZWNrYm94Q29udHJvbCkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlICdyYW5nZSc6IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmFuZ2VDb250cm9sID0gdGhpcy5jcmVhdGVSYW5nZUZvcm1Db250cm9sKGl0ZW0pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0uYWRkQ29udHJvbChpdGVtLmlkLCByYW5nZUNvbnRyb2wsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtU3luY3MuYWRkKHRoaXMuc3luY1JhbmdlRnJvbVRvQW5kU2xpZGVyKHJhbmdlQ29udHJvbCkpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAndG9nZ2xlJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3JtLmFkZENvbnRyb2woaXRlbS5pZCwgdGhpcy5jcmVhdGVUb2dnbGVGb3JtQ29udHJvbChpdGVtKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J/RgNC10L7QsdGA0LDQt9GD0LXRgiDQt9C90LDRh9C10L3QuNGPINGE0L7RgNC80Ysg0LIg0L7QsdGK0LXQutGCINGE0LjQu9GM0YLRgNC+0LIg0YHQstC+0LnRgdGC0LIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUg0JfQvdCw0YfQtdC90LjRjyDRhNC+0YDQvNGLLlxuICAgICAqIEByZXR1cm5zINCe0LHRitC10LrRgiDRhNC40LvRjNGC0YDQvtCyINGB0LLQvtC50YHRgtCyLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBidWlsZFByb3BlcnR5RmlsdGVycyh2YWx1ZTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pOiBTY1Byb3BlcnR5RmlsdGVycyB7XG4gICAgICAgIGNvbnN0IHJlc3VsdDogU2NQcm9wZXJ0eUZpbHRlcnMgPSB7fTtcblxuICAgICAgICB0aGlzLmZpbHRlcnMoKT8uZm9yRWFjaCgoZmlsdGVySXRlbSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29udHJvbFZhbHVlID0gdmFsdWVbZmlsdGVySXRlbS5pZF07XG5cbiAgICAgICAgICAgIGlmIChpc05pbChjb250cm9sVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzd2l0Y2ggKGZpbHRlckl0ZW0udHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2NoZWNrYm94JzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzQ2hlY2tib3hGaWx0ZXIocmVzdWx0LCBmaWx0ZXJJdGVtLCBjb250cm9sVmFsdWUgYXMgUmVjb3JkPHN0cmluZywgYm9vbGVhbj4pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICdyYW5nZSc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc1JhbmdlRmlsdGVyKHJlc3VsdCwgZmlsdGVySXRlbS5pZCwgY29udHJvbFZhbHVlIGFzIHsgZnJvbTogbnVtYmVyOyB0bzogbnVtYmVyIH0pO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICd0b2dnbGUnOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NUb2dnbGVGaWx0ZXIocmVzdWx0LCBmaWx0ZXJJdGVtLmlkLCBjb250cm9sVmFsdWUgYXMgYm9vbGVhbik7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQodC+0LfQtNCw0ZHRgiBGb3JtR3JvdXAg0LTQu9GPIGNoZWNrYm94OiDQvdCwINC60LDQttC00YvQuSB7QGNvZGUgdmFsdWUuaWR9IOKAlCDQsdGD0LvQtdCy0YvQuSDQutC+0L3RgtGA0L7Quy5cbiAgICAgKlxuICAgICAqINCV0LTQuNC90YvQuSDRhNC+0YDQvNCw0YIg0Lgg0LTQu9GPINC+0LTQvdC+0LPQviwg0Lgg0LTQu9GPINC80L3QvtC20LXRgdGC0LLQsCDQt9C90LDRh9C10L3QuNC5OiDRiNCw0LHQu9C+0L0g0YDQtdC90LTQtdGA0LjRgiDQuNGFINC+0LTQuNC90LDQutC+0LLQvi5cbiAgICAgKiDQoNCw0LfQu9C40YfQuNC1INCyIEFQSS3QstGL0LLQvtC00LUg0LTQu9GPINC+0LTQuNC90L7Rh9C90L7Qs9C+INC30L3QsNGH0LXQvdC40Y8gKGJvb2xlYW4g0LLQvNC10YHRgtC+INC80LDRgdGB0LjQstCwKSDQvtCx0YDQsNCx0LDRgtGL0LLQsNC10YLRgdGPINCyIHtAbGluayBwcm9jZXNzQ2hlY2tib3hGaWx0ZXJ9LlxuICAgICAqXG4gICAgICogQHBhcmFtIGNoZWNrYm94RmlsdGVyINCk0LjQu9GM0YLRgCDRgtC40L/QsCBjaGVja2JveC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY3JlYXRlQ2hlY2tib3hGb3JtQ29udHJvbChjaGVja2JveEZpbHRlcjogU2NJQ2hlY2tib3hGaWx0ZXIpOiBGb3JtR3JvdXA8UmVjb3JkPHN0cmluZywgRm9ybUNvbnRyb2w8Ym9vbGVhbj4+PiB7XG4gICAgICAgIGNvbnN0IGlzU2VsZWN0ZWQgPSAoaWQ6IHN0cmluZyk6IGJvb2xlYW4gPT4gY2hlY2tib3hGaWx0ZXIuc2VsZWN0ZWRWYWx1ZXM/LmluY2x1ZGVzKGlkKSA/PyBmYWxzZTtcbiAgICAgICAgY29uc3QgY29udHJvbHM6IFJlY29yZDxzdHJpbmcsIEZvcm1Db250cm9sPGJvb2xlYW4+PiA9IHt9O1xuXG4gICAgICAgIGNoZWNrYm94RmlsdGVyLnZhbHVlcy5mb3JFYWNoKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgY29udHJvbHNbdmFsdWUuaWRdID0gbmV3IEZvcm1Db250cm9sKGlzU2VsZWN0ZWQodmFsdWUuaWQpLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbmV3IEZvcm1Hcm91cChjb250cm9scyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHQvtC30LTQsNGR0YIge0BsaW5rIEZvcm1Hcm91cH0g0LTQu9GPIHJhbmdlOiB7QGNvZGUgZnJvbX0sIHtAY29kZSB0b30sIHtAY29kZSBzbGlkZXJ9ICjQutC+0YDRgtC10LYg0LTQu9GPIHtAbGluayBUdWlSYW5nZX0pLlxuICAgICAqXG4gICAgICogQHBhcmFtIHJhbmdlRmlsdGVyINCk0LjQu9GM0YLRgCDRgtC40L/QsCByYW5nZS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY3JlYXRlUmFuZ2VGb3JtQ29udHJvbChyYW5nZUZpbHRlcjogU2NSYW5nZUZpbHRlcik6IEZvcm1Hcm91cDx7XG4gICAgICAgIGZyb206IEZvcm1Db250cm9sPG51bWJlcj47XG4gICAgICAgIHRvOiBGb3JtQ29udHJvbDxudW1iZXI+O1xuICAgICAgICBzbGlkZXI6IEZvcm1Db250cm9sPFtudW1iZXIsIG51bWJlcl0+O1xuICAgIH0+IHtcbiAgICAgICAgY29uc3QgZnJvbVZhbHVlID0gTnVtYmVyKHJhbmdlRmlsdGVyLnNlbGVjdGVkTWluID8/IHJhbmdlRmlsdGVyLm1pbik7XG4gICAgICAgIGNvbnN0IHRvVmFsdWUgPSBOdW1iZXIocmFuZ2VGaWx0ZXIuc2VsZWN0ZWRNYXggPz8gcmFuZ2VGaWx0ZXIubWF4KTtcblxuICAgICAgICByZXR1cm4gbmV3IEZvcm1Hcm91cCh7XG4gICAgICAgICAgICBmcm9tOiBuZXcgRm9ybUNvbnRyb2woZnJvbVZhbHVlLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pLFxuICAgICAgICAgICAgdG86IG5ldyBGb3JtQ29udHJvbCh0b1ZhbHVlLCB7IG5vbk51bGxhYmxlOiB0cnVlIH0pLFxuICAgICAgICAgICAgc2xpZGVyOiBuZXcgRm9ybUNvbnRyb2w8W251bWJlciwgbnVtYmVyXT4oW2Zyb21WYWx1ZSwgdG9WYWx1ZV0sIHsgbm9uTnVsbGFibGU6IHRydWUgfSksXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCg0LXQsNC70LjQt9GD0LXRgiBzaW5nbGUtc2VsZWN0INC/0L7QstC10LTQtdC90LjQtSDQtNC70Y8gRm9ybUdyb3VwINGBINCx0YPQu9C10LLRi9C80Lgg0LrQvtC90YLRgNC+0LvQsNC80Lg6XG4gICAgICog0L/RgNC4INC/0L7Rj9Cy0LvQtdC90LjQuCDQvdC+0LLQvtCz0L4gdHJ1ZSDQvtGB0YLQsNC70YzQvdGL0LUg0LrQvtC90YLRgNC+0LvRiyDQs9GA0YPQv9C/0Ysg0YHQsdGA0LDRgdGL0LLQsNGO0YLRgdGPINCyIGZhbHNlLlxuICAgICAqXG4gICAgICog0KHQvtGF0YDQsNC90Y/QtdGCINC/0L7RgdC70LXQtNC90LXQtSDCq9GB0YLQsNCx0LjQu9GM0L3QvtC1wrsg0YHQvtGB0YLQvtGP0L3QuNC1INC4INGB0YDQsNCy0L3QuNCy0LDQtdGCINGB0LvQtdC00YPRjtGJ0LXQtSDQt9C90LDRh9C10L3QuNC1INGBINC90LjQvCDigJRcbiAgICAgKiDQvdC+0LLRi9C5IHRydWUgKNC+0YLRgdGD0YLRgdGC0LLQvtCy0LDQuyDQsiBwcmV2KSDRgdGH0LjRgtCw0LXRgtGB0Y8g0LLRi9Cx0YDQsNC90L3Ri9C8LCDQvtGB0YLQsNC70YzQvdGL0LUg0YHQsdGA0LDRgdGL0LLQsNGO0YLRgdGPINGH0LXRgNC10Lcgc2V0VmFsdWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZ3JvdXAgRm9ybUdyb3VwIGNoZWNrYm94LdGE0LjQu9GM0YLRgNCwIChpZCDihpIgYm9vbGVhbikuXG4gICAgICovXG4gICAgcHJpdmF0ZSBzeW5jU2luZ2xlU2VsZWN0Q2hlY2tib3goZ3JvdXA6IEZvcm1Hcm91cDxSZWNvcmQ8c3RyaW5nLCBGb3JtQ29udHJvbDxib29sZWFuPj4+KTogU3Vic2NyaXB0aW9uIHtcbiAgICAgICAgbGV0IHByZXZpb3VzU3RhdGUgPSBncm91cC5nZXRSYXdWYWx1ZSgpIGFzIFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+O1xuXG4gICAgICAgIHJldHVybiBncm91cC52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY3VycmVudCA9IHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+O1xuICAgICAgICAgICAgY29uc3QgbmV3bHlDaGVja2VkID0gT2JqZWN0LmVudHJpZXMoY3VycmVudCkuZmluZCgoW2lkLCBpc0NoZWNrZWRdKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHNlY3VyaXR5L2RldGVjdC1vYmplY3QtaW5qZWN0aW9uXG4gICAgICAgICAgICAgICAgcmV0dXJuIGlzQ2hlY2tlZCAmJiAhcHJldmlvdXNTdGF0ZVtpZF07XG4gICAgICAgICAgICB9KT8uWzBdO1xuXG4gICAgICAgICAgICBpZiAoIW5ld2x5Q2hlY2tlZCkge1xuICAgICAgICAgICAgICAgIHByZXZpb3VzU3RhdGUgPSB7IC4uLmN1cnJlbnQgfTtcblxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbmV4dDogUmVjb3JkPHN0cmluZywgYm9vbGVhbj4gPSB7fTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKGdyb3VwLmNvbnRyb2xzKS5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzZWN1cml0eS9kZXRlY3Qtb2JqZWN0LWluamVjdGlvblxuICAgICAgICAgICAgICAgIG5leHRbaWRdID0gaWQgPT09IG5ld2x5Q2hlY2tlZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcHJldmlvdXNTdGF0ZSA9IG5leHQ7XG4gICAgICAgICAgICBncm91cC5zZXRWYWx1ZShuZXh0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHQstGP0LfRi9Cy0LDQtdGCINC/0L7Qu9GPIMKr0L7RgsK7L8Kr0LTQvsK7INGBINC60L7QvdGC0YDQvtC70L7QvCDRgdC70LDQudC00LXRgNCwLlxuICAgICAqXG4gICAgICogQHBhcmFtIGdyb3VwIEZvcm1Hcm91cCByYW5nZS3RhNC40LvRjNGC0YDQsC5cbiAgICAgKi9cbiAgICBwcml2YXRlIHN5bmNSYW5nZUZyb21Ub0FuZFNsaWRlcihncm91cDogRm9ybUdyb3VwKTogU3Vic2NyaXB0aW9uIHtcbiAgICAgICAgY29uc3QgZnJvbSA9IGdyb3VwLmdldCgnZnJvbScpO1xuICAgICAgICBjb25zdCB0byA9IGdyb3VwLmdldCgndG8nKTtcbiAgICAgICAgY29uc3Qgc2xpZGVyID0gZ3JvdXAuZ2V0KCdzbGlkZXInKTtcblxuICAgICAgICBpZiAoIWZyb20gfHwgIXRvIHx8ICFzbGlkZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdWIgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgICAgICAgLy8g0JjQvdC/0YPRgtGLIOKGkiDRgdC70LDQudC00LXRgDsg0LXRgdC70LggwqvQvtGCwrsgPiDCq9C00L7Cuywg0L/QvtC00L3QuNC80LDQtdC8IMKr0LTQvsK7INC00L4gwqvQvtGCwrsuXG4gICAgICAgIGNvbnN0IGFwcGx5U2xpZGVyRnJvbUlucHV0cyA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxvdyA9IE51bWJlcihmcm9tLnZhbHVlKTtcbiAgICAgICAgICAgIGxldCBoaWdoID0gTnVtYmVyKHRvLnZhbHVlKTtcblxuICAgICAgICAgICAgaWYgKGxvdyA+IGhpZ2gpIHtcbiAgICAgICAgICAgICAgICBoaWdoID0gbG93O1xuICAgICAgICAgICAgICAgIHRvLnNldFZhbHVlKGhpZ2gsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY3VycmVudFBhaXIgPSBzbGlkZXIudmFsdWUgYXMgW251bWJlciwgbnVtYmVyXTtcblxuICAgICAgICAgICAgaWYgKGN1cnJlbnRQYWlyWzBdICE9PSBsb3cgfHwgY3VycmVudFBhaXJbMV0gIT09IGhpZ2gpIHtcbiAgICAgICAgICAgICAgICBzbGlkZXIuc2V0VmFsdWUoW2xvdywgaGlnaF0sIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICBzbGlkZXIubWFya0FzRGlydHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBzdWIuYWRkKG1lcmdlKGZyb20udmFsdWVDaGFuZ2VzLCB0by52YWx1ZUNoYW5nZXMpLnN1YnNjcmliZShhcHBseVNsaWRlckZyb21JbnB1dHMpKTtcblxuICAgICAgICBzdWIuYWRkKFxuICAgICAgICAgICAgc2xpZGVyLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgW2xvdywgaGlnaF0gPSB2YWx1ZSBhcyBbbnVtYmVyLCBudW1iZXJdO1xuXG4gICAgICAgICAgICAgICAgaWYgKGZyb20udmFsdWUgIT09IGxvdykge1xuICAgICAgICAgICAgICAgICAgICBmcm9tLnNldFZhbHVlKGxvdywgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICBmcm9tLm1hcmtBc0RpcnR5KCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRvLnZhbHVlICE9PSBoaWdoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRvLnNldFZhbHVlKGhpZ2gsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgdG8ubWFya0FzRGlydHkoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuXG4gICAgICAgIC8vINCh0L7QstC/0LDRgdGC0Ywg0YEg0L/QvtC70Y/QvNC4INC/0YDQuCDQv9C10YDQstC+0Lwg0L/QvtC60LDQt9C1ICjRg9C20LUg0YHQvtCy0L/QsNC00LDQtdGCINC/0YDQuCDRgdC+0LfQtNCw0L3QuNC4LCDQvdC+INC90LAg0LLRgdGP0LrQuNC5INGB0LvRg9GH0LDQuSkuXG4gICAgICAgIGFwcGx5U2xpZGVyRnJvbUlucHV0cygpO1xuXG4gICAgICAgIHJldHVybiBzdWI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHQvtC30LTQsNC10YIgRm9ybUNvbnRyb2wg0LTQu9GPIHRvZ2dsZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB0b2dnbGVGaWx0ZXIg0KTQuNC70YzRgtGAINGC0LjQv9CwIHRvZ2dsZS5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgY3JlYXRlVG9nZ2xlRm9ybUNvbnRyb2wodG9nZ2xlRmlsdGVyOiBTY1RvZ2dsZUZpbHRlcik6IEZvcm1Db250cm9sPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBGb3JtQ29udHJvbCh0b2dnbGVGaWx0ZXIuc2VsZWN0ZWRWYWx1ZSA/PyBmYWxzZSwgeyBub25OdWxsYWJsZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQntCx0YDQsNCx0LDRgtGL0LLQsNC10YIgY2hlY2tib3g6IEZvcm1Hcm91cCDihpIgc3RyaW5nW10g0LLRi9Cx0YDQsNC90L3Ri9GFIGlkOyDQtNC70Y8g0LXQtNC40L3RgdGC0LLQtdC90L3QvtCz0L4g0LfQvdCw0YfQtdC90LjRjyDigJQgYm9vbGVhbiAo0LrQsNC6IHRvZ2dsZSkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcmVzdWx0INCe0LHRitC10LrRgiDRgNC10LfRg9C70YzRgtCw0YLQsCDQtNC70Y8g0LfQsNC/0L7Qu9C90LXQvdC40Y8uXG4gICAgICogQHBhcmFtIGNoZWNrYm94RmlsdGVyINCc0LXRgtCw0YTQuNC70YzRgtGAIGNoZWNrYm94LlxuICAgICAqIEBwYXJhbSBjb250cm9sVmFsdWUg0JfQvdCw0YfQtdC90LjQtSDQutC+0L3RgtGA0L7Qu9CwINGE0L7RgNC80YsgKNC30LDQv9C40YHRjCBpZCDihpIgYm9vbGVhbikuXG4gICAgICovXG4gICAgcHJpdmF0ZSBwcm9jZXNzQ2hlY2tib3hGaWx0ZXIocmVzdWx0OiBTY1Byb3BlcnR5RmlsdGVycywgY2hlY2tib3hGaWx0ZXI6IFNjSUNoZWNrYm94RmlsdGVyLCBjb250cm9sVmFsdWU6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkSWRzID0gT2JqZWN0LmVudHJpZXMoY29udHJvbFZhbHVlKVxuICAgICAgICAgICAgLmZpbHRlcigoWywgaXNTZWxlY3RlZF0pID0+IGlzU2VsZWN0ZWQpXG4gICAgICAgICAgICAubWFwKChbaWRdKSA9PiBpZCk7XG5cbiAgICAgICAgaWYgKHNlbGVjdGVkSWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHNlY3VyaXR5L2RldGVjdC1vYmplY3QtaW5qZWN0aW9uLCBuby1wYXJhbS1yZWFzc2lnblxuICAgICAgICByZXN1bHRbY2hlY2tib3hGaWx0ZXIuaWRdID0gc2VsZWN0ZWRJZHM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7QsdGA0LDQsdCw0YLRi9Cy0LDQtdGCIHJhbmdlINGE0LjQu9GM0YLRgC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSByZXN1bHQg0J7QsdGK0LXQutGCINGA0LXQt9GD0LvRjNGC0LDRgtCwINC00LvRjyDQt9Cw0L/QvtC70L3QtdC90LjRjy5cbiAgICAgKiBAcGFyYW0gZmlsdGVySWQg0JjQtNC10L3RgtC40YTQuNC60LDRgtC+0YAg0YTQuNC70YzRgtGA0LAuXG4gICAgICogQHBhcmFtIHJhbmdlINCX0L3QsNGH0LXQvdC40LUg0LrQvtC90YLRgNC+0LvQsCDRhNC+0YDQvNGLICjQvtCx0YrQtdC60YIg0YEg0LPRgNCw0L3QuNGG0LDQvNC4KS5cbiAgICAgKiBAcGFyYW0gcmFuZ2UuZnJvbSDQndCw0YfQsNC70YzQvdC+0LUg0LfQvdCw0YfQtdC90LjQtSDQtNC40LDQv9Cw0LfQvtC90LAuXG4gICAgICogQHBhcmFtIHJhbmdlLnRvINCa0L7QvdC10YfQvdC+0LUg0LfQvdCw0YfQtdC90LjQtSDQtNC40LDQv9Cw0LfQvtC90LAuXG4gICAgICovXG4gICAgcHJpdmF0ZSBwcm9jZXNzUmFuZ2VGaWx0ZXIocmVzdWx0OiBTY1Byb3BlcnR5RmlsdGVycywgZmlsdGVySWQ6IHN0cmluZywgcmFuZ2U6IHsgZnJvbTogbnVtYmVyOyB0bzogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHNlY3VyaXR5L2RldGVjdC1vYmplY3QtaW5qZWN0aW9uLCBuby1wYXJhbS1yZWFzc2lnblxuICAgICAgICByZXN1bHRbZmlsdGVySWRdID0ge1xuICAgICAgICAgICAgZnJvbTogU3RyaW5nKHJhbmdlLmZyb20pLFxuICAgICAgICAgICAgdG86IFN0cmluZyhyYW5nZS50byksXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0J7QsdGA0LDQsdCw0YLRi9Cy0LDQtdGCIHRvZ2dsZSDRhNC40LvRjNGC0YAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcmVzdWx0INCe0LHRitC10LrRgiDRgNC10LfRg9C70YzRgtCw0YLQsCDQtNC70Y8g0LfQsNC/0L7Qu9C90LXQvdC40Y8uXG4gICAgICogQHBhcmFtIGZpbHRlcklkINCY0LTQtdC90YLQuNGE0LjQutCw0YLQvtGAINGE0LjQu9GM0YLRgNCwLlxuICAgICAqIEBwYXJhbSBjb250cm9sVmFsdWUg0JfQvdCw0YfQtdC90LjQtSDQutC+0L3RgtGA0L7Qu9CwINGE0L7RgNC80YsuXG4gICAgICovXG4gICAgcHJpdmF0ZSBwcm9jZXNzVG9nZ2xlRmlsdGVyKHJlc3VsdDogU2NQcm9wZXJ0eUZpbHRlcnMsIGZpbHRlcklkOiBzdHJpbmcsIGNvbnRyb2xWYWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBpZiAoY29udHJvbFZhbHVlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc2VjdXJpdHkvZGV0ZWN0LW9iamVjdC1pbmplY3Rpb24sIG5vLXBhcmFtLXJlYXNzaWduXG4gICAgICAgICAgICByZXN1bHRbZmlsdGVySWRdID0gY29udHJvbFZhbHVlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHQsdGA0LDRgdGL0LLQsNC10YIg0L/QvtC70LUgwqvQvtGCwrsg0LTQuNCw0L/QsNC30L7QvdCwINC6INC80LjQvdC40LzQsNC70YzQvdC+0LzRgyDQt9C90LDRh9C10L3QuNGOINGE0LjQu9GM0YLRgNCwLlxuICAgICAqXG4gICAgICogQHBhcmFtIGZpbHRlcklkINCY0LTQtdC90YLQuNGE0LjQutCw0YLQvtGAINGE0LjQu9GM0YLRgNCwLlxuICAgICAqIEBwYXJhbSBtaW4g0JzQuNC90LjQvNCw0LvRjNC90L7QtSDQt9C90LDRh9C10L3QuNC1INC00LjQsNC/0LDQt9C+0L3QsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVzZXRSYW5nZUZyb20oZmlsdGVySWQ6IHN0cmluZywgbWluOiBzdHJpbmcgfCBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5mb3JtLmdldChmaWx0ZXJJZCk/LmdldCgnZnJvbScpPy5yZXNldCgrbWluKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQodCx0YDQsNGB0YvQstCw0LXRgiDQv9C+0LvQtSDCq9C00L7CuyDQtNC40LDQv9Cw0LfQvtC90LAg0Log0LzQsNC60YHQuNC80LDQu9GM0L3QvtC80YMg0LfQvdCw0YfQtdC90LjRjiDRhNC40LvRjNGC0YDQsC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBmaWx0ZXJJZCDQmNC00LXQvdGC0LjRhNC40LrQsNGC0L7RgCDRhNC40LvRjNGC0YDQsC5cbiAgICAgKiBAcGFyYW0gbWF4INCc0LDQutGB0LjQvNCw0LvRjNC90L7QtSDQt9C90LDRh9C10L3QuNC1INC00LjQsNC/0LDQt9C+0L3QsC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgcmVzZXRSYW5nZVRvKGZpbHRlcklkOiBzdHJpbmcsIG1heDogc3RyaW5nIHwgbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZm9ybS5nZXQoZmlsdGVySWQpPy5nZXQoJ3RvJyk/LnJlc2V0KCttYXgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqINCh0LHRgNCw0YHRi9Cy0LDQtdGCINCy0YHQtSDRh9C10LrQsdC+0LrRgdGLINCz0YDRg9C/0L/RiyDQsiBgZmFsc2VgLlxuICAgICAqXG4gICAgICogQHBhcmFtIGZpbHRlcklkINCY0LTQtdC90YLQuNGE0LjQutCw0YLQvtGAINGE0LjQu9GM0YLRgNCwICjQutC70Y7RhyBGb3JtR3JvdXAg0LIg0YTQvtGA0LzQtSkuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHJlc2V0Q2hlY2tib3hHcm91cChmaWx0ZXJJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5mb3JtLmdldChmaWx0ZXJJZCkgYXMgRm9ybUdyb3VwPFJlY29yZDxzdHJpbmcsIEZvcm1Db250cm9sPGJvb2xlYW4+Pj4gfCBudWxsO1xuXG4gICAgICAgIGlmICghZ3JvdXApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc2V0VmFsdWU6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+ID0ge307XG4gICAgICAgIE9iamVjdC5rZXlzKGdyb3VwLmNvbnRyb2xzKS5mb3JFYWNoKChpZCkgPT4ge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHNlY3VyaXR5L2RldGVjdC1vYmplY3QtaW5qZWN0aW9uXG4gICAgICAgICAgICByZXNldFZhbHVlW2lkXSA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICAgICAgZ3JvdXAucmVzZXQocmVzZXRWYWx1ZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHQsdGA0LDRgdGL0LLQsNC10YIg0LLRgdC1INGE0LjQu9GM0YLRgNGLINC4INC+0L/QvtCy0LXRidCw0LXRgiDRgNC+0LTQuNGC0LXQu9GPINC+INC90LDQttCw0YLQuNC4INC60L3QvtC/0LrQuCDRgdCx0YDQvtGB0LAuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIG9uUmVzZXRGaWx0ZXJzQ2xpY2soKTogdm9pZCB7XG4gICAgICAgIHRoaXMucmVzZXRBbGxGaWx0ZXJzKCk7XG4gICAgICAgIHRoaXMucmVzZXRGaWx0ZXJzLmVtaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDQntC/0L7QstC10YnQsNC10YIg0YDQvtC00LjRgtC10LvRjyDQviDQvdCw0LbQsNGC0LjQuCDQutC90L7Qv9C60Lgg0L/QvtC60LDQt9CwINGA0LXQt9GD0LvRjNGC0LDRgtC+0LIuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIG9uU2hvd1Jlc3VsdHNDbGljaygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zaG93UmVzdWx0cy5lbWl0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog0KHQsdGA0LDRgdGL0LLQsNC10YIg0LLRgdC1INGE0LjQu9GM0YLRgNGLINC6INC40YHRhdC+0LTQvdGL0Lwg0LfQvdCw0YfQtdC90LjRj9C8LlxuICAgICAqL1xuICAgIHByaXZhdGUgcmVzZXRBbGxGaWx0ZXJzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmZpbHRlcnMoKT8uZm9yRWFjaCgoZmlsdGVySXRlbSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29udHJvbCA9IHRoaXMuZm9ybS5nZXQoZmlsdGVySXRlbS5pZCk7XG5cbiAgICAgICAgICAgIGlmICghY29udHJvbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc3dpdGNoIChmaWx0ZXJJdGVtLnR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdjaGVja2JveCc6IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ3JvdXAgPSBjb250cm9sIGFzIEZvcm1Hcm91cDxSZWNvcmQ8c3RyaW5nLCBGb3JtQ29udHJvbDxib29sZWFuPj4+O1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNldFZhbHVlOiBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPiA9IHt9O1xuICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhncm91cC5jb250cm9scykuZm9yRWFjaCgoaWQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBzZWN1cml0eS9kZXRlY3Qtb2JqZWN0LWluamVjdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRWYWx1ZVtpZF0gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwLnJlc2V0KHJlc2V0VmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSAndG9nZ2xlJzpcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbC5yZXNldChmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJ3JhbmdlJzoge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBncm91cCA9IGNvbnRyb2wgYXMgRm9ybUdyb3VwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBtaW4gPSArZmlsdGVySXRlbS5taW47XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1heCA9ICtmaWx0ZXJJdGVtLm1heDtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXAucmVzZXQoeyBmcm9tOiBtaW4sIHRvOiBtYXgsIHNsaWRlcjogW21pbiwgbWF4XSB9KTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJAaWYgKGZpbHRlcnMoKT8ubGVuZ3RoKSB7XG4gICAgPGZvcm1cbiAgICAgICAgW2Zvcm1Hcm91cF09XCJmb3JtXCJcbiAgICAgICAgY2xhc3M9XCJmbGV4IGZsZXgtY29sIHBiLTFcIlxuICAgID5cbiAgICAgICAgQGZvciAoZmlsdGVyIG9mIGZpbHRlcnMoKTsgdHJhY2sgZmlsdGVyLmlkOyBsZXQgaXNGaXJzdCA9ICRmaXJzdCkge1xuICAgICAgICAgICAgQGlmICghaXNGaXJzdCkge1xuICAgICAgICAgICAgICAgIDxociBjbGFzcz1cIm15LTMgdy1mdWxsIGgtcHhcIiAvPlxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBnYXAtMlwiPlxuICAgICAgICAgICAgICAgIDwhLS0g0JfQsNCz0L7Qu9C+0LLQvtC6INCz0YDRg9C/0L/Riy4g0JTQu9GPIHRvZ2dsZSDQv9C+0LTQv9C40YHQuCDQvdC10YI6INC80LXRgtC60LAg0LjQtNGR0YIg0L/RgNGP0LzQviDRgNGP0LTQvtC8INGBINGB0LDQvNC40LwgY2hlY2tib3guIC0tPlxuICAgICAgICAgICAgICAgIEBpZiAoZmlsdGVyLnR5cGUgIT09ICd0b2dnbGUnKSB7XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtYm9keS1zLWJvbGRcIj57eyBmaWx0ZXIubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIDwhLS0gQ2hlY2tib3g6IEZvcm1Hcm91cCh2YWx1ZS5pZCDihpIgYm9vbGVhbikg0LTQu9GPINC70Y7QsdC+0LPQviDRh9C40YHQu9CwINC30L3QsNGH0LXQvdC40LkuXG4gICAgICAgICAgICAgICAgICAgICDQoNCw0LfQstC40LvQutCwINC+0LTQvdC+L9C80L3QvtCz0L4g0LfQvdCw0YfQtdC90LjQuSDQstGL0L3QtdGB0LXQvdCwINCyIFRTICjRgdC8LiBwcm9jZXNzQ2hlY2tib3hGaWx0ZXIpLlxuICAgICAgICAgICAgICAgICAgICAgbmctdGVtcGxhdGUg0LLQvdGD0YLRgNC4IGZvcm1Hcm91cE5hbWU6INC40L3QsNGH0LUgcmVhY3RpdmUgZm9ybXMg0L3QtSDQvdCw0LnQtNGR0YIgQ29udHJvbENvbnRhaW5lciDQv9GA0Lgg0L/RgNC+0LXQutGG0LjQuCDQsiDQtNC+0YfQtdGA0L3QuNC5INC60L7QvNC/0L7QvdC10L3Rgi4gLS0+XG4gICAgICAgICAgICAgICAgQGlmIChmaWx0ZXIudHlwZSA9PT0gJ2NoZWNrYm94Jykge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXggZmxleC1jb2wgZ2FwLTJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Hcm91cE5hbWVdPVwiZmlsdGVyLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNjLWNhdGFsb2ctZmlsdGVyLWNvbGxhcHNpYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2l0ZW1zQ291bnRdPVwiZmlsdGVyLnZhbHVlcy5sZW5ndGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93UmVzZXRdPVwiZm9ybS5nZXQoZmlsdGVyLmlkKT8uZGlydHkgPz8gZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZXNldEdyb3VwKT1cInJlc2V0Q2hlY2tib3hHcm91cChmaWx0ZXIuaWQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sIGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZm9yICh2YWx1ZSBvZiBmaWx0ZXIudmFsdWVzOyB0cmFjayB2YWx1ZS5pZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJ2YWx1ZS5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dWlDaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWJvZHktc1wiPnt7IHZhbHVlLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NjLWNhdGFsb2ctZmlsdGVyLWNvbGxhcHNpYmxlPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIFRvZ2dsZTog0L7QtNC40L0gYm9vbGVhbiDQvdCwINC60L7RgNC90LUg0YTQvtGA0LzRiywg0L/QvtC00L/QuNGB0YwgPSBmaWx0ZXIubGFiZWwgLS0+XG4gICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoZmlsdGVyLnR5cGUgPT09ICd0b2dnbGUnKSB7XG4gICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cImZpbHRlci5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHVpQ2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1ib2R5LXMtYm9sZFwiPnt7IGZpbHRlci5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cblxuICAgICAgICAgICAgICAgICAgICA8IS0tIFJhbmdlOiBGb3JtR3JvdXAoZnJvbSwgdG8sIHNsaWRlcikg0YEg0LTQstGD0YHRgtC+0YDQvtC90L3QtdC5INGB0LjQvdGF0YDQvtC90LjQt9Cw0YbQuNC10LkgLS0+XG4gICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoZmlsdGVyLnR5cGUgPT09ICdyYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Hcm91cE5hbWVdPVwiZmlsdGVyLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZmxleCBmbGV4LWNvbCBnYXAtM1wiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGdhcC0zIHB4LTFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHVpTGFiZWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtaW4tdy0wIGZsZXgtMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDQntGCXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0dWktdGV4dGZpZWxkIFt0dWlUZXh0ZmllbGRDbGVhbmVyXT1cImZhbHNlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY1NlbGVjdE9uRm9jdXNpblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR1aUlucHV0TnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZnJvbVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3R1aU51bWJlckZvcm1hdF09XCJ7IHByZWNpc2lvbjogMCB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluXT1cIitmaWx0ZXIubWluXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4XT1cIitmaWx0ZXIubWF4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZm9ybS5nZXQoZmlsdGVyLmlkKT8uZ2V0KCdmcm9tJyk/LmRpcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dWlJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPVwieHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBlYXJhbmNlPVwiaWNvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGljb25TdGFydD1cIkB0dWkueFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZXNldFJhbmdlRnJvbShmaWx0ZXIuaWQsIGZpbHRlci5taW4pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHVpLXRleHRmaWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0dWlMYWJlbFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm1pbi13LTAgZmxleC0xXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgINCU0L5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHR1aS10ZXh0ZmllbGQgW3R1aVRleHRmaWVsZENsZWFuZXJdPVwiZmFsc2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjU2VsZWN0T25Gb2N1c2luXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHVpSW5wdXROdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJ0b1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3R1aU51bWJlckZvcm1hdF09XCJ7IHByZWNpc2lvbjogMCB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluXT1cIitmaWx0ZXIubWluXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4XT1cIitmaWx0ZXIubWF4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZm9ybS5nZXQoZmlsdGVyLmlkKT8uZ2V0KCd0bycpPy5kaXJ0eSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHVpSWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cInhzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZWFyYW5jZT1cImljb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpY29uU3RhcnQ9XCJAdHVpLnhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVzZXRSYW5nZVRvKGZpbHRlci5pZCwgZmlsdGVyLm1heClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90dWktdGV4dGZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPHR1aS1yYW5nZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9XCJtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJzbGlkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaW5dPVwiK2ZpbHRlci5taW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhdPVwiK2ZpbHRlci5tYXhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS4tLXR1aS10aGlja25lc3MucmVtXT1cIjAuMjVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHVpQnV0dG9uXG4gICAgICAgICAgICBhcHBlYXJhbmNlPVwic2Vjb25kYXJ5XCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJtdC0yXCJcbiAgICAgICAgICAgIChjbGljayk9XCJvblJlc2V0RmlsdGVyc0NsaWNrKClcIlxuICAgICAgICA+XG4gICAgICAgICAgICDQodCx0YDQvtGB0LjRgtGMINGE0LjQu9GM0YLRgNGLXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICBAaWYgKHNob3dSZXN1bHRzQnV0dG9uKCkpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICB0dWlCdXR0b25cbiAgICAgICAgICAgICAgICBhcHBlYXJhbmNlPVwicHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJtdC0yXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwib25TaG93UmVzdWx0c0NsaWNrKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgINCf0L7QutCw0LfQsNGC0Ywg0YDQtdC30YPQu9GM0YLQsNGC0YtcbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9XG4gICAgPC9mb3JtPlxufVxuIl19
|