@sumaris-net/ngx-components 18.2.27-alpha1 → 18.2.28-alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/doc/changelog.md +9 -4
  2. package/esm2022/public_api.mjs +1 -2
  3. package/esm2022/src/app/core/form/properties/properties.table.mjs +1 -1
  4. package/esm2022/src/app/core/install/install-upgrade-card.component.mjs +8 -6
  5. package/esm2022/src/app/core/services/network.service.mjs +2 -2
  6. package/esm2022/src/app/core/services/storage/entity-store.class.mjs +5 -2
  7. package/esm2022/src/app/core/table/testing/table.testing.mjs +2 -2
  8. package/esm2022/src/app/core/table/testing/table2.testing.mjs +1 -1
  9. package/esm2022/src/app/shared/form/field.component.mjs +1 -1
  10. package/esm2022/src/app/shared/inputs.mjs +2 -6
  11. package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +37 -44
  12. package/esm2022/src/app/shared/material/boolean/testing/boolean.test.page.mjs +3 -3
  13. package/esm2022/src/app/shared/material/latlong/latlong.utils.mjs +25 -16
  14. package/esm2022/src/app/shared/material/latlong/material.latlong.mjs +5 -14
  15. package/esm2022/src/app/shared/material/latlong/material.latlong.module.mjs +5 -6
  16. package/esm2022/src/app/shared/material/latlong/testing/latlong.test.mjs +7 -18
  17. package/esm2022/src/app/shared/material/testing/common.test.mjs +1 -1
  18. package/fesm2022/sumaris-net.ngx-components.mjs +123 -741
  19. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  20. package/package.json +1 -1
  21. package/public_api.d.ts +0 -1
  22. package/src/app/shared/material/boolean/material.boolean.d.ts +6 -7
  23. package/src/app/shared/material/latlong/latlong.utils.d.ts +0 -10
  24. package/src/app/shared/material/latlong/material.latlong.d.ts +1 -1
  25. package/src/app/shared/material/latlong/material.latlong.module.d.ts +14 -15
  26. package/src/app/shared/material/latlong/testing/latlong.test.d.ts +2 -3
  27. package/src/assets/i18n/fr.json +1 -8
  28. package/src/assets/manifest.json +1 -1
  29. package/esm2022/src/app/shared/material/latlong/material.latlong2.mjs +0 -631
  30. package/src/app/shared/material/latlong/material.latlong2.d.ts +0 -164
@@ -1,631 +0,0 @@
1
- import { booleanAttribute, ChangeDetectionStrategy, Component, EventEmitter, forwardRef, Inject, Input, numberAttribute, Optional, Output, ViewChild, } from '@angular/core';
2
- import { FormControl, NG_VALUE_ACCESSOR, Validators, } from '@angular/forms';
3
- import { MAT_FORM_FIELD_DEFAULT_OPTIONS, } from '@angular/material/form-field';
4
- import { merge, Subscription } from 'rxjs';
5
- import { filter } from 'rxjs/operators';
6
- import { isNil, isNilOrBlank, isNotNil } from '../../functions';
7
- import { isMobile } from '../../platforms';
8
- import { SharedValidators } from '../../validator/validators';
9
- import { MAT_FORM_FIELD_DEFAULT_APPEARANCE, MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING } from '../material.config';
10
- import { computeDecimalDegrees, LAT_LONG_DEFAULT_MAX_DECIMALS, splitNumberToFieldsDD, splitNumberToFieldsDDMM, splitNumberToFieldsDDMMSS, } from './latlong.utils';
11
- import * as i0 from "@angular/core";
12
- import * as i1 from "@angular/forms";
13
- import * as i2 from "@angular/common";
14
- import * as i3 from "@ionic/angular";
15
- import * as i4 from "../../directives/autofocus.directive";
16
- import * as i5 from "@angular/material/form-field";
17
- import * as i6 from "@angular/material/input";
18
- import * as i7 from "@angular/material/button";
19
- import * as i8 from "@angular/material/icon";
20
- import * as i9 from "@angular/material/select";
21
- import * as i10 from "@angular/material/core";
22
- import * as i11 from "@ngx-translate/core";
23
- import * as i12 from "../../pipes/latlong-format.pipe";
24
- import * as i13 from "../../pipes/arrays.pipe";
25
- import * as i14 from "../../pipes/maps.pipe";
26
- import * as i15 from "../../pipes/string.pipes";
27
- import * as i16 from "../../pipes/types.pipes";
28
- const noop = () => { };
29
- export class MatLatLongField2 {
30
- cd;
31
- formGroupDir;
32
- _onChangeCallback = noop;
33
- _onTouchedCallback = noop;
34
- _subscription = new Subscription();
35
- _disabling = false;
36
- _writing = false;
37
- _appearance = null;
38
- _subscriptSizing = null;
39
- _readonly = false;
40
- _tabindex;
41
- _defaultAppearance;
42
- _defaultSubscriptSizing;
43
- _focused = false;
44
- _touched = false;
45
- degreesControl;
46
- minutesControl;
47
- secondsControl;
48
- signControl;
49
- showMinutes = false;
50
- showSeconds = false;
51
- showSignControl;
52
- degreesPlaceholder;
53
- minutesPlaceholder;
54
- secondsPlaceholder;
55
- maxDecimals = LAT_LONG_DEFAULT_MAX_DECIMALS;
56
- i18nErrorKeys = SharedValidators.I18N_ERROR_KEYS;
57
- minMaxValues;
58
- inputWidth;
59
- formControl;
60
- formControlName;
61
- type;
62
- pattern;
63
- required = false;
64
- floatLabel = 'auto';
65
- placeholder;
66
- defaultSign;
67
- autofocus = false;
68
- mobile;
69
- degreesSymbolUnit = '°';
70
- minutesSymbolUnit = "'";
71
- secondsSymbolUnit = '"';
72
- clearable = true;
73
- set tabindex(value) {
74
- if (this._tabindex !== value) {
75
- this._tabindex = value;
76
- setTimeout(() => this.updateTabIndex());
77
- }
78
- }
79
- get tabindex() {
80
- return this._tabindex;
81
- }
82
- set appearance(value) {
83
- this._appearance = value;
84
- }
85
- get appearance() {
86
- return this._appearance || this._defaultAppearance;
87
- }
88
- set readonly(value) {
89
- this._readonly = value;
90
- this.markForCheck();
91
- }
92
- get readonly() {
93
- return this._readonly;
94
- }
95
- set subscriptSizing(value) {
96
- this._subscriptSizing = value;
97
- }
98
- get subscriptSizing() {
99
- return this._subscriptSizing || this._defaultSubscriptSizing;
100
- }
101
- get showFields() {
102
- return isNotNil(this.formControl.value) || this._focused;
103
- }
104
- get disabled() {
105
- return this.readonly || this.formControl.disabled;
106
- }
107
- // eslint-disable-next-line @angular-eslint/no-output-on-prefix,@angular-eslint/no-output-rename
108
- keyupEnter = new EventEmitter();
109
- // eslint-disable-next-line @angular-eslint/no-output-rename
110
- blurred = new EventEmitter();
111
- // eslint-disable-next-line @angular-eslint/no-output-rename
112
- focused = new EventEmitter();
113
- formField;
114
- fakeInput;
115
- inputDegrees;
116
- inputMinutes;
117
- inputSeconds;
118
- inputSign;
119
- constructor(cd, formGroupDir, defaultOptions) {
120
- this.cd = cd;
121
- this.formGroupDir = formGroupDir;
122
- this._defaultSubscriptSizing = defaultOptions?.subscriptSizing || MAT_FORM_FIELD_DEFAULT_SUBSCRIPT_SIZING;
123
- this._defaultAppearance = defaultOptions?.appearance || MAT_FORM_FIELD_DEFAULT_APPEARANCE;
124
- }
125
- ngOnInit() {
126
- this.mobile = this.mobile ?? isMobile(window);
127
- this.type = this.type || 'latitude';
128
- this.pattern = this.pattern || 'DDMM';
129
- this.showSignControl = this.pattern !== 'DD';
130
- const degreesValidators = [this.type === 'latitude' ? SharedValidators.latitude : SharedValidators.longitude];
131
- const minutesValidators = [];
132
- const secondsValidators = [];
133
- this.minMaxValues = {};
134
- switch (this.pattern) {
135
- case 'DD':
136
- this.maxDecimals = 7;
137
- degreesValidators.push(SharedValidators.decimal({ maxDecimals: this.maxDecimals }));
138
- this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.DD_PLACEHOLDER' : 'COMMON.LAT_LONG.DDD_PLACEHOLDER';
139
- this.inputWidth = {
140
- degrees: '95%',
141
- degreesUnit: '5%',
142
- };
143
- break;
144
- case 'DDMM':
145
- this.maxDecimals = 3;
146
- this.showMinutes = true;
147
- this.minMaxValues['minutes'] = {
148
- min: 0,
149
- max: 60 - this.computeDecimalPart(1, this.maxDecimals),
150
- step: this.computeDecimalPart(1, this.maxDecimals),
151
- };
152
- degreesValidators.push(SharedValidators.integer);
153
- minutesValidators.push(Validators.min(this.minMaxValues.minutes.min));
154
- minutesValidators.push(Validators.max(this.minMaxValues.minutes.max));
155
- minutesValidators.push(SharedValidators.decimal({ maxDecimals: this.maxDecimals }));
156
- this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
157
- this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM_MMM';
158
- this.inputWidth = {
159
- degrees: '35%',
160
- degreesUnit: '5%',
161
- minutes: '55%',
162
- minutesUnit: '5%',
163
- };
164
- break;
165
- default: // Default is DDMMSS
166
- this.maxDecimals = 2;
167
- this.showMinutes = true;
168
- this.showSeconds = true;
169
- this.minMaxValues['minutes'] = {
170
- min: 0,
171
- max: 59,
172
- step: 1,
173
- };
174
- this.minMaxValues['seconds'] = {
175
- min: 0,
176
- max: 60 - this.computeDecimalPart(1, this.maxDecimals),
177
- step: this.computeDecimalPart(1, this.maxDecimals),
178
- };
179
- degreesValidators.push(SharedValidators.integer);
180
- minutesValidators.push(SharedValidators.integer);
181
- minutesValidators.push(Validators.min(this.minMaxValues.minutes.min));
182
- minutesValidators.push(Validators.max(this.minMaxValues.minutes.max));
183
- secondsValidators.push(Validators.min(this.minMaxValues.seconds.min));
184
- secondsValidators.push(Validators.max(this.minMaxValues.seconds.max));
185
- secondsValidators.push(SharedValidators.decimal({ maxDecimals: this.maxDecimals }));
186
- this.degreesPlaceholder = this.type === 'latitude' ? 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DD' : 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.DDD';
187
- this.minutesPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.MM';
188
- this.secondsPlaceholder = 'COMMON.LAT_LONG.SINGLE_FIELD_PATTERN.SS_SS';
189
- this.inputWidth = {
190
- degrees: '25%',
191
- degreesUnit: '5%',
192
- minutes: '25%',
193
- minutesUnit: '5%',
194
- seconds: '35%',
195
- secondsUnit: '5%',
196
- };
197
- break;
198
- }
199
- // Must be done after set this.maxDecimals in switch block above
200
- this.minMaxValues['degrees'] = {
201
- min: this.pattern === 'DD' ? (this.type === 'latitude' ? -90 : -180) : 0,
202
- max: this.type === 'latitude' ? 90 : 180,
203
- step: this.pattern === 'DD' ? this.computeDecimalPart(1, this.maxDecimals) : 1,
204
- };
205
- this.formControl =
206
- this.formControl || (this.formControlName && this.formGroupDir && this.formGroupDir.form.get(this.formControlName));
207
- if (!this.formControl)
208
- throw new Error("Missing mandatory attribute 'formControl' or 'formControlName' in <mat-latlong-field>.");
209
- this.degreesControl = new FormControl(null, degreesValidators);
210
- this.minutesControl = new FormControl(null, minutesValidators);
211
- this.secondsControl = new FormControl(null, secondsValidators);
212
- this.signControl = new FormControl(null);
213
- this._subscription.add(merge(this.degreesControl.valueChanges, this.minutesControl.valueChanges, this.secondsControl.valueChanges, this.signControl.valueChanges).subscribe((_) => this.onFormChange()));
214
- // Listen status changes (when done outside the component - e.g. when setErrors() is calling on the formControl)
215
- this._subscription.add(this.formControl.statusChanges
216
- .pipe(filter(() => !this.readonly && !this._writing && !this._disabling) // Skip
217
- )
218
- .subscribe(() => this.markForCheck()));
219
- }
220
- ngOnDestroy() {
221
- this._subscription.unsubscribe();
222
- }
223
- registerOnChange(fn) {
224
- this._onChangeCallback = fn;
225
- }
226
- registerOnTouched(fn) {
227
- this._onTouchedCallback = fn;
228
- }
229
- writeValue(value) {
230
- if (this._writing)
231
- return;
232
- this._writing = true;
233
- if (value !== this.formControl.value) {
234
- this.formControl.patchValue(value, { emitEvent: false });
235
- this._onChangeCallback(value);
236
- }
237
- const result = this.computeLatLongFormGroupValue(value);
238
- console.debug('[mat-latlong-field] Changing value of inputs:', value, result);
239
- this.patchValue(result, { emitEvent: false });
240
- this._writing = false;
241
- this.markForCheck();
242
- setTimeout(() => {
243
- this.updateFakeInput();
244
- this.updateTabIndex();
245
- });
246
- }
247
- setDisabledState(isDisabled) {
248
- if (this._disabling)
249
- return;
250
- this._disabling = true;
251
- if (isDisabled) {
252
- this.degreesControl.disable();
253
- this.minutesControl.disable();
254
- this.secondsControl.disable();
255
- this.signControl.disable();
256
- }
257
- else {
258
- this.degreesControl.enable();
259
- this.minutesControl.enable();
260
- this.secondsControl.enable();
261
- this.signControl.enable();
262
- }
263
- this._disabling = false;
264
- this.markForCheck();
265
- }
266
- clearValue(event) {
267
- event?.stopPropagation();
268
- this.writeValue(null);
269
- }
270
- get inputsElements() {
271
- return (this.inputDegrees ? [this.inputDegrees.nativeElement] : [])
272
- .concat(this.inputMinutes ? [this.inputMinutes.nativeElement] : [])
273
- .concat(this.inputSeconds ? [this.inputSeconds.nativeElement] : [])
274
- .concat(this.inputSign ? [this.inputSign.nativeElement] : [])
275
- .concat(this.fakeInput ? [this.fakeInput.nativeElement] : []);
276
- }
277
- onFocusFakeInput(event) {
278
- if (!this.showFields) {
279
- event.preventDefault();
280
- // Hide the fake input
281
- this.fakeInput?.nativeElement.classList.add('cdk-visually-hidden');
282
- }
283
- this._touched = this.formControl.touched;
284
- // Focus on first input
285
- this.focus();
286
- }
287
- onBlurFakeInput(event) {
288
- const internalEvent = this.inputsElements.some((el) => el === event.relatedTarget);
289
- if (internalEvent && !this._touched) {
290
- // Workaround to remove touched on the fakeInput
291
- this.formControl.markAsUntouched();
292
- }
293
- }
294
- _onFocusInput(event) {
295
- const internalEvent = this.inputsElements.some((el) => el === event.relatedTarget);
296
- if (!internalEvent) {
297
- this.focus(false /*focusOnDegrees*/);
298
- }
299
- }
300
- _onBlurInput(event) {
301
- const internalEvent = this.inputsElements.some((el) => el === event.relatedTarget);
302
- if (!internalEvent) {
303
- this._focused = false;
304
- if (this.appearance == 'fill') {
305
- this.formField._lineRipple.deactivate();
306
- }
307
- this.blurred.emit(event);
308
- this.updateFakeInput();
309
- this.updateTabIndex();
310
- this._touched = true;
311
- this.formControl.markAsTouched();
312
- this._checkIfTouched();
313
- }
314
- }
315
- _onClickInput(event) {
316
- // Avoid mat-form-field to give focus to fake input
317
- event.stopPropagation();
318
- }
319
- focus(focusOnDegrees) {
320
- if (this._focused)
321
- return true; // Already focused
322
- const showFields = this.showFields;
323
- this._focused = true;
324
- this.markForCheck();
325
- setTimeout(() => {
326
- if (!showFields && focusOnDegrees !== false)
327
- this.inputDegrees.nativeElement.focus();
328
- if (this.appearance == 'fill') {
329
- this.formField._lineRipple.activate();
330
- }
331
- // Add a blur listener on each inputs
332
- /*const inputElements: HTMLElement[] = this.inputsElements;
333
- inputElements.filter(isNotNil).forEach(
334
- (el) =>
335
- (el.onblur = (e) => {
336
- //console.debug('onblur to element=', e.relatedTarget);
337
-
338
- // Setup a one-time focus event handler
339
- const focusListener = (focusEvent: FocusEvent) => {
340
- // Remove the event listener after it has been executed once
341
- window.removeEventListener('focus', focusListener);
342
-
343
- //console.debug('NExt focus element=', focusEvent.target);
344
- const internalEvent = inputElements.includes(focusEvent.target as HTMLElement);
345
-
346
- if (!internalEvent) {
347
- this._focused = false;
348
- this.updateFakeInput();
349
- this.updateTabIndex();
350
- //this._onTouchedCallback();
351
-
352
- this.formField._lineRipple.deactivate();
353
- this.blurred.emit(focusEvent);
354
-
355
- // this._touched = true;
356
- // this.formControl.markAsUntouched();
357
- // this._checkIfTouched();
358
- }
359
- };
360
- window.addEventListener('focus', focusListener, true);
361
- })
362
- );*/
363
- this.updateFakeInput();
364
- this.updateTabIndex();
365
- }, 250);
366
- }
367
- format(rawValue) {
368
- const values = this.computeLatLongFormGroupValue(rawValue);
369
- if (values.degrees === null)
370
- return '';
371
- let result = `${values.degrees}° `;
372
- if (values.minutes !== null)
373
- result += `${values.minutes}' `;
374
- if (values.seconds !== null)
375
- result += `${values.seconds}" `;
376
- if (this.type === 'latitude') {
377
- result += values.sign === 1 ? 'N' : 'S';
378
- }
379
- else {
380
- result += values.sign === 1 ? 'E' : 'W';
381
- }
382
- return result;
383
- }
384
- computeDecimalPart(value, nbOfDecimals) {
385
- return value * 10 ** (nbOfDecimals * -1);
386
- }
387
- computeLatLongFormGroupValue(rawValue) {
388
- const isLongitude = this.type === 'longitude';
389
- const value = typeof rawValue === 'string' ? parseFloat(rawValue.replace(/,/g, '.')) : rawValue;
390
- const result = {
391
- degrees: null,
392
- minutes: null,
393
- seconds: null,
394
- sign: isNotNil(value)
395
- ? value < 0
396
- ? -1
397
- : 1
398
- : // Use default sign, if any
399
- this.defaultSign && this.defaultSign === '-'
400
- ? -1
401
- : 1,
402
- };
403
- if (value === 0) {
404
- result.degrees = 0;
405
- }
406
- else if (isNotNil(value)) {
407
- if (this.pattern === 'DD') {
408
- const splitValue = splitNumberToFieldsDD(value, {
409
- longitude: isLongitude,
410
- pattern: this.pattern,
411
- maxDecimals: this.maxDecimals,
412
- fixLatLong: true,
413
- }).slice(1); // remove sign;
414
- result.degrees = (splitValue[0] + this.computeDecimalPart(splitValue[1] ?? 0, this.maxDecimals)) * (result.sign || 1) || null;
415
- }
416
- else if (this.pattern === 'DDMM') {
417
- const splitValue = splitNumberToFieldsDDMM(value, {
418
- longitude: isLongitude,
419
- pattern: this.pattern,
420
- maxDecimals: this.maxDecimals,
421
- fixLatLong: true,
422
- });
423
- result['minutes'] = Math.abs((splitValue[1] ?? 0) + this.computeDecimalPart(splitValue[2] ?? 0, this.maxDecimals)) || null;
424
- result['degrees'] = Math.abs(!result['minutes'] && isNilOrBlank(splitValue[0]) ? null : (splitValue[0] ?? 0));
425
- }
426
- else {
427
- // Default // DDMMSS
428
- const splitValue = splitNumberToFieldsDDMMSS(value, {
429
- longitude: isLongitude,
430
- pattern: this.pattern,
431
- maxDecimals: this.maxDecimals,
432
- fixLatLong: true,
433
- });
434
- result['seconds'] = Math.abs((splitValue[2] ?? 0) + this.computeDecimalPart(splitValue[3] ?? 0, this.maxDecimals)) || null;
435
- result['minutes'] = !result['seconds'] && !splitValue[1] ? null : Math.abs(splitValue[1] ?? 0);
436
- result['degrees'] = !result['seconds'] && !result['minutes'] && isNilOrBlank(splitValue[0]) ? null : Math.abs(splitValue[0] ?? 0);
437
- }
438
- }
439
- return result;
440
- }
441
- markAsTouched() {
442
- this.formControl.markAsTouched();
443
- this.degreesControl.markAsTouched();
444
- this.minutesControl.markAsTouched();
445
- this.secondsControl.markAsTouched();
446
- this.signControl.markAsTouched();
447
- this._onTouchedCallback();
448
- }
449
- /* -- private method -- */
450
- patchValue(values, opts) {
451
- this.degreesControl.patchValue(values.degrees, opts);
452
- this.minutesControl.patchValue(values.minutes, opts);
453
- this.secondsControl.patchValue(values.seconds, opts);
454
- this.signControl.patchValue(values.sign, opts);
455
- }
456
- onFormChange() {
457
- if (this._writing)
458
- return; // Skip if call by self
459
- this._writing = true;
460
- // DEBUG
461
- console.debug('[mat-latlong-field] onFormChange ');
462
- const degrees = this.degreesControl.value;
463
- const minutes = this.minutesControl.value;
464
- const seconds = this.secondsControl.value;
465
- const sign = this.signControl.value;
466
- const incompleteValue = isNil(degrees) && (isNotNil(minutes) || isNotNil(seconds));
467
- const invalid = incompleteValue || this.degreesControl.invalid || this.minutesControl.invalid || this.secondsControl.invalid || this.signControl.invalid;
468
- if (invalid) {
469
- // DEBUG
470
- console.debug(`[mat-latlong-field] onFormChange() error -> incompleteValue: ${incompleteValue}`);
471
- this.formControl.markAsPending({ onlySelf: true });
472
- this.formControl.setErrors({
473
- invalid: incompleteValue,
474
- ...this.degreesControl.errors,
475
- ...this.minutesControl.errors,
476
- ...this.secondsControl.errors,
477
- ...this.signControl.errors,
478
- });
479
- if (this.degreesControl.dirty || this.minutesControl.dirty || this.secondsControl.dirty || this.signControl.dirty) {
480
- this.formControl.markAsDirty();
481
- }
482
- this._writing = false;
483
- return;
484
- }
485
- // Compute decimal values
486
- const value = isNil(degrees) || this.pattern === 'DD' ? degrees : computeDecimalDegrees(degrees, minutes, seconds, sign, this.maxDecimals);
487
- // Set model value
488
- this.emitChange(value);
489
- this._writing = false;
490
- this.markForCheck();
491
- }
492
- emitChange(value) {
493
- if (this.formControl.value !== value) {
494
- // DEBUG
495
- console.debug('[mat-latlong-field] Emit new value: ' + value);
496
- this.formControl.setValue(value, { emitEvent: false });
497
- // Changes comes from inside function: use the callback
498
- this._onChangeCallback(value);
499
- // Check if need to update controls
500
- this._checkIfTouched();
501
- }
502
- }
503
- _checkIfTouched() {
504
- if (this.formControl.touched) {
505
- this._onTouchedCallback();
506
- this.markForCheck();
507
- this._touched = true;
508
- }
509
- else {
510
- this._touched = false;
511
- }
512
- }
513
- markForCheck() {
514
- this.cd.markForCheck();
515
- }
516
- /**
517
- * Show/Hide the fake input
518
- */
519
- updateFakeInput() {
520
- if (this.showFields) {
521
- this.fakeInput?.nativeElement.classList.add('cdk-visually-hidden');
522
- }
523
- else {
524
- this.fakeInput?.nativeElement.classList.remove('cdk-visually-hidden');
525
- }
526
- // TODO: check if need
527
- this.markForCheck();
528
- }
529
- /**
530
- * This is a special case, because, this component has a temporary component displayed before the first focus event
531
- */
532
- updateTabIndex() {
533
- if (isNil(this._tabindex))
534
- return;
535
- if (this.fakeInput) {
536
- this.fakeInput.nativeElement.tabIndex = this._tabindex;
537
- }
538
- this.markForCheck();
539
- }
540
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField2, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.FormGroupDirective, optional: true }, { token: MAT_FORM_FIELD_DEFAULT_OPTIONS }], target: i0.ɵɵFactoryTarget.Component });
541
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.11", type: MatLatLongField2, selector: "mat-latlong-field", inputs: { formControl: "formControl", formControlName: "formControlName", type: "type", pattern: ["latLongPattern", "pattern"], required: "required", floatLabel: "floatLabel", placeholder: "placeholder", defaultSign: "defaultSign", autofocus: "autofocus", mobile: ["mobile", "mobile", booleanAttribute], degreesSymbolUnit: "degreesSymbolUnit", minutesSymbolUnit: "minutesSymbolUnit", secondsSymbolUnit: "secondsSymbolUnit", clearable: ["clearable", "clearable", booleanAttribute], tabindex: ["tabindex", "tabindex", numberAttribute], appearance: "appearance", readonly: "readonly", subscriptSizing: "subscriptSizing" }, outputs: { keyupEnter: "keyup.enter", blurred: "blur", focused: "focus" }, providers: [
542
- {
543
- provide: NG_VALUE_ACCESSOR,
544
- multi: true,
545
- useExisting: forwardRef(() => MatLatLongField2),
546
- },
547
- ], viewQueries: [{ propertyName: "formField", first: true, predicate: ["formField"], descendants: true }, { propertyName: "fakeInput", first: true, predicate: ["fakeInput"], descendants: true }, { propertyName: "inputDegrees", first: true, predicate: ["inputDegrees"], descendants: true }, { propertyName: "inputMinutes", first: true, predicate: ["inputMinutes"], descendants: true }, { propertyName: "inputSeconds", first: true, predicate: ["inputSeconds"], descendants: true }, { propertyName: "inputSign", first: true, predicate: ["inputSign"], descendants: true }], ngImport: i0, template: "<!-- readonly -->\n@if (readonly) {\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n class=\"mat-form-field-disabled\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && !!placeholder) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input matInput hidden type=\"text\" readonly [formControl]=\"formControl\" />\n <ion-text>\n {{\n formControl.value\n | latLongFormat: { pattern: pattern, maxDecimals: maxDecimals, type: type, placeholderChar: '' }\n }}\n </ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <!-- hints -->\n <mat-hint [class.cdk-visually-hidden]=\"formControl.invalid\">\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n </mat-form-field>\n} @else {\n <!-- writable -->\n <ion-grid class=\"ion-no-padding {{ appearance }}\">\n <ion-row class=\"ion-no-padding no-wrap\">\n <!-- degrees -->\n <ion-col class=\"degrees ion-no-padding\">\n <mat-form-field\n #formField\n [floatLabel]=\"\n showFields && (!floatLabel || floatLabel === 'auto') ? 'always' : (floatLabel | asFloatLabelType)\n \"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signControl.invalid || formControl.invalid)\"\n class=\"values\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && placeholder | isNotNilOrBlank) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input\n matInput\n #fakeInput\n type=\"text\"\n readonly=\"true\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [appAutofocus]=\"!showFields && autofocus\"\n [tabindex]=\"tabindex\"\n [class.cdk-visually-hidden]=\"showFields\"\n (focus)=\"onFocusFakeInput($event)\"\n (blur)=\"onBlurFakeInput($event)\"\n />\n <input\n matInput\n #inputDegrees\n [style.width]=\"showFields ? inputWidth.degrees : '100%'\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n [formControl]=\"degreesControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"showFields && autofocus\"\n [min]=\"minMaxValues.degrees.min\"\n [max]=\"minMaxValues.degrees.max\"\n [step]=\"minMaxValues.degrees.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n [class.cdk-visually-hidden]=\"!showFields\"\n />\n <span\n class=\"symbol-unit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n [style.width]=\"this.inputWidth.degreesUnit\"\n >\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n matInput\n #inputMinutes\n [style.width]=\"this.inputWidth.minutes\"\n [class.cdk-visually-hidden]=\"!showFields\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n [formControl]=\"minutesControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [min]=\"minMaxValues.minutes.min\"\n [max]=\"minMaxValues.minutes.max\"\n [step]=\"minMaxValues.minutes.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span\n class=\"symbol-unit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n [style.width]=\"this.inputWidth.minutesUnit\"\n >\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n matInput\n #inputSeconds\n [style.width]=\"inputWidth.seconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n [formControl]=\"secondsControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [min]=\"minMaxValues.seconds.min\"\n [max]=\"minMaxValues.seconds.max\"\n [step]=\"minMaxValues.seconds.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span\n [style.width]=\"this.inputWidth.secondsUnit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n class=\"symbol-unit\"\n >\n {{ secondsSymbolUnit }}\n </span>\n }\n\n @if (!showSignControl) {\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n }\n </mat-form-field>\n </ion-col>\n\n <!-- sign -->\n @if (showSignControl) {\n <ion-col class=\"sign ion-no-padding {{ type }}\">\n @switch (type) {\n @case ('latitude') {\n <!-- sign on latitude -->\n <mat-form-field\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && signControl.invalid\"\n >\n <mat-label></mat-label>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' | translate\"\n [tabindex]=\"tabindex !== undefined ? tabindex + 1 : undefined\"\n >\n <mat-option [value]=\"1\">{{ 'COMMON.LAT_LONG.LAT_SIGN_N' | translate }}</mat-option>\n <mat-option [value]=\"-1\">{{ 'COMMON.LAT_LONG.LAT_SIGN_S' | translate }}</mat-option>\n </mat-select>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n }\n @case ('longitude') {\n <!-- sign on longitude -->\n <mat-form-field\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && signControl.invalid\"\n >\n <mat-label></mat-label>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER' | translate\"\n [tabindex]=\"tabindex !== undefined ? tabindex + 1 : undefined\"\n >\n <mat-option [value]=\"1\" translate>{{ 'COMMON.LAT_LONG.LONG_SIGN_E' | translate }}</mat-option>\n <mat-option [value]=\"-1\" translate>{{ 'COMMON.LAT_LONG.LONG_SIGN_W' | translate }}</mat-option>\n </mat-select>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n }\n }\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n\n <!-- Do the same as MatFromField since angular 15 (see component source)-->\n <div\n class=\"mat-mdc-form-field-subscript-wrapper\"\n [class.mat-mdc-form-field-bottom-align]=\"subscriptSizing === 'fixed'\"\n [class.mat-mdc-form-field-subscript-dynamic-size]=\"subscriptSizing === 'dynamic'\"\n >\n @if (formControl.touched && formControl.invalid) {\n <!-- errors -->\n <div class=\"mat-mdc-form-field-error-wrapper\">\n @if (formControl.errors | mapKeys | arrayFirst; as errorKey) {\n <mat-error>\n {{ i18nErrorKeys | mapGet: errorKey | translate: (formControl.errors | mapGet: errorKey) }}\n </mat-error>\n } @else {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n </div>\n } @else {\n <!-- hints -->\n <mat-hint>\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n }\n </div>\n}\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\n @if (clearable && !readonly) {\n <button\n matSuffix\n mat-icon-button\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearValue($event)\"\n [hidden]=\"formControl.value | isNil\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #matErrorTemplate>\n <ng-content select=\"mat-error,[matError]\"></ng-content>\n</ng-template>\n\n<ng-template #matHintTemplate>\n <div class=\"mat-mdc-form-field-hint-wrapper\">\n <ng-content select=\"mat-hint:not([align='end']),[matHint]\"></ng-content>\n <div class=\"mat-mdc-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint[align='end']\"></ng-content>\n </div>\n</ng-template>\n", styles: [":host{display:inline-block;width:100%;min-width:140px;position:relative;--ion-grid-column-padding: 0}mat-form-field{width:100%}mat-form-field .datetime-md{padding:0!important}.sign mat-form-field.mat-mdc-form-field-should-float .mat-mdc-form-field-placeholder{max-width:inherit}ion-row.no-wrap{flex-wrap:nowrap}ion-grid ion-col.degrees{--min-width: 130px;min-width:var(--min-width)}ion-grid ion-col.minutes{--min-width: 105px;min-width:var(--min-width);max-width:var(--min-width)}ion-grid ion-col.seconds{--min-width: 105px;min-width:var(--min-width);max-width:var(--min-width)}ion-grid ion-col.sign{--min-width: 58px;--max-width: 65px;min-width:var(--min-width);max-width:var(--max-width)}input[type=number]{text-align:right}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}span.symbol-unit{display:inline-block;text-align:center;font-weight:700;font-size:1.3em}\n"], dependencies: [{ kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.IonCol, selector: "ion-col", inputs: ["offset", "offsetLg", "offsetMd", "offsetSm", "offsetXl", "offsetXs", "pull", "pullLg", "pullMd", "pullSm", "pullXl", "pullXs", "push", "pushLg", "pushMd", "pushSm", "pushXl", "pushXs", "size", "sizeLg", "sizeMd", "sizeSm", "sizeXl", "sizeXs"] }, { kind: "component", type: i3.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i3.IonRow, selector: "ion-row" }, { kind: "component", type: i3.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { 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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "component", type: i5.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i5.MatLabel, selector: "mat-label" }, { kind: "directive", type: i5.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i5.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i5.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i5.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i6.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i7.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i10.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i11.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "pipe", type: i12.LatLongFormatPipe, name: "latLongFormat" }, { kind: "pipe", type: i13.ArrayFirstPipe, name: "arrayFirst" }, { kind: "pipe", type: i14.MapGetPipe, name: "mapGet" }, { kind: "pipe", type: i14.MapKeysPipe, name: "mapKeys" }, { kind: "pipe", type: i15.IsNotNilOrBlankPipe, name: "isNotNilOrBlank" }, { kind: "pipe", type: i15.IsNilPipe, name: "isNil" }, { kind: "pipe", type: i16.AsFloatLabelTypePipe, name: "asFloatLabelType" }, { kind: "pipe", type: i11.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
548
- }
549
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.11", ngImport: i0, type: MatLatLongField2, decorators: [{
550
- type: Component,
551
- args: [{ selector: 'mat-latlong-field', providers: [
552
- {
553
- provide: NG_VALUE_ACCESSOR,
554
- multi: true,
555
- useExisting: forwardRef(() => MatLatLongField2),
556
- },
557
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- readonly -->\n@if (readonly) {\n <mat-form-field\n [floatLabel]=\"floatLabel | asFloatLabelType\"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"subscriptSizing\"\n class=\"mat-form-field-disabled\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && !!placeholder) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input matInput hidden type=\"text\" readonly [formControl]=\"formControl\" />\n <ion-text>\n {{\n formControl.value\n | latLongFormat: { pattern: pattern, maxDecimals: maxDecimals, type: type, placeholderChar: '' }\n }}\n </ion-text>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n\n <!-- hints -->\n <mat-hint [class.cdk-visually-hidden]=\"formControl.invalid\">\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n </mat-form-field>\n} @else {\n <!-- writable -->\n <ion-grid class=\"ion-no-padding {{ appearance }}\">\n <ion-row class=\"ion-no-padding no-wrap\">\n <!-- degrees -->\n <ion-col class=\"degrees ion-no-padding\">\n <mat-form-field\n #formField\n [floatLabel]=\"\n showFields && (!floatLabel || floatLabel === 'auto') ? 'always' : (floatLabel | asFloatLabelType)\n \"\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && (signControl.invalid || formControl.invalid)\"\n class=\"values\"\n >\n <div matPrefix>\n <ng-container *ngTemplateOutlet=\"matPrefixTemplate\"></ng-container>\n </div>\n\n @if (floatLabel !== 'never' && placeholder | isNotNilOrBlank) {\n <mat-label>{{ placeholder }}</mat-label>\n }\n\n <input\n matInput\n #fakeInput\n type=\"text\"\n readonly=\"true\"\n [formControl]=\"formControl\"\n [required]=\"required\"\n [appAutofocus]=\"!showFields && autofocus\"\n [tabindex]=\"tabindex\"\n [class.cdk-visually-hidden]=\"showFields\"\n (focus)=\"onFocusFakeInput($event)\"\n (blur)=\"onBlurFakeInput($event)\"\n />\n <input\n matInput\n #inputDegrees\n [style.width]=\"showFields ? inputWidth.degrees : '100%'\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"degreesPlaceholder | translate\"\n [formControl]=\"degreesControl\"\n [required]=\"required\"\n [tabindex]=\"tabindex\"\n [appAutofocus]=\"showFields && autofocus\"\n [min]=\"minMaxValues.degrees.min\"\n [max]=\"minMaxValues.degrees.max\"\n [step]=\"minMaxValues.degrees.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n [class.cdk-visually-hidden]=\"!showFields\"\n />\n <span\n class=\"symbol-unit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n [style.width]=\"this.inputWidth.degreesUnit\"\n >\n {{ degreesSymbolUnit }}\n </span>\n\n @if (showMinutes) {\n <input\n matInput\n #inputMinutes\n [style.width]=\"this.inputWidth.minutes\"\n [class.cdk-visually-hidden]=\"!showFields\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"minutesPlaceholder | translate\"\n [formControl]=\"minutesControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [min]=\"minMaxValues.minutes.min\"\n [max]=\"minMaxValues.minutes.max\"\n [step]=\"minMaxValues.minutes.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span\n class=\"symbol-unit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n [style.width]=\"this.inputWidth.minutesUnit\"\n >\n {{ minutesSymbolUnit }}\n </span>\n }\n\n @if (showSeconds) {\n <input\n matInput\n #inputSeconds\n [style.width]=\"inputWidth.seconds\"\n [class.cdk-visually-hidden]=\"!showFields\"\n type=\"number\"\n autocomplete=\"off\"\n [placeholder]=\"secondsPlaceholder | translate\"\n [formControl]=\"secondsControl\"\n [required]=\"false\"\n [tabindex]=\"tabindex\"\n [min]=\"minMaxValues.seconds.min\"\n [max]=\"minMaxValues.seconds.max\"\n [step]=\"minMaxValues.seconds.step\"\n (focus)=\"_onFocusInput($event)\"\n (blur)=\"_onBlurInput($event)\"\n (click)=\"_onClickInput($event)\"\n />\n <span\n [style.width]=\"this.inputWidth.secondsUnit\"\n [class.cdk-visually-hidden]=\"!showFields\"\n class=\"symbol-unit\"\n >\n {{ secondsSymbolUnit }}\n </span>\n }\n\n @if (!showSignControl) {\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n }\n </mat-form-field>\n </ion-col>\n\n <!-- sign -->\n @if (showSignControl) {\n <ion-col class=\"sign ion-no-padding {{ type }}\">\n @switch (type) {\n @case ('latitude') {\n <!-- sign on latitude -->\n <mat-form-field\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && signControl.invalid\"\n >\n <mat-label></mat-label>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"'COMMON.LAT_LONG.LAT_SIGN_PLACEHOLDER' | translate\"\n [tabindex]=\"tabindex !== undefined ? tabindex + 1 : undefined\"\n >\n <mat-option [value]=\"1\">{{ 'COMMON.LAT_LONG.LAT_SIGN_N' | translate }}</mat-option>\n <mat-option [value]=\"-1\">{{ 'COMMON.LAT_LONG.LAT_SIGN_S' | translate }}</mat-option>\n </mat-select>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n }\n @case ('longitude') {\n <!-- sign on longitude -->\n <mat-form-field\n [appearance]=\"appearance\"\n [subscriptSizing]=\"'dynamic'\"\n [class.mdc-text-field--invalid]=\"formControl.touched && signControl.invalid\"\n >\n <mat-label></mat-label>\n <mat-select\n #inputSign\n [formControl]=\"signControl\"\n [placeholder]=\"'COMMON.LAT_LONG.LONG_SIGN_PLACEHOLDER' | translate\"\n [tabindex]=\"tabindex !== undefined ? tabindex + 1 : undefined\"\n >\n <mat-option [value]=\"1\" translate>{{ 'COMMON.LAT_LONG.LONG_SIGN_E' | translate }}</mat-option>\n <mat-option [value]=\"-1\" translate>{{ 'COMMON.LAT_LONG.LONG_SIGN_W' | translate }}</mat-option>\n </mat-select>\n\n <div matSuffix>\n <ng-container *ngTemplateOutlet=\"matSuffixTemplate\"></ng-container>\n </div>\n </mat-form-field>\n }\n }\n </ion-col>\n }\n </ion-row>\n </ion-grid>\n\n <!-- Do the same as MatFromField since angular 15 (see component source)-->\n <div\n class=\"mat-mdc-form-field-subscript-wrapper\"\n [class.mat-mdc-form-field-bottom-align]=\"subscriptSizing === 'fixed'\"\n [class.mat-mdc-form-field-subscript-dynamic-size]=\"subscriptSizing === 'dynamic'\"\n >\n @if (formControl.touched && formControl.invalid) {\n <!-- errors -->\n <div class=\"mat-mdc-form-field-error-wrapper\">\n @if (formControl.errors | mapKeys | arrayFirst; as errorKey) {\n <mat-error>\n {{ i18nErrorKeys | mapGet: errorKey | translate: (formControl.errors | mapGet: errorKey) }}\n </mat-error>\n } @else {\n <ng-container *ngTemplateOutlet=\"matErrorTemplate\"></ng-container>\n }\n </div>\n } @else {\n <!-- hints -->\n <mat-hint>\n <ng-container *ngTemplateOutlet=\"matHintTemplate\"></ng-container>\n </mat-hint>\n }\n </div>\n}\n\n<ng-template #matPrefixTemplate>\n <ng-content select=\"[matPrefix]\"></ng-content>\n</ng-template>\n\n<ng-template #matSuffixTemplate>\n @if (clearable && !readonly) {\n <button\n matSuffix\n mat-icon-button\n tabindex=\"-1\"\n type=\"button\"\n (click)=\"clearValue($event)\"\n [hidden]=\"formControl.value | isNil\"\n >\n <mat-icon>close</mat-icon>\n </button>\n }\n\n <ng-content select=\"[matSuffix]\"></ng-content>\n</ng-template>\n\n<ng-template #matErrorTemplate>\n <ng-content select=\"mat-error,[matError]\"></ng-content>\n</ng-template>\n\n<ng-template #matHintTemplate>\n <div class=\"mat-mdc-form-field-hint-wrapper\">\n <ng-content select=\"mat-hint:not([align='end']),[matHint]\"></ng-content>\n <div class=\"mat-mdc-form-field-hint-spacer\"></div>\n <ng-content select=\"mat-hint[align='end']\"></ng-content>\n </div>\n</ng-template>\n", styles: [":host{display:inline-block;width:100%;min-width:140px;position:relative;--ion-grid-column-padding: 0}mat-form-field{width:100%}mat-form-field .datetime-md{padding:0!important}.sign mat-form-field.mat-mdc-form-field-should-float .mat-mdc-form-field-placeholder{max-width:inherit}ion-row.no-wrap{flex-wrap:nowrap}ion-grid ion-col.degrees{--min-width: 130px;min-width:var(--min-width)}ion-grid ion-col.minutes{--min-width: 105px;min-width:var(--min-width);max-width:var(--min-width)}ion-grid ion-col.seconds{--min-width: 105px;min-width:var(--min-width);max-width:var(--min-width)}ion-grid ion-col.sign{--min-width: 58px;--max-width: 65px;min-width:var(--min-width);max-width:var(--max-width)}input[type=number]{text-align:right}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}span.symbol-unit{display:inline-block;text-align:center;font-weight:700;font-size:1.3em}\n"] }]
558
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.FormGroupDirective, decorators: [{
559
- type: Optional
560
- }] }, { type: undefined, decorators: [{
561
- type: Inject,
562
- args: [MAT_FORM_FIELD_DEFAULT_OPTIONS]
563
- }] }], propDecorators: { formControl: [{
564
- type: Input
565
- }], formControlName: [{
566
- type: Input
567
- }], type: [{
568
- type: Input
569
- }], pattern: [{
570
- type: Input,
571
- args: ['latLongPattern']
572
- }], required: [{
573
- type: Input
574
- }], floatLabel: [{
575
- type: Input
576
- }], placeholder: [{
577
- type: Input
578
- }], defaultSign: [{
579
- type: Input
580
- }], autofocus: [{
581
- type: Input
582
- }], mobile: [{
583
- type: Input,
584
- args: [{ transform: booleanAttribute }]
585
- }], degreesSymbolUnit: [{
586
- type: Input
587
- }], minutesSymbolUnit: [{
588
- type: Input
589
- }], secondsSymbolUnit: [{
590
- type: Input
591
- }], clearable: [{
592
- type: Input,
593
- args: [{ transform: booleanAttribute }]
594
- }], tabindex: [{
595
- type: Input,
596
- args: [{ transform: numberAttribute }]
597
- }], appearance: [{
598
- type: Input
599
- }], readonly: [{
600
- type: Input
601
- }], subscriptSizing: [{
602
- type: Input
603
- }], keyupEnter: [{
604
- type: Output,
605
- args: ['keyup.enter']
606
- }], blurred: [{
607
- type: Output,
608
- args: ['blur']
609
- }], focused: [{
610
- type: Output,
611
- args: ['focus']
612
- }], formField: [{
613
- type: ViewChild,
614
- args: ['formField']
615
- }], fakeInput: [{
616
- type: ViewChild,
617
- args: ['fakeInput']
618
- }], inputDegrees: [{
619
- type: ViewChild,
620
- args: ['inputDegrees']
621
- }], inputMinutes: [{
622
- type: ViewChild,
623
- args: ['inputMinutes']
624
- }], inputSeconds: [{
625
- type: ViewChild,
626
- args: ['inputSeconds']
627
- }], inputSign: [{
628
- type: ViewChild,
629
- args: ['inputSign']
630
- }] } });
631
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0ZXJpYWwubGF0bG9uZzIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3NoYXJlZC9tYXRlcmlhbC9sYXRsb25nL21hdGVyaWFsLmxhdGxvbmcyLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9zaGFyZWQvbWF0ZXJpYWwvbGF0bG9uZy9tYXRlcmlhbC5sYXRsb25nMi5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsdUJBQXVCLEVBRXZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBQ0wsZUFBZSxFQUdmLFFBQVEsRUFDUixNQUFNLEVBQ04sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFTCxXQUFXLEVBRVgsaUJBQWlCLEVBR2pCLFVBQVUsR0FDWCxNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFDTCw4QkFBOEIsR0FLL0IsTUFBTSw4QkFBOEIsQ0FBQztBQUN0QyxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEMsT0FBTyxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSx1Q0FBdUMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hILE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsNkJBQTZCLEVBRzdCLHFCQUFxQixFQUNyQix1QkFBdUIsRUFDdkIseUJBQXlCLEdBQzFCLE1BQU0saUJBQWlC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c0JBQWhDLFNBQVM7dUJBQUMsV0FBVztnQkFDRSxTQUFTO3NCQUFoQyxTQUFTO3VCQUFDLFdBQVc7Z0JBQ0ssWUFBWTtzQkFBdEMsU0FBUzt1QkFBQyxjQUFjO2dCQUNFLFlBQVk7c0JBQXRDLFNBQVM7dUJBQUMsY0FBYztnQkFDRSxZQUFZO3NCQUF0QyxTQUFTO3VCQUFDLGNBQWM7Z0JBQ0QsU0FBUztzQkFBaEMsU0FBUzt1QkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgYm9vbGVhbkF0dHJpYnV0ZSxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgbnVtYmVyQXR0cmlidXRlLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIENvbnRyb2xWYWx1ZUFjY2Vzc29yLFxuICBGb3JtQ29udHJvbCxcbiAgRm9ybUdyb3VwRGlyZWN0aXZlLFxuICBOR19WQUxVRV9BQ0NFU1NPUixcbiAgVW50eXBlZEZvcm1Db250cm9sLFxuICBWYWxpZGF0b3JGbixcbiAgVmFsaWRhdG9ycyxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgTUFUX0ZPUk1fRklFTERfREVGQVVMVF9PUFRJT05TLFxuICBNYXRGb3JtRmllbGQsXG4gIE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UsXG4gIE1hdEZvcm1GaWVsZERlZmF1bHRPcHRpb25zLFxuICBTdWJzY3JpcHRTaXppbmcsXG59IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgbWVyZ2UsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQXBwRmxvYXRMYWJlbFR5cGUgfSBmcm9tICcuLi8uLi9mb3JtL2ZpZWxkLm1vZGVsJztcbmltcG9ydCB7IGlzTmlsLCBpc05pbE9yQmxhbmssIGlzTm90TmlsIH0gZnJvbSAnLi4vLi4vZnVuY3Rpb25zJztcbmltcG9ydCB7IGlzTW9iaWxlIH0gZnJvbSAnLi4vLi4vcGxhdGZvcm1zJztcbmltcG9ydCB7IFNoYXJlZFZhbGlkYXRvcnMgfSBmcm9tICcuLi8uLi92YWxpZGF0b3IvdmFsaWRhdG9ycyc7XG5pbXBvcnQgeyBNQVRfRk9STV9GSUVMRF9ERUZBVUxUX0FQUEVBUkFOQ0UsIE1BVF9GT1JNX0ZJRUxEX0RFRkFVTFRfU1VCU0NSSVBUX1NJWklORyB9IGZyb20gJy4uL21hdGVyaWFsLmNvbmZpZyc7XG5pbXBvcnQge1xuICBjb21wdXRlRGVjaW1hbERlZ3JlZXMsXG4gIExBVF9MT05HX0RFRkFVTFRfTUFYX0RFQ0lNQUxTLFxuICBMYXRMb25nUGF0dGVybixcbiAgTGF0TG9uZ1R5cGUsXG4gIHNwbGl0TnVtYmVyVG9GaWVsZHNERCxcbiAgc3BsaXROdW1iZXJUb0ZpZWxkc0RETU0sXG4gIHNwbGl0TnVtYmVyVG9GaWVsZHNERE1NU1MsXG59IGZyb20gJy4vbGF0bG9uZy51dGlscyc7XG5cbmNvbnN0IG5vb3AgPSAoKSA9PiB7fTtcblxuZGVjbGFyZSB0eXBlIExhdExvbmdTaWduID0gMSB8IC0xO1xuaW50ZXJmYWNlIElMYXRMb25nRGF0YSB7XG4gIGRlZ3JlZXM6IG51bWJlcjtcbiAgbWludXRlczogbnVtYmVyO1xuICBzZWNvbmRzOiBudW1iZXI7XG4gIHNpZ246IExhdExvbmdTaWduO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdtYXQtbGF0bG9uZy1maWVsZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9tYXRlcmlhbC5sYXRsb25nMi5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbWF0ZXJpYWwubGF0bG9uZzIuc2NzcyddLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIG11bHRpOiB0cnVlLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTWF0TGF0TG9uZ0ZpZWxkMiksXG4gICAgfSxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIE1hdExhdExvbmdGaWVsZDIgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuICBwcml2YXRlIF9vbkNoYW5nZUNhbGxiYWNrOiAoXzogYW55KSA9PiB2b2lkID0gbm9vcDtcbiAgcHJpdmF0ZSBfb25Ub3VjaGVkQ2FsbGJhY2s6ICgpID0+IHZvaWQgPSBub29wO1xuICBwcml2YXRlIF9zdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgX2Rpc2FibGluZyA9IGZhbHNlO1xuICBwcml2YXRlIF93cml0aW5nID0gZmFsc2U7XG4gIHByaXZhdGUgX2FwcGVhcmFuY2U6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfc3Vic2NyaXB0U2l6aW5nOiBTdWJzY3JpcHRTaXppbmcgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfcmVhZG9ubHkgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfdGFiaW5kZXg6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGVmYXVsdEFwcGVhcmFuY2U6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlZmF1bHRTdWJzY3JpcHRTaXppbmc6IFN1YnNjcmlwdFNpemluZztcblxuICBwcm90ZWN0ZWQgX2ZvY3VzZWQgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIF90b3VjaGVkID0gZmFsc2U7XG4gIHByb3RlY3RlZCBkZWdyZWVzQ29udHJvbDogRm9ybUNvbnRyb2w8bnVtYmVyPjtcbiAgcHJvdGVjdGVkIG1pbnV0ZXNDb250cm9sOiBGb3JtQ29udHJvbDxudW1iZXI+O1xuICBwcm90ZWN0ZWQgc2Vjb25kc0NvbnRyb2w6IEZvcm1Db250cm9sPG51bWJlcj47XG4gIHByb3RlY3RlZCBzaWduQ29udHJvbDogRm9ybUNvbnRyb2w8TGF0TG9uZ1NpZ24+O1xuICBwcm90ZWN0ZWQgc2hvd01pbnV0ZXMgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHNob3dTZWNvbmRzID0gZmFsc2U7XG4gIHByb3RlY3RlZCBzaG93U2lnbkNvbnRyb2w6IGJvb2xlYW47XG4gIHByb3RlY3RlZCBkZWdyZWVzUGxhY2Vob2xkZXI6IHN0cmluZztcbiAgcHJvdGVjdGVkIG1pbnV0ZXNQbGFjZWhvbGRlcjogc3RyaW5nO1xuICBwcm90ZWN0ZWQgc2Vjb25kc1BsYWNlaG9sZGVyOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBtYXhEZWNpbWFscyA9IExBVF9MT05HX0RFRkFVTFRfTUFYX0RFQ0lNQUxTO1xuICBwcm90ZWN0ZWQgaTE4bkVycm9yS2V5cyA9IFNoYXJlZFZhbGlkYXRvcnMuSTE4Tl9FUlJPUl9LRVlTO1xuICBwcm90ZWN0ZWQgbWluTWF4VmFsdWVzOiB7XG4gICAgZGVncmVlcz86IHsgbWluOiBudW1iZXI7IG1heDogbnVtYmVyOyBzdGVwOiBudW1iZXIgfTtcbiAgICBtaW51dGVzPzogeyBtaW46IG51bWJlcjsgbWF4OiBudW1iZXI7IHN0ZXA6IG51bWJlciB9O1xuICAgIHNlY29uZHM/OiB7IG1pbjogbnVtYmVyOyBtYXg6IG51bWJlcjsgc3RlcDogbnVtYmVyIH07XG4gIH07XG4gIHByb3RlY3RlZCBpbnB1dFdpZHRoOiB7XG4gICAgZGVncmVlczogc3RyaW5nO1xuICAgIGRlZ3JlZXNVbml0OiBzdHJpbmc7XG4gICAgbWludXRlcz86IHN0cmluZztcbiAgICBtaW51dGVzVW5pdD86IHN0cmluZztcbiAgICBzZWNvbmRzPzogc3RyaW5nO1xuICAgIHNlY29uZHNVbml0Pzogc3RyaW5nO1xuICB9O1xuXG4gIEBJbnB1dCgpIGZvcm1Db250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2w7XG4gIEBJbnB1dCgpIGZvcm1Db250cm9sTmFtZTogc3RyaW5nO1xuICBASW5wdXQoKSB0eXBlOiBMYXRMb25nVHlwZTtcbiAgQElucHV0KCdsYXRMb25nUGF0dGVybicpIHBhdHRlcm46IExhdExvbmdQYXR0ZXJuO1xuICBASW5wdXQoKSByZXF1aXJlZCA9IGZhbHNlO1xuICBASW5wdXQoKSBmbG9hdExhYmVsOiBBcHBGbG9hdExhYmVsVHlwZSA9ICdhdXRvJztcbiAgQElucHV0KCkgcGxhY2Vob2xkZXI6IHN0cmluZztcbiAgQElucHV0KCkgZGVmYXVsdFNpZ246ICctJyB8ICcrJztcbiAgQElucHV0KCkgYXV0b2ZvY3VzID0gZmFsc2U7XG4gIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBtb2JpbGU6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGRlZ3JlZXNTeW1ib2xVbml0ID0gJ8KwJztcbiAgQElucHV0KCkgbWludXRlc1N5bWJvbFVuaXQgPSBcIidcIjtcbiAgQElucHV0KCkgc2Vjb25kc1N5bWJvbFVuaXQgPSAnXCInO1xuICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgY2xlYXJhYmxlID0gdHJ1ZTtcblxuICBASW5wdXQoeyB0cmFuc2Zvcm06IG51bWJlckF0dHJpYnV0ZSB9KSBzZXQgdGFiaW5kZXgodmFsdWU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLl90YWJpbmRleCAhPT0gdmFsdWUpIHtcbiAgICAgIHRoaXMuX3RhYmluZGV4ID0gdmFsdWU7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMudXBkYXRlVGFiSW5kZXgoKSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHRhYmluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuX3RhYmluZGV4O1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IGFwcGVhcmFuY2UodmFsdWU6IE1hdEZvcm1GaWVsZEFwcGVhcmFuY2UpIHtcbiAgICB0aGlzLl9hcHBlYXJhbmNlID0gdmFsdWU7XG4gIH1cbiAgZ2V0IGFwcGVhcmFuY2UoKTogTWF0Rm9ybUZpZWxkQXBwZWFyYW5jZSB7XG4gICAgcmV0dXJuIHRoaXMuX2FwcGVhcmFuY2UgfHwgdGhpcy5fZGVmYXVsdEFwcGVhcmFuY2U7XG4gIH1cblxuICBASW5wdXQoKSBzZXQgcmVhZG9ubHkodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9yZWFkb25seSA9IHZhbHVlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBnZXQgcmVhZG9ubHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRvbmx5O1xuICB9XG5cbiAgQElucHV0KClcbiAgc2V0IHN1YnNjcmlwdFNpemluZyh2YWx1ZTogU3Vic2NyaXB0U2l6aW5nKSB7XG4gICAgdGhpcy5fc3Vic2NyaXB0U2l6aW5nID0gdmFsdWU7XG4gIH1cbiAgZ2V0IHN1YnNjcmlwdFNpemluZygpOiBTdWJzY3JpcHRTaXppbmcge1xuICAgIHJldHVybiB0aGlzLl9zdWJzY3JpcHRTaXppbmcgfHwgdGhpcy5fZGVmYXVsdFN1YnNjcmlwdFNpemluZztcbiAgfVxuXG4gIGdldCBzaG93RmllbGRzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc05vdE5pbCh0aGlzLmZvcm1Db250cm9sLnZhbHVlKSB8fCB0aGlzLl9mb2N1c2VkO1xuICB9XG5cbiAgZ2V0IGRpc2FibGVkKCk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMucmVhZG9ubHkgfHwgdGhpcy5mb3JtQ29udHJvbC5kaXNhYmxlZDtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvbm8tb3V0cHV0LW9uLXByZWZpeCxAYW5ndWxhci1lc2xpbnQvbm8tb3V0cHV0LXJlbmFtZVxuICBAT3V0cHV0KCdrZXl1cC5lbnRlcicpIGtleXVwRW50ZXIgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9uby1vdXRwdXQtcmVuYW1lXG4gIEBPdXRwdXQoJ2JsdXInKSBibHVycmVkID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L25vLW91dHB1dC1yZW5hbWVcbiAgQE91dHB1dCgnZm9jdXMnKSBmb2N1c2VkID0gbmV3IEV2ZW50RW1pdHRlcjxGb2N1c0V2ZW50PigpO1xuXG4gIEBWaWV3Q2hpbGQoJ2Zvcm1GaWVsZCcpIGZvcm1GaWVsZDogTWF0Rm9ybUZpZWxkO1xuICBAVmlld0NoaWxkKCdmYWtlSW5wdXQnKSBmYWtlSW5wdXQ6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2lucHV0RGVncmVlcycpIGlucHV0RGVncmVlczogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnaW5wdXRNaW51dGVzJykgaW5wdXRNaW51dGVzOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdpbnB1dFNlY29uZHMnKSBpbnB1dFNlY29uZHM6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2lucHV0U2lnbicpIGlucHV0U2lnbjogRWxlbWVudFJlZjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIGZvcm1Hcm91cERpcjogRm9ybUdyb3VwRGlyZWN0aXZlLFxuICAgIEBJbmplY3QoTUFUX0ZPUk1fRklFTERfREVGQVVMVF9PUFRJT05TKSBkZWZhdWx0T3B0aW9ucz86IE1hdEZvcm1GaWVsZERlZmF1bHRPcHRpb25zXG4gICkge1xuICAgIHRoaXMuX2RlZmF1bHRTdWJzY3JpcHRTaXppbmcgPSBkZWZhdWx0T3B0aW9ucz8uc3Vic2NyaXB0U2l6aW5nIHx8IE1BVF9GT1JNX0ZJRUxEX0RFRkFVTFRfU1VCU0NSSVBUX1NJWklORztcbiAgICB0aGlzLl9kZWZhdWx0QXBwZWFyYW5jZSA9IGRlZmF1bHRPcHRpb25zPy5hcHBlYXJhbmNlIHx8IE1BVF9GT1JNX0ZJRUxEX0RFRkFVTFRfQVBQRUFSQU5DRTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMubW9iaWxlID0gdGhpcy5tb2JpbGUgPz8gaXNNb2JpbGUod2luZG93KTtcbiAgICB0aGlzLnR5cGUgPSB0aGlzLnR5cGUgfHwgJ2xhdGl0dWRlJztcbiAgICB0aGlzLnBhdHRlcm4gPSB0aGlzLnBhdHRlcm4gfHwgJ0RETU0nO1xuICAgIHRoaXMuc2hvd1NpZ25Db250cm9sID0gdGhpcy5wYXR0ZXJuICE9PSAnREQnO1xuXG4gICAgY29uc3QgZGVncmVlc1ZhbGlkYXRvcnM6IFZhbGlkYXRvckZuW10gPSBbdGhpcy50eXBlID09PSAnbGF0aXR1ZGUnID8gU2hhcmVkVmFsaWRhdG9ycy5sYXRpdHVkZSA6IFNoYXJlZFZhbGlkYXRvcnMubG9uZ2l0dWRlXTtcbiAgICBjb25zdCBtaW51dGVzVmFsaWRhdG9yczogVmFsaWRhdG9yRm5bXSA9IFtdO1xuICAgIGNvbnN0IHNlY29uZHNWYWxpZGF0b3JzOiBWYWxpZGF0b3JGbltdID0gW107XG5cbiAgICB0aGlzLm1pbk1heFZhbHVlcyA9IHt9O1xuXG4gICAgc3dpdGNoICh0aGlzLnBhdHRlcm4pIHtcbiAgICAgIGNhc2UgJ0REJzpcbiAgICAgICAgdGhpcy5tYXhEZWNpbWFscyA9IDc7XG4gICAgICAgIGRlZ3JlZXNWYWxpZGF0b3JzLnB1c2goU2hhcmVkVmFsaWRhdG9ycy5kZWNpbWFsKHsgbWF4RGVjaW1hbHM6IHRoaXMubWF4RGVjaW1hbHMgfSkpO1xuICAgICAgICB0aGlzLmRlZ3JlZXNQbGFjZWhvbGRlciA9IHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJyA/ICdDT01NT04uTEFUX0xPTkcuRERfUExBQ0VIT0xERVInIDogJ0NPTU1PTi5MQVRfTE9ORy5ERERfUExBQ0VIT0xERVInO1xuICAgICAgICB0aGlzLmlucHV0V2lkdGggPSB7XG4gICAgICAgICAgZGVncmVlczogJzk1JScsXG4gICAgICAgICAgZGVncmVlc1VuaXQ6ICc1JScsXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnRERNTSc6XG4gICAgICAgIHRoaXMubWF4RGVjaW1hbHMgPSAzO1xuICAgICAgICB0aGlzLnNob3dNaW51dGVzID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5taW5NYXhWYWx1ZXNbJ21pbnV0ZXMnXSA9IHtcbiAgICAgICAgICBtaW46IDAsXG4gICAgICAgICAgbWF4OiA2MCAtIHRoaXMuY29tcHV0ZURlY2ltYWxQYXJ0KDEsIHRoaXMubWF4RGVjaW1hbHMpLFxuICAgICAgICAgIHN0ZXA6IHRoaXMuY29tcHV0ZURlY2ltYWxQYXJ0KDEsIHRoaXMubWF4RGVjaW1hbHMpLFxuICAgICAgICB9O1xuICAgICAgICBkZWdyZWVzVmFsaWRhdG9ycy5wdXNoKFNoYXJlZFZhbGlkYXRvcnMuaW50ZWdlcik7XG4gICAgICAgIG1pbnV0ZXNWYWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5taW4odGhpcy5taW5NYXhWYWx1ZXMubWludXRlcy5taW4pKTtcbiAgICAgICAgbWludXRlc1ZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLm1heCh0aGlzLm1pbk1heFZhbHVlcy5taW51dGVzLm1heCkpO1xuICAgICAgICBtaW51dGVzVmFsaWRhdG9ycy5wdXNoKFNoYXJlZFZhbGlkYXRvcnMuZGVjaW1hbCh7IG1heERlY2ltYWxzOiB0aGlzLm1heERlY2ltYWxzIH0pKTtcbiAgICAgICAgdGhpcy5kZWdyZWVzUGxhY2Vob2xkZXIgPSB0aGlzLnR5cGUgPT09ICdsYXRpdHVkZScgPyAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLkREJyA6ICdDT01NT04uTEFUX0xPTkcuU0lOR0xFX0ZJRUxEX1BBVFRFUk4uREREJztcbiAgICAgICAgdGhpcy5taW51dGVzUGxhY2Vob2xkZXIgPSAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLk1NX01NTSc7XG4gICAgICAgIHRoaXMuaW5wdXRXaWR0aCA9IHtcbiAgICAgICAgICBkZWdyZWVzOiAnMzUlJyxcbiAgICAgICAgICBkZWdyZWVzVW5pdDogJzUlJyxcbiAgICAgICAgICBtaW51dGVzOiAnNTUlJyxcbiAgICAgICAgICBtaW51dGVzVW5pdDogJzUlJyxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OiAvLyBEZWZhdWx0IGlzIERETU1TU1xuICAgICAgICB0aGlzLm1heERlY2ltYWxzID0gMjtcbiAgICAgICAgdGhpcy5zaG93TWludXRlcyA9IHRydWU7XG4gICAgICAgIHRoaXMuc2hvd1NlY29uZHMgPSB0cnVlO1xuICAgICAgICB0aGlzLm1pbk1heFZhbHVlc1snbWludXRlcyddID0ge1xuICAgICAgICAgIG1pbjogMCxcbiAgICAgICAgICBtYXg6IDU5LFxuICAgICAgICAgIHN0ZXA6IDEsXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMubWluTWF4VmFsdWVzWydzZWNvbmRzJ10gPSB7XG4gICAgICAgICAgbWluOiAwLFxuICAgICAgICAgIG1heDogNjAgLSB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydCgxLCB0aGlzLm1heERlY2ltYWxzKSxcbiAgICAgICAgICBzdGVwOiB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydCgxLCB0aGlzLm1heERlY2ltYWxzKSxcbiAgICAgICAgfTtcbiAgICAgICAgZGVncmVlc1ZhbGlkYXRvcnMucHVzaChTaGFyZWRWYWxpZGF0b3JzLmludGVnZXIpO1xuICAgICAgICBtaW51dGVzVmFsaWRhdG9ycy5wdXNoKFNoYXJlZFZhbGlkYXRvcnMuaW50ZWdlcik7XG4gICAgICAgIG1pbnV0ZXNWYWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5taW4odGhpcy5taW5NYXhWYWx1ZXMubWludXRlcy5taW4pKTtcbiAgICAgICAgbWludXRlc1ZhbGlkYXRvcnMucHVzaChWYWxpZGF0b3JzLm1heCh0aGlzLm1pbk1heFZhbHVlcy5taW51dGVzLm1heCkpO1xuICAgICAgICBzZWNvbmRzVmFsaWRhdG9ycy5wdXNoKFZhbGlkYXRvcnMubWluKHRoaXMubWluTWF4VmFsdWVzLnNlY29uZHMubWluKSk7XG4gICAgICAgIHNlY29uZHNWYWxpZGF0b3JzLnB1c2goVmFsaWRhdG9ycy5tYXgodGhpcy5taW5NYXhWYWx1ZXMuc2Vjb25kcy5tYXgpKTtcbiAgICAgICAgc2Vjb25kc1ZhbGlkYXRvcnMucHVzaChTaGFyZWRWYWxpZGF0b3JzLmRlY2ltYWwoeyBtYXhEZWNpbWFsczogdGhpcy5tYXhEZWNpbWFscyB9KSk7XG4gICAgICAgIHRoaXMuZGVncmVlc1BsYWNlaG9sZGVyID0gdGhpcy50eXBlID09PSAnbGF0aXR1ZGUnID8gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5ERCcgOiAnQ09NTU9OLkxBVF9MT05HLlNJTkdMRV9GSUVMRF9QQVRURVJOLkRERCc7XG4gICAgICAgIHRoaXMubWludXRlc1BsYWNlaG9sZGVyID0gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5NTSc7XG4gICAgICAgIHRoaXMuc2Vjb25kc1BsYWNlaG9sZGVyID0gJ0NPTU1PTi5MQVRfTE9ORy5TSU5HTEVfRklFTERfUEFUVEVSTi5TU19TUyc7XG4gICAgICAgIHRoaXMuaW5wdXRXaWR0aCA9IHtcbiAgICAgICAgICBkZWdyZWVzOiAnMjUlJyxcbiAgICAgICAgICBkZWdyZWVzVW5pdDogJzUlJyxcbiAgICAgICAgICBtaW51dGVzOiAnMjUlJyxcbiAgICAgICAgICBtaW51dGVzVW5pdDogJzUlJyxcbiAgICAgICAgICBzZWNvbmRzOiAnMzUlJyxcbiAgICAgICAgICBzZWNvbmRzVW5pdDogJzUlJyxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgLy8gTXVzdCBiZSBkb25lIGFmdGVyIHNldCB0aGlzLm1heERlY2ltYWxzIGluIHN3aXRjaCBibG9jayBhYm92ZVxuICAgIHRoaXMubWluTWF4VmFsdWVzWydkZWdyZWVzJ10gPSB7XG4gICAgICBtaW46IHRoaXMucGF0dGVybiA9PT0gJ0REJyA/ICh0aGlzLnR5cGUgPT09ICdsYXRpdHVkZScgPyAtOTAgOiAtMTgwKSA6IDAsXG4gICAgICBtYXg6IHRoaXMudHlwZSA9PT0gJ2xhdGl0dWRlJyA/IDkwIDogMTgwLFxuICAgICAgc3RlcDogdGhpcy5wYXR0ZXJuID09PSAnREQnID8gdGhpcy5jb21wdXRlRGVjaW1hbFBhcnQoMSwgdGhpcy5tYXhEZWNpbWFscykgOiAxLFxuICAgIH07XG5cbiAgICB0aGlzLmZvcm1Db250cm9sID1cbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wgfHwgKHRoaXMuZm9ybUNvbnRyb2xOYW1lICYmIHRoaXMuZm9ybUdyb3VwRGlyICYmICh0aGlzLmZvcm1Hcm91cERpci5mb3JtLmdldCh0aGlzLmZvcm1Db250cm9sTmFtZSkgYXMgVW50eXBlZEZvcm1Db250cm9sKSk7XG4gICAgaWYgKCF0aGlzLmZvcm1Db250cm9sKSB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIG1hbmRhdG9yeSBhdHRyaWJ1dGUgJ2Zvcm1Db250cm9sJyBvciAnZm9ybUNvbnRyb2xOYW1lJyBpbiA8bWF0LWxhdGxvbmctZmllbGQ+LlwiKTtcblxuICAgIHRoaXMuZGVncmVlc0NvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2w8bnVtYmVyPihudWxsLCBkZWdyZWVzVmFsaWRhdG9ycyk7XG4gICAgdGhpcy5taW51dGVzQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbDxudW1iZXI+KG51bGwsIG1pbnV0ZXNWYWxpZGF0b3JzKTtcbiAgICB0aGlzLnNlY29uZHNDb250cm9sID0gbmV3IEZvcm1Db250cm9sPG51bWJlcj4obnVsbCwgc2Vjb25kc1ZhbGlkYXRvcnMpO1xuICAgIHRoaXMuc2lnbkNvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2w8TGF0TG9uZ1NpZ24+KG51bGwpO1xuXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIG1lcmdlKFxuICAgICAgICB0aGlzLmRlZ3JlZXNDb250cm9sLnZhbHVlQ2hhbmdlcyxcbiAgICAgICAgdGhpcy5taW51dGVzQ29udHJvbC52YWx1ZUNoYW5nZXMsXG4gICAgICAgIHRoaXMuc2Vjb25kc0NvbnRyb2wudmFsdWVDaGFuZ2VzLFxuICAgICAgICB0aGlzLnNpZ25Db250cm9sLnZhbHVlQ2hhbmdlc1xuICAgICAgKS5zdWJzY3JpYmUoKF8pID0+IHRoaXMub25Gb3JtQ2hhbmdlKCkpXG4gICAgKTtcblxuICAgIC8vIExpc3RlbiBzdGF0dXMgY2hhbmdlcyAod2hlbiBkb25lIG91dHNpZGUgdGhlIGNvbXBvbmVudCAgLSBlLmcuIHdoZW4gc2V0RXJyb3JzKCkgaXMgY2FsbGluZyBvbiB0aGUgZm9ybUNvbnRyb2wpXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wuc3RhdHVzQ2hhbmdlc1xuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaWx0ZXIoKCkgPT4gIXRoaXMucmVhZG9ubHkgJiYgIXRoaXMuX3dyaXRpbmcgJiYgIXRoaXMuX2Rpc2FibGluZykgLy8gU2tpcFxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5tYXJrRm9yQ2hlY2soKSlcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLl9vbkNoYW5nZUNhbGxiYWNrID0gZm47XG4gIH1cblxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5fb25Ub3VjaGVkQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IG51bWJlciB8IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLl93cml0aW5nKSByZXR1cm47XG4gICAgdGhpcy5fd3JpdGluZyA9IHRydWU7XG5cbiAgICBpZiAodmFsdWUgIT09IHRoaXMuZm9ybUNvbnRyb2wudmFsdWUpIHtcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wucGF0Y2hWYWx1ZSh2YWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgdGhpcy5fb25DaGFuZ2VDYWxsYmFjayh2YWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jb21wdXRlTGF0TG9uZ0Zvcm1Hcm91cFZhbHVlKHZhbHVlKTtcbiAgICBjb25zb2xlLmRlYnVnKCdbbWF0LWxhdGxvbmctZmllbGRdIENoYW5naW5nIHZhbHVlIG9mIGlucHV0czonLCB2YWx1ZSwgcmVzdWx0KTtcbiAgICB0aGlzLnBhdGNoVmFsdWUocmVzdWx0LCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XG5cbiAgICB0aGlzLl93cml0aW5nID0gZmFsc2U7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVGYWtlSW5wdXQoKTtcbiAgICAgIHRoaXMudXBkYXRlVGFiSW5kZXgoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLl9kaXNhYmxpbmcpIHJldHVybjtcblxuICAgIHRoaXMuX2Rpc2FibGluZyA9IHRydWU7XG4gICAgaWYgKGlzRGlzYWJsZWQpIHtcbiAgICAgIHRoaXMuZGVncmVlc0NvbnRyb2wuZGlzYWJsZSgpO1xuICAgICAgdGhpcy5taW51dGVzQ29udHJvbC5kaXNhYmxlKCk7XG4gICAgICB0aGlzLnNlY29uZHNDb250cm9sLmRpc2FibGUoKTtcbiAgICAgIHRoaXMuc2lnbkNvbnRyb2wuZGlzYWJsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlZ3JlZXNDb250cm9sLmVuYWJsZSgpO1xuICAgICAgdGhpcy5taW51dGVzQ29udHJvbC5lbmFibGUoKTtcbiAgICAgIHRoaXMuc2Vjb25kc0NvbnRyb2wuZW5hYmxlKCk7XG4gICAgICB0aGlzLnNpZ25Db250cm9sLmVuYWJsZSgpO1xuICAgIH1cbiAgICB0aGlzLl9kaXNhYmxpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgY2xlYXJWYWx1ZShldmVudD86IEV2ZW50KSB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMud3JpdGVWYWx1ZShudWxsKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgaW5wdXRzRWxlbWVudHMoKTogSFRNTEVsZW1lbnRbXSB7XG4gICAgcmV0dXJuICh0aGlzLmlucHV0RGVncmVlcyA/IFt0aGlzLmlucHV0RGVncmVlcy5uYXRpdmVFbGVtZW50XSA6IFtdKVxuICAgICAgLmNvbmNhdCh0aGlzLmlucHV0TWludXRlcyA/IFt0aGlzLmlucHV0TWludXRlcy5uYXRpdmVFbGVtZW50XSA6IFtdKVxuICAgICAgLmNvbmNhdCh0aGlzLmlucHV0U2Vjb25kcyA/IFt0aGlzLmlucHV0U2Vjb25kcy5uYXRpdmVFbGVtZW50XSA6IFtdKVxuICAgICAgLmNvbmNhdCh0aGlzLmlucHV0U2lnbiA/IFt0aGlzLmlucHV0U2lnbi5uYXRpdmVFbGVtZW50XSA6IFtdKVxuICAgICAgLmNvbmNhdCh0aGlzLmZha2VJbnB1dCA/IFt0aGlzLmZha2VJbnB1dC5uYXRpdmVFbGVtZW50XSA6IFtdKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkZvY3VzRmFrZUlucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgaWYgKCF0aGlzLnNob3dGaWVsZHMpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIC8vIEhpZGUgdGhlIGZha2UgaW5wdXRcbiAgICAgIHRoaXMuZmFrZUlucHV0Py5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Nkay12aXN1YWxseS1oaWRkZW4nKTtcbiAgICB9XG5cbiAgICB0aGlzLl90b3VjaGVkID0gdGhpcy5mb3JtQ29udHJvbC50b3VjaGVkO1xuXG4gICAgLy8gRm9jdXMgb24gZmlyc3QgaW5wdXRcbiAgICB0aGlzLmZvY3VzKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25CbHVyRmFrZUlucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgY29uc3QgaW50ZXJuYWxFdmVudCA9IHRoaXMuaW5wdXRzRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC5yZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoaW50ZXJuYWxFdmVudCAmJiAhdGhpcy5fdG91Y2hlZCkge1xuICAgICAgLy8gV29ya2Fyb3VuZCB0byByZW1vdmUgdG91Y2hlZCBvbiB0aGUgZmFrZUlucHV0XG4gICAgICB0aGlzLmZvcm1Db250cm9sLm1hcmtBc1VudG91Y2hlZCgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfb25Gb2N1c0lucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgY29uc3QgaW50ZXJuYWxFdmVudCA9IHRoaXMuaW5wdXRzRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC5yZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoIWludGVybmFsRXZlbnQpIHtcbiAgICAgIHRoaXMuZm9jdXMoZmFsc2UgLypmb2N1c09uRGVncmVlcyovKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQmx1cklucHV0KGV2ZW50OiBGb2N1c0V2ZW50KSB7XG4gICAgY29uc3QgaW50ZXJuYWxFdmVudCA9IHRoaXMuaW5wdXRzRWxlbWVudHMuc29tZSgoZWwpID0+IGVsID09PSBldmVudC5yZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoIWludGVybmFsRXZlbnQpIHtcbiAgICAgIHRoaXMuX2ZvY3VzZWQgPSBmYWxzZTtcbiAgICAgIGlmICh0aGlzLmFwcGVhcmFuY2UgPT0gJ2ZpbGwnKSB7XG4gICAgICAgIHRoaXMuZm9ybUZpZWxkLl9saW5lUmlwcGxlLmRlYWN0aXZhdGUoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5ibHVycmVkLmVtaXQoZXZlbnQpO1xuXG4gICAgICB0aGlzLnVwZGF0ZUZha2VJbnB1dCgpO1xuICAgICAgdGhpcy51cGRhdGVUYWJJbmRleCgpO1xuXG4gICAgICB0aGlzLl90b3VjaGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xuICAgICAgdGhpcy5fY2hlY2tJZlRvdWNoZWQoKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgX29uQ2xpY2tJbnB1dChldmVudDogRXZlbnQpIHtcbiAgICAvLyBBdm9pZCBtYXQtZm9ybS1maWVsZCB0byBnaXZlIGZvY3VzIHRvIGZha2UgaW5wdXRcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIGZvY3VzKGZvY3VzT25EZWdyZWVzPzogYm9vbGVhbikge1xuICAgIGlmICh0aGlzLl9mb2N1c2VkKSByZXR1cm4gdHJ1ZTsgLy8gQWxyZWFkeSBmb2N1c2VkXG4gICAgY29uc3Qgc2hvd0ZpZWxkcyA9IHRoaXMuc2hvd0ZpZWxkcztcbiAgICB0aGlzLl9mb2N1c2VkID0gdHJ1ZTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAoIXNob3dGaWVsZHMgJiYgZm9jdXNPbkRlZ3JlZXMgIT09IGZhbHNlKSB0aGlzLmlucHV0RGVncmVlcy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG5cbiAgICAgIGlmICh0aGlzLmFwcGVhcmFuY2UgPT0gJ2ZpbGwnKSB7XG4gICAgICAgIHRoaXMuZm9ybUZpZWxkLl9saW5lUmlwcGxlLmFjdGl2YXRlKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEFkZCBhIGJsdXIgbGlzdGVuZXIgb24gZWFjaCBpbnB1dHNcbiAgICAgIC8qY29uc3QgaW5wdXRFbGVtZW50czogSFRNTEVsZW1lbnRbXSA9IHRoaXMuaW5wdXRzRWxlbWVudHM7XG4gICAgICBpbnB1dEVsZW1lbnRzLmZpbHRlcihpc05vdE5pbCkuZm9yRWFjaChcbiAgICAgICAgKGVsKSA9PlxuICAgICAgICAgIChlbC5vbmJsdXIgPSAoZSkgPT4ge1xuICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdvbmJsdXIgdG8gZWxlbWVudD0nLCBlLnJlbGF0ZWRUYXJnZXQpO1xuXG4gICAgICAgICAgICAvLyBTZXR1cCBhIG9uZS10aW1lIGZvY3VzIGV2ZW50IGhhbmRsZXJcbiAgICAgICAgICAgIGNvbnN0IGZvY3VzTGlzdGVuZXIgPSAoZm9jdXNFdmVudDogRm9jdXNFdmVudCkgPT4ge1xuICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyIGFmdGVyIGl0IGhhcyBiZWVuIGV4ZWN1dGVkIG9uY2VcbiAgICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzJywgZm9jdXNMaXN0ZW5lcik7XG5cbiAgICAgICAgICAgICAgLy9jb25zb2xlLmRlYnVnKCdORXh0IGZvY3VzIGVsZW1lbnQ9JywgZm9jdXNFdmVudC50YXJnZXQpO1xuICAgICAgICAgICAgICBjb25zdCBpbnRlcm5hbEV2ZW50ID0gaW5wdXRFbGVtZW50cy5pbmNsdWRlcyhmb2N1c0V2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudCk7XG5cbiAgICAgICAgICAgICAgaWYgKCFpbnRlcm5hbEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZm9jdXNlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRmFrZUlucHV0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVUYWJJbmRleCgpO1xuICAgICAgICAgICAgICAgIC8vdGhpcy5fb25Ub3VjaGVkQ2FsbGJhY2soKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuZm9ybUZpZWxkLl9saW5lUmlwcGxlLmRlYWN0aXZhdGUoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmJsdXJyZWQuZW1pdChmb2N1c0V2ZW50KTtcblxuICAgICAgICAgICAgICAgIC8vIHRoaXMuX3RvdWNoZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIC8vIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzVW50b3VjaGVkKCk7XG4gICAgICAgICAgICAgICAgLy8gdGhpcy5fY2hlY2tJZlRvdWNoZWQoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdmb2N1cycsIGZvY3VzTGlzdGVuZXIsIHRydWUpO1xuICAgICAgICAgIH0pXG4gICAgICApOyovXG5cbiAgICAgIHRoaXMudXBkYXRlRmFrZUlucHV0KCk7XG4gICAgICB0aGlzLnVwZGF0ZVRhYkluZGV4KCk7XG4gICAgfSwgMjUwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBmb3JtYXQocmF3VmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgdmFsdWVzID0gdGhpcy5jb21wdXRlTGF0TG9uZ0Zvcm1Hcm91cFZhbHVlKHJhd1ZhbHVlKTtcbiAgICBpZiAodmFsdWVzLmRlZ3JlZXMgPT09IG51bGwpIHJldHVybiAnJztcbiAgICBsZXQgcmVzdWx0ID0gYCR7dmFsdWVzLmRlZ3JlZXN9wrAgYDtcbiAgICBpZiAodmFsdWVzLm1pbnV0ZXMgIT09IG51bGwpIHJlc3VsdCArPSBgJHt2YWx1ZXMubWludXRlc30nIGA7XG4gICAgaWYgKHZhbHVlcy5zZWNvbmRzICE9PSBudWxsKSByZXN1bHQgKz0gYCR7dmFsdWVzLnNlY29uZHN9XCIgYDtcbiAgICBpZiAodGhpcy50eXBlID09PSAnbGF0aXR1ZGUnKSB7XG4gICAgICByZXN1bHQgKz0gdmFsdWVzLnNpZ24gPT09IDEgPyAnTicgOiAnUyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCArPSB2YWx1ZXMuc2lnbiA9PT0gMSA/ICdFJyA6ICdXJztcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb21wdXRlRGVjaW1hbFBhcnQodmFsdWU6IG51bWJlciwgbmJPZkRlY2ltYWxzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIHJldHVybiB2YWx1ZSAqIDEwICoqIChuYk9mRGVjaW1hbHMgKiAtMSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29tcHV0ZUxhdExvbmdGb3JtR3JvdXBWYWx1ZShyYXdWYWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogSUxhdExvbmdEYXRhIHtcbiAgICBjb25zdCBpc0xvbmdpdHVkZSA9IHRoaXMudHlwZSA9PT0gJ2xvbmdpdHVkZSc7XG5cbiAgICBjb25zdCB2YWx1ZSA9IHR5cGVvZiByYXdWYWx1ZSA9PT0gJ3N0cmluZycgPyBwYXJzZUZsb2F0KHJhd1ZhbHVlLnJlcGxhY2UoLywvZywgJy4nKSkgOiByYXdWYWx1ZTtcbiAgICBjb25zdCByZXN1bHQ6IElMYXRMb25nRGF0YSA9IHtcbiAgICAgIGRlZ3JlZXM6IG51bGwsXG4gICAgICBtaW51dGVzOiBudWxsLFxuICAgICAgc2Vjb25kczogbnVsbCxcbiAgICAgIHNpZ246IGlzTm90TmlsKHZhbHVlKVxuICAgICAgICA/IHZhbHVlIDwgMFxuICAgICAgICAgID8gLTFcbiAgICAgICAgICA6IDFcbiAgICAgICAgOiAvLyBVc2UgZGVmYXVsdCBzaWduLCBpZiBhbnlcbiAgICAgICAgICB0aGlzLmRlZmF1bHRTaWduICYmIHRoaXMuZGVmYXVsdFNpZ24gPT09ICctJ1xuICAgICAgICAgID8gLTFcbiAgICAgICAgICA6IDEsXG4gICAgfTtcblxuICAgIGlmICh2YWx1ZSA9PT0gMCkge1xuICAgICAgcmVzdWx0LmRlZ3JlZXMgPSAwO1xuICAgIH0gZWxzZSBpZiAoaXNOb3ROaWwodmFsdWUpKSB7XG4gICAgICBpZiAodGhpcy5wYXR0ZXJuID09PSAnREQnKSB7XG4gICAgICAgIGNvbnN0IHNwbGl0VmFsdWUgPSBzcGxpdE51bWJlclRvRmllbGRzREQodmFsdWUsIHtcbiAgICAgICAgICBsb25naXR1ZGU6IGlzTG9uZ2l0dWRlLFxuICAgICAgICAgIHBhdHRlcm46IHRoaXMucGF0dGVybixcbiAgICAgICAgICBtYXhEZWNpbWFsczogdGhpcy5tYXhEZWNpbWFscyxcbiAgICAgICAgICBmaXhMYXRMb25nOiB0cnVlLFxuICAgICAgICB9KS5zbGljZSgxKSBhcyBudW1iZXJbXTsgLy8gcmVtb3ZlIHNpZ247XG4gICAgICAgIHJlc3VsdC5kZWdyZWVzID0gKHNwbGl0VmFsdWVbMF0gKyB0aGlzLmNvbXB1dGVEZWNpbWFsUGFydChzcGxpdFZhbHVlWzFdID8/IDAsIHRoaXMubWF4RGVjaW1hbHMpKSAqIChyZXN1bHQuc2lnbiB8fCAxKSB8fCBudWxsO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnBhdHRlcm4gPT09ICdERE1NJykge1xuICAgICAgICBjb25zdCBzcGxpdFZhbHVlID0gc3BsaXROdW1iZXJUb0ZpZWxkc0RETU0odmFsdWUsIHtcbiAgICAgICAgICBsb25naXR1ZGU6IGlzTG9uZ2l0dWRlLFxuICAgICAgICAgIHBhdHRlcm46IHRoaXMucGF0dGVybixcbiAgICAgICAgICBtYXhEZWNpbWFsczogdGhpcy5tYXhEZWNpbWFscyxcbiAgICAgICAgICBmaXhMYXRMb25nOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0WydtaW51dGVzJ10gPSBNYXRoLmFicygoc3BsaXRWYWx1ZVsxXSA/PyAwKSArIHRoaXMuY29tcHV0ZURlY2ltYWxQYXJ0KHNwbGl0VmFsdWVbMl0gPz8gMCwgdGhpcy5tYXhEZWNpbWFscykpIHx8IG51bGw7XG4gICAgICAgIHJlc3VsdFsnZGVncmVlcyddID0gTWF0aC5hYnMoIXJlc3VsdFsnbWludXRlcyddICYmIGlzTmlsT3JCbGFuayhzcGxpdFZhbHVlWzBdKSA/IG51bGwgOiAoc3BsaXRWYWx1ZVswXSA/PyAwKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBEZWZhdWx0IC8vIERETU1TU1xuICAgICAgICBjb25zdCBzcGxpdFZhbHVlID0gc3BsaXROdW1iZXJUb0ZpZWxkc0RETU1TUyh2YWx1ZSwge1xuICAgICAgICAgIGxvbmdpdHVkZTogaXNMb25naXR1ZGUsXG4gICAgICAgICAgcGF0dGVybjogdGhpcy5wYXR0ZXJuLFxuICAgICAgICAgIG1heERlY2ltYWxzOiB0aGlzLm1heERlY2ltYWxzLFxuICAgICAgICAgIGZpeExhdExvbmc6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXN1bHRbJ3NlY29uZHMnXSA9IE1hdGguYWJzKChzcGxpdFZhbHVlWzJdID8/IDApICsgdGhpcy5jb21wdXRlRGVjaW1hbFBhcnQoc3BsaXRWYWx1ZVszXSA/PyAwLCB0aGlzLm1heERlY2ltYWxzKSkgfHwgbnVsbDtcbiAgICAgICAgcmVzdWx0WydtaW51dGVzJ10gPSAhcmVzdWx0WydzZWNvbmRzJ10gJiYgIXNwbGl0VmFsdWVbMV0gPyBudWxsIDogTWF0aC5hYnMoc3BsaXRWYWx1ZVsxXSA/PyAwKTtcbiAgICAgICAgcmVzdWx0WydkZWdyZWVzJ10gPSAhcmVzdWx0WydzZWNvbmRzJ10gJiYgIXJlc3VsdFsnbWludXRlcyddICYmIGlzTmlsT3JCbGFuayhzcGxpdFZhbHVlWzBdKSA/IG51bGwgOiBNYXRoLmFicyhzcGxpdFZhbHVlWzBdID8/IDApO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0FzVG91Y2hlZCgpIHtcbiAgICB0aGlzLmZvcm1Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLmRlZ3JlZXNDb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLm1pbnV0ZXNDb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLnNlY29uZHNDb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLnNpZ25Db250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLl9vblRvdWNoZWRDYWxsYmFjaygpO1xuICB9XG5cbiAgLyogLS0gcHJpdmF0ZSBtZXRob2QgLS0gKi9cblxuICBwcml2YXRlIHBhdGNoVmFsdWUodmFsdWVzOiBJTGF0TG9uZ0RhdGEsIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIHRoaXMuZGVncmVlc0NvbnRyb2wucGF0Y2hWYWx1ZSh2YWx1ZXMuZGVncmVlcywgb3B0cyk7XG4gICAgdGhpcy5taW51dGVzQ29udHJvbC5wYXRjaFZhbHVlKHZhbHVlcy5taW51dGVzLCBvcHRzKTtcbiAgICB0aGlzLnNlY29uZHNDb250cm9sLnBhdGNoVmFsdWUodmFsdWVzLnNlY29uZHMsIG9wdHMpO1xuICAgIHRoaXMuc2lnbkNvbnRyb2wucGF0Y2hWYWx1ZSh2YWx1ZXMuc2lnbiwgb3B0cyk7XG4gIH1cblxuICBwcml2YXRlIG9uRm9ybUNoYW5nZSgpIHtcbiAgICBpZiAodGhpcy5fd3JpdGluZykgcmV0dXJuOyAvLyBTa2lwIGlmIGNhbGwgYnkgc2VsZlxuICAgIHRoaXMuX3dyaXRpbmcgPSB0cnVlO1xuXG4gICAgLy8gREVCVUdcbiAgICBjb25zb2xlLmRlYnVnKCdbbWF0LWxhdGxvbmctZmllbGRdIG9uRm9ybUNoYW5nZSAnKTtcblxuICAgIGNvbnN0IGRlZ3JlZXMgPSB0aGlzLmRlZ3JlZXNDb250cm9sLnZhbHVlO1xuICAgIGNvbnN0IG1pbnV0ZXMgPSB0aGlzLm1pbnV0ZXNDb250cm9sLnZhbHVlO1xuICAgIGNvbnN0IHNlY29uZHMgPSB0aGlzLnNlY29uZHNDb250cm9sLnZhbHVlO1xuICAgIGNvbnN0IHNpZ24gPSB0aGlzLnNpZ25Db250cm9sLnZhbHVlO1xuXG4gICAgY29uc3QgaW5jb21wbGV0ZVZhbHVlID0gaXNOaWwoZGVncmVlcykgJiYgKGlzTm90TmlsKG1pbnV0ZXMpIHx8IGlzTm90TmlsKHNlY29uZHMpKTtcbiAgICBjb25zdCBpbnZhbGlkID1cbiAgICAgIGluY29tcGxldGVWYWx1ZSB8fCB0aGlzLmRlZ3JlZXNDb250cm9sLmludmFsaWQgfHwgdGhpcy5taW51dGVzQ29udHJvbC5pbnZhbGlkIHx8IHRoaXMuc2Vjb25kc0NvbnRyb2wuaW52YWxpZCB8fCB0aGlzLnNpZ25Db250cm9sLmludmFsaWQ7XG4gICAgaWYgKGludmFsaWQpIHtcbiAgICAgIC8vIERFQlVHXG4gICAgICBjb25zb2xlLmRlYnVnKGBbbWF0LWxhdGxvbmctZmllbGRdIG9uRm9ybUNoYW5nZSgpIGVycm9yIC0+IGluY29tcGxldGVWYWx1ZTogJHtpbmNvbXBsZXRlVmFsdWV9YCk7XG5cbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzUGVuZGluZyh7IG9ubHlTZWxmOiB0cnVlIH0pO1xuICAgICAgdGhpcy5mb3JtQ29udHJvbC5zZXRFcnJvcnMoe1xuICAgICAgICBpbnZhbGlkOiBpbmNvbXBsZXRlVmFsdWUsXG4gICAgICAgIC4uLnRoaXMuZGVncmVlc0NvbnRyb2wuZXJyb3JzLFxuICAgICAgICAuLi50aGlzLm1pbnV0ZXNDb250cm9sLmVycm9ycyxcbiAgICAgICAgLi4udGhpcy5zZWNvbmRzQ29udHJvbC5lcnJvcnMsXG4gICAgICAgIC4uLnRoaXMuc2lnbkNvbnRyb2wuZXJyb3JzLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICh0aGlzLmRlZ3JlZXNDb250cm9sLmRpcnR5IHx8IHRoaXMubWludXRlc0NvbnRyb2wuZGlydHkgfHwgdGhpcy5zZWNvbmRzQ29udHJvbC5kaXJ0eSB8fCB0aGlzLnNpZ25Db250cm9sLmRpcnR5KSB7XG4gICAgICAgIHRoaXMuZm9ybUNvbnRyb2wubWFya0FzRGlydHkoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fd3JpdGluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIENvbXB1dGUgZGVjaW1hbCB2YWx1ZXNcbiAgICBjb25zdCB2YWx1ZSA9IGlzTmlsKGRlZ3JlZXMpIHx8IHRoaXMucGF0dGVybiA9PT0gJ0REJyA/IGRlZ3JlZXMgOiBjb21wdXRlRGVjaW1hbERlZ3JlZXMoZGVncmVlcywgbWludXRlcywgc2Vjb25kcywgc2lnbiwgdGhpcy5tYXhEZWNpbWFscyk7XG5cbiAgICAvLyBTZXQgbW9kZWwgdmFsdWVcbiAgICB0aGlzLmVtaXRDaGFuZ2UodmFsdWUpO1xuXG4gICAgdGhpcy5fd3JpdGluZyA9IGZhbHNlO1xuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDaGFuZ2UodmFsdWU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmZvcm1Db250cm9sLnZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgLy8gREVCVUdcbiAgICAgIGNvbnNvbGUuZGVidWcoJ1ttYXQtbGF0bG9uZy1maWVsZF0gRW1pdCBuZXcgdmFsdWU6ICcgKyB2YWx1ZSk7XG5cbiAgICAgIHRoaXMuZm9ybUNvbnRyb2wuc2V0VmFsdWUodmFsdWUsIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcblxuICAgICAgLy8gQ2hhbmdlcyBjb21lcyBmcm9tIGluc2lkZSBmdW5jdGlvbjogdXNlIHRoZSBjYWxsYmFja1xuICAgICAgdGhpcy5fb25DaGFuZ2VDYWxsYmFjayh2YWx1ZSk7XG5cbiAgICAgIC8vIENoZWNrIGlmIG5lZWQgdG8gdXBkYXRlIGNvbnRyb2xzXG4gICAgICB0aGlzLl9jaGVja0lmVG91Y2hlZCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2NoZWNrSWZUb3VjaGVkKCkge1xuICAgIGlmICh0aGlzLmZvcm1Db250cm9sLnRvdWNoZWQpIHtcbiAgICAgIHRoaXMuX29uVG91Y2hlZENhbGxiYWNrKCk7XG4gICAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICAgICAgdGhpcy5fdG91Y2hlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3RvdWNoZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1hcmtGb3JDaGVjaygpIHtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNob3cvSGlkZSB0aGUgZmFrZSBpbnB1dFxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVGYWtlSW5wdXQoKSB7XG4gICAgaWYgKHRoaXMuc2hvd0ZpZWxkcykge1xuICAgICAgdGhpcy5mYWtlSW5wdXQ/Lm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnY2RrLXZpc3VhbGx5LWhpZGRlbicpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZha2VJbnB1dD8ubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKCdjZGstdmlzdWFsbHktaGlkZGVuJyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogY2hlY2sgaWYgbmVlZFxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSwgYmVjYXVzZSwgdGhpcyBjb21wb25lbnQgaGFzIGEgdGVtcG9yYXJ5IGNvbXBvbmVudCBkaXNwbGF5ZWQgYmVmb3JlIHRoZSBmaXJzdCBmb2N1cyBldmVudFxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVUYWJJbmRleCgpIHtcbiAgICBpZiAoaXNOaWwodGhpcy5fdGFiaW5kZXgpKSByZXR1cm47XG5cbiAgICBpZiAodGhpcy5mYWtlSW5wdXQpIHtcbiAgICAgIHRoaXMuZmFrZUlucHV0Lm5hdGl2ZUVsZW1lbnQudGFiSW5kZXggPSB0aGlzLl90YWJpbmRleDtcbiAgICB9XG5cbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8IS0tIHJlYWRvbmx5IC0tPlxuQGlmIChyZWFkb25seSkge1xuICA8bWF0LWZvcm0tZmllbGRcbiAgICBbZmxvYXRMYWJlbF09XCJmbG9hdExhYmVsIHwgYXNGbG9hdExhYmVsVHlwZVwiXG4gICAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gICAgW3N1YnNjcmlwdFNpemluZ109XCJzdWJzY3JpcHRTaXppbmdcIlxuICAgIGNsYXNzPVwibWF0LWZvcm0tZmllbGQtZGlzYWJsZWRcIlxuICA+XG4gICAgPGRpdiBtYXRQcmVmaXg+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0UHJlZml4VGVtcGxhdGVcIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cblxuICAgIEBpZiAoZmxvYXRMYWJlbCAhPT0gJ25ldmVyJyAmJiAhIXBsYWNlaG9sZGVyKSB7XG4gICAgICA8bWF0LWxhYmVsPnt7IHBsYWNlaG9sZGVyIH19PC9tYXQtbGFiZWw+XG4gICAgfVxuXG4gICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiB0eXBlPVwidGV4dFwiIHJlYWRvbmx5IFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFwiIC8+XG4gICAgPGlvbi10ZXh0PlxuICAgICAge3tcbiAgICAgICAgZm9ybUNvbnRyb2wudmFsdWVcbiAgICAgICAgICB8IGxhdExvbmdGb3JtYXQ6IHsgcGF0dGVybjogcGF0dGVybiwgbWF4RGVjaW1hbHM6IG1heERlY2ltYWxzLCB0eXBlOiB0eXBlLCBwbGFjZWhvbGRlckNoYXI6ICcnIH1cbiAgICAgIH19XG4gICAgPC9pb24tdGV4dD5cblxuICAgIDxkaXYgbWF0U3VmZml4PlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIGhpbnRzIC0tPlxuICAgIDxtYXQtaGludCBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCJmb3JtQ29udHJvbC5pbnZhbGlkXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWF0SGludFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9tYXQtaGludD5cbiAgPC9tYXQtZm9ybS1maWVsZD5cbn0gQGVsc2Uge1xuICA8IS0tIHdyaXRhYmxlIC0tPlxuICA8aW9uLWdyaWQgY2xhc3M9XCJpb24tbm8tcGFkZGluZyB7eyBhcHBlYXJhbmNlIH19XCI+XG4gICAgPGlvbi1yb3cgY2xhc3M9XCJpb24tbm8tcGFkZGluZyBuby13cmFwXCI+XG4gICAgICA8IS0tIGRlZ3JlZXMgLS0+XG4gICAgICA8aW9uLWNvbCBjbGFzcz1cImRlZ3JlZXMgaW9uLW5vLXBhZGRpbmdcIj5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkXG4gICAgICAgICAgI2Zvcm1GaWVsZFxuICAgICAgICAgIFtmbG9hdExhYmVsXT1cIlxuICAgICAgICAgICAgc2hvd0ZpZWxkcyAmJiAoIWZsb2F0TGFiZWwgfHwgZmxvYXRMYWJlbCA9PT0gJ2F1dG8nKSA/ICdhbHdheXMnIDogKGZsb2F0TGFiZWwgfCBhc0Zsb2F0TGFiZWxUeXBlKVxuICAgICAgICAgIFwiXG4gICAgICAgICAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gICAgICAgICAgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIlxuICAgICAgICAgIFtjbGFzcy5tZGMtdGV4dC1maWVsZC0taW52YWxpZF09XCJmb3JtQ29udHJvbC50b3VjaGVkICYmIChzaWduQ29udHJvbC5pbnZhbGlkIHx8IGZvcm1Db250cm9sLmludmFsaWQpXCJcbiAgICAgICAgICBjbGFzcz1cInZhbHVlc1wiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IG1hdFByZWZpeD5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRQcmVmaXhUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgQGlmIChmbG9hdExhYmVsICE9PSAnbmV2ZXInICYmIHBsYWNlaG9sZGVyIHwgaXNOb3ROaWxPckJsYW5rKSB7XG4gICAgICAgICAgICA8bWF0LWxhYmVsPnt7IHBsYWNlaG9sZGVyIH19PC9tYXQtbGFiZWw+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgI2Zha2VJbnB1dFxuICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgcmVhZG9ubHk9XCJ0cnVlXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbFwiXG4gICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgICAgW2FwcEF1dG9mb2N1c109XCIhc2hvd0ZpZWxkcyAmJiBhdXRvZm9jdXNcIlxuICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICAgIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cInNob3dGaWVsZHNcIlxuICAgICAgICAgICAgKGZvY3VzKT1cIm9uRm9jdXNGYWtlSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAoYmx1cik9XCJvbkJsdXJGYWtlSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgLz5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAjaW5wdXREZWdyZWVzXG4gICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwic2hvd0ZpZWxkcyA/IGlucHV0V2lkdGguZGVncmVlcyA6ICcxMDAlJ1wiXG4gICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgIGF1dG9jb21wbGV0ZT1cIm9mZlwiXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiZGVncmVlc1BsYWNlaG9sZGVyIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJkZWdyZWVzQ29udHJvbFwiXG4gICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxuICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICAgIFthcHBBdXRvZm9jdXNdPVwic2hvd0ZpZWxkcyAmJiBhdXRvZm9jdXNcIlxuICAgICAgICAgICAgW21pbl09XCJtaW5NYXhWYWx1ZXMuZGVncmVlcy5taW5cIlxuICAgICAgICAgICAgW21heF09XCJtaW5NYXhWYWx1ZXMuZGVncmVlcy5tYXhcIlxuICAgICAgICAgICAgW3N0ZXBdPVwibWluTWF4VmFsdWVzLmRlZ3JlZXMuc3RlcFwiXG4gICAgICAgICAgICAoZm9jdXMpPVwiX29uRm9jdXNJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChibHVyKT1cIl9vbkJsdXJJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgIChjbGljayk9XCJfb25DbGlja0lucHV0KCRldmVudClcIlxuICAgICAgICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgIGNsYXNzPVwic3ltYm9sLXVuaXRcIlxuICAgICAgICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cInRoaXMuaW5wdXRXaWR0aC5kZWdyZWVzVW5pdFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgZGVncmVlc1N5bWJvbFVuaXQgfX1cbiAgICAgICAgICA8L3NwYW4+XG5cbiAgICAgICAgICBAaWYgKHNob3dNaW51dGVzKSB7XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgI2lucHV0TWludXRlc1xuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwidGhpcy5pbnB1dFdpZHRoLm1pbnV0ZXNcIlxuICAgICAgICAgICAgICBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCIhc2hvd0ZpZWxkc1wiXG4gICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwibWludXRlc1BsYWNlaG9sZGVyIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cIm1pbnV0ZXNDb250cm9sXCJcbiAgICAgICAgICAgICAgW3JlcXVpcmVkXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4XCJcbiAgICAgICAgICAgICAgW21pbl09XCJtaW5NYXhWYWx1ZXMubWludXRlcy5taW5cIlxuICAgICAgICAgICAgICBbbWF4XT1cIm1pbk1heFZhbHVlcy5taW51dGVzLm1heFwiXG4gICAgICAgICAgICAgIFtzdGVwXT1cIm1pbk1heFZhbHVlcy5taW51dGVzLnN0ZXBcIlxuICAgICAgICAgICAgICAoZm9jdXMpPVwiX29uRm9jdXNJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGJsdXIpPVwiX29uQmx1cklucHV0KCRldmVudClcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiX29uQ2xpY2tJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICBjbGFzcz1cInN5bWJvbC11bml0XCJcbiAgICAgICAgICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwidGhpcy5pbnB1dFdpZHRoLm1pbnV0ZXNVbml0XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgbWludXRlc1N5bWJvbFVuaXQgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBAaWYgKHNob3dTZWNvbmRzKSB7XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgI2lucHV0U2Vjb25kc1xuICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiaW5wdXRXaWR0aC5zZWNvbmRzXCJcbiAgICAgICAgICAgICAgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIXNob3dGaWVsZHNcIlxuICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInNlY29uZHNQbGFjZWhvbGRlciB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJzZWNvbmRzQ29udHJvbFwiXG4gICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJmYWxzZVwiXG4gICAgICAgICAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleFwiXG4gICAgICAgICAgICAgIFttaW5dPVwibWluTWF4VmFsdWVzLnNlY29uZHMubWluXCJcbiAgICAgICAgICAgICAgW21heF09XCJtaW5NYXhWYWx1ZXMuc2Vjb25kcy5tYXhcIlxuICAgICAgICAgICAgICBbc3RlcF09XCJtaW5NYXhWYWx1ZXMuc2Vjb25kcy5zdGVwXCJcbiAgICAgICAgICAgICAgKGZvY3VzKT1cIl9vbkZvY3VzSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgIChibHVyKT1cIl9vbkJsdXJJbnB1dCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cIl9vbkNsaWNrSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgW3N0eWxlLndpZHRoXT1cInRoaXMuaW5wdXRXaWR0aC5zZWNvbmRzVW5pdFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cIiFzaG93RmllbGRzXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJzeW1ib2wtdW5pdFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIHt7IHNlY29uZHNTeW1ib2xVbml0IH19XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQGlmICghc2hvd1NpZ25Db250cm9sKSB7XG4gICAgICAgICAgICA8ZGl2IG1hdFN1ZmZpeD5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICA8L2lvbi1jb2w+XG5cbiAgICAgIDwhLS0gc2lnbiAtLT5cbiAgICAgIEBpZiAoc2hvd1NpZ25Db250cm9sKSB7XG4gICAgICAgIDxpb24tY29sIGNsYXNzPVwic2lnbiBpb24tbm8tcGFkZGluZyB7eyB0eXBlIH19XCI+XG4gICAgICAgICAgQHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgQGNhc2UgKCdsYXRpdHVkZScpIHtcbiAgICAgICAgICAgICAgPCEtLSBzaWduIG9uIGxhdGl0dWRlIC0tPlxuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGRcbiAgICAgICAgICAgICAgICBbYXBwZWFyYW5jZV09XCJhcHBlYXJhbmNlXCJcbiAgICAgICAgICAgICAgICBbc3Vic2NyaXB0U2l6aW5nXT1cIidkeW5hbWljJ1wiXG4gICAgICAgICAgICAgICAgW2NsYXNzLm1kYy10ZXh0LWZpZWxkLS1pbnZhbGlkXT1cImZvcm1Db250cm9sLnRvdWNoZWQgJiYgc2lnbkNvbnRyb2wuaW52YWxpZFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPjwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAjaW5wdXRTaWduXG4gICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwic2lnbkNvbnRyb2xcIlxuICAgICAgICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidDT01NT04uTEFUX0xPTkcuTEFUX1NJR05fUExBQ0VIT0xERVInIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCJ0YWJpbmRleCAhPT0gdW5kZWZpbmVkID8gdGFiaW5kZXggKyAxIDogdW5kZWZpbmVkXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiMVwiPnt7ICdDT01NT04uTEFUX0xPTkcuTEFUX1NJR05fTicgfCB0cmFuc2xhdGUgfX08L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwiLTFcIj57eyAnQ09NTU9OLkxBVF9MT05HLkxBVF9TSUdOX1MnIHwgdHJhbnNsYXRlIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cblxuICAgICAgICAgICAgICAgIDxkaXYgbWF0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAY2FzZSAoJ2xvbmdpdHVkZScpIHtcbiAgICAgICAgICAgICAgPCEtLSBzaWduIG9uIGxvbmdpdHVkZSAtLT5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkXG4gICAgICAgICAgICAgICAgW2FwcGVhcmFuY2VdPVwiYXBwZWFyYW5jZVwiXG4gICAgICAgICAgICAgICAgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5tZGMtdGV4dC1maWVsZC0taW52YWxpZF09XCJmb3JtQ29udHJvbC50b3VjaGVkICYmIHNpZ25Db250cm9sLmludmFsaWRcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD48L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgI2lucHV0U2lnblxuICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cInNpZ25Db250cm9sXCJcbiAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInQ09NTU9OLkxBVF9MT05HLkxPTkdfU0lHTl9QTEFDRUhPTERFUicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgW3RhYmluZGV4XT1cInRhYmluZGV4ICE9PSB1bmRlZmluZWQgPyB0YWJpbmRleCArIDEgOiB1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCIxXCIgdHJhbnNsYXRlPnt7ICdDT01NT04uTEFUX0xPTkcuTE9OR19TSUdOX0UnIHwgdHJhbnNsYXRlIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIi0xXCIgdHJhbnNsYXRlPnt7ICdDT01NT04uTEFUX0xPTkcuTE9OR19TSUdOX1cnIHwgdHJhbnNsYXRlIH19PC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cblxuICAgICAgICAgICAgICAgIDxkaXYgbWF0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdFN1ZmZpeFRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA8L2lvbi1jb2w+XG4gICAgICB9XG4gICAgPC9pb24tcm93PlxuICA8L2lvbi1ncmlkPlxuXG4gIDwhLS0gRG8gdGhlIHNhbWUgYXMgTWF0RnJvbUZpZWxkIHNpbmNlIGFuZ3VsYXIgMTUgKHNlZSBjb21wb25lbnQgc291cmNlKS0tPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJtYXQtbWRjLWZvcm0tZmllbGQtc3Vic2NyaXB0LXdyYXBwZXJcIlxuICAgIFtjbGFzcy5tYXQtbWRjLWZvcm0tZmllbGQtYm90dG9tLWFsaWduXT1cInN1YnNjcmlwdFNpemluZyA9PT0gJ2ZpeGVkJ1wiXG4gICAgW2NsYXNzLm1hdC1tZGMtZm9ybS1maWVsZC1zdWJzY3JpcHQtZHluYW1pYy1zaXplXT1cInN1YnNjcmlwdFNpemluZyA9PT0gJ2R5bmFtaWMnXCJcbiAgPlxuICAgIEBpZiAoZm9ybUNvbnRyb2wudG91Y2hlZCAmJiBmb3JtQ29udHJvbC5pbnZhbGlkKSB7XG4gICAgICA8IS0tIGVycm9ycyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJtYXQtbWRjLWZvcm0tZmllbGQtZXJyb3Itd3JhcHBlclwiPlxuICAgICAgICBAaWYgKGZvcm1Db250cm9sLmVycm9ycyB8IG1hcEtleXMgfCBhcnJheUZpcnN0OyBhcyBlcnJvcktleSkge1xuICAgICAgICAgIDxtYXQtZXJyb3I+XG4gICAgICAgICAgICB7eyBpMThuRXJyb3JLZXlzIHwgbWFwR2V0OiBlcnJvcktleSB8IHRyYW5zbGF0ZTogKGZvcm1Db250cm9sLmVycm9ycyB8IG1hcEdldDogZXJyb3JLZXkpIH19XG4gICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJtYXRFcnJvclRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIH0gQGVsc2Uge1xuICAgICAgPCEtLSBoaW50cyAtLT5cbiAgICAgIDxtYXQtaGludD5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIm1hdEhpbnRUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9tYXQtaGludD5cbiAgICB9XG4gIDwvZGl2PlxufVxuXG48bmctdGVtcGxhdGUgI21hdFByZWZpeFRlbXBsYXRlPlxuICA8bmctY29udGVudCBzZWxlY3Q9XCJbbWF0UHJlZml4XVwiPjwvbmctY29udGVudD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbWF0U3VmZml4VGVtcGxhdGU+XG4gIEBpZiAoY2xlYXJhYmxlICYmICFyZWFkb25seSkge1xuICAgIDxidXR0b25cbiAgICAgIG1hdFN1ZmZpeFxuICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgKGNsaWNrKT1cImNsZWFyVmFsdWUoJGV2ZW50KVwiXG4gICAgICBbaGlkZGVuXT1cImZvcm1Db250cm9sLnZhbHVlIHwgaXNOaWxcIlxuICAgID5cbiAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gIH1cblxuICA8bmctY29udGVudCBzZWxlY3Q9XCJbbWF0U3VmZml4XVwiPjwvbmctY29udGVudD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbWF0RXJyb3JUZW1wbGF0ZT5cbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwibWF0LWVycm9yLFttYXRFcnJvcl1cIj48L25nLWNvbnRlbnQ+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI21hdEhpbnRUZW1wbGF0ZT5cbiAgPGRpdiBjbGFzcz1cIm1hdC1tZGMtZm9ybS1maWVsZC1oaW50LXdyYXBwZXJcIj5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJtYXQtaGludDpub3QoW2FsaWduPSdlbmQnXSksW21hdEhpbnRdXCI+PC9uZy1jb250ZW50PlxuICAgIDxkaXYgY2xhc3M9XCJtYXQtbWRjLWZvcm0tZmllbGQtaGludC1zcGFjZXJcIj48L2Rpdj5cbiAgICA8bmctY29udGVudCBzZWxlY3Q9XCJtYXQtaGludFthbGlnbj0nZW5kJ11cIj48L25nLWNvbnRlbnQ+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==