@sumaris-net/ngx-components 2.6.6-rc2 → 2.6.6-rc4

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/esm2020/src/app/admin/services/person.service.mjs +23 -22
  2. package/esm2020/src/app/admin/services/validator/person.validator.mjs +58 -21
  3. package/esm2020/src/app/admin/users/users.mjs +26 -7
  4. package/esm2020/src/app/core/account/account.page.mjs +28 -29
  5. package/esm2020/src/app/core/form/properties/properties.table.mjs +7 -4
  6. package/esm2020/src/app/core/graphql/graphql.service.mjs +14 -6
  7. package/esm2020/src/app/core/menu/menu.service.mjs +2 -2
  8. package/esm2020/src/app/core/services/base-entity-service.class.mjs +43 -19
  9. package/esm2020/src/app/core/services/base-graphql-service.class.mjs +6 -2
  10. package/esm2020/src/app/core/services/errors.mjs +2 -1
  11. package/esm2020/src/app/core/services/model/person.model.mjs +10 -1
  12. package/esm2020/src/app/core/services/validator/account.validator.mjs +26 -41
  13. package/esm2020/src/app/core/services/validator/base.validator.class.mjs +2 -2
  14. package/fesm2015/sumaris-net.ngx-components.mjs +221 -142
  15. package/fesm2015/sumaris-net.ngx-components.mjs.map +1 -1
  16. package/fesm2020/sumaris-net.ngx-components.mjs +231 -143
  17. package/fesm2020/sumaris-net.ngx-components.mjs.map +1 -1
  18. package/package.json +1 -1
  19. package/src/app/admin/services/validator/person.validator.d.ts +20 -11
  20. package/src/app/core/account/account.page.d.ts +3 -3
  21. package/src/app/core/form/properties/properties.table.d.ts +2 -1
  22. package/src/app/core/graphql/graphql.service.d.ts +1 -1
  23. package/src/app/core/services/base-entity-service.class.d.ts +22 -3
  24. package/src/app/core/services/errors.d.ts +1 -0
  25. package/src/app/core/services/model/person.model.d.ts +1 -0
  26. package/src/app/core/services/validator/account.validator.d.ts +16 -9
  27. package/src/app/core/services/validator/base.validator.class.d.ts +1 -1
  28. package/src/assets/i18n/en-US.json +1 -0
  29. package/src/assets/i18n/en.json +1 -0
  30. package/src/assets/manifest.json +1 -1
@@ -11,6 +11,7 @@ import { filter, map } from 'rxjs/operators';
11
11
  import { CORE_CONFIG_OPTIONS } from '../services/config/core.config';
12
12
  import { PropertyEntity } from '../form/properties/properties.table';
13
13
  import { isNotNil } from '../../shared/functions';
14
+ import { environment } from '../../../environments/environment';
14
15
  import * as i0 from "@angular/core";
15
16
  import * as i1 from "@angular/forms";
16
17
  import * as i2 from "../services/account.service";
@@ -51,7 +52,7 @@ export class AccountPage extends AppForm {
51
52
  confirmed: false,
52
53
  notConfirmed: false,
53
54
  sending: false,
54
- error: undefined
55
+ error: undefined,
55
56
  };
56
57
  this.latLongFormats = LAT_LONG_PATTERNS;
57
58
  this.saving = false;
@@ -64,6 +65,7 @@ export class AccountPage extends AppForm {
64
65
  // this.settingsContentForm = (this.settingsForm.controls['content'] as UntypedFormGroup);
65
66
  // this.form.addControl('settings', this.settingsForm);
66
67
  this.mobile = this.settings.mobile;
68
+ this.debug = !environment.production;
67
69
  // By default, disable the form
68
70
  this.disable();
69
71
  }
@@ -76,17 +78,17 @@ export class AccountPage extends AppForm {
76
78
  ngOnInit() {
77
79
  super.ngOnInit();
78
80
  // Get user options
79
- this.optionDefinitions = this.accountService.optionDefs.slice()
80
- .filter(definition => !definition.minProfile || this.accountService.hasMinProfile(definition.minProfile));
81
+ this.optionDefinitions = this.accountService.optionDefs
82
+ .slice()
83
+ .filter((definition) => !definition.minProfile || this.accountService.hasMinProfile(definition.minProfile));
81
84
  // Observed some events
82
- this.registerSubscription(this.accountService.onLogin.pipe(filter(() => !this.saving)).subscribe(account => this.onLogin(account)));
85
+ this.registerSubscription(this.accountService.onLogin.pipe(filter(() => !this.saving)).subscribe((account) => this.onLogin(account)));
83
86
  this.registerSubscription(this.accountService.onLogout.subscribe(() => this.onLogout()));
84
87
  this.registerSubscription(this.onCancel.subscribe(() => {
85
88
  this.setValue(this.accountService.account);
86
89
  this.markAsPristine();
87
90
  }));
88
- this.registerSubscription(this.accountService.$additionalFields
89
- .subscribe((additionalFields) => {
91
+ this.registerSubscription(this.accountService.$additionalFields.subscribe((additionalFields) => {
90
92
  this.additionalFields = additionalFields.slice(); // Copy
91
93
  if (this.accountService.isLogin()) {
92
94
  this.onLogin(this.accountService.account);
@@ -95,7 +97,7 @@ export class AccountPage extends AppForm {
95
97
  this.markAsLoaded();
96
98
  }
97
99
  }));
98
- this.registerSubscription(this.configService.config.subscribe(value => {
100
+ this.registerSubscription(this.configService.config.subscribe((value) => {
99
101
  this.accountReadOnly = value.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.ACCOUNT_READONLY);
100
102
  this.authTokenEnabled = value.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.AUTH_TOKEN_ENABLED);
101
103
  }));
@@ -111,13 +113,12 @@ export class AccountPage extends AppForm {
111
113
  console.debug('[account] Logged account: ', account);
112
114
  this.isLogin = true;
113
115
  this.setValue(account);
114
- this.email.confirmed = account && account.email && (account.statusId !== StatusIds.TEMPORARY);
116
+ this.email.confirmed = account && account.email && account.statusId !== StatusIds.TEMPORARY;
115
117
  this.email.notConfirmed = account && account.email && (!account.statusId || account.statusId === StatusIds.TEMPORARY);
116
118
  this.networkSubscription?.unsubscribe();
117
119
  this.networkSubscription = combineLatest([
118
120
  this.configService.config,
119
- this.network.onNetworkStatusChanges
120
- .pipe(map(connectionType => connectionType !== 'none'))
121
+ this.network.onNetworkStatusChanges.pipe(map((connectionType) => connectionType !== 'none')),
121
122
  ]).subscribe(([config, online]) => {
122
123
  if (online) {
123
124
  const accountReadOnly = config.getPropertyAsBoolean(CORE_CONFIG_OPTIONS.ACCOUNT_READONLY);
@@ -153,8 +154,9 @@ export class AccountPage extends AppForm {
153
154
  const properties = data?.settings?.asLocalSettings()?.properties || {};
154
155
  const propertiesEntities = [];
155
156
  this.optionDefinitions
156
- .filter(definition => !definition.minProfile || this.accountService.hasMinProfile(definition.minProfile))
157
- .map(definition => definition.key).forEach(key => {
157
+ .filter((definition) => !definition.minProfile || this.accountService.hasMinProfile(definition.minProfile))
158
+ .map((definition) => definition.key)
159
+ .forEach((key) => {
158
160
  if (isNotNil(properties[key])) {
159
161
  propertiesEntities.push(PropertyEntity.fromObject({ id: key, value: properties[key] }));
160
162
  }
@@ -168,7 +170,7 @@ export class AccountPage extends AppForm {
168
170
  this.tokensTable.value = data.tokens;
169
171
  }
170
172
  }
171
- async refresh(event) {
173
+ async refresh(_) {
172
174
  this.disable();
173
175
  this.markAsLoading();
174
176
  return this.accountService.reload();
@@ -194,13 +196,13 @@ export class AccountPage extends AppForm {
194
196
  this.email.sending = true;
195
197
  console.debug('[account] Sending confirmation email...');
196
198
  try {
197
- await this.accountService.sendConfirmationEmail(json.email, json.settings && json.settings.locale || this.translate.currentLang);
199
+ await this.accountService.sendConfirmationEmail(json.email, (json.settings && json.settings.locale) || this.translate.currentLang);
198
200
  console.debug('[account] Confirmation email sent.');
199
201
  this.email.sending = false;
200
202
  }
201
203
  catch (err) {
202
204
  this.email.sending = false;
203
- this.email.error = err && err.message || err;
205
+ this.email.error = (err && err.message) || err;
204
206
  }
205
207
  }
206
208
  async save(event) {
@@ -218,8 +220,8 @@ export class AccountPage extends AppForm {
218
220
  this.saving = true;
219
221
  this.error = undefined;
220
222
  const newAccount = Account.fromObject({
221
- ...(this.accountService.account.asObject()),
222
- ...(this.form.value)
223
+ ...this.accountService.account.asObject(),
224
+ ...this.form.value,
223
225
  });
224
226
  if (this.propertiesTable) {
225
227
  // merge properties
@@ -246,7 +248,7 @@ export class AccountPage extends AppForm {
246
248
  }
247
249
  catch (err) {
248
250
  console.error(err);
249
- this.error = err && err.message || err;
251
+ this.error = (err && err.message) || err;
250
252
  return false;
251
253
  }
252
254
  finally {
@@ -266,20 +268,17 @@ export class AccountPage extends AppForm {
266
268
  this.form.controls.firstName.disable();
267
269
  }
268
270
  // Always disable some additional fields
269
- this.additionalFields
270
- .forEach(field => {
271
+ this.additionalFields.forEach((field) => {
271
272
  const control = this.form.controls[field.key];
272
273
  if (!control)
273
274
  return; // Skip
274
- const disabled = field.extra?.account && field.extra.account.disabled || false;
275
+ const disabled = (field.extra?.account && field.extra.account.disabled) || false;
275
276
  if (disabled && control.enabled) {
276
277
  control.disable();
277
278
  }
278
- const required = field.extra?.account && field.extra.account.required || false;
279
+ const required = (field.extra?.account && field.extra.account.required) || false;
279
280
  if (!field.required && required) {
280
- control.setValidators(control.validator
281
- ? Validators.compose([control.validator, Validators.required])
282
- : Validators.required);
281
+ control.setValidators(control.validator ? Validators.compose([control.validator, Validators.required]) : Validators.required);
283
282
  }
284
283
  });
285
284
  this.markForCheck();
@@ -287,7 +286,7 @@ export class AccountPage extends AppForm {
287
286
  async cancel() {
288
287
  await super.cancel();
289
288
  }
290
- async close(event) {
289
+ async close(_) {
291
290
  if (this.saving)
292
291
  return;
293
292
  // Back to home
@@ -298,10 +297,10 @@ export class AccountPage extends AppForm {
298
297
  }
299
298
  }
300
299
  AccountPage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AccountPage, deps: [{ token: i0.Injector }, { token: i1.UntypedFormBuilder }, { token: i2.AccountService }, { token: i3.NetworkService }, { token: i4.NavController }, { token: i5.AccountValidatorService }, { token: i6.ConfigService }, { token: i0.ChangeDetectorRef }, { token: APP_LOCALES }], target: i0.ɵɵFactoryTarget.Component });
301
- AccountPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AccountPage, selector: "app-account-page", viewQueries: [{ propertyName: "tabGroup", first: true, predicate: ["tabGroup"], descendants: true, static: true }, { propertyName: "propertiesTable", first: true, predicate: ["propertiesTable"], descendants: true, static: true }, { propertyName: "tokensTable", first: true, predicate: ["tokensTable"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar [title]=\"'ACCOUNT.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n [canGoBack]=\"false\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- loader -->\n <ion-spinner *ngIf=\"loading || saving; else endButtons\"></ion-spinner>\n\n <ng-template #endButtons>\n <!-- refresh button (if online) -->\n <ion-button [matTooltip]=\"'COMMON.BTN_REFRESH'|translate\"\n *ngIf=\"network.online\"\n (click)=\"refresh($event)\">\n <mat-icon slot=\"icon-only\">refresh</mat-icon>\n </ion-button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content>\n\n <!-- error -->\n <ion-item *ngIf=\"error && mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <form [formGroup]=\"form\" novalidate class=\"form-container\">\n\n <mat-tab-group #tabGroup [(selectedIndex)]=\"selectedTabIndex\" dynamicHeight>\n\n <!-- TAB: user details -->\n <mat-tab label=\"{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}\" class=\"ion-padding\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"person-circle\"></ion-icon>\n </mat-icon>\n <ion-label>{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}</ion-label>\n <ion-icon slot=\"end\" name=\"alert-circle\" color=\"danger\" *ngIf=\"submitted && form.invalid\"></ion-icon>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.USER_DETAILS.DESCRIPTION'|translate\"></p>\n\n <!--h1>Identit\u00E9</h1-->\n\n <!-- Email -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.EMAIL'|translate\"\n formControlName=\"email\" autocomplete=\"section-red email\">\n <mat-error *ngIf=\"form.controls.email.hasError('required') && form.controls.email.dirty\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.email.hasError('email') && form.controls.email.dirty\">\n <span>{{'ERROR.FIELD_NOT_VALID_EMAIL' | translate }}</span>\n </mat-error>\n </mat-form-field>\n\n <ion-grid *ngIf=\"email.notConfirmed\" class=\"ion-no-padding ion-padding-bottom\">\n <ion-row>\n <ion-col color=\"danger\">\n <ion-icon slot=\"start\" color=\"danger\" name=\"alert-circle\" color=\"danger\"></ion-icon>\n <ion-text [innerHTML]=\"'ACCOUNT.EMAIL_NOT_CONFIRMED_LABEL'|translate\"></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row style=\"height: 51px;\">\n <ion-col style=\"text-align: right;\">\n <ion-text>\n <small [innerHTML]=\"'ACCOUNT.EMAIL_NOT_RECEIVED_QUESTION'|translate\"></small>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"secondary\" *ngIf=\"!email.sending\" (click)=\"sendConfirmationEmail($event)\">\n {{'ACCOUNT.BTN_RESEND'|translate}}\n </ion-button>\n <ion-spinner class=\"ion-no-padding\" *ngIf=\"email.sending\"></ion-spinner>\n </ion-col>\n </ion-row>\n\n <ion-row *ngIf=\"email.error && !email.sending\">\n <ion-col>\n <span *ngIf=\"email.error && !email.sending\" [innerHTML]=\"email.error|translate\"></span>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Last name -->\n <mat-form-field>\n <input matInput [appAutofocus]=\"true\" [autofocusDelay]=\"500\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n formControlName=\"lastName\"\n autocomplete=\"section-blue family-name\"\n required>\n <mat-error *ngIf=\"form.controls.lastName.hasError('required') && form.controls.lastName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.lastName.hasError('minlength') && form.controls.lastName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n <!-- First name -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.FIRST_NAME'|translate\" formControlName=\"firstName\" autocomplete=\"section-blue given-name\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('required') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('minlength') && form.controls.firstName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n\n <!-- Additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\">\n <app-form-field [definition]=\"definition\"\n [formControlName]=\"definition.key\"\n [required]=\"definition.extra && definition.extra.account && definition.extra.account.required || false\">\n </app-form-field>\n </ng-container>\n\n <h3 translate>ACCOUNT.USER_DETAILS.TECHNICAL_DIVIDER</h3>\n\n <!-- profile -->\n <mat-form-field>\n <input matInput hidden readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PROFILE'|translate\"\n formControlName=\"mainProfile\" required>\n <span>{{'USER.PROFILE_ENUM.' + form.controls.mainProfile.value | translate}}</span>\n <mat-error *ngIf=\"form.controls.firstName.hasError('mainProfile') && form.controls.mainProfile.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- pubkey -->\n <mat-form-field>\n <input matInput readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PUBKEY'|translate\" formControlName=\"pubkey\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n\n </div>\n </mat-tab>\n\n <!-- TAB: settings -->\n <mat-tab label=\"{{'ACCOUNT.SETTINGS.TITLE'|translate}}\" formGroupName=\"settings\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"settings\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.SETTINGS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.SETTINGS.DESCRIPTION'|translate\"></p>\n\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.locale.hasError('required') && settingsForm?.controls.locale.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.' + item + '_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.latLongFormat.hasError('required') && settingsForm?.controls.latLongFormat.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n </div>\n\n <!-- Options table -->\n <div class=\"options-table\" [class.cdk-visually-hidden]=\"optionDefinitions | isEmptyArray\">\n <app-properties-table\n #propertiesTable\n i18nColumnPrefix=\"ACCOUNT.SETTINGS.OPTIONS.\"\n [definitions]=\"optionDefinitions\"\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-properties-table>\n </div>\n\n </mat-tab>\n\n <!-- TAB: tokens -->\n <mat-tab *ngIf=\"authTokenEnabled\" label=\"{{'ACCOUNT.TOKENS.TITLE'|translate}}\" formGroupName=\"tokens\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"ticket\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.TOKENS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n <p [innerHTML]=\"'ACCOUNT.TOKENS.DESCRIPTION'|translate\"></p>\n </div>\n\n <!-- Tokens table -->\n <div class=\"tokens-table\">\n <app-user-token-table\n #tokensTable\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-user-token-table>\n </div>\n\n </mat-tab>\n </mat-tab-group>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || !valid || saving\">\n <!-- error -->\n <ion-item *ngIf=\"error && !mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n", styles: ["mat-tab-group .mat-tab-body-content{padding:var(--ion-grid-padding);display:grid}form{width:100%}form mat-form-field{width:100%}div.options-table{height:calc(100vh - 380px)}div.tokens-table{height:calc(100vh - 250px)}\n"], dependencies: [{ kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.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: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i8.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i9.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i10.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: i11.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i13.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i14.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { kind: "directive", type: i14.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i14.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "directive", type: i15.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i16.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "component", type: i17.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i18.AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "tabindex", "autofocus", "clearable", "chipColor", "debug", "class"], outputs: ["keyup.enter"] }, { kind: "component", type: i19.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave", "showSaveAndClose", "showSaveAndNext"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: i20.AppPropertiesTable, selector: "app-properties-table", inputs: ["definitions", "showToolbar"] }, { kind: "component", type: i21.UserTokenTable, selector: "app-user-token-table", inputs: ["useSticky"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }, { kind: "pipe", type: i22.EmptyArrayPipe, name: "isEmptyArray" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
300
+ AccountPage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: AccountPage, selector: "app-account-page", viewQueries: [{ propertyName: "tabGroup", first: true, predicate: ["tabGroup"], descendants: true, static: true }, { propertyName: "propertiesTable", first: true, predicate: ["propertiesTable"], descendants: true, static: true }, { propertyName: "tokensTable", first: true, predicate: ["tokensTable"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<app-toolbar [title]=\"'ACCOUNT.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n [canGoBack]=\"false\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- loader -->\n <ion-spinner *ngIf=\"loading || saving; else endButtons\"></ion-spinner>\n\n <ng-template #endButtons>\n <!-- refresh button (if online) -->\n <ion-button [matTooltip]=\"'COMMON.BTN_REFRESH'|translate\"\n *ngIf=\"network.online\"\n (click)=\"refresh($event)\">\n <mat-icon slot=\"icon-only\">refresh</mat-icon>\n </ion-button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content>\n\n <!-- error -->\n <ion-item *ngIf=\"error && mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <form [formGroup]=\"form\" novalidate class=\"form-container\">\n\n <mat-tab-group #tabGroup [(selectedIndex)]=\"selectedTabIndex\" dynamicHeight>\n\n <!-- TAB: user details -->\n <mat-tab label=\"{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}\" class=\"ion-padding\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"person-circle\"></ion-icon>\n </mat-icon>\n <ion-label>{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}</ion-label>\n <ion-icon slot=\"end\" name=\"alert-circle\" color=\"danger\" *ngIf=\"submitted && form.invalid\"></ion-icon>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.USER_DETAILS.DESCRIPTION'|translate\"></p>\n\n <!--h1>Identit\u00E9</h1-->\n\n <!-- Email -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.EMAIL'|translate\"\n formControlName=\"email\" autocomplete=\"section-red email\">\n <mat-error *ngIf=\"form.controls.email.hasError('required') && form.controls.email.dirty\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.email.hasError('email') && form.controls.email.dirty\">\n <span>{{'ERROR.FIELD_NOT_VALID_EMAIL' | translate }}</span>\n </mat-error>\n </mat-form-field>\n\n <ion-grid *ngIf=\"email.notConfirmed\" class=\"ion-no-padding ion-padding-bottom\">\n <ion-row>\n <ion-col color=\"danger\">\n <ion-icon slot=\"start\" color=\"danger\" name=\"alert-circle\"></ion-icon>\n <ion-text [innerHTML]=\"'ACCOUNT.EMAIL_NOT_CONFIRMED_LABEL'|translate\"></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row style=\"height: 51px;\">\n <ion-col style=\"text-align: right;\">\n <ion-text>\n <small [innerHTML]=\"'ACCOUNT.EMAIL_NOT_RECEIVED_QUESTION'|translate\"></small>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"secondary\" *ngIf=\"!email.sending\" (click)=\"sendConfirmationEmail($event)\">\n {{'ACCOUNT.BTN_RESEND'|translate}}\n </ion-button>\n <ion-spinner class=\"ion-no-padding\" *ngIf=\"email.sending\"></ion-spinner>\n </ion-col>\n </ion-row>\n\n <ion-row *ngIf=\"email.error && !email.sending\">\n <ion-col>\n <span *ngIf=\"email.error && !email.sending\" [innerHTML]=\"email.error|translate\"></span>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Last name -->\n <mat-form-field>\n <input matInput [appAutofocus]=\"true\" [autofocusDelay]=\"500\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n formControlName=\"lastName\"\n autocomplete=\"section-blue family-name\"\n required>\n <mat-error *ngIf=\"form.controls.lastName.hasError('required') && form.controls.lastName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.lastName.hasError('minlength') && form.controls.lastName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n <!-- First name -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.FIRST_NAME'|translate\" formControlName=\"firstName\" autocomplete=\"section-blue given-name\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('required') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('minlength') && form.controls.firstName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n\n <!-- Additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\">\n <app-form-field [definition]=\"definition\"\n [formControlName]=\"definition.key\"\n [required]=\"definition.extra && definition.extra.account && definition.extra.account.required || false\">\n </app-form-field>\n </ng-container>\n\n <h3 translate>ACCOUNT.USER_DETAILS.TECHNICAL_DIVIDER</h3>\n\n <!-- profile -->\n <mat-form-field>\n <input matInput hidden readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PROFILE'|translate\"\n formControlName=\"mainProfile\" required>\n <span>{{'USER.PROFILE_ENUM.' + form.controls.mainProfile.value | translate}}</span>\n <mat-error *ngIf=\"form.controls.firstName.hasError('mainProfile') && form.controls.mainProfile.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- pubkey -->\n <mat-form-field>\n <input matInput readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PUBKEY'|translate\" formControlName=\"pubkey\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n\n </div>\n </mat-tab>\n\n <!-- TAB: settings -->\n <mat-tab label=\"{{'ACCOUNT.SETTINGS.TITLE'|translate}}\" formGroupName=\"settings\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"settings\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.SETTINGS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.SETTINGS.DESCRIPTION'|translate\"></p>\n\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.locale.hasError('required') && settingsForm?.controls.locale.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.' + item + '_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.latLongFormat.hasError('required') && settingsForm?.controls.latLongFormat.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n </div>\n\n <!-- Options table -->\n <div class=\"options-table\" [class.cdk-visually-hidden]=\"optionDefinitions | isEmptyArray\">\n <app-properties-table\n #propertiesTable\n i18nColumnPrefix=\"ACCOUNT.SETTINGS.OPTIONS.\"\n [definitions]=\"optionDefinitions\"\n [debug]=\"debug\"\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-properties-table>\n </div>\n\n </mat-tab>\n\n <!-- TAB: tokens -->\n <mat-tab *ngIf=\"authTokenEnabled\" label=\"{{'ACCOUNT.TOKENS.TITLE'|translate}}\" formGroupName=\"tokens\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"ticket\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.TOKENS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n <p [innerHTML]=\"'ACCOUNT.TOKENS.DESCRIPTION'|translate\"></p>\n </div>\n\n <!-- Tokens table -->\n <div class=\"tokens-table\">\n <app-user-token-table\n #tokensTable\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-user-token-table>\n </div>\n\n </mat-tab>\n </mat-tab-group>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || !valid || saving\">\n <!-- error -->\n <ion-item *ngIf=\"error && !mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n", styles: ["mat-tab-group .mat-tab-body-content{padding:var(--ion-grid-padding);display:grid}form{width:100%}form mat-form-field{width:100%}div.options-table{height:calc(100vh - 380px)}div.tokens-table{height:calc(100vh - 250px)}\n"], dependencies: [{ kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: i4.IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: i4.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: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFooter, selector: "ion-footer", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: i4.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: i4.IonItem, selector: "ion-item", inputs: ["button", "color", "counter", "counterFormatter", "detail", "detailIcon", "disabled", "download", "fill", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "shape", "target", "type"] }, { kind: "component", type: i4.IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "component", type: i4.IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i8.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i9.MatError, selector: "mat-error", inputs: ["id"] }, { kind: "component", type: i9.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i9.MatPrefix, selector: "[matPrefix]" }, { kind: "directive", type: i10.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: i11.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i12.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { kind: "component", type: i13.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { kind: "component", type: i14.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "disableRipple"], exportAs: ["matTabGroup"] }, { kind: "directive", type: i14.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i14.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "directive", type: i15.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i16.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "component", type: i17.ToolbarComponent, selector: "app-toolbar", inputs: ["progressBarMode", "title", "color", "class", "backHref", "defaultBackHref", "hasValidate", "hasClose", "hasSearch", "canGoBack", "canShowMenu"], outputs: ["onValidate", "onClose", "onValidateAndClose", "onBackClick", "onSearch"] }, { kind: "component", type: i18.AppFormField, selector: "app-form-field", inputs: ["definition", "required", "readonly", "disabled", "formControl", "formControlName", "placeholder", "compact", "floatLabel", "tabindex", "autofocus", "clearable", "chipColor", "debug", "class"], outputs: ["keyup.enter"] }, { kind: "component", type: i19.FormButtonsBarComponent, selector: "app-form-buttons-bar", inputs: ["disabled", "disabledCancel", "classList", "saveButtonColor", "backText", "cancelText", "nextText", "showBack", "showCancel", "showNext", "showSave", "showSaveAndClose", "showSaveAndNext"], outputs: ["onCancel", "onSave", "onNext", "onBack", "onSaveAndClose", "onSaveAndNext"] }, { kind: "component", type: i20.AppPropertiesTable, selector: "app-properties-table", inputs: ["definitions", "showToolbar", "debug"] }, { kind: "component", type: i21.UserTokenTable, selector: "app-user-token-table", inputs: ["useSticky"] }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }, { kind: "pipe", type: i22.EmptyArrayPipe, name: "isEmptyArray" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
302
301
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: AccountPage, decorators: [{
303
302
  type: Component,
304
- args: [{ selector: 'app-account-page', changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar [title]=\"'ACCOUNT.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n [canGoBack]=\"false\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- loader -->\n <ion-spinner *ngIf=\"loading || saving; else endButtons\"></ion-spinner>\n\n <ng-template #endButtons>\n <!-- refresh button (if online) -->\n <ion-button [matTooltip]=\"'COMMON.BTN_REFRESH'|translate\"\n *ngIf=\"network.online\"\n (click)=\"refresh($event)\">\n <mat-icon slot=\"icon-only\">refresh</mat-icon>\n </ion-button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content>\n\n <!-- error -->\n <ion-item *ngIf=\"error && mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <form [formGroup]=\"form\" novalidate class=\"form-container\">\n\n <mat-tab-group #tabGroup [(selectedIndex)]=\"selectedTabIndex\" dynamicHeight>\n\n <!-- TAB: user details -->\n <mat-tab label=\"{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}\" class=\"ion-padding\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"person-circle\"></ion-icon>\n </mat-icon>\n <ion-label>{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}</ion-label>\n <ion-icon slot=\"end\" name=\"alert-circle\" color=\"danger\" *ngIf=\"submitted && form.invalid\"></ion-icon>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.USER_DETAILS.DESCRIPTION'|translate\"></p>\n\n <!--h1>Identit\u00E9</h1-->\n\n <!-- Email -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.EMAIL'|translate\"\n formControlName=\"email\" autocomplete=\"section-red email\">\n <mat-error *ngIf=\"form.controls.email.hasError('required') && form.controls.email.dirty\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.email.hasError('email') && form.controls.email.dirty\">\n <span>{{'ERROR.FIELD_NOT_VALID_EMAIL' | translate }}</span>\n </mat-error>\n </mat-form-field>\n\n <ion-grid *ngIf=\"email.notConfirmed\" class=\"ion-no-padding ion-padding-bottom\">\n <ion-row>\n <ion-col color=\"danger\">\n <ion-icon slot=\"start\" color=\"danger\" name=\"alert-circle\" color=\"danger\"></ion-icon>\n <ion-text [innerHTML]=\"'ACCOUNT.EMAIL_NOT_CONFIRMED_LABEL'|translate\"></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row style=\"height: 51px;\">\n <ion-col style=\"text-align: right;\">\n <ion-text>\n <small [innerHTML]=\"'ACCOUNT.EMAIL_NOT_RECEIVED_QUESTION'|translate\"></small>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"secondary\" *ngIf=\"!email.sending\" (click)=\"sendConfirmationEmail($event)\">\n {{'ACCOUNT.BTN_RESEND'|translate}}\n </ion-button>\n <ion-spinner class=\"ion-no-padding\" *ngIf=\"email.sending\"></ion-spinner>\n </ion-col>\n </ion-row>\n\n <ion-row *ngIf=\"email.error && !email.sending\">\n <ion-col>\n <span *ngIf=\"email.error && !email.sending\" [innerHTML]=\"email.error|translate\"></span>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Last name -->\n <mat-form-field>\n <input matInput [appAutofocus]=\"true\" [autofocusDelay]=\"500\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n formControlName=\"lastName\"\n autocomplete=\"section-blue family-name\"\n required>\n <mat-error *ngIf=\"form.controls.lastName.hasError('required') && form.controls.lastName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.lastName.hasError('minlength') && form.controls.lastName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n <!-- First name -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.FIRST_NAME'|translate\" formControlName=\"firstName\" autocomplete=\"section-blue given-name\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('required') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('minlength') && form.controls.firstName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n\n <!-- Additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\">\n <app-form-field [definition]=\"definition\"\n [formControlName]=\"definition.key\"\n [required]=\"definition.extra && definition.extra.account && definition.extra.account.required || false\">\n </app-form-field>\n </ng-container>\n\n <h3 translate>ACCOUNT.USER_DETAILS.TECHNICAL_DIVIDER</h3>\n\n <!-- profile -->\n <mat-form-field>\n <input matInput hidden readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PROFILE'|translate\"\n formControlName=\"mainProfile\" required>\n <span>{{'USER.PROFILE_ENUM.' + form.controls.mainProfile.value | translate}}</span>\n <mat-error *ngIf=\"form.controls.firstName.hasError('mainProfile') && form.controls.mainProfile.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- pubkey -->\n <mat-form-field>\n <input matInput readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PUBKEY'|translate\" formControlName=\"pubkey\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n\n </div>\n </mat-tab>\n\n <!-- TAB: settings -->\n <mat-tab label=\"{{'ACCOUNT.SETTINGS.TITLE'|translate}}\" formGroupName=\"settings\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"settings\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.SETTINGS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.SETTINGS.DESCRIPTION'|translate\"></p>\n\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.locale.hasError('required') && settingsForm?.controls.locale.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.' + item + '_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.latLongFormat.hasError('required') && settingsForm?.controls.latLongFormat.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n </div>\n\n <!-- Options table -->\n <div class=\"options-table\" [class.cdk-visually-hidden]=\"optionDefinitions | isEmptyArray\">\n <app-properties-table\n #propertiesTable\n i18nColumnPrefix=\"ACCOUNT.SETTINGS.OPTIONS.\"\n [definitions]=\"optionDefinitions\"\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-properties-table>\n </div>\n\n </mat-tab>\n\n <!-- TAB: tokens -->\n <mat-tab *ngIf=\"authTokenEnabled\" label=\"{{'ACCOUNT.TOKENS.TITLE'|translate}}\" formGroupName=\"tokens\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"ticket\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.TOKENS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n <p [innerHTML]=\"'ACCOUNT.TOKENS.DESCRIPTION'|translate\"></p>\n </div>\n\n <!-- Tokens table -->\n <div class=\"tokens-table\">\n <app-user-token-table\n #tokensTable\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-user-token-table>\n </div>\n\n </mat-tab>\n </mat-tab-group>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || !valid || saving\">\n <!-- error -->\n <ion-item *ngIf=\"error && !mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n", styles: ["mat-tab-group .mat-tab-body-content{padding:var(--ion-grid-padding);display:grid}form{width:100%}form mat-form-field{width:100%}div.options-table{height:calc(100vh - 380px)}div.tokens-table{height:calc(100vh - 250px)}\n"] }]
303
+ args: [{ selector: 'app-account-page', changeDetection: ChangeDetectionStrategy.OnPush, template: "<app-toolbar [title]=\"'ACCOUNT.TITLE'|translate\" color=\"primary\"\n [hasValidate]=\"dirty && !saving\"\n [hasClose]=\"!dirty && !saving\"\n (onValidate)=\"save($event)\"\n [canGoBack]=\"false\"\n (onClose)=\"close($event)\">\n\n <ion-buttons slot=\"end\">\n <!-- loader -->\n <ion-spinner *ngIf=\"loading || saving; else endButtons\"></ion-spinner>\n\n <ng-template #endButtons>\n <!-- refresh button (if online) -->\n <ion-button [matTooltip]=\"'COMMON.BTN_REFRESH'|translate\"\n *ngIf=\"network.online\"\n (click)=\"refresh($event)\">\n <mat-icon slot=\"icon-only\">refresh</mat-icon>\n </ion-button>\n </ng-template>\n </ion-buttons>\n</app-toolbar>\n\n<ion-content>\n\n <!-- error -->\n <ion-item *ngIf=\"error && mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n\n <form [formGroup]=\"form\" novalidate class=\"form-container\">\n\n <mat-tab-group #tabGroup [(selectedIndex)]=\"selectedTabIndex\" dynamicHeight>\n\n <!-- TAB: user details -->\n <mat-tab label=\"{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}\" class=\"ion-padding\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"person-circle\"></ion-icon>\n </mat-icon>\n <ion-label>{{'ACCOUNT.USER_DETAILS.TITLE'|translate}}</ion-label>\n <ion-icon slot=\"end\" name=\"alert-circle\" color=\"danger\" *ngIf=\"submitted && form.invalid\"></ion-icon>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.USER_DETAILS.DESCRIPTION'|translate\"></p>\n\n <!--h1>Identit\u00E9</h1-->\n\n <!-- Email -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.EMAIL'|translate\"\n formControlName=\"email\" autocomplete=\"section-red email\">\n <mat-error *ngIf=\"form.controls.email.hasError('required') && form.controls.email.dirty\" translate>ERROR.FIELD_REQUIRED</mat-error>\n <mat-error *ngIf=\"form.controls.email.hasError('email') && form.controls.email.dirty\">\n <span>{{'ERROR.FIELD_NOT_VALID_EMAIL' | translate }}</span>\n </mat-error>\n </mat-form-field>\n\n <ion-grid *ngIf=\"email.notConfirmed\" class=\"ion-no-padding ion-padding-bottom\">\n <ion-row>\n <ion-col color=\"danger\">\n <ion-icon slot=\"start\" color=\"danger\" name=\"alert-circle\"></ion-icon>\n <ion-text [innerHTML]=\"'ACCOUNT.EMAIL_NOT_CONFIRMED_LABEL'|translate\"></ion-text>\n </ion-col>\n </ion-row>\n\n <ion-row style=\"height: 51px;\">\n <ion-col style=\"text-align: right;\">\n <ion-text>\n <small [innerHTML]=\"'ACCOUNT.EMAIL_NOT_RECEIVED_QUESTION'|translate\"></small>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ion-button fill=\"solid\" color=\"secondary\" *ngIf=\"!email.sending\" (click)=\"sendConfirmationEmail($event)\">\n {{'ACCOUNT.BTN_RESEND'|translate}}\n </ion-button>\n <ion-spinner class=\"ion-no-padding\" *ngIf=\"email.sending\"></ion-spinner>\n </ion-col>\n </ion-row>\n\n <ion-row *ngIf=\"email.error && !email.sending\">\n <ion-col>\n <span *ngIf=\"email.error && !email.sending\" [innerHTML]=\"email.error|translate\"></span>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n <!-- Last name -->\n <mat-form-field>\n <input matInput [appAutofocus]=\"true\" [autofocusDelay]=\"500\" [placeholder]=\"'USER.LAST_NAME'|translate\"\n formControlName=\"lastName\"\n autocomplete=\"section-blue family-name\"\n required>\n <mat-error *ngIf=\"form.controls.lastName.hasError('required') && form.controls.lastName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.lastName.hasError('minlength') && form.controls.lastName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n <!-- First name -->\n <mat-form-field>\n <input matInput [placeholder]=\"'USER.FIRST_NAME'|translate\" formControlName=\"firstName\" autocomplete=\"section-blue given-name\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('required') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('minlength') && form.controls.firstName.dirty\">\n <span>{{'ERROR.FIELD_MIN_LENGTH' | translate: {minLength: 2} }}</span>\n </mat-error>\n </mat-form-field>\n\n\n <!-- Additional fields -->\n <ng-container *ngFor=\"let definition of additionalFields\">\n <app-form-field [definition]=\"definition\"\n [formControlName]=\"definition.key\"\n [required]=\"definition.extra && definition.extra.account && definition.extra.account.required || false\">\n </app-form-field>\n </ng-container>\n\n <h3 translate>ACCOUNT.USER_DETAILS.TECHNICAL_DIVIDER</h3>\n\n <!-- profile -->\n <mat-form-field>\n <input matInput hidden readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PROFILE'|translate\"\n formControlName=\"mainProfile\" required>\n <span>{{'USER.PROFILE_ENUM.' + form.controls.mainProfile.value | translate}}</span>\n <mat-error *ngIf=\"form.controls.firstName.hasError('mainProfile') && form.controls.mainProfile.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- pubkey -->\n <mat-form-field>\n <input matInput readonly=\"true\" [placeholder]=\"'ACCOUNT.USER_DETAILS.PUBKEY'|translate\" formControlName=\"pubkey\"\n required>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.firstName.hasError('pubkey') && form.controls.firstName.dirty\">\n <span translate>ERROR.FIELD_NOT_VALID_PUBKEY</span>\n </mat-error>\n </mat-form-field>\n\n </div>\n </mat-tab>\n\n <!-- TAB: settings -->\n <mat-tab label=\"{{'ACCOUNT.SETTINGS.TITLE'|translate}}\" formGroupName=\"settings\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"settings\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.SETTINGS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n\n <p [innerHTML]=\"'ACCOUNT.SETTINGS.DESCRIPTION'|translate\"></p>\n\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LOCALE'|translate\" formControlName=\"locale\" required>\n <mat-option *ngFor=\"let item of locales\" [value]=\"item.key\">\n {{item.value}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.locale.hasError('required') && settingsForm?.controls.locale.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n <!-- lat/long format-->\n <mat-form-field>\n <mat-select [placeholder]=\"'ACCOUNT.SETTINGS.LAT_LONG_FORMAT'|translate\" formControlName=\"latLongFormat\"\n required>\n <mat-option *ngFor=\"let item of latLongFormats\" [value]=\"item\">\n {{'COMMON.LAT_LONG.' + item + '_PLACEHOLDER'|translate}}\n </mat-option>\n </mat-select>\n <mat-error *ngIf=\"settingsForm?.controls.latLongFormat.hasError('required') && settingsForm?.controls.latLongFormat.dirty\"\n translate>ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-form-field>\n\n </div>\n\n <!-- Options table -->\n <div class=\"options-table\" [class.cdk-visually-hidden]=\"optionDefinitions | isEmptyArray\">\n <app-properties-table\n #propertiesTable\n i18nColumnPrefix=\"ACCOUNT.SETTINGS.OPTIONS.\"\n [definitions]=\"optionDefinitions\"\n [debug]=\"debug\"\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-properties-table>\n </div>\n\n </mat-tab>\n\n <!-- TAB: tokens -->\n <mat-tab *ngIf=\"authTokenEnabled\" label=\"{{'ACCOUNT.TOKENS.TITLE'|translate}}\" formGroupName=\"tokens\">\n <ng-template mat-tab-label>\n <mat-icon>\n <ion-icon matPrefix slot=\"start\" name=\"ticket\"></ion-icon>\n </mat-icon>\n <ion-label translate>ACCOUNT.TOKENS.TITLE</ion-label>\n </ng-template>\n\n <div class=\"ion-padding\">\n <p [innerHTML]=\"'ACCOUNT.TOKENS.DESCRIPTION'|translate\"></p>\n </div>\n\n <!-- Tokens table -->\n <div class=\"tokens-table\">\n <app-user-token-table\n #tokensTable\n [canEdit]=\"true\"\n (onDirty)=\"$event ? markAsDirty() : undefined\"\n ></app-user-token-table>\n </div>\n\n </mat-tab>\n </mat-tab-group>\n\n\n </form>\n</ion-content>\n\n<ion-footer hidden-xs hidden-sm hidden-mobile>\n <app-form-buttons-bar (onCancel)=\"cancel()\" (onSave)=\"save($event)\" [disabled]=\"!form.dirty || !valid || saving\">\n <!-- error -->\n <ion-item *ngIf=\"error && !mobile\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" class=\"error\" [innerHTML]=\"error|translate\"></ion-label>\n </ion-item>\n </app-form-buttons-bar>\n</ion-footer>\n", styles: ["mat-tab-group .mat-tab-body-content{padding:var(--ion-grid-padding);display:grid}form{width:100%}form mat-form-field{width:100%}div.options-table{height:calc(100vh - 380px)}div.tokens-table{height:calc(100vh - 250px)}\n"] }]
305
304
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i1.UntypedFormBuilder }, { type: i2.AccountService }, { type: i3.NetworkService }, { type: i4.NavController }, { type: i5.AccountValidatorService }, { type: i6.ConfigService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
306
305
  type: Inject,
307
306
  args: [APP_LOCALES]
@@ -315,4 +314,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
315
314
  type: ViewChild,
316
315
  args: ['tokensTable', { static: true }]
317
316
  }] } });
318
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudC5wYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2FjY291bnQvYWNjb3VudC5wYWdlLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2FjY291bnQvYWNjb3VudC5wYWdlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLHVCQUF1QixFQUFxQixTQUFTLEVBQUUsTUFBTSxFQUErQixTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDcEksT0FBTyxFQUFDLGFBQWEsRUFBZSxNQUFNLE1BQU0sQ0FBQztBQUVqRCxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0saUNBQWlDLENBQUM7QUFDeEQsT0FBTyxFQUF1QyxVQUFVLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRixPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDM0MsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBRWhELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLDZDQUE2QyxDQUFDO0FBQzlFLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUN2RCxPQUFPLEVBQUMsV0FBVyxFQUE4QixNQUFNLGtDQUFrQyxDQUFDO0FBSTFGLE9BQU8sRUFBQyxNQUFNLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFHM0MsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkUsT0FBTyxFQUFxQixjQUFjLEVBQUMsTUFBTSxxQ0FBcUMsQ0FBQztBQUV2RixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVVoRCxNQUFNLE9BQU8sV0FBWSxTQUFRLE9BQWdCO0lBb0MvQyxZQUNFLFFBQWtCLEVBQ1gsV0FBK0IsRUFDL0Is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clJlZiwgQ29tcG9uZW50LCBJbmplY3QsIEluamVjdG9yLCBPbkRlc3Ryb3ksIE9uSW5pdCwgVmlld0NoaWxkfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Y29tYmluZUxhdGVzdCwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7QWNjb3VudFNlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2VzL2FjY291bnQuc2VydmljZSc7XG5pbXBvcnQge0FjY291bnR9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsL2FjY291bnQubW9kZWwnO1xuaW1wb3J0IHtVbnR5cGVkRm9ybUJ1aWxkZXIsIFVudHlwZWRGb3JtR3JvdXAsIFZhbGlkYXRvcnN9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7QWNjb3VudFZhbGlkYXRvclNlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2VzL3ZhbGlkYXRvci9hY2NvdW50LnZhbGlkYXRvcic7XG5pbXBvcnQge0FwcEZvcm19IGZyb20gJy4uL2Zvcm0vZm9ybS5jbGFzcyc7XG5pbXBvcnQge0FwcEZvcm1VdGlsc30gZnJvbSAnLi4vZm9ybS9mb3JtLnV0aWxzJztcbmltcG9ydCB7Rm9ybUZpZWxkRGVmaW5pdGlvbn0gZnJvbSAnLi4vLi4vc2hhcmVkL2Zvcm0vZmllbGQubW9kZWwnO1xuaW1wb3J0IHtMQVRfTE9OR19QQVRURVJOU30gZnJvbSAnLi4vLi4vc2hhcmVkL21hdGVyaWFsL2xhdGxvbmcvbGF0bG9uZy51dGlscyc7XG5pbXBvcnQge1N0YXR1c0lkc30gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvbW9kZWwuZW51bSc7XG5pbXBvcnQge0FQUF9MT0NBTEVTLCBMb2NhbGVDb25maWcsIExvY2FsU2V0dGluZ3N9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsL3NldHRpbmdzLm1vZGVsJztcbmltcG9ydCB7Um91dGVyfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtDYW5MZWF2ZX0gZnJvbSAnLi4vLi4vc2hhcmVkL2d1YXJkL2NvbXBvbmVudC1kaXJ0eS5ndWFyZCc7XG5pbXBvcnQge05ldHdvcmtTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlcy9uZXR3b3JrLnNlcnZpY2UnO1xuaW1wb3J0IHtmaWx0ZXIsIG1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtNYXRUYWJHcm91cH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFicyc7XG5pbXBvcnQge0NvbmZpZ1NlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2VzL2NvbmZpZy5zZXJ2aWNlJztcbmltcG9ydCB7Q09SRV9DT05GSUdfT1BUSU9OU30gZnJvbSAnLi4vc2VydmljZXMvY29uZmlnL2NvcmUuY29uZmlnJztcbmltcG9ydCB7QXBwUHJvcGVydGllc1RhYmxlLCBQcm9wZXJ0eUVudGl0eX0gZnJvbSAnLi4vZm9ybS9wcm9wZXJ0aWVzL3Byb3BlcnRpZXMudGFibGUnO1xuaW1wb3J0IHtQcm9wZXJ0aWVzTWFwfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHtpc05vdE5pbH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQge1VzZXJUb2tlblRhYmxlfSBmcm9tICcuL3Rva2VuLnRhYmxlJztcbmltcG9ydCB7TmF2Q29udHJvbGxlcn0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtYWNjb3VudC1wYWdlJyxcbiAgdGVtcGxhdGVVcmw6ICdhY2NvdW50LnBhZ2UuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2FjY291bnQucGFnZS5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIEFjY291bnRQYWdlIGV4dGVuZHMgQXBwRm9ybTxBY2NvdW50PiBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBDYW5MZWF2ZSB7XG4gIEBWaWV3Q2hpbGQoJ3RhYkdyb3VwJywge3N0YXRpYzogdHJ1ZX0pIHRhYkdyb3VwOiBNYXRUYWJHcm91cDtcbiAgQFZpZXdDaGlsZCgncHJvcGVydGllc1RhYmxlJywge3N0YXRpYzogdHJ1ZX0pIHByb3BlcnRpZXNUYWJsZTogQXBwUHJvcGVydGllc1RhYmxlO1xuICBAVmlld0NoaWxkKCd0b2tlbnNUYWJsZScsIHtzdGF0aWM6IHRydWV9KSB0b2tlbnNUYWJsZTogVXNlclRva2VuVGFibGU7XG5cbiAgc2VsZWN0ZWRUYWJJbmRleCA9IDA7XG4gIGlzTG9naW46IGJvb2xlYW47XG4gIGNoYW5nZXNTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgbmV0d29ya1N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBlbWFpbDogYW55ID0ge1xuICAgIGNvbmZpcm1lZDogZmFsc2UsXG4gICAgbm90Q29uZmlybWVkOiBmYWxzZSxcbiAgICBzZW5kaW5nOiBmYWxzZSxcbiAgICBlcnJvcjogdW5kZWZpbmVkXG4gIH07XG4gIGFkZGl0aW9uYWxGaWVsZHM6IEZvcm1GaWVsZERlZmluaXRpb25bXTtcbiAgb3B0aW9uRGVmaW5pdGlvbnM6IEZvcm1GaWVsZERlZmluaXRpb25bXTtcblxuICBnZXQgc2V0dGluZ3NGb3JtKCk6IFVudHlwZWRGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZvcm0uZ2V0KCdzZXR0aW5ncycpIGFzIFVudHlwZWRGb3JtR3JvdXA7XG4gIH1cblxuICAvLyBzZXR0aW5nc0NvbnRlbnRGb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xuICBsb2NhbGVzOiBMb2NhbGVDb25maWdbXTtcbiAgbGF0TG9uZ0Zvcm1hdHMgPSBMQVRfTE9OR19QQVRURVJOUztcbiAgc2F2aW5nID0gZmFsc2U7XG4gIHN1Ym1pdHRlZCA9IGZhbHNlO1xuICBhY2NvdW50UmVhZE9ubHkgPSBmYWxzZTtcbiAgcmVhZG9ubHkgbW9iaWxlOiBib29sZWFuO1xuXG4gIGdldCB2YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gc3VwZXIudmFsaWQgJiYgKHRoaXMucHJvcGVydGllc1RhYmxlPy52YWxpZCB8fCB0cnVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhdXRoVG9rZW5FbmFibGVkID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHB1YmxpYyBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgIHB1YmxpYyBhY2NvdW50U2VydmljZTogQWNjb3VudFNlcnZpY2UsXG4gICAgcHVibGljIG5ldHdvcms6IE5ldHdvcmtTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBuYXZDb250cm9sbGVyOiBOYXZDb250cm9sbGVyLFxuICAgIHByb3RlY3RlZCB2YWxpZGF0b3JTZXJ2aWNlOiBBY2NvdW50VmFsaWRhdG9yU2VydmljZSxcbiAgICAvLyBwcm90ZWN0ZWQgc2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlOiBVc2VyU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjb25maWdTZXJ2aWNlOiBDb25maWdTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQEluamVjdChBUFBfTE9DQUxFUykgbG9jYWxlc1xuICApIHtcbiAgICBzdXBlcihpbmplY3RvciwgdmFsaWRhdG9yU2VydmljZS5nZXRGb3JtR3JvdXAoYWNjb3VudFNlcnZpY2UuYWNjb3VudCkpO1xuXG4gICAgdGhpcy5sb2NhbGVzID0gbG9jYWxlcztcblxuICAgIC8vIEFkZCBzZXR0aW5ncyBmbyBmb3JtXG4gICAgLy8gdGhpcy5zZXR0aW5nc0Zvcm0gPSBzZXR0aW5nc1ZhbGlkYXRvclNlcnZpY2UuZ2V0Rm9ybUdyb3VwKGFjY291bnRTZXJ2aWNlLmFjY291bnQgJiYgYWNjb3VudFNlcnZpY2UuYWNjb3VudC5zZXR0aW5ncyk7XG4gICAgLy8gdGhpcy5zZXR0aW5nc0NvbnRlbnRGb3JtID0gKHRoaXMuc2V0dGluZ3NGb3JtLmNvbnRyb2xzWydjb250ZW50J10gYXMgVW50eXBlZEZvcm1Hcm91cCk7XG4gICAgLy8gdGhpcy5mb3JtLmFkZENvbnRyb2woJ3NldHRpbmdzJywgdGhpcy5zZXR0aW5nc0Zvcm0pO1xuXG4gICAgdGhpcy5tb2JpbGUgPSB0aGlzLnNldHRpbmdzLm1vYmlsZTtcblxuICAgIC8vIEJ5IGRlZmF1bHQsIGRpc2FibGUgdGhlIGZvcm1cbiAgICB0aGlzLmRpc2FibGUoKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHN1cGVyLm5nT25Jbml0KCk7XG5cbiAgICAvLyBHZXQgdXNlciBvcHRpb25zXG4gICAgdGhpcy5vcHRpb25EZWZpbml0aW9ucyA9IHRoaXMuYWNjb3VudFNlcnZpY2Uub3B0aW9uRGVmcy5zbGljZSgpXG4gICAgICAuZmlsdGVyKGRlZmluaXRpb24gPT4gIWRlZmluaXRpb24ubWluUHJvZmlsZSB8fCB0aGlzLmFjY291bnRTZXJ2aWNlLmhhc01pblByb2ZpbGUoZGVmaW5pdGlvbi5taW5Qcm9maWxlKSk7XG5cbiAgICAvLyBPYnNlcnZlZCBzb21lIGV2ZW50c1xuICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24odGhpcy5hY2NvdW50U2VydmljZS5vbkxvZ2luLnBpcGUoZmlsdGVyKCgpID0+ICF0aGlzLnNhdmluZykpLnN1YnNjcmliZShhY2NvdW50ID0+IHRoaXMub25Mb2dpbihhY2NvdW50KSkpO1xuICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24odGhpcy5hY2NvdW50U2VydmljZS5vbkxvZ291dC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5vbkxvZ291dCgpKSk7XG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbih0aGlzLm9uQ2FuY2VsLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnNldFZhbHVlKHRoaXMuYWNjb3VudFNlcnZpY2UuYWNjb3VudCk7XG4gICAgICB0aGlzLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgfSkpO1xuXG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbih0aGlzLmFjY291bnRTZXJ2aWNlLiRhZGRpdGlvbmFsRmllbGRzXG4gICAgICAuc3Vic2NyaWJlKChhZGRpdGlvbmFsRmllbGRzKSA9PiB7XG4gICAgICAgIHRoaXMuYWRkaXRpb25hbEZpZWxkcyA9IGFkZGl0aW9uYWxGaWVsZHMuc2xpY2UoKTsgLy8gQ29weVxuICAgICAgICBpZiAodGhpcy5hY2NvdW50U2VydmljZS5pc0xvZ2luKCkpIHtcbiAgICAgICAgICB0aGlzLm9uTG9naW4odGhpcy5hY2NvdW50U2VydmljZS5hY2NvdW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm1hcmtBc0xvYWRlZCgpO1xuICAgICAgICB9XG4gICAgICB9KSk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKFxuICAgICAgdGhpcy5jb25maWdTZXJ2aWNlLmNvbmZpZy5zdWJzY3JpYmUodmFsdWUgPT4ge1xuICAgICAgICB0aGlzLmFjY291bnRSZWFkT25seSA9IHZhbHVlLmdldFByb3BlcnR5QXNCb29sZWFuKENPUkVfQ09ORklHX09QVElPTlMuQUNDT1VOVF9SRUFET05MWSk7XG4gICAgICAgIHRoaXMuYXV0aFRva2VuRW5hYmxlZCA9IHZhbHVlLmdldFByb3BlcnR5QXNCb29sZWFuKENPUkVfQ09ORklHX09QVElPTlMuQVVUSF9UT0tFTl9FTkFCTEVEKTtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIC8vIFJlYWxpZ24gdGFiLCBhZnRlciBhIGRlbGF5IGJlY2F1c2UgdGhlIHRhYiBjYW4gYmUgZGlzYWJsZWQgd2hlbiBjb21wb25lbnQgaXMgY3JlYXRlZFxuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50YWJHcm91cC5yZWFsaWduSW5rQmFyKCksIDUwMCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xuICAgIHRoaXMuc3RvcExpc3RlbkNoYW5nZXMoKTtcbiAgICB0aGlzLm5ldHdvcmtTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBvbkxvZ2luKGFjY291bnQ6IEFjY291bnQpIHtcbiAgICBjb25zb2xlLmRlYnVnKCdbYWNjb3VudF0gTG9nZ2VkIGFjY291bnQ6ICcsIGFjY291bnQpO1xuICAgIHRoaXMuaXNMb2dpbiA9IHRydWU7XG5cbiAgICB0aGlzLnNldFZhbHVlKGFjY291bnQpO1xuXG4gICAgdGhpcy5lbWFpbC5jb25maXJtZWQgPSBhY2NvdW50ICYmIGFjY291bnQuZW1haWwgJiYgKGFjY291bnQuc3RhdHVzSWQgIT09IFN0YXR1c0lkcy5URU1QT1JBUlkpO1xuICAgIHRoaXMuZW1haWwubm90Q29uZmlybWVkID0gYWNjb3VudCAmJiBhY2NvdW50LmVtYWlsICYmICghYWNjb3VudC5zdGF0dXNJZCB8fCBhY2NvdW50LnN0YXR1c0lkID09PSBTdGF0dXNJZHMuVEVNUE9SQVJZKTtcblxuICAgIHRoaXMubmV0d29ya1N1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLm5ldHdvcmtTdWJzY3JpcHRpb24gPWNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy5jb25maWdTZXJ2aWNlLmNvbmZpZyxcbiAgICAgIHRoaXMubmV0d29yay5vbk5ldHdvcmtTdGF0dXNDaGFuZ2VzXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIG1hcChjb25uZWN0aW9uVHlwZSA9PiBjb25uZWN0aW9uVHlwZSAhPT0gJ25vbmUnKSxcbiAgICAgICAgKVxuICAgIF0pLnN1YnNjcmliZSgoW2NvbmZpZywgb25saW5lXSkgPT4ge1xuICAgICAgaWYgKG9ubGluZSkge1xuICAgICAgICBjb25zdCBhY2NvdW50UmVhZE9ubHkgPSBjb25maWcuZ2V0UHJvcGVydHlBc0Jvb2xlYW4oQ09SRV9DT05GSUdfT1BUSU9OUy5BQ0NPVU5UX1JFQURPTkxZKTtcbiAgICAgICAgdGhpcy5lbmFibGUoeyBhY2NvdW50UmVhZE9ubHkgfSk7XG4gICAgICAgIHRoaXMubWFya0FzUHJpc3RpbmUoKTtcbiAgICAgICAgdGhpcy5zdGFydExpc3RlbkNoYW5nZXMoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGlzYWJsZSgpO1xuICAgICAgICB0aGlzLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICAgIHRoaXMuc3RvcExpc3RlbkNoYW5nZXMoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWFya0FzTG9hZGVkKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgb25Mb2dvdXQoKSB7XG4gICAgdGhpcy5pc0xvZ2luID0gZmFsc2U7XG4gICAgdGhpcy5lbWFpbC5jb25maXJtZWQgPSBmYWxzZTtcbiAgICB0aGlzLmVtYWlsLm5vdENvbmZpcm1lZCA9IGZhbHNlO1xuICAgIHRoaXMuZW1haWwuc2VuZGluZyA9IGZhbHNlO1xuICAgIHRoaXMuZW1haWwuZXJyb3IgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5mb3JtLnJlc2V0KCk7XG4gICAgdGhpcy5kaXNhYmxlKCk7XG5cbiAgICB0aGlzLm5ldHdvcmtTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG5cbiAgICB0aGlzLnN0b3BMaXN0ZW5DaGFuZ2VzKCk7XG5cbiAgICAvLyBCYWNrIHRvIGhvbWVcbiAgICB0aGlzLm5hdkNvbnRyb2xsZXIubmF2aWdhdGVSb290KCcvJyk7XG5cbiAgfVxuXG4gIGFzeW5jIHNldFZhbHVlKGRhdGE6IEFjY291bnQsIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW47IG9ubHlTZWxmPzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgc3VwZXIuc2V0VmFsdWUoZGF0YSwgb3B0cyk7XG5cbiAgICAvLyBTZXQgb3B0aW9uc1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPSBkYXRhPy5zZXR0aW5ncz8uYXNMb2NhbFNldHRpbmdzKCk/LnByb3BlcnRpZXMgfHwge307XG4gICAgY29uc3QgcHJvcGVydGllc0VudGl0aWVzOiBQcm9wZXJ0eUVudGl0eVtdID0gW107XG4gICAgdGhpcy5vcHRpb25EZWZpbml0aW9uc1xuICAgICAgLmZpbHRlcihkZWZpbml0aW9uID0+ICFkZWZpbml0aW9uLm1pblByb2ZpbGUgfHwgdGhpcy5hY2NvdW50U2VydmljZS5oYXNNaW5Qcm9maWxlKGRlZmluaXRpb24ubWluUHJvZmlsZSkpXG4gICAgICAubWFwKGRlZmluaXRpb24gPT4gZGVmaW5pdGlvbi5rZXkpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmIChpc05vdE5pbChwcm9wZXJ0aWVzW2tleV0pKSB7XG4gICAgICAgIHByb3BlcnRpZXNFbnRpdGllcy5wdXNoKFByb3BlcnR5RW50aXR5LmZyb21PYmplY3Qoe2lkOiBrZXksIHZhbHVlOiBwcm9wZXJ0aWVzW2tleV19KSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5wcm9wZXJ0aWVzVGFibGUpIHtcbiAgICAgIGF3YWl0IHRoaXMucHJvcGVydGllc1RhYmxlLnJlYWR5KCk7XG4gICAgICB0aGlzLnByb3BlcnRpZXNUYWJsZS52YWx1ZSA9IHByb3BlcnRpZXNFbnRpdGllcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy50b2tlbnNUYWJsZSkge1xuICAgICAgYXdhaXQgdGhpcy50b2tlbnNUYWJsZS5yZWFkeSgpO1xuICAgICAgdGhpcy50b2tlbnNUYWJsZS52YWx1ZSA9IGRhdGEudG9rZW5zO1xuICAgIH1cblxuICB9XG5cbiAgYXN5bmMgcmVmcmVzaChldmVudD86IEV2ZW50KSB7XG5cbiAgICB0aGlzLmRpc2FibGUoKTtcbiAgICB0aGlzLm1hcmtBc0xvYWRpbmcoKTtcblxuICAgIHJldHVybiB0aGlzLmFjY291bnRTZXJ2aWNlLnJlbG9hZCgpO1xuICB9XG5cbiAgc3RhcnRMaXN0ZW5DaGFuZ2VzKCkge1xuICAgIGlmICh0aGlzLmNoYW5nZXNTdWJzY3JpcHRpb24pIHJldHVybjsgLy8gYWxyZWFkeSBzdGFydGVkXG4gICAgdGhpcy5jaGFuZ2VzU3Vic2NyaXB0aW9uID0gdGhpcy5hY2NvdW50U2VydmljZS5saXN0ZW5DaGFuZ2VzKCk7XG4gIH1cblxuICBzdG9wTGlzdGVuQ2hhbmdlcygpIHtcbiAgICBpZiAoIXRoaXMuY2hhbmdlc1N1YnNjcmlwdGlvbikgcmV0dXJuO1xuICAgIHRoaXMuY2hhbmdlc1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuY2hhbmdlc1N1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGFzeW5jIHNlbmRDb25maXJtYXRpb25FbWFpbChldmVudDogTW91c2VFdmVudCkge1xuICAgIGNvbnN0IGpzb24gPSB0aGlzLmZvcm0udmFsdWU7XG4gICAganNvbi5lbWFpbCA9IHRoaXMuZm9ybS5jb250cm9sc1snZW1haWwnXS52YWx1ZTtcbiAgICBpZiAoIWpzb24uZW1haWwgfHwgIXRoaXMuZW1haWwubm90Q29uZmlybWVkKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHRoaXMuZW1haWwuc2VuZGluZyA9IHRydWU7XG4gICAgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIFNlbmRpbmcgY29uZmlybWF0aW9uIGVtYWlsLi4uJyk7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuYWNjb3VudFNlcnZpY2Uuc2VuZENvbmZpcm1hdGlvbkVtYWlsKFxuICAgICAgICBqc29uLmVtYWlsLFxuICAgICAgICBqc29uLnNldHRpbmdzICYmIGpzb24uc2V0dGluZ3MubG9jYWxlIHx8IHRoaXMudHJhbnNsYXRlLmN1cnJlbnRMYW5nXG4gICAgICApO1xuICAgICAgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIENvbmZpcm1hdGlvbiBlbWFpbCBzZW50LicpO1xuICAgICAgdGhpcy5lbWFpbC5zZW5kaW5nID0gZmFsc2U7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmVtYWlsLnNlbmRpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuZW1haWwuZXJyb3IgPSBlcnIgJiYgZXJyLm1lc3NhZ2UgfHwgZXJyO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNhdmUoZXZlbnQpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAodGhpcy5zYXZpbmcpIHJldHVybiBmYWxzZTtcblxuICAgIGlmICghdGhpcy5mb3JtLnZhbGlkKSB7XG4gICAgICBhd2FpdCBBcHBGb3JtVXRpbHMud2FpdFdoaWxlUGVuZGluZyh0aGlzLmZvcm0pO1xuXG4gICAgICBpZiAodGhpcy5mb3JtLmludmFsaWQpIHtcbiAgICAgICAgQXBwRm9ybVV0aWxzLmxvZ0Zvcm1FcnJvcnModGhpcy5mb3JtKTtcbiAgICAgICAgdGhpcy5mb3JtLm1hcmtBbGxBc1RvdWNoZWQoKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc3VibWl0dGVkID0gdHJ1ZTtcbiAgICB0aGlzLnNhdmluZyA9IHRydWU7XG4gICAgdGhpcy5lcnJvciA9IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IG5ld0FjY291bnQgPSBBY2NvdW50LmZyb21PYmplY3Qoe1xuICAgICAgLi4uKHRoaXMuYWNjb3VudFNlcnZpY2UuYWNjb3VudC5hc09iamVjdCgpKSxcbiAgICAgIC4uLih0aGlzLmZvcm0udmFsdWUpXG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5wcm9wZXJ0aWVzVGFibGUpIHtcbiAgICAgIC8vIG1lcmdlIHByb3BlcnRpZXNcbiAgICAgIGF3YWl0IHRoaXMucHJvcGVydGllc1RhYmxlLnNhdmUoKTtcbiAgICAgIGNvbnN0IHByb3BlcnR5RW50aXRpZXMgPSB0aGlzLnByb3BlcnRpZXNUYWJsZS52YWx1ZSB8fCBbXTtcbiAgICAgIGNvbnN0IHByb3BlcnRpZXM6IFByb3BlcnRpZXNNYXAgPSBwcm9wZXJ0eUVudGl0aWVzLnJlZHVjZSgocmVzLCBpdGVtKSA9PiB7XG4gICAgICAgIHJlc1tpdGVtLmlkXSA9IGl0ZW0udmFsdWU7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9LCB7fSk7XG4gICAgICBuZXdBY2NvdW50LnNldHRpbmdzLm1lcmdlKDxMb2NhbFNldHRpbmdzPntwcm9wZXJ0aWVzfSwgWydwcm9wZXJ0aWVzJ10pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRva2Vuc1RhYmxlKSB7XG4gICAgICBhd2FpdCB0aGlzLnRva2Vuc1RhYmxlLnNhdmUoKTtcbiAgICAgIG5ld0FjY291bnQudG9rZW5zID0gdGhpcy50b2tlbnNUYWJsZS52YWx1ZTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmRlYnVnKCdbYWNjb3VudF0gU2F2aW5nIGFjY291bnQuLi4nLCBuZXdBY2NvdW50KTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5kaXNhYmxlKCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuYWNjb3VudFNlcnZpY2Uuc2F2ZShuZXdBY2NvdW50KTtcblxuICAgICAgLy8gUmVsb2FkXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMub25Mb2dpbih0aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQpLCAxMDApO1xuXG4gICAgICB0aGlzLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHRoaXMuZXJyb3IgPSBlcnIgJiYgZXJyLm1lc3NhZ2UgfHwgZXJyO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5lbmFibGUoKTtcbiAgICB9XG4gIH1cblxuICBlbmFibGUob3B0cz86IHtcbiAgICBhY2NvdW50UmVhZE9ubHk/OiBib29sZWFuO1xuICAgIG9ubHlTZWxmPzogYm9vbGVhbjtcbiAgICBlbWl0RXZlbnQ/OiBib29sZWFuO1xuICB9KSB7XG4gICAgc3VwZXIuZW5hYmxlKCk7XG5cbiAgICAvLyBTb21lIGZpZWxkcyBhcmUgYWx3YXlzIGRpc2FibGVcbiAgICB0aGlzLmZvcm0uY29udHJvbHMuZW1haWwuZGlzYWJsZSgpO1xuICAgIHRoaXMuZm9ybS5jb250cm9scy5tYWluUHJvZmlsZS5kaXNhYmxlKCk7XG4gICAgdGhpcy5mb3JtLmNvbnRyb2xzLnB1YmtleS5kaXNhYmxlKCk7XG5cbiAgICAvLyBEaXNhYmxlIGFjY291bnQgZmllbGRzIGlmIHJlYWRvbmx5IGJ5IGNvbmZpZ3VyYXRpb25cbiAgICBpZiAob3B0cz8uYWNjb3VudFJlYWRPbmx5KSB7XG4gICAgICB0aGlzLmZvcm0uY29udHJvbHMubGFzdE5hbWUuZGlzYWJsZSgpO1xuICAgICAgdGhpcy5mb3JtLmNvbnRyb2xzLmZpcnN0TmFtZS5kaXNhYmxlKCk7XG4gICAgfVxuXG4gICAgLy8gQWx3YXlzIGRpc2FibGUgc29tZSBhZGRpdGlvbmFsIGZpZWxkc1xuICAgIHRoaXMuYWRkaXRpb25hbEZpZWxkc1xuICAgICAgLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgICBjb25zdCBjb250cm9sID0gdGhpcy5mb3JtLmNvbnRyb2xzW2ZpZWxkLmtleV07XG4gICAgICAgIGlmICghY29udHJvbCkgcmV0dXJuOyAvLyBTa2lwXG5cbiAgICAgICAgY29uc3QgZGlzYWJsZWQgPSBmaWVsZC5leHRyYT8uYWNjb3VudCAmJiBmaWVsZC5leHRyYS5hY2NvdW50LmRpc2FibGVkIHx8IGZhbHNlO1xuICAgICAgICBpZiAoZGlzYWJsZWQgJiYgY29udHJvbC5lbmFibGVkKSB7XG4gICAgICAgICAgY29udHJvbC5kaXNhYmxlKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVxdWlyZWQgPSBmaWVsZC5leHRyYT8uYWNjb3VudCAmJiBmaWVsZC5leHRyYS5hY2NvdW50LnJlcXVpcmVkIHx8IGZhbHNlO1xuICAgICAgICBpZiAoIWZpZWxkLnJlcXVpcmVkICYmIHJlcXVpcmVkKSB7XG4gICAgICAgICAgY29udHJvbC5zZXRWYWxpZGF0b3JzKGNvbnRyb2wudmFsaWRhdG9yXG4gICAgICAgICAgICA/IFZhbGlkYXRvcnMuY29tcG9zZShbY29udHJvbC52YWxpZGF0b3IsIFZhbGlkYXRvcnMucmVxdWlyZWRdKVxuICAgICAgICAgICAgOiBWYWxpZGF0b3JzLnJlcXVpcmVkKTtcbiAgICAgICAgfVxuXG4gICAgICB9KTtcbiAgICB0aGlzLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgYXN5bmMgY2FuY2VsKCkge1xuICAgIGF3YWl0IHN1cGVyLmNhbmNlbCgpO1xuICB9XG5cbiAgYXN5bmMgY2xvc2UoZXZlbnQ/OiBFdmVudCkge1xuICAgIGlmICh0aGlzLnNhdmluZykgcmV0dXJuO1xuXG4gICAgLy8gQmFjayB0byBob21lXG4gICAgcmV0dXJuIHRoaXMubmF2Q29udHJvbGxlci5uYXZpZ2F0ZVJvb3QoJy8nKTsgLy8gYmFjayB0byBob21lXG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxufVxuIiwiPGFwcC10b29sYmFyIFt0aXRsZV09XCInQUNDT1VOVC5USVRMRSd8dHJhbnNsYXRlXCIgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICBbaGFzVmFsaWRhdGVdPVwiZGlydHkgJiYgIXNhdmluZ1wiXG4gICAgICAgICAgICAgW2hhc0Nsb3NlXT1cIiFkaXJ0eSAmJiAhc2F2aW5nXCJcbiAgICAgICAgICAgICAob25WYWxpZGF0ZSk9XCJzYXZlKCRldmVudClcIlxuICAgICAgICAgICAgIFtjYW5Hb0JhY2tdPVwiZmFsc2VcIlxuICAgICAgICAgICAgIChvbkNsb3NlKT1cImNsb3NlKCRldmVudClcIj5cblxuICA8aW9uLWJ1dHRvbnMgc2xvdD1cImVuZFwiPlxuICAgIDwhLS0gbG9hZGVyIC0tPlxuICAgIDxpb24tc3Bpbm5lciAqbmdJZj1cImxvYWRpbmcgfHwgc2F2aW5nOyBlbHNlIGVuZEJ1dHRvbnNcIj48L2lvbi1zcGlubmVyPlxuXG4gICAgPG5nLXRlbXBsYXRlICNlbmRCdXR0b25zPlxuICAgICAgPCEtLSByZWZyZXNoIGJ1dHRvbiAoaWYgb25saW5lKSAtLT5cbiAgICAgIDxpb24tYnV0dG9uIFttYXRUb29sdGlwXT1cIidDT01NT04uQlROX1JFRlJFU0gnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAqbmdJZj1cIm5ldHdvcmsub25saW5lXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZWZyZXNoKCRldmVudClcIj5cbiAgICAgICAgPG1hdC1pY29uIHNsb3Q9XCJpY29uLW9ubHlcIj5yZWZyZXNoPC9tYXQtaWNvbj5cbiAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L2lvbi1idXR0b25zPlxuPC9hcHAtdG9vbGJhcj5cblxuPGlvbi1jb250ZW50PlxuXG4gIDwhLS0gZXJyb3IgLS0+XG4gIDxpb24taXRlbSAqbmdJZj1cImVycm9yICYmIG1vYmlsZVwiIGxpbmVzPVwibm9uZVwiPlxuICAgIDxpb24taWNvbiBjb2xvcj1cImRhbmdlclwiIHNsb3Q9XCJzdGFydFwiIG5hbWU9XCJhbGVydC1jaXJjbGVcIj48L2lvbi1pY29uPlxuICAgIDxpb24tbGFiZWwgY29sb3I9XCJkYW5nZXJcIiBjbGFzcz1cImVycm9yXCIgW2lubmVySFRNTF09XCJlcnJvcnx0cmFuc2xhdGVcIj48L2lvbi1sYWJlbD5cbiAgPC9pb24taXRlbT5cblxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZvcm1cIiBub3ZhbGlkYXRlIGNsYXNzPVwiZm9ybS1jb250YWluZXJcIj5cblxuICAgIDxtYXQtdGFiLWdyb3VwICN0YWJHcm91cCBbKHNlbGVjdGVkSW5kZXgpXT1cInNlbGVjdGVkVGFiSW5kZXhcIiBkeW5hbWljSGVpZ2h0PlxuXG4gICAgICA8IS0tIFRBQjogdXNlciBkZXRhaWxzIC0tPlxuICAgICAgPG1hdC10YWIgbGFiZWw9XCJ7eydBQ0NPVU5ULlVTRVJfREVUQUlMUy5USVRMRSd8dHJhbnNsYXRlfX1cIiBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBtYXQtdGFiLWxhYmVsPlxuICAgICAgICAgIDxtYXQtaWNvbj5cbiAgICAgICAgICAgIDxpb24taWNvbiBtYXRQcmVmaXggc2xvdD1cInN0YXJ0XCIgbmFtZT1cInBlcnNvbi1jaXJjbGVcIj48L2lvbi1pY29uPlxuICAgICAgICAgIDwvbWF0LWljb24+XG4gICAgICAgICAgPGlvbi1sYWJlbD57eydBQ0NPVU5ULlVTRVJfREVUQUlMUy5USVRMRSd8dHJhbnNsYXRlfX08L2lvbi1sYWJlbD5cbiAgICAgICAgICA8aW9uLWljb24gc2xvdD1cImVuZFwiIG5hbWU9XCJhbGVydC1jaXJjbGVcIiBjb2xvcj1cImRhbmdlclwiICpuZ0lmPVwic3VibWl0dGVkICYmIGZvcm0uaW52YWxpZFwiPjwvaW9uLWljb24+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG5cbiAgICAgICAgICA8cCBbaW5uZXJIVE1MXT1cIidBQ0NPVU5ULlVTRVJfREVUQUlMUy5ERVNDUklQVElPTid8dHJhbnNsYXRlXCI+PC9wPlxuXG4gICAgICAgICAgPCEtLWgxPklkZW50aXTDqTwvaDEtLT5cblxuICAgICAgICAgIDwhLS0gRW1haWwgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFtwbGFjZWhvbGRlcl09XCInVVNFUi5FTUFJTCd8dHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJlbWFpbFwiIGF1dG9jb21wbGV0ZT1cInNlY3Rpb24tcmVkIGVtYWlsXCI+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5lbWFpbC5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiBmb3JtLmNvbnRyb2xzLmVtYWlsLmRpcnR5XCIgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5lbWFpbC5oYXNFcnJvcignZW1haWwnKSAmJiBmb3JtLmNvbnRyb2xzLmVtYWlsLmRpcnR5XCI+XG4gICAgICAgICAgICAgIDxzcGFuPnt7J0VSUk9SLkZJRUxEX05PVF9WQUxJRF9FTUFJTCcgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgPGlvbi1ncmlkICpuZ0lmPVwiZW1haWwubm90Q29uZmlybWVkXCIgY2xhc3M9XCJpb24tbm8tcGFkZGluZyBpb24tcGFkZGluZy1ib3R0b21cIj5cbiAgICAgICAgICAgIDxpb24tcm93PlxuICAgICAgICAgICAgICA8aW9uLWNvbCBjb2xvcj1cImRhbmdlclwiPlxuICAgICAgICAgICAgICAgIDxpb24taWNvbiBzbG90PVwic3RhcnRcIiBjb2xvcj1cImRhbmdlclwiIG5hbWU9XCJhbGVydC1jaXJjbGVcIiBjb2xvcj1cImRhbmdlclwiPjwvaW9uLWljb24+XG4gICAgICAgICAgICAgICAgPGlvbi10ZXh0IFtpbm5lckhUTUxdPVwiJ0FDQ09VTlQuRU1BSUxfTk9UX0NPTkZJUk1FRF9MQUJFTCd8dHJhbnNsYXRlXCI+PC9pb24tdGV4dD5cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgPC9pb24tcm93PlxuXG4gICAgICAgICAgICA8aW9uLXJvdyBzdHlsZT1cImhlaWdodDogNTFweDtcIj5cbiAgICAgICAgICAgICAgPGlvbi1jb2wgc3R5bGU9XCJ0ZXh0LWFsaWduOiByaWdodDtcIj5cbiAgICAgICAgICAgICAgICA8aW9uLXRleHQ+XG4gICAgICAgICAgICAgICAgICA8c21hbGwgW2lubmVySFRNTF09XCInQUNDT1VOVC5FTUFJTF9OT1RfUkVDRUlWRURfUVVFU1RJT04nfHRyYW5zbGF0ZVwiPjwvc21hbGw+XG4gICAgICAgICAgICAgICAgPC9pb24tdGV4dD5cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgICA8aW9uLWNvbCBzaXplPVwiYXV0b1wiPlxuICAgICAgICAgICAgICAgIDxpb24tYnV0dG9uIGZpbGw9XCJzb2xpZFwiIGNvbG9yPVwic2Vjb25kYXJ5XCIgKm5nSWY9XCIhZW1haWwuc2VuZGluZ1wiIChjbGljayk9XCJzZW5kQ29uZmlybWF0aW9uRW1haWwoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAge3snQUNDT1VOVC5CVE5fUkVTRU5EJ3x0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICAgIDwvaW9uLWJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8aW9uLXNwaW5uZXIgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiICpuZ0lmPVwiZW1haWwuc2VuZGluZ1wiPjwvaW9uLXNwaW5uZXI+XG4gICAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgIDwvaW9uLXJvdz5cblxuICAgICAgICAgICAgPGlvbi1yb3cgKm5nSWY9XCJlbWFpbC5lcnJvciAmJiAhZW1haWwuc2VuZGluZ1wiPlxuICAgICAgICAgICAgICA8aW9uLWNvbD5cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImVtYWlsLmVycm9yICYmICFlbWFpbC5zZW5kaW5nXCIgW2lubmVySFRNTF09XCJlbWFpbC5lcnJvcnx0cmFuc2xhdGVcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDwvaW9uLWNvbD5cbiAgICAgICAgICAgIDwvaW9uLXJvdz5cbiAgICAgICAgICA8L2lvbi1ncmlkPlxuXG4gICAgICAgICAgPCEtLSBMYXN0IG5hbWUgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFthcHBBdXRvZm9jdXNdPVwidHJ1ZVwiIFthdXRvZm9jdXNEZWxheV09XCI1MDBcIiBbcGxhY2Vob2xkZXJdPVwiJ1VTRVIuTEFTVF9OQU1FJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cImxhc3ROYW1lXCJcbiAgICAgICAgICAgICAgICAgICBhdXRvY29tcGxldGU9XCJzZWN0aW9uLWJsdWUgZmFtaWx5LW5hbWVcIlxuICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMubGFzdE5hbWUuaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgZm9ybS5jb250cm9scy5sYXN0TmFtZS5kaXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5sYXN0TmFtZS5oYXNFcnJvcignbWlubGVuZ3RoJykgJiYgZm9ybS5jb250cm9scy5sYXN0TmFtZS5kaXJ0eVwiPlxuICAgICAgICAgICAgICA8c3Bhbj57eydFUlJPUi5GSUVMRF9NSU5fTEVOR1RIJyB8IHRyYW5zbGF0ZToge21pbkxlbmd0aDogMn0gfX08L3NwYW4+XG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgPCEtLSBGaXJzdCBuYW1lIC0tPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbcGxhY2Vob2xkZXJdPVwiJ1VTRVIuRklSU1RfTkFNRSd8dHJhbnNsYXRlXCIgZm9ybUNvbnRyb2xOYW1lPVwiZmlyc3ROYW1lXCIgYXV0b2NvbXBsZXRlPVwic2VjdGlvbi1ibHVlIGdpdmVuLW5hbWVcIlxuICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuZmlyc3ROYW1lLmhhc0Vycm9yKCdyZXF1aXJlZCcpICYmIGZvcm0uY29udHJvbHMuZmlyc3ROYW1lLmRpcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmZpcnN0TmFtZS5oYXNFcnJvcignbWlubGVuZ3RoJykgJiYgZm9ybS5jb250cm9scy5maXJzdE5hbWUuZGlydHlcIj5cbiAgICAgICAgICAgICAgPHNwYW4+e3snRVJST1IuRklFTERfTUlOX0xFTkdUSCcgfCB0cmFuc2xhdGU6IHttaW5MZW5ndGg6IDJ9IH19PC9zcGFuPlxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuXG4gICAgICAgICAgPCEtLSBBZGRpdGlvbmFsIGZpZWxkcyAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBkZWZpbml0aW9uIG9mIGFkZGl0aW9uYWxGaWVsZHNcIj5cbiAgICAgICAgICAgIDxhcHAtZm9ybS1maWVsZCBbZGVmaW5pdGlvbl09XCJkZWZpbml0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xOYW1lXT1cImRlZmluaXRpb24ua2V5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwiZGVmaW5pdGlvbi5leHRyYSAmJiBkZWZpbml0aW9uLmV4dHJhLmFjY291bnQgJiYgZGVmaW5pdGlvbi5leHRyYS5hY2NvdW50LnJlcXVpcmVkIHx8IGZhbHNlXCI+XG4gICAgICAgICAgICA8L2FwcC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPGgzIHRyYW5zbGF0ZT5BQ0NPVU5ULlVTRVJfREVUQUlMUy5URUNITklDQUxfRElWSURFUjwvaDM+XG5cbiAgICAgICAgICA8IS0tIHByb2ZpbGUgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IGhpZGRlbiByZWFkb25seT1cInRydWVcIiBbcGxhY2Vob2xkZXJdPVwiJ0FDQ09VTlQuVVNFUl9ERVRBSUxTLlBST0ZJTEUnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwibWFpblByb2ZpbGVcIiByZXF1aXJlZD5cbiAgICAgICAgICAgIDxzcGFuPnt7J1VTRVIuUFJPRklMRV9FTlVNLicgKyBmb3JtLmNvbnRyb2xzLm1haW5Qcm9maWxlLnZhbHVlIHwgdHJhbnNsYXRlfX08L3NwYW4+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5maXJzdE5hbWUuaGFzRXJyb3IoJ21haW5Qcm9maWxlJykgJiYgZm9ybS5jb250cm9scy5tYWluUHJvZmlsZS5kaXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICAgIDwhLS0gcHVia2V5IC0tPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCByZWFkb25seT1cInRydWVcIiBbcGxhY2Vob2xkZXJdPVwiJ0FDQ09VTlQuVVNFUl9ERVRBSUxTLlBVQktFWSd8dHJhbnNsYXRlXCIgZm9ybUNvbnRyb2xOYW1lPVwicHVia2V5XCJcbiAgICAgICAgICAgICAgICAgICByZXF1aXJlZD5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmZpcnN0TmFtZS5oYXNFcnJvcigncHVia2V5JykgJiYgZm9ybS5jb250cm9scy5maXJzdE5hbWUuZGlydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuZmlyc3ROYW1lLmhhc0Vycm9yKCdwdWJrZXknKSAmJiBmb3JtLmNvbnRyb2xzLmZpcnN0TmFtZS5kaXJ0eVwiPlxuICAgICAgICAgICAgICA8c3BhbiB0cmFuc2xhdGU+RVJST1IuRklFTERfTk9UX1ZBTElEX1BVQktFWTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L21hdC10YWI+XG5cbiAgICAgIDwhLS0gVEFCOiBzZXR0aW5ncyAtLT5cbiAgICAgIDxtYXQtdGFiIGxhYmVsPVwie3snQUNDT1VOVC5TRVRUSU5HUy5USVRMRSd8dHJhbnNsYXRlfX1cIiBmb3JtR3JvdXBOYW1lPVwic2V0dGluZ3NcIj5cbiAgICAgICAgPG5nLXRlbXBsYXRlIG1hdC10YWItbGFiZWw+XG4gICAgICAgICAgPG1hdC1pY29uPlxuICAgICAgICAgICAgPGlvbi1pY29uIG1hdFByZWZpeCBzbG90PVwic3RhcnRcIiBuYW1lPVwic2V0dGluZ3NcIj48L2lvbi1pY29uPlxuICAgICAgICAgIDwvbWF0LWljb24+XG4gICAgICAgICAgPGlvbi1sYWJlbCB0cmFuc2xhdGU+QUNDT1VOVC5TRVRUSU5HUy5USVRMRTwvaW9uLWxhYmVsPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpb24tcGFkZGluZ1wiPlxuXG4gICAgICAgICAgPHAgW2lubmVySFRNTF09XCInQUNDT1VOVC5TRVRUSU5HUy5ERVNDUklQVElPTid8dHJhbnNsYXRlXCI+PC9wPlxuXG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPG1hdC1zZWxlY3QgW3BsYWNlaG9sZGVyXT1cIidBQ0NPVU5ULlNFVFRJTkdTLkxPQ0FMRSd8dHJhbnNsYXRlXCIgZm9ybUNvbnRyb2xOYW1lPVwibG9jYWxlXCIgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBpdGVtIG9mIGxvY2FsZXNcIiBbdmFsdWVdPVwiaXRlbS5rZXlcIj5cbiAgICAgICAgICAgICAgICB7e2l0ZW0udmFsdWV9fVxuICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwic2V0dGluZ3NGb3JtPy5jb250cm9scy5sb2NhbGUuaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgc2V0dGluZ3NGb3JtPy5jb250cm9scy5sb2NhbGUuZGlydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIGxhdC9sb25nIGZvcm1hdC0tPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtc2VsZWN0IFtwbGFjZWhvbGRlcl09XCInQUNDT1VOVC5TRVRUSU5HUy5MQVRfTE9OR19GT1JNQVQnfHRyYW5zbGF0ZVwiIGZvcm1Db250cm9sTmFtZT1cImxhdExvbmdGb3JtYXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgIDxtYXQtb3B0aW9uICpuZ0Zvcj1cImxldCBpdGVtIG9mIGxhdExvbmdGb3JtYXRzXCIgW3ZhbHVlXT1cIml0ZW1cIj5cbiAgICAgICAgICAgICAgICB7eydDT01NT04uTEFUX0xPTkcuJyArIGl0ZW0gKyAnX1BMQUNFSE9MREVSJ3x0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwic2V0dGluZ3NGb3JtPy5jb250cm9scy5sYXRMb25nRm9ybWF0Lmhhc0Vycm9yKCdyZXF1aXJlZCcpICYmIHNldHRpbmdzRm9ybT8uY29udHJvbHMubGF0TG9uZ0Zvcm1hdC5kaXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIE9wdGlvbnMgdGFibGUgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJvcHRpb25zLXRhYmxlXCIgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwib3B0aW9uRGVmaW5pdGlvbnMgfCBpc0VtcHR5QXJyYXlcIj5cbiAgICAgICAgICA8YXBwLXByb3BlcnRpZXMtdGFibGVcbiAgICAgICAgICAgICNwcm9wZXJ0aWVzVGFibGVcbiAgICAgICAgICAgIGkxOG5Db2x1bW5QcmVmaXg9XCJBQ0NPVU5ULlNFVFRJTkdTLk9QVElPTlMuXCJcbiAgICAgICAgICAgIFtkZWZpbml0aW9uc109XCJvcHRpb25EZWZpbml0aW9uc1wiXG4gICAgICAgICAgICBbY2FuRWRpdF09XCJ0cnVlXCJcbiAgICAgICAgICAgIChvbkRpcnR5KT1cIiRldmVudCA/IG1hcmtBc0RpcnR5KCkgOiB1bmRlZmluZWRcIlxuICAgICAgICAgID48L2FwcC1wcm9wZXJ0aWVzLXRhYmxlPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgPC9tYXQtdGFiPlxuXG4gICAgICA8IS0tIFRBQjogdG9rZW5zIC0tPlxuICAgICAgPG1hdC10YWIgKm5nSWY9XCJhdXRoVG9rZW5FbmFibGVkXCIgbGFiZWw9XCJ7eydBQ0NPVU5ULlRPS0VOUy5USVRMRSd8dHJhbnNsYXRlfX1cIiBmb3JtR3JvdXBOYW1lPVwidG9rZW5zXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBtYXQtdGFiLWxhYmVsPlxuICAgICAgICAgIDxtYXQtaWNvbj5cbiAgICAgICAgICAgIDxpb24taWNvbiBtYXRQcmVmaXggc2xvdD1cInN0YXJ0XCIgbmFtZT1cInRpY2tldFwiPjwvaW9uLWljb24+XG4gICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5BQ0NPVU5ULlRPS0VOUy5USVRMRTwvaW9uLWxhYmVsPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpb24tcGFkZGluZ1wiPlxuICAgICAgICAgIDxwIFtpbm5lckhUTUxdPVwiJ0FDQ09VTlQuVE9LRU5TLkRFU0NSSVBUSU9OJ3x0cmFuc2xhdGVcIj48L3A+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gVG9rZW5zIHRhYmxlIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidG9rZW5zLXRhYmxlXCI+XG4gICAgICAgICAgPGFwcC11c2VyLXRva2VuLXRhYmxlXG4gICAgICAgICAgICAjdG9rZW5zVGFibGVcbiAgICAgICAgICAgIFtjYW5FZGl0XT1cInRydWVcIlxuICAgICAgICAgICAgKG9uRGlydHkpPVwiJGV2ZW50ID8gbWFya0FzRGlydHkoKSA6IHVuZGVmaW5lZFwiXG4gICAgICAgICAgPjwvYXBwLXVzZXItdG9rZW4tdGFibGU+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICA8L21hdC10YWI+XG4gICAgPC9tYXQtdGFiLWdyb3VwPlxuXG5cbiAgPC9mb3JtPlxuPC9pb24tY29udGVudD5cblxuPGlvbi1mb290ZXIgaGlkZGVuLXhzIGhpZGRlbi1zbSBoaWRkZW4tbW9iaWxlPlxuICA8YXBwLWZvcm0tYnV0dG9ucy1iYXIgKG9uQ2FuY2VsKT1cImNhbmNlbCgpXCIgKG9uU2F2ZSk9XCJzYXZlKCRldmVudClcIiBbZGlzYWJsZWRdPVwiIWZvcm0uZGlydHkgfHwgIXZhbGlkIHx8IHNhdmluZ1wiPlxuICAgIDwhLS0gZXJyb3IgLS0+XG4gICAgPGlvbi1pdGVtICpuZ0lmPVwiZXJyb3IgJiYgIW1vYmlsZVwiIGxpbmVzPVwibm9uZVwiPlxuICAgICAgPGlvbi1pY29uIGNvbG9yPVwiZGFuZ2VyXCIgc2xvdD1cInN0YXJ0XCIgbmFtZT1cImFsZXJ0LWNpcmNsZVwiPjwvaW9uLWljb24+XG4gICAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJlcnJvclwiIFtpbm5lckhUTUxdPVwiZXJyb3J8dHJhbnNsYXRlXCI+PC9pb24tbGFiZWw+XG4gICAgPC9pb24taXRlbT5cbiAgPC9hcHAtZm9ybS1idXR0b25zLWJhcj5cbjwvaW9uLWZvb3Rlcj5cbiJdfQ==
317
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3VudC5wYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2FjY291bnQvYWNjb3VudC5wYWdlLnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2FjY291bnQvYWNjb3VudC5wYWdlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFxQixTQUFTLEVBQUUsTUFBTSxFQUErQixTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEksT0FBTyxFQUFFLGFBQWEsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFFbkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzFELE9BQU8sRUFBd0MsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUNoRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDekQsT0FBTyxFQUFFLFdBQVcsRUFBK0IsTUFBTSxrQ0FBa0MsQ0FBQztBQUc1RixPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3JFLE9BQU8sRUFBc0IsY0FBYyxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFFekYsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBUWhFLE1BQU0sT0FBTyxXQUFZLFNB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RSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUNGLFdBQVc7c0JBQXRELFNBQVM7dUJBQUMsYUFBYSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBJbmplY3QsIEluamVjdG9yLCBPbkRlc3Ryb3ksIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjb21iaW5lTGF0ZXN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEFjY291bnRTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYWNjb3VudC5zZXJ2aWNlJztcbmltcG9ydCB7IEFjY291bnQgfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9hY2NvdW50Lm1vZGVsJztcbmltcG9ydCB7IFVudHlwZWRGb3JtQnVpbGRlciwgVW50eXBlZEZvcm1Hcm91cCwgVmFsaWRhdG9ycyB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEFjY291bnRWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvdmFsaWRhdG9yL2FjY291bnQudmFsaWRhdG9yJztcbmltcG9ydCB7IEFwcEZvcm0gfSBmcm9tICcuLi9mb3JtL2Zvcm0uY2xhc3MnO1xuaW1wb3J0IHsgQXBwRm9ybVV0aWxzIH0gZnJvbSAnLi4vZm9ybS9mb3JtLnV0aWxzJztcbmltcG9ydCB7IEZvcm1GaWVsZERlZmluaXRpb24gfSBmcm9tICcuLi8uLi9zaGFyZWQvZm9ybS9maWVsZC5tb2RlbCc7XG5pbXBvcnQgeyBMQVRfTE9OR19QQVRURVJOUyB9IGZyb20gJy4uLy4uL3NoYXJlZC9tYXRlcmlhbC9sYXRsb25nL2xhdGxvbmcudXRpbHMnO1xuaW1wb3J0IHsgU3RhdHVzSWRzIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvbW9kZWwuZW51bSc7XG5pbXBvcnQgeyBBUFBfTE9DQUxFUywgTG9jYWxlQ29uZmlnLCBMb2NhbFNldHRpbmdzIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvc2V0dGluZ3MubW9kZWwnO1xuaW1wb3J0IHsgQ2FuTGVhdmUgfSBmcm9tICcuLi8uLi9zaGFyZWQvZ3VhcmQvY29tcG9uZW50LWRpcnR5Lmd1YXJkJztcbmltcG9ydCB7IE5ldHdvcmtTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvbmV0d29yay5zZXJ2aWNlJztcbmltcG9ydCB7IGZpbHRlciwgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgTWF0VGFiR3JvdXAgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcbmltcG9ydCB7IENvbmZpZ1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBDT1JFX0NPTkZJR19PUFRJT05TIH0gZnJvbSAnLi4vc2VydmljZXMvY29uZmlnL2NvcmUuY29uZmlnJztcbmltcG9ydCB7IEFwcFByb3BlcnRpZXNUYWJsZSwgUHJvcGVydHlFbnRpdHkgfSBmcm9tICcuLi9mb3JtL3Byb3BlcnRpZXMvcHJvcGVydGllcy50YWJsZSc7XG5pbXBvcnQgeyBQcm9wZXJ0aWVzTWFwIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IGlzTm90TmlsIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5pbXBvcnQgeyBVc2VyVG9rZW5UYWJsZSB9IGZyb20gJy4vdG9rZW4udGFibGUnO1xuaW1wb3J0IHsgTmF2Q29udHJvbGxlciB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7IGVudmlyb25tZW50IH0gZnJvbSAnLi4vLi4vLi4vZW52aXJvbm1lbnRzL2Vudmlyb25tZW50JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWFjY291bnQtcGFnZScsXG4gIHRlbXBsYXRlVXJsOiAnYWNjb3VudC5wYWdlLmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9hY2NvdW50LnBhZ2Uuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgQWNjb3VudFBhZ2UgZXh0ZW5kcyBBcHBGb3JtPEFjY291bnQ+IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIENhbkxlYXZlIHtcbiAgQFZpZXdDaGlsZCgndGFiR3JvdXAnLCB7IHN0YXRpYzogdHJ1ZSB9KSB0YWJHcm91cDogTWF0VGFiR3JvdXA7XG4gIEBWaWV3Q2hpbGQoJ3Byb3BlcnRpZXNUYWJsZScsIHsgc3RhdGljOiB0cnVlIH0pIHByb3BlcnRpZXNUYWJsZTogQXBwUHJvcGVydGllc1RhYmxlO1xuICBAVmlld0NoaWxkKCd0b2tlbnNUYWJsZScsIHsgc3RhdGljOiB0cnVlIH0pIHRva2Vuc1RhYmxlOiBVc2VyVG9rZW5UYWJsZTtcblxuICBzZWxlY3RlZFRhYkluZGV4ID0gMDtcbiAgaXNMb2dpbjogYm9vbGVhbjtcbiAgY2hhbmdlc1N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBuZXR3b3JrU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG4gIGVtYWlsOiBhbnkgPSB7XG4gICAgY29uZmlybWVkOiBmYWxzZSxcbiAgICBub3RDb25maXJtZWQ6IGZhbHNlLFxuICAgIHNlbmRpbmc6IGZhbHNlLFxuICAgIGVycm9yOiB1bmRlZmluZWQsXG4gIH07XG4gIGFkZGl0aW9uYWxGaWVsZHM6IEZvcm1GaWVsZERlZmluaXRpb25bXTtcbiAgb3B0aW9uRGVmaW5pdGlvbnM6IEZvcm1GaWVsZERlZmluaXRpb25bXTtcblxuICBnZXQgc2V0dGluZ3NGb3JtKCk6IFVudHlwZWRGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZvcm0uZ2V0KCdzZXR0aW5ncycpIGFzIFVudHlwZWRGb3JtR3JvdXA7XG4gIH1cblxuICAvLyBzZXR0aW5nc0NvbnRlbnRGb3JtOiBVbnR5cGVkRm9ybUdyb3VwO1xuICBsb2NhbGVzOiBMb2NhbGVDb25maWdbXTtcbiAgbGF0TG9uZ0Zvcm1hdHMgPSBMQVRfTE9OR19QQVRURVJOUztcbiAgc2F2aW5nID0gZmFsc2U7XG4gIHN1Ym1pdHRlZCA9IGZhbHNlO1xuICBhY2NvdW50UmVhZE9ubHkgPSBmYWxzZTtcbiAgcmVhZG9ubHkgbW9iaWxlOiBib29sZWFuO1xuXG4gIGdldCB2YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gc3VwZXIudmFsaWQgJiYgKHRoaXMucHJvcGVydGllc1RhYmxlPy52YWxpZCB8fCB0cnVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhdXRoVG9rZW5FbmFibGVkID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHB1YmxpYyBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyLFxuICAgIHB1YmxpYyBhY2NvdW50U2VydmljZTogQWNjb3VudFNlcnZpY2UsXG4gICAgcHVibGljIG5ldHdvcms6IE5ldHdvcmtTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBuYXZDb250cm9sbGVyOiBOYXZDb250cm9sbGVyLFxuICAgIHByb3RlY3RlZCB2YWxpZGF0b3JTZXJ2aWNlOiBBY2NvdW50VmFsaWRhdG9yU2VydmljZSxcbiAgICAvLyBwcm90ZWN0ZWQgc2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlOiBVc2VyU2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjb25maWdTZXJ2aWNlOiBDb25maWdTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQEluamVjdChBUFBfTE9DQUxFUykgbG9jYWxlczogTG9jYWxlQ29uZmlnW11cbiAgKSB7XG4gICAgc3VwZXIoaW5qZWN0b3IsIHZhbGlkYXRvclNlcnZpY2UuZ2V0Rm9ybUdyb3VwKGFjY291bnRTZXJ2aWNlLmFjY291bnQpKTtcblxuICAgIHRoaXMubG9jYWxlcyA9IGxvY2FsZXM7XG5cbiAgICAvLyBBZGQgc2V0dGluZ3MgZm8gZm9ybVxuICAgIC8vIHRoaXMuc2V0dGluZ3NGb3JtID0gc2V0dGluZ3NWYWxpZGF0b3JTZXJ2aWNlLmdldEZvcm1Hcm91cChhY2NvdW50U2VydmljZS5hY2NvdW50ICYmIGFjY291bnRTZXJ2aWNlLmFjY291bnQuc2V0dGluZ3MpO1xuICAgIC8vIHRoaXMuc2V0dGluZ3NDb250ZW50Rm9ybSA9ICh0aGlzLnNldHRpbmdzRm9ybS5jb250cm9sc1snY29udGVudCddIGFzIFVudHlwZWRGb3JtR3JvdXApO1xuICAgIC8vIHRoaXMuZm9ybS5hZGRDb250cm9sKCdzZXR0aW5ncycsIHRoaXMuc2V0dGluZ3NGb3JtKTtcblxuICAgIHRoaXMubW9iaWxlID0gdGhpcy5zZXR0aW5ncy5tb2JpbGU7XG4gICAgdGhpcy5kZWJ1ZyA9ICFlbnZpcm9ubWVudC5wcm9kdWN0aW9uO1xuXG4gICAgLy8gQnkgZGVmYXVsdCwgZGlzYWJsZSB0aGUgZm9ybVxuICAgIHRoaXMuZGlzYWJsZSgpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgc3VwZXIubmdPbkluaXQoKTtcblxuICAgIC8vIEdldCB1c2VyIG9wdGlvbnNcbiAgICB0aGlzLm9wdGlvbkRlZmluaXRpb25zID0gdGhpcy5hY2NvdW50U2VydmljZS5vcHRpb25EZWZzXG4gICAgICAuc2xpY2UoKVxuICAgICAgLmZpbHRlcigoZGVmaW5pdGlvbikgPT4gIWRlZmluaXRpb24ubWluUHJvZmlsZSB8fCB0aGlzLmFjY291bnRTZXJ2aWNlLmhhc01pblByb2ZpbGUoZGVmaW5pdGlvbi5taW5Qcm9maWxlKSk7XG5cbiAgICAvLyBPYnNlcnZlZCBzb21lIGV2ZW50c1xuICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24odGhpcy5hY2NvdW50U2VydmljZS5vbkxvZ2luLnBpcGUoZmlsdGVyKCgpID0+ICF0aGlzLnNhdmluZykpLnN1YnNjcmliZSgoYWNjb3VudCkgPT4gdGhpcy5vbkxvZ2luKGFjY291bnQpKSk7XG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbih0aGlzLmFjY291bnRTZXJ2aWNlLm9uTG9nb3V0LnN1YnNjcmliZSgoKSA9PiB0aGlzLm9uTG9nb3V0KCkpKTtcbiAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKFxuICAgICAgdGhpcy5vbkNhbmNlbC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLnNldFZhbHVlKHRoaXMuYWNjb3VudFNlcnZpY2UuYWNjb3VudCk7XG4gICAgICAgIHRoaXMubWFya0FzUHJpc3RpbmUoKTtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHRoaXMucmVnaXN0ZXJTdWJzY3JpcHRpb24oXG4gICAgICB0aGlzLmFjY291bnRTZXJ2aWNlLiRhZGRpdGlvbmFsRmllbGRzLnN1YnNjcmliZSgoYWRkaXRpb25hbEZpZWxkcykgPT4ge1xuICAgICAgICB0aGlzLmFkZGl0aW9uYWxGaWVsZHMgPSBhZGRpdGlvbmFsRmllbGRzLnNsaWNlKCk7IC8vIENvcHlcbiAgICAgICAgaWYgKHRoaXMuYWNjb3VudFNlcnZpY2UuaXNMb2dpbigpKSB7XG4gICAgICAgICAgdGhpcy5vbkxvZ2luKHRoaXMuYWNjb3VudFNlcnZpY2UuYWNjb3VudCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5tYXJrQXNMb2FkZWQoKTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuXG4gICAgdGhpcy5yZWdpc3RlclN1YnNjcmlwdGlvbihcbiAgICAgIHRoaXMuY29uZmlnU2VydmljZS5jb25maWcuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgICB0aGlzLmFjY291bnRSZWFkT25seSA9IHZhbHVlLmdldFByb3BlcnR5QXNCb29sZWFuKENPUkVfQ09ORklHX09QVElPTlMuQUNDT1VOVF9SRUFET05MWSk7XG4gICAgICAgIHRoaXMuYXV0aFRva2VuRW5hYmxlZCA9IHZhbHVlLmdldFByb3BlcnR5QXNCb29sZWFuKENPUkVfQ09ORklHX09QVElPTlMuQVVUSF9UT0tFTl9FTkFCTEVEKTtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIC8vIFJlYWxpZ24gdGFiLCBhZnRlciBhIGRlbGF5IGJlY2F1c2UgdGhlIHRhYiBjYW4gYmUgZGlzYWJsZWQgd2hlbiBjb21wb25lbnQgaXMgY3JlYXRlZFxuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy50YWJHcm91cC5yZWFsaWduSW5rQmFyKCksIDUwMCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xuICAgIHRoaXMuc3RvcExpc3RlbkNoYW5nZXMoKTtcbiAgICB0aGlzLm5ldHdvcmtTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICBvbkxvZ2luKGFjY291bnQ6IEFjY291bnQpIHtcbiAgICBjb25zb2xlLmRlYnVnKCdbYWNjb3VudF0gTG9nZ2VkIGFjY291bnQ6ICcsIGFjY291bnQpO1xuICAgIHRoaXMuaXNMb2dpbiA9IHRydWU7XG5cbiAgICB0aGlzLnNldFZhbHVlKGFjY291bnQpO1xuXG4gICAgdGhpcy5lbWFpbC5jb25maXJtZWQgPSBhY2NvdW50ICYmIGFjY291bnQuZW1haWwgJiYgYWNjb3VudC5zdGF0dXNJZCAhPT0gU3RhdHVzSWRzLlRFTVBPUkFSWTtcbiAgICB0aGlzLmVtYWlsLm5vdENvbmZpcm1lZCA9IGFjY291bnQgJiYgYWNjb3VudC5lbWFpbCAmJiAoIWFjY291bnQuc3RhdHVzSWQgfHwgYWNjb3VudC5zdGF0dXNJZCA9PT0gU3RhdHVzSWRzLlRFTVBPUkFSWSk7XG5cbiAgICB0aGlzLm5ldHdvcmtTdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5uZXR3b3JrU3Vic2NyaXB0aW9uID0gY29tYmluZUxhdGVzdChbXG4gICAgICB0aGlzLmNvbmZpZ1NlcnZpY2UuY29uZmlnLFxuICAgICAgdGhpcy5uZXR3b3JrLm9uTmV0d29ya1N0YXR1c0NoYW5nZXMucGlwZShtYXAoKGNvbm5lY3Rpb25UeXBlKSA9PiBjb25uZWN0aW9uVHlwZSAhPT0gJ25vbmUnKSksXG4gICAgXSkuc3Vic2NyaWJlKChbY29uZmlnLCBvbmxpbmVdKSA9PiB7XG4gICAgICBpZiAob25saW5lKSB7XG4gICAgICAgIGNvbnN0IGFjY291bnRSZWFkT25seSA9IGNvbmZpZy5nZXRQcm9wZXJ0eUFzQm9vbGVhbihDT1JFX0NPTkZJR19PUFRJT05TLkFDQ09VTlRfUkVBRE9OTFkpO1xuICAgICAgICB0aGlzLmVuYWJsZSh7IGFjY291bnRSZWFkT25seSB9KTtcbiAgICAgICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuICAgICAgICB0aGlzLnN0YXJ0TGlzdGVuQ2hhbmdlcygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlKCk7XG4gICAgICAgIHRoaXMubWFya0FzUHJpc3RpbmUoKTtcbiAgICAgICAgdGhpcy5zdG9wTGlzdGVuQ2hhbmdlcygpO1xuICAgICAgfVxuICAgICAgdGhpcy5tYXJrQXNMb2FkZWQoKTtcbiAgICB9KTtcblxuICAgIHRoaXMubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBvbkxvZ291dCgpIHtcbiAgICB0aGlzLmlzTG9naW4gPSBmYWxzZTtcbiAgICB0aGlzLmVtYWlsLmNvbmZpcm1lZCA9IGZhbHNlO1xuICAgIHRoaXMuZW1haWwubm90Q29uZmlybWVkID0gZmFsc2U7XG4gICAgdGhpcy5lbWFpbC5zZW5kaW5nID0gZmFsc2U7XG4gICAgdGhpcy5lbWFpbC5lcnJvciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmZvcm0ucmVzZXQoKTtcbiAgICB0aGlzLmRpc2FibGUoKTtcblxuICAgIHRoaXMubmV0d29ya1N1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcblxuICAgIHRoaXMuc3RvcExpc3RlbkNoYW5nZXMoKTtcblxuICAgIC8vIEJhY2sgdG8gaG9tZVxuICAgIHRoaXMubmF2Q29udHJvbGxlci5uYXZpZ2F0ZVJvb3QoJy8nKTtcbiAgfVxuXG4gIGFzeW5jIHNldFZhbHVlKGRhdGE6IEFjY291bnQsIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW47IG9ubHlTZWxmPzogYm9vbGVhbiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgc3VwZXIuc2V0VmFsdWUoZGF0YSwgb3B0cyk7XG5cbiAgICAvLyBTZXQgb3B0aW9uc1xuICAgIGNvbnN0IHByb3BlcnRpZXMgPSBkYXRhPy5zZXR0aW5ncz8uYXNMb2NhbFNldHRpbmdzKCk/LnByb3BlcnRpZXMgfHwge307XG4gICAgY29uc3QgcHJvcGVydGllc0VudGl0aWVzOiBQcm9wZXJ0eUVudGl0eVtdID0gW107XG4gICAgdGhpcy5vcHRpb25EZWZpbml0aW9uc1xuICAgICAgLmZpbHRlcigoZGVmaW5pdGlvbikgPT4gIWRlZmluaXRpb24ubWluUHJvZmlsZSB8fCB0aGlzLmFjY291bnRTZXJ2aWNlLmhhc01pblByb2ZpbGUoZGVmaW5pdGlvbi5taW5Qcm9maWxlKSlcbiAgICAgIC5tYXAoKGRlZmluaXRpb24pID0+IGRlZmluaXRpb24ua2V5KVxuICAgICAgLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICBpZiAoaXNOb3ROaWwocHJvcGVydGllc1trZXldKSkge1xuICAgICAgICAgIHByb3BlcnRpZXNFbnRpdGllcy5wdXNoKFByb3BlcnR5RW50aXR5LmZyb21PYmplY3QoeyBpZDoga2V5LCB2YWx1ZTogcHJvcGVydGllc1trZXldIH0pKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICBpZiAodGhpcy5wcm9wZXJ0aWVzVGFibGUpIHtcbiAgICAgIGF3YWl0IHRoaXMucHJvcGVydGllc1RhYmxlLnJlYWR5KCk7XG4gICAgICB0aGlzLnByb3BlcnRpZXNUYWJsZS52YWx1ZSA9IHByb3BlcnRpZXNFbnRpdGllcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy50b2tlbnNUYWJsZSkge1xuICAgICAgYXdhaXQgdGhpcy50b2tlbnNUYWJsZS5yZWFkeSgpO1xuICAgICAgdGhpcy50b2tlbnNUYWJsZS52YWx1ZSA9IGRhdGEudG9rZW5zO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHJlZnJlc2goXz86IEV2ZW50KSB7XG4gICAgdGhpcy5kaXNhYmxlKCk7XG4gICAgdGhpcy5tYXJrQXNMb2FkaW5nKCk7XG5cbiAgICByZXR1cm4gdGhpcy5hY2NvdW50U2VydmljZS5yZWxvYWQoKTtcbiAgfVxuXG4gIHN0YXJ0TGlzdGVuQ2hhbmdlcygpIHtcbiAgICBpZiAodGhpcy5jaGFuZ2VzU3Vic2NyaXB0aW9uKSByZXR1cm47IC8vIGFscmVhZHkgc3RhcnRlZFxuICAgIHRoaXMuY2hhbmdlc1N1YnNjcmlwdGlvbiA9IHRoaXMuYWNjb3VudFNlcnZpY2UubGlzdGVuQ2hhbmdlcygpO1xuICB9XG5cbiAgc3RvcExpc3RlbkNoYW5nZXMoKSB7XG4gICAgaWYgKCF0aGlzLmNoYW5nZXNTdWJzY3JpcHRpb24pIHJldHVybjtcbiAgICB0aGlzLmNoYW5nZXNTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmNoYW5nZXNTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gIH1cblxuICBhc3luYyBzZW5kQ29uZmlybWF0aW9uRW1haWwoZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBjb25zdCBqc29uID0gdGhpcy5mb3JtLnZhbHVlO1xuICAgIGpzb24uZW1haWwgPSB0aGlzLmZvcm0uY29udHJvbHNbJ2VtYWlsJ10udmFsdWU7XG4gICAgaWYgKCFqc29uLmVtYWlsIHx8ICF0aGlzLmVtYWlsLm5vdENvbmZpcm1lZCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLmVtYWlsLnNlbmRpbmcgPSB0cnVlO1xuICAgIGNvbnNvbGUuZGVidWcoJ1thY2NvdW50XSBTZW5kaW5nIGNvbmZpcm1hdGlvbiBlbWFpbC4uLicpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmFjY291bnRTZXJ2aWNlLnNlbmRDb25maXJtYXRpb25FbWFpbChqc29uLmVtYWlsLCAoanNvbi5zZXR0aW5ncyAmJiBqc29uLnNldHRpbmdzLmxvY2FsZSkgfHwgdGhpcy50cmFuc2xhdGUuY3VycmVudExhbmcpO1xuICAgICAgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIENvbmZpcm1hdGlvbiBlbWFpbCBzZW50LicpO1xuICAgICAgdGhpcy5lbWFpbC5zZW5kaW5nID0gZmFsc2U7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLmVtYWlsLnNlbmRpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuZW1haWwuZXJyb3IgPSAoZXJyICYmIGVyci5tZXNzYWdlKSB8fCBlcnI7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2F2ZShldmVudCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0aGlzLnNhdmluZykgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKCF0aGlzLmZvcm0udmFsaWQpIHtcbiAgICAgIGF3YWl0IEFwcEZvcm1VdGlscy53YWl0V2hpbGVQZW5kaW5nKHRoaXMuZm9ybSk7XG5cbiAgICAgIGlmICh0aGlzLmZvcm0uaW52YWxpZCkge1xuICAgICAgICBBcHBGb3JtVXRpbHMubG9nRm9ybUVycm9ycyh0aGlzLmZvcm0pO1xuICAgICAgICB0aGlzLmZvcm0ubWFya0FsbEFzVG91Y2hlZCgpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zdWJtaXR0ZWQgPSB0cnVlO1xuICAgIHRoaXMuc2F2aW5nID0gdHJ1ZTtcbiAgICB0aGlzLmVycm9yID0gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgbmV3QWNjb3VudCA9IEFjY291bnQuZnJvbU9iamVjdCh7XG4gICAgICAuLi50aGlzLmFjY291bnRTZXJ2aWNlLmFjY291bnQuYXNPYmplY3QoKSxcbiAgICAgIC4uLnRoaXMuZm9ybS52YWx1ZSxcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLnByb3BlcnRpZXNUYWJsZSkge1xuICAgICAgLy8gbWVyZ2UgcHJvcGVydGllc1xuICAgICAgYXdhaXQgdGhpcy5wcm9wZXJ0aWVzVGFibGUuc2F2ZSgpO1xuICAgICAgY29uc3QgcHJvcGVydHlFbnRpdGllcyA9IHRoaXMucHJvcGVydGllc1RhYmxlLnZhbHVlIHx8IFtdO1xuICAgICAgY29uc3QgcHJvcGVydGllczogUHJvcGVydGllc01hcCA9IHByb3BlcnR5RW50aXRpZXMucmVkdWNlKChyZXMsIGl0ZW0pID0+IHtcbiAgICAgICAgcmVzW2l0ZW0uaWRdID0gaXRlbS52YWx1ZTtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH0sIHt9KTtcbiAgICAgIG5ld0FjY291bnQuc2V0dGluZ3MubWVyZ2UoPExvY2FsU2V0dGluZ3M+eyBwcm9wZXJ0aWVzIH0sIFsncHJvcGVydGllcyddKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy50b2tlbnNUYWJsZSkge1xuICAgICAgYXdhaXQgdGhpcy50b2tlbnNUYWJsZS5zYXZlKCk7XG4gICAgICBuZXdBY2NvdW50LnRva2VucyA9IHRoaXMudG9rZW5zVGFibGUudmFsdWU7XG4gICAgfVxuXG4gICAgY29uc29sZS5kZWJ1ZygnW2FjY291bnRdIFNhdmluZyBhY2NvdW50Li4uJywgbmV3QWNjb3VudCk7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuZGlzYWJsZSgpO1xuXG4gICAgICBhd2FpdCB0aGlzLmFjY291bnRTZXJ2aWNlLnNhdmUobmV3QWNjb3VudCk7XG5cbiAgICAgIC8vIFJlbG9hZFxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLm9uTG9naW4odGhpcy5hY2NvdW50U2VydmljZS5hY2NvdW50KSwgMTAwKTtcblxuICAgICAgdGhpcy5tYXJrQXNQcmlzdGluZSgpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICB0aGlzLmVycm9yID0gKGVyciAmJiBlcnIubWVzc2FnZSkgfHwgZXJyO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnNhdmluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5lbmFibGUoKTtcbiAgICB9XG4gIH1cblxuICBlbmFibGUob3B0cz86IHsgYWNjb3VudFJlYWRPbmx5PzogYm9vbGVhbjsgb25seVNlbGY/OiBib29sZWFuOyBlbWl0RXZlbnQ/OiBib29sZWFuIH0pIHtcbiAgICBzdXBlci5lbmFibGUoKTtcblxuICAgIC8vIFNvbWUgZmllbGRzIGFyZSBhbHdheXMgZGlzYWJsZVxuICAgIHRoaXMuZm9ybS5jb250cm9scy5lbWFpbC5kaXNhYmxlKCk7XG4gICAgdGhpcy5mb3JtLmNvbnRyb2xzLm1haW5Qcm9maWxlLmRpc2FibGUoKTtcbiAgICB0aGlzLmZvcm0uY29udHJvbHMucHVia2V5LmRpc2FibGUoKTtcblxuICAgIC8vIERpc2FibGUgYWNjb3VudCBmaWVsZHMgaWYgcmVhZG9ubHkgYnkgY29uZmlndXJhdGlvblxuICAgIGlmIChvcHRzPy5hY2NvdW50UmVhZE9ubHkpIHtcbiAgICAgIHRoaXMuZm9ybS5jb250cm9scy5sYXN0TmFtZS5kaXNhYmxlKCk7XG4gICAgICB0aGlzLmZvcm0uY29udHJvbHMuZmlyc3ROYW1lLmRpc2FibGUoKTtcbiAgICB9XG5cbiAgICAvLyBBbHdheXMgZGlzYWJsZSBzb21lIGFkZGl0aW9uYWwgZmllbGRzXG4gICAgdGhpcy5hZGRpdGlvbmFsRmllbGRzLmZvckVhY2goKGZpZWxkKSA9PiB7XG4gICAgICBjb25zdCBjb250cm9sID0gdGhpcy5mb3JtLmNvbnRyb2xzW2ZpZWxkLmtleV07XG4gICAgICBpZiAoIWNvbnRyb2wpIHJldHVybjsgLy8gU2tpcFxuXG4gICAgICBjb25zdCBkaXNhYmxlZCA9IChmaWVsZC5leHRyYT8uYWNjb3VudCAmJiBmaWVsZC5leHRyYS5hY2NvdW50LmRpc2FibGVkKSB8fCBmYWxzZTtcbiAgICAgIGlmIChkaXNhYmxlZCAmJiBjb250cm9sLmVuYWJsZWQpIHtcbiAgICAgICAgY29udHJvbC5kaXNhYmxlKCk7XG4gICAgICB9XG4gICAgICBjb25zdCByZXF1aXJlZCA9IChmaWVsZC5leHRyYT8uYWNjb3VudCAmJiBmaWVsZC5leHRyYS5hY2NvdW50LnJlcXVpcmVkKSB8fCBmYWxzZTtcbiAgICAgIGlmICghZmllbGQucmVxdWlyZWQgJiYgcmVxdWlyZWQpIHtcbiAgICAgICAgY29udHJvbC5zZXRWYWxpZGF0b3JzKGNvbnRyb2wudmFsaWRhdG9yID8gVmFsaWRhdG9ycy5jb21wb3NlKFtjb250cm9sLnZhbGlkYXRvciwgVmFsaWRhdG9ycy5yZXF1aXJlZF0pIDogVmFsaWRhdG9ycy5yZXF1aXJlZCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIGFzeW5jIGNhbmNlbCgpIHtcbiAgICBhd2FpdCBzdXBlci5jYW5jZWwoKTtcbiAgfVxuXG4gIGFzeW5jIGNsb3NlKF8/OiBFdmVudCkge1xuICAgIGlmICh0aGlzLnNhdmluZykgcmV0dXJuO1xuXG4gICAgLy8gQmFjayB0byBob21lXG4gICAgcmV0dXJuIHRoaXMubmF2Q29udHJvbGxlci5uYXZpZ2F0ZVJvb3QoJy8nKTsgLy8gYmFjayB0byBob21lXG4gIH1cblxuICBwcm90ZWN0ZWQgbWFya0ZvckNoZWNrKCkge1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cbiIsIjxhcHAtdG9vbGJhciBbdGl0bGVdPVwiJ0FDQ09VTlQuVElUTEUnfHRyYW5zbGF0ZVwiIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICAgICAgICAgW2hhc1ZhbGlkYXRlXT1cImRpcnR5ICYmICFzYXZpbmdcIlxuICAgICAgICAgICAgIFtoYXNDbG9zZV09XCIhZGlydHkgJiYgIXNhdmluZ1wiXG4gICAgICAgICAgICAgKG9uVmFsaWRhdGUpPVwic2F2ZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICBbY2FuR29CYWNrXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAob25DbG9zZSk9XCJjbG9zZSgkZXZlbnQpXCI+XG5cbiAgPGlvbi1idXR0b25zIHNsb3Q9XCJlbmRcIj5cbiAgICA8IS0tIGxvYWRlciAtLT5cbiAgICA8aW9uLXNwaW5uZXIgKm5nSWY9XCJsb2FkaW5nIHx8IHNhdmluZzsgZWxzZSBlbmRCdXR0b25zXCI+PC9pb24tc3Bpbm5lcj5cblxuICAgIDxuZy10ZW1wbGF0ZSAjZW5kQnV0dG9ucz5cbiAgICAgIDwhLS0gcmVmcmVzaCBidXR0b24gKGlmIG9ubGluZSkgLS0+XG4gICAgICA8aW9uLWJ1dHRvbiBbbWF0VG9vbHRpcF09XCInQ09NTU9OLkJUTl9SRUZSRVNIJ3x0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJuZXR3b3JrLm9ubGluZVwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVmcmVzaCgkZXZlbnQpXCI+XG4gICAgICAgIDxtYXQtaWNvbiBzbG90PVwiaWNvbi1vbmx5XCI+cmVmcmVzaDwvbWF0LWljb24+XG4gICAgICA8L2lvbi1idXR0b24+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9pb24tYnV0dG9ucz5cbjwvYXBwLXRvb2xiYXI+XG5cbjxpb24tY29udGVudD5cblxuICA8IS0tIGVycm9yIC0tPlxuICA8aW9uLWl0ZW0gKm5nSWY9XCJlcnJvciAmJiBtb2JpbGVcIiBsaW5lcz1cIm5vbmVcIj5cbiAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJlcnJvclwiIFtpbm5lckhUTUxdPVwiZXJyb3J8dHJhbnNsYXRlXCI+PC9pb24tbGFiZWw+XG4gIDwvaW9uLWl0ZW0+XG5cbiAgPGZvcm0gW2Zvcm1Hcm91cF09XCJmb3JtXCIgbm92YWxpZGF0ZSBjbGFzcz1cImZvcm0tY29udGFpbmVyXCI+XG5cbiAgICA8bWF0LXRhYi1ncm91cCAjdGFiR3JvdXAgWyhzZWxlY3RlZEluZGV4KV09XCJzZWxlY3RlZFRhYkluZGV4XCIgZHluYW1pY0hlaWdodD5cblxuICAgICAgPCEtLSBUQUI6IHVzZXIgZGV0YWlscyAtLT5cbiAgICAgIDxtYXQtdGFiIGxhYmVsPVwie3snQUNDT1VOVC5VU0VSX0RFVEFJTFMuVElUTEUnfHRyYW5zbGF0ZX19XCIgY2xhc3M9XCJpb24tcGFkZGluZ1wiPlxuICAgICAgICA8bmctdGVtcGxhdGUgbWF0LXRhYi1sYWJlbD5cbiAgICAgICAgICA8bWF0LWljb24+XG4gICAgICAgICAgICA8aW9uLWljb24gbWF0UHJlZml4IHNsb3Q9XCJzdGFydFwiIG5hbWU9XCJwZXJzb24tY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgIDxpb24tbGFiZWw+e3snQUNDT1VOVC5VU0VSX0RFVEFJTFMuVElUTEUnfHRyYW5zbGF0ZX19PC9pb24tbGFiZWw+XG4gICAgICAgICAgPGlvbi1pY29uIHNsb3Q9XCJlbmRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCIgY29sb3I9XCJkYW5nZXJcIiAqbmdJZj1cInN1Ym1pdHRlZCAmJiBmb3JtLmludmFsaWRcIj48L2lvbi1pY29uPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpb24tcGFkZGluZ1wiPlxuXG4gICAgICAgICAgPHAgW2lubmVySFRNTF09XCInQUNDT1VOVC5VU0VSX0RFVEFJTFMuREVTQ1JJUFRJT04nfHRyYW5zbGF0ZVwiPjwvcD5cblxuICAgICAgICAgIDwhLS1oMT5JZGVudGl0w6k8L2gxLS0+XG5cbiAgICAgICAgICA8IS0tIEVtYWlsIC0tPlxuICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbcGxhY2Vob2xkZXJdPVwiJ1VTRVIuRU1BSUwnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZW1haWxcIiBhdXRvY29tcGxldGU9XCJzZWN0aW9uLXJlZCBlbWFpbFwiPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuZW1haWwuaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgZm9ybS5jb250cm9scy5lbWFpbC5kaXJ0eVwiIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuZW1haWwuaGFzRXJyb3IoJ2VtYWlsJykgJiYgZm9ybS5jb250cm9scy5lbWFpbC5kaXJ0eVwiPlxuICAgICAgICAgICAgICA8c3Bhbj57eydFUlJPUi5GSUVMRF9OT1RfVkFMSURfRU1BSUwnIHwgdHJhbnNsYXRlIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICAgIDxpb24tZ3JpZCAqbmdJZj1cImVtYWlsLm5vdENvbmZpcm1lZFwiIGNsYXNzPVwiaW9uLW5vLXBhZGRpbmcgaW9uLXBhZGRpbmctYm90dG9tXCI+XG4gICAgICAgICAgICA8aW9uLXJvdz5cbiAgICAgICAgICAgICAgPGlvbi1jb2wgY29sb3I9XCJkYW5nZXJcIj5cbiAgICAgICAgICAgICAgICA8aW9uLWljb24gc2xvdD1cInN0YXJ0XCIgY29sb3I9XCJkYW5nZXJcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICAgICAgICAgICAgICA8aW9uLXRleHQgW2lubmVySFRNTF09XCInQUNDT1VOVC5FTUFJTF9OT1RfQ09ORklSTUVEX0xBQkVMJ3x0cmFuc2xhdGVcIj48L2lvbi10ZXh0PlxuICAgICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgICA8L2lvbi1yb3c+XG5cbiAgICAgICAgICAgIDxpb24tcm93IHN0eWxlPVwiaGVpZ2h0OiA1MXB4O1wiPlxuICAgICAgICAgICAgICA8aW9uLWNvbCBzdHlsZT1cInRleHQtYWxpZ246IHJpZ2h0O1wiPlxuICAgICAgICAgICAgICAgIDxpb24tdGV4dD5cbiAgICAgICAgICAgICAgICAgIDxzbWFsbCBbaW5uZXJIVE1MXT1cIidBQ0NPVU5ULkVNQUlMX05PVF9SRUNFSVZFRF9RVUVTVElPTid8dHJhbnNsYXRlXCI+PC9zbWFsbD5cbiAgICAgICAgICAgICAgICA8L2lvbi10ZXh0PlxuICAgICAgICAgICAgICA8L2lvbi1jb2w+XG4gICAgICAgICAgICAgIDxpb24tY29sIHNpemU9XCJhdXRvXCI+XG4gICAgICAgICAgICAgICAgPGlvbi1idXR0b24gZmlsbD1cInNvbGlkXCIgY29sb3I9XCJzZWNvbmRhcnlcIiAqbmdJZj1cIiFlbWFpbC5zZW5kaW5nXCIgKGNsaWNrKT1cInNlbmRDb25maXJtYXRpb25FbWFpbCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICB7eydBQ0NPVU5ULkJUTl9SRVNFTkQnfHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgPC9pb24tYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxpb24tc3Bpbm5lciBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCIgKm5nSWY9XCJlbWFpbC5zZW5kaW5nXCI+PC9pb24tc3Bpbm5lcj5cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgPC9pb24tcm93PlxuXG4gICAgICAgICAgICA8aW9uLXJvdyAqbmdJZj1cImVtYWlsLmVycm9yICYmICFlbWFpbC5zZW5kaW5nXCI+XG4gICAgICAgICAgICAgIDxpb24tY29sPlxuICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZW1haWwuZXJyb3IgJiYgIWVtYWlsLnNlbmRpbmdcIiBbaW5uZXJIVE1MXT1cImVtYWlsLmVycm9yfHRyYW5zbGF0ZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9pb24tY29sPlxuICAgICAgICAgICAgPC9pb24tcm93PlxuICAgICAgICAgIDwvaW9uLWdyaWQ+XG5cbiAgICAgICAgICA8IS0tIExhc3QgbmFtZSAtLT5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgW2FwcEF1dG9mb2N1c109XCJ0cnVlXCIgW2F1dG9mb2N1c0RlbGF5XT1cIjUwMFwiIFtwbGFjZWhvbGRlcl09XCInVVNFUi5MQVNUX05BTUUnfHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwibGFzdE5hbWVcIlxuICAgICAgICAgICAgICAgICAgIGF1dG9jb21wbGV0ZT1cInNlY3Rpb24tYmx1ZSBmYW1pbHktbmFtZVwiXG4gICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5sYXN0TmFtZS5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiBmb3JtLmNvbnRyb2xzLmxhc3ROYW1lLmRpcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmxhc3ROYW1lLmhhc0Vycm9yKCdtaW5sZW5ndGgnKSAmJiBmb3JtLmNvbnRyb2xzLmxhc3ROYW1lLmRpcnR5XCI+XG4gICAgICAgICAgICAgIDxzcGFuPnt7J0VSUk9SLkZJRUxEX01JTl9MRU5HVEgnIHwgdHJhbnNsYXRlOiB7bWluTGVuZ3RoOiAyfSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgICAgICA8IS0tIEZpcnN0IG5hbWUgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFtwbGFjZWhvbGRlcl09XCInVVNFUi5GSVJTVF9OQU1FJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJmaXJzdE5hbWVcIiBhdXRvY29tcGxldGU9XCJzZWN0aW9uLWJsdWUgZ2l2ZW4tbmFtZVwiXG4gICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5maXJzdE5hbWUuaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgZm9ybS5jb250cm9scy5maXJzdE5hbWUuZGlydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGU+RVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuZmlyc3ROYW1lLmhhc0Vycm9yKCdtaW5sZW5ndGgnKSAmJiBmb3JtLmNvbnRyb2xzLmZpcnN0TmFtZS5kaXJ0eVwiPlxuICAgICAgICAgICAgICA8c3Bhbj57eydFUlJPUi5GSUVMRF9NSU5fTEVOR1RIJyB8IHRyYW5zbGF0ZToge21pbkxlbmd0aDogMn0gfX08L3NwYW4+XG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG5cbiAgICAgICAgICA8IS0tIEFkZGl0aW9uYWwgZmllbGRzIC0tPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGRlZmluaXRpb24gb2YgYWRkaXRpb25hbEZpZWxkc1wiPlxuICAgICAgICAgICAgPGFwcC1mb3JtLWZpZWxkIFtkZWZpbml0aW9uXT1cImRlZmluaXRpb25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbE5hbWVdPVwiZGVmaW5pdGlvbi5rZXlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJkZWZpbml0aW9uLmV4dHJhICYmIGRlZmluaXRpb24uZXh0cmEuYWNjb3VudCAmJiBkZWZpbml0aW9uLmV4dHJhLmFjY291bnQucmVxdWlyZWQgfHwgZmFsc2VcIj5cbiAgICAgICAgICAgIDwvYXBwLWZvcm0tZmllbGQ+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICA8aDMgdHJhbnNsYXRlPkFDQ09VTlQuVVNFUl9ERVRBSUxTLlRFQ0hOSUNBTF9ESVZJREVSPC9oMz5cblxuICAgICAgICAgIDwhLS0gcHJvZmlsZSAtLT5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgaGlkZGVuIHJlYWRvbmx5PVwidHJ1ZVwiIFtwbGFjZWhvbGRlcl09XCInQUNDT1VOVC5VU0VSX0RFVEFJTFMuUFJPRklMRSd8dHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJtYWluUHJvZmlsZVwiIHJlcXVpcmVkPlxuICAgICAgICAgICAgPHNwYW4+e3snVVNFUi5QUk9GSUxFX0VOVU0uJyArIGZvcm0uY29udHJvbHMubWFpblByb2ZpbGUudmFsdWUgfCB0cmFuc2xhdGV9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJmb3JtLmNvbnRyb2xzLmZpcnN0TmFtZS5oYXNFcnJvcignbWFpblByb2ZpbGUnKSAmJiBmb3JtLmNvbnRyb2xzLm1haW5Qcm9maWxlLmRpcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgICAgPCEtLSBwdWJrZXkgLS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IHJlYWRvbmx5PVwidHJ1ZVwiIFtwbGFjZWhvbGRlcl09XCInQUNDT1VOVC5VU0VSX0RFVEFJTFMuUFVCS0VZJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJwdWJrZXlcIlxuICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPlxuICAgICAgICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImZvcm0uY29udHJvbHMuZmlyc3ROYW1lLmhhc0Vycm9yKCdwdWJrZXknKSAmJiBmb3JtLmNvbnRyb2xzLmZpcnN0TmFtZS5kaXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5maXJzdE5hbWUuaGFzRXJyb3IoJ3B1YmtleScpICYmIGZvcm0uY29udHJvbHMuZmlyc3ROYW1lLmRpcnR5XCI+XG4gICAgICAgICAgICAgIDxzcGFuIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9OT1RfVkFMSURfUFVCS0VZPC9zcGFuPlxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbWF0LXRhYj5cblxuICAgICAgPCEtLSBUQUI6IHNldHRpbmdzIC0tPlxuICAgICAgPG1hdC10YWIgbGFiZWw9XCJ7eydBQ0NPVU5ULlNFVFRJTkdTLlRJVExFJ3x0cmFuc2xhdGV9fVwiIGZvcm1Hcm91cE5hbWU9XCJzZXR0aW5nc1wiPlxuICAgICAgICA8bmctdGVtcGxhdGUgbWF0LXRhYi1sYWJlbD5cbiAgICAgICAgICA8bWF0LWljb24+XG4gICAgICAgICAgICA8aW9uLWljb24gbWF0UHJlZml4IHNsb3Q9XCJzdGFydFwiIG5hbWU9XCJzZXR0aW5nc1wiPjwvaW9uLWljb24+XG4gICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5BQ0NPVU5ULlNFVFRJTkdTLlRJVExFPC9pb24tbGFiZWw+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImlvbi1wYWRkaW5nXCI+XG5cbiAgICAgICAgICA8cCBbaW5uZXJIVE1MXT1cIidBQ0NPVU5ULlNFVFRJTkdTLkRFU0NSSVBUSU9OJ3x0cmFuc2xhdGVcIj48L3A+XG5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICA8bWF0LXNlbGVjdCBbcGxhY2Vob2xkZXJdPVwiJ0FDQ09VTlQuU0VUVElOR1MuTE9DQUxFJ3x0cmFuc2xhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJsb2NhbGVcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgbG9jYWxlc1wiIFt2YWx1ZV09XCJpdGVtLmtleVwiPlxuICAgICAgICAgICAgICAgIHt7aXRlbS52YWx1ZX19XG4gICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJzZXR0aW5nc0Zvcm0/LmNvbnRyb2xzLmxvY2FsZS5oYXNFcnJvcigncmVxdWlyZWQnKSAmJiBzZXR0aW5nc0Zvcm0/LmNvbnRyb2xzLmxvY2FsZS5kaXJ0eVwiXG4gICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZT5FUlJPUi5GSUVMRF9SRVFVSVJFRFxuICAgICAgICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgICAgICAgIDwhLS0gbGF0L2xvbmcgZm9ybWF0LS0+XG4gICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgPG1hdC1zZWxlY3QgW3BsYWNlaG9sZGVyXT1cIidBQ0NPVU5ULlNFVFRJTkdTLkxBVF9MT05HX0ZPUk1BVCd8dHJhbnNsYXRlXCIgZm9ybUNvbnRyb2xOYW1lPVwibGF0TG9uZ0Zvcm1hdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD5cbiAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IGl0ZW0gb2YgbGF0TG9uZ0Zvcm1hdHNcIiBbdmFsdWVdPVwiaXRlbVwiPlxuICAgICAgICAgICAgICAgIHt7J0NPTU1PTi5MQVRfTE9ORy4nICsgaXRlbSArICdfUExBQ0VIT0xERVInfHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgIDxtYXQtZXJyb3IgKm5nSWY9XCJzZXR0aW5nc0Zvcm0/LmNvbnRyb2xzLmxhdExvbmdGb3JtYXQuaGFzRXJyb3IoJ3JlcXVpcmVkJykgJiYgc2V0dGluZ3NGb3JtPy5jb250cm9scy5sYXRMb25nRm9ybWF0LmRpcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlPkVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gT3B0aW9ucyB0YWJsZSAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm9wdGlvbnMtdGFibGVcIiBbY2xhc3MuY2RrLXZpc3VhbGx5LWhpZGRlbl09XCJvcHRpb25EZWZpbml0aW9ucyB8IGlzRW1wdHlBcnJheVwiPlxuICAgICAgICAgIDxhcHAtcHJvcGVydGllcy10YWJsZVxuICAgICAgICAgICAgI3Byb3BlcnRpZXNUYWJsZVxuICAgICAgICAgICAgaTE4bkNvbHVtblByZWZpeD1cIkFDQ09VTlQuU0VUVElOR1MuT1BUSU9OUy5cIlxuICAgICAgICAgICAgW2RlZmluaXRpb25zXT1cIm9wdGlvbkRlZmluaXRpb25zXCJcbiAgICAgICAgICAgIFtkZWJ1Z109XCJkZWJ1Z1wiXG4gICAgICAgICAgICBbY2FuRWRpdF09XCJ0cnVlXCJcbiAgICAgICAgICAgIChvbkRpcnR5KT1cIiRldmVudCA/IG1hcmtBc0RpcnR5KCkgOiB1bmRlZmluZWRcIlxuICAgICAgICAgID48L2FwcC1wcm9wZXJ0aWVzLXRhYmxlPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgPC9tYXQtdGFiPlxuXG4gICAgICA8IS0tIFRBQjogdG9rZW5zIC0tPlxuICAgICAgPG1hdC10YWIgKm5nSWY9XCJhdXRoVG9rZW5FbmFibGVkXCIgbGFiZWw9XCJ7eydBQ0NPVU5ULlRPS0VOUy5USVRMRSd8dHJhbnNsYXRlfX1cIiBmb3JtR3JvdXBOYW1lPVwidG9rZW5zXCI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBtYXQtdGFiLWxhYmVsPlxuICAgICAgICAgIDxtYXQtaWNvbj5cbiAgICAgICAgICAgIDxpb24taWNvbiBtYXRQcmVmaXggc2xvdD1cInN0YXJ0XCIgbmFtZT1cInRpY2tldFwiPjwvaW9uLWljb24+XG4gICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgICA8aW9uLWxhYmVsIHRyYW5zbGF0ZT5BQ0NPVU5ULlRPS0VOUy5USVRMRTwvaW9uLWxhYmVsPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJpb24tcGFkZGluZ1wiPlxuICAgICAgICAgIDxwIFtpbm5lckhUTUxdPVwiJ0FDQ09VTlQuVE9LRU5TLkRFU0NSSVBUSU9OJ3x0cmFuc2xhdGVcIj48L3A+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gVG9rZW5zIHRhYmxlIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidG9rZW5zLXRhYmxlXCI+XG4gICAgICAgICAgPGFwcC11c2VyLXRva2VuLXRhYmxlXG4gICAgICAgICAgICAjdG9rZW5zVGFibGVcbiAgICAgICAgICAgIFtjYW5FZGl0XT1cInRydWVcIlxuICAgICAgICAgICAgKG9uRGlydHkpPVwiJGV2ZW50ID8gbWFya0FzRGlydHkoKSA6IHVuZGVmaW5lZFwiXG4gICAgICAgICAgPjwvYXBwLXVzZXItdG9rZW4tdGFibGU+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICA8L21hdC10YWI+XG4gICAgPC9tYXQtdGFiLWdyb3VwPlxuXG5cbiAgPC9mb3JtPlxuPC9pb24tY29udGVudD5cblxuPGlvbi1mb290ZXIgaGlkZGVuLXhzIGhpZGRlbi1zbSBoaWRkZW4tbW9iaWxlPlxuICA8YXBwLWZvcm0tYnV0dG9ucy1iYXIgKG9uQ2FuY2VsKT1cImNhbmNlbCgpXCIgKG9uU2F2ZSk9XCJzYXZlKCRldmVudClcIiBbZGlzYWJsZWRdPVwiIWZvcm0uZGlydHkgfHwgIXZhbGlkIHx8IHNhdmluZ1wiPlxuICAgIDwhLS0gZXJyb3IgLS0+XG4gICAgPGlvbi1pdGVtICpuZ0lmPVwiZXJyb3IgJiYgIW1vYmlsZVwiIGxpbmVzPVwibm9uZVwiPlxuICAgICAgPGlvbi1pY29uIGNvbG9yPVwiZGFuZ2VyXCIgc2xvdD1cInN0YXJ0XCIgbmFtZT1cImFsZXJ0LWNpcmNsZVwiPjwvaW9uLWljb24+XG4gICAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJlcnJvclwiIFtpbm5lckhUTUxdPVwiZXJyb3J8dHJhbnNsYXRlXCI+PC9pb24tbGFiZWw+XG4gICAgPC9pb24taXRlbT5cbiAgPC9hcHAtZm9ybS1idXR0b25zLWJhcj5cbjwvaW9uLWZvb3Rlcj5cbiJdfQ==