@sumaris-net/ngx-components 18.23.49 → 18.23.52

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 (77) hide show
  1. package/doc/changelog.md +4 -0
  2. package/esm2022/public_api.mjs +2 -1
  3. package/esm2022/src/app/admin/users/users.mjs +25 -22
  4. package/esm2022/src/app/core/account/new-token.form.mjs +12 -9
  5. package/esm2022/src/app/core/account/token.table.mjs +14 -11
  6. package/esm2022/src/app/core/form/array/testing/form-array.test.mjs +9 -6
  7. package/esm2022/src/app/core/form/buttons/form-buttons-bar.component.mjs +8 -5
  8. package/esm2022/src/app/core/form/list/list.form.mjs +8 -5
  9. package/esm2022/src/app/core/form/properties/properties.form.mjs +12 -9
  10. package/esm2022/src/app/core/form/properties/properties.table.mjs +15 -12
  11. package/esm2022/src/app/core/form/text-popover/text-popover.component.mjs +10 -7
  12. package/esm2022/src/app/core/home/home.mjs +21 -18
  13. package/esm2022/src/app/core/menu/menu.component.mjs +10 -7
  14. package/esm2022/src/app/core/settings/settings.page.mjs +10 -7
  15. package/esm2022/src/app/core/table/column/actions-column.component.mjs +8 -5
  16. package/esm2022/src/app/core/table/column/nav-actions-column.component.mjs +9 -6
  17. package/esm2022/src/app/core/table/testing/table.testing.mjs +27 -23
  18. package/esm2022/src/app/core/table/testing/table2.testing.mjs +25 -22
  19. package/esm2022/src/app/shared/constants.mjs +3 -1
  20. package/esm2022/src/app/shared/directives/autotooltip.directive.mjs +35 -0
  21. package/esm2022/src/app/shared/directives/directives.module.mjs +33 -4
  22. package/esm2022/src/app/shared/image/gallery/image-gallery.component.mjs +15 -12
  23. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +13 -11
  24. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +4 -2
  25. package/esm2022/src/app/shared/material/boolean/boolean.module.mjs +5 -2
  26. package/esm2022/src/app/shared/material/boolean/material.boolean.mjs +9 -6
  27. package/esm2022/src/app/shared/material/boolean/testing/boolean.test.page.mjs +15 -4
  28. package/esm2022/src/app/shared/material/chips/chips.module.mjs +5 -2
  29. package/esm2022/src/app/shared/material/chips/material.chips.mjs +14 -12
  30. package/esm2022/src/app/shared/named-filter/named-filter-selector.component.mjs +8 -5
  31. package/esm2022/src/app/shared/storage/storage-explorer.component.mjs +11 -9
  32. package/esm2022/src/app/social/feed/feed.component.mjs +15 -12
  33. package/esm2022/src/app/social/job/progression/job-progression.icon.mjs +11 -8
  34. package/esm2022/src/app/social/job/progression/job-progression.list.mjs +12 -9
  35. package/esm2022/src/app/social/user-event/notification/user-event-notification.icon.mjs +12 -8
  36. package/esm2022/src/app/social/user-event/notification/user-event-notification.list.mjs +12 -9
  37. package/esm2022/src/app/social/user-event/notification/user-event-notification.modal.mjs +9 -6
  38. package/fesm2022/sumaris-net.ngx-components.mjs +194 -89
  39. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  40. package/package.json +1 -1
  41. package/public_api.d.ts +1 -0
  42. package/src/app/admin/users/users.d.ts +1 -0
  43. package/src/app/core/account/new-token.form.d.ts +1 -0
  44. package/src/app/core/account/token.table.d.ts +1 -0
  45. package/src/app/core/form/array/testing/form-array.test.d.ts +1 -0
  46. package/src/app/core/form/buttons/form-buttons-bar.component.d.ts +1 -0
  47. package/src/app/core/form/list/list.form.d.ts +1 -0
  48. package/src/app/core/form/properties/properties.form.d.ts +1 -0
  49. package/src/app/core/form/properties/properties.table.d.ts +1 -0
  50. package/src/app/core/form/text-popover/text-popover.component.d.ts +1 -0
  51. package/src/app/core/home/home.d.ts +1 -0
  52. package/src/app/core/menu/menu.component.d.ts +1 -0
  53. package/src/app/core/settings/settings.page.d.ts +1 -0
  54. package/src/app/core/table/column/actions-column.component.d.ts +1 -0
  55. package/src/app/core/table/column/nav-actions-column.component.d.ts +1 -0
  56. package/src/app/core/table/testing/table.testing.d.ts +1 -0
  57. package/src/app/core/table/testing/table2.testing.d.ts +1 -0
  58. package/src/app/shared/constants.d.ts +2 -0
  59. package/src/app/shared/directives/autotooltip.directive.d.ts +14 -0
  60. package/src/app/shared/directives/directives.module.d.ts +4 -3
  61. package/src/app/shared/image/gallery/image-gallery.component.d.ts +1 -0
  62. package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +1 -0
  63. package/src/app/shared/material/autocomplete/material.autocomplete.module.d.ts +2 -1
  64. package/src/app/shared/material/boolean/boolean.module.d.ts +2 -1
  65. package/src/app/shared/material/boolean/material.boolean.d.ts +1 -0
  66. package/src/app/shared/material/boolean/testing/boolean.test.page.d.ts +5 -0
  67. package/src/app/shared/material/chips/chips.module.d.ts +2 -1
  68. package/src/app/shared/material/chips/material.chips.d.ts +1 -0
  69. package/src/app/shared/named-filter/named-filter-selector.component.d.ts +1 -0
  70. package/src/app/shared/storage/storage-explorer.component.d.ts +1 -0
  71. package/src/app/social/feed/feed.component.d.ts +1 -0
  72. package/src/app/social/job/progression/job-progression.icon.d.ts +1 -0
  73. package/src/app/social/job/progression/job-progression.list.d.ts +1 -0
  74. package/src/app/social/user-event/notification/user-event-notification.icon.d.ts +1 -0
  75. package/src/app/social/user-event/notification/user-event-notification.list.d.ts +2 -0
  76. package/src/app/social/user-event/notification/user-event-notification.modal.d.ts +1 -0
  77. package/src/assets/manifest.json +1 -1
@@ -1,7 +1,8 @@
1
- import { Component, Input } from '@angular/core';
1
+ import { Component, inject, Input } from '@angular/core';
2
2
  import { AppForm } from '../form/form.class';
3
3
  import { PlatformService } from '../services/platform.service';
4
4
  import { isNilOrBlank, isNotNilOrBlank } from '../../shared/functions';
5
+ import { APP_SHOW_TOOLTIP } from '../../shared/constants';
5
6
  import * as i0 from "@angular/core";
6
7
  import * as i1 from "../services/validator/user-token.validator";
7
8
  import * as i2 from "../services/account.service";
@@ -13,11 +14,12 @@ import * as i7 from "@angular/material/form-field";
13
14
  import * as i8 from "@angular/material/input";
14
15
  import * as i9 from "@angular/material/icon";
15
16
  import * as i10 from "@angular/material/button";
16
- import * as i11 from "../../shared/material/datetime/material.date";
17
- import * as i12 from "../../shared/material/chips/material.chips";
18
- import * as i13 from "../../shared/directives/autofocus.directive";
19
- import * as i14 from "../../shared/pipes/string.pipes";
20
- import * as i15 from "../../shared/pipes/form.pipes";
17
+ import * as i11 from "@angular/material/tooltip";
18
+ import * as i12 from "../../shared/material/datetime/material.date";
19
+ import * as i13 from "../../shared/material/chips/material.chips";
20
+ import * as i14 from "../../shared/directives/autofocus.directive";
21
+ import * as i15 from "../../shared/pipes/string.pipes";
22
+ import * as i16 from "../../shared/pipes/form.pipes";
21
23
  export class NewTokenForm extends AppForm {
22
24
  validator;
23
25
  accountService;
@@ -28,6 +30,7 @@ export class NewTokenForm extends AppForm {
28
30
  existingNames;
29
31
  mobile;
30
32
  platform;
33
+ showTooltip = inject(APP_SHOW_TOOLTIP, { optional: true });
31
34
  constructor(injector, validator, accountService, cd) {
32
35
  super(injector, validator.getFormGroup());
33
36
  this.validator = validator;
@@ -89,11 +92,11 @@ export class NewTokenForm extends AppForm {
89
92
  this.cd.markForCheck();
90
93
  }
91
94
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NewTokenForm, deps: [{ token: i0.Injector }, { token: i1.UserTokenValidatorService }, { token: i2.AccountService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
92
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: NewTokenForm, selector: "app-new-token-form", inputs: { showScopes: "showScopes", tokenScopes: "tokenScopes", existingNames: "existingNames", mobile: "mobile" }, usesInheritance: true, ngImport: i0, template: "<form class=\"form-container\" [formGroup]=\"form\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-form-field>\n <mat-label>{{ 'ACCOUNT.TOKENS.CREATE.NAME' | translate }}</mat-label>\n <input\n matInput\n [appAutofocus]=\"true\"\n [autofocusDelay]=\"500\"\n formControlName=\"name\"\n autocomplete=\"off\"\n required\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n />\n <mat-error *ngIf=\"form.controls.name.hasError('required') && form.controls.name.touched\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.name.hasError('notAlreadyExists') && form.controls.name.touched\" translate>\n ACCOUNT.TOKENS.CREATE.NAME_ALREADY_EXISTS\n </mat-error>\n </mat-form-field>\n </ion-col>\n </ion-row>\n @if (showScopes) {\n <ion-row>\n <ion-col>\n <mat-chips-field\n formControlName=\"scopes\"\n appearance=\"fill\"\n chipColor=\"primary\"\n [placeholder]=\"'ACCOUNT.TOKENS.CREATE.SCOPES' | translate\"\n [config]=\"tokenConfig\"\n [mobile]=\"mobile\"\n [debug]=\"false\"\n [required]=\"true\"\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n >\n <mat-error *ngIf=\"form.controls.name.hasError('notEmptyArray') && form.controls.name.touched\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-chips-field>\n </ion-col>\n </ion-row>\n }\n <ion-row>\n <ion-col>\n <mat-date-field\n formControlName=\"expirationDate\"\n [placeholder]=\"'ACCOUNT.TOKENS.CREATE.EXPIRATION_DATE' | translate\"\n [mobile]=\"mobile\"\n [required]=\"true\"\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n ></mat-date-field>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <ion-button\n *ngIf=\"form | formGetValue: 'token' | isNilOrBlank; else showToken\"\n [title]=\"'ACCOUNT.TOKENS.CREATE.BTN_GENERATE_TITLE' | translate\"\n (click)=\"generate($event)\"\n [disabled]=\"form.invalid\"\n >\n {{ 'ACCOUNT.TOKENS.CREATE.BTN_GENERATE' | translate }}\n </ion-button>\n <ng-template #showToken>\n <p><b translate>ACCOUNT.TOKENS.CREATE.COPY_HELP</b></p>\n <mat-form-field subscriptSizing=\"dynamic\">\n <textarea\n matInput\n formControlName=\"token\"\n readonly\n style=\"height: auto; background-color: lightgray\"\n rows=\"8\"\n ></textarea>\n <button\n matSuffix\n mat-icon-button\n [title]=\"'ACCOUNT.TOKENS.CREATE.BTN_COPY_TITLE' | translate\"\n (click)=\"copy($event)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </mat-form-field>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n</form>\n", dependencies: [{ kind: "directive", type: i3.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.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.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i8.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: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i11.MatDate, selector: "mat-date-field", inputs: ["formControl", "formControlName", "placeholder", "floatLabel", "mobile", "compact", "autofocus", "clearable", "required", "startDate", "timezone", "datePickerFilter", "appearance", "subscriptSizing", "readonly", "tabindex"] }, { kind: "component", type: i12.MatChipsField, selector: "mat-chips-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "placeholder", "suggestFn", "required", "mobile", "readonly", "clearable", "debounceTime", "displaySeparator", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "autofocus", "config", "i18nPrefix", "noResultMessage", "panelClass", "panelWidth", "disableRipple", "matAutocompletePosition", "itemSize", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "chipColor", "debug", "applyImplicitValue", "dropButtonTitle", "clearButtonTitle", "trimSearchText", "hideRequiredMarker", "colSizes", "separatorKeysCodes", "showChips", "appearance", "subscriptSizing", "class", "filter", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keyup.enter"] }, { kind: "directive", type: i13.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i14.IsNilOrBlankPipe, name: "isNilOrBlank" }, { kind: "pipe", type: i14.IsNotNilOrBlankPipe, name: "isNotNilOrBlank" }, { kind: "pipe", type: i15.FormGetValuePipe, name: "formGetValue" }] });
95
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: NewTokenForm, selector: "app-new-token-form", inputs: { showScopes: "showScopes", tokenScopes: "tokenScopes", existingNames: "existingNames", mobile: "mobile" }, usesInheritance: true, ngImport: i0, template: "<form class=\"form-container\" [formGroup]=\"form\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-form-field>\n <mat-label>{{ 'ACCOUNT.TOKENS.CREATE.NAME' | translate }}</mat-label>\n <input\n matInput\n [appAutofocus]=\"true\"\n [autofocusDelay]=\"500\"\n formControlName=\"name\"\n autocomplete=\"off\"\n required\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n />\n <mat-error *ngIf=\"form.controls.name.hasError('required') && form.controls.name.touched\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.name.hasError('notAlreadyExists') && form.controls.name.touched\" translate>\n ACCOUNT.TOKENS.CREATE.NAME_ALREADY_EXISTS\n </mat-error>\n </mat-form-field>\n </ion-col>\n </ion-row>\n @if (showScopes) {\n <ion-row>\n <ion-col>\n <mat-chips-field\n formControlName=\"scopes\"\n appearance=\"fill\"\n chipColor=\"primary\"\n [placeholder]=\"'ACCOUNT.TOKENS.CREATE.SCOPES' | translate\"\n [config]=\"tokenConfig\"\n [mobile]=\"mobile\"\n [debug]=\"false\"\n [required]=\"true\"\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n >\n <mat-error *ngIf=\"form.controls.name.hasError('notEmptyArray') && form.controls.name.touched\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-chips-field>\n </ion-col>\n </ion-row>\n }\n <ion-row>\n <ion-col>\n <mat-date-field\n formControlName=\"expirationDate\"\n [placeholder]=\"'ACCOUNT.TOKENS.CREATE.EXPIRATION_DATE' | translate\"\n [mobile]=\"mobile\"\n [required]=\"true\"\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n ></mat-date-field>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <ion-button\n *ngIf=\"form | formGetValue: 'token' | isNilOrBlank; else showToken\"\n [title]=\"!showTooltip ? ('ACCOUNT.TOKENS.CREATE.BTN_GENERATE_TITLE' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('ACCOUNT.TOKENS.CREATE.BTN_GENERATE_TITLE' | translate) : ''\"\n (click)=\"generate($event)\"\n [disabled]=\"form.invalid\"\n >\n {{ 'ACCOUNT.TOKENS.CREATE.BTN_GENERATE' | translate }}\n </ion-button>\n <ng-template #showToken>\n <p><b translate>ACCOUNT.TOKENS.CREATE.COPY_HELP</b></p>\n <mat-form-field subscriptSizing=\"dynamic\">\n <textarea\n matInput\n formControlName=\"token\"\n readonly\n style=\"height: auto; background-color: lightgray\"\n rows=\"8\"\n ></textarea>\n <button\n matSuffix\n mat-icon-button\n [title]=\"!showTooltip ? ('ACCOUNT.TOKENS.CREATE.BTN_COPY_TITLE' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('ACCOUNT.TOKENS.CREATE.BTN_COPY_TITLE' | translate) : ''\"\n (click)=\"copy($event)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </mat-form-field>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n</form>\n", dependencies: [{ kind: "directive", type: i3.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.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.IonGrid, selector: "ion-grid", inputs: ["fixed"] }, { kind: "component", type: i4.IonRow, selector: "ion-row" }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.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: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i6.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i7.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i7.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i7.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i8.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: i9.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i10.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i12.MatDate, selector: "mat-date-field", inputs: ["formControl", "formControlName", "placeholder", "floatLabel", "mobile", "compact", "autofocus", "clearable", "required", "startDate", "timezone", "datePickerFilter", "appearance", "subscriptSizing", "readonly", "tabindex"] }, { kind: "component", type: i13.MatChipsField, selector: "mat-chips-field", inputs: ["equals", "logPrefix", "formControl", "formControlName", "floatLabel", "placeholder", "suggestFn", "required", "mobile", "readonly", "clearable", "debounceTime", "displaySeparator", "displayWith", "displayAttributes", "displayColumnSizes", "displayColumnNames", "highlightAccent", "showAllOnFocus", "showPanelOnFocus", "autofocus", "config", "i18nPrefix", "noResultMessage", "panelClass", "panelWidth", "disableRipple", "matAutocompletePosition", "itemSize", "fetchMoreThreshold", "suggestLengthThreshold", "showLoadingSpinner", "chipColor", "debug", "applyImplicitValue", "dropButtonTitle", "clearButtonTitle", "trimSearchText", "hideRequiredMarker", "colSizes", "separatorKeysCodes", "showChips", "appearance", "subscriptSizing", "class", "filter", "tabindex", "items"], outputs: ["click", "blur", "focus", "dropButtonClick", "keydown.escape", "keyup.enter"] }, { kind: "directive", type: i14.AutofocusDirective, selector: "[autofocus], input[appAutofocus]", inputs: ["appAutofocus", "autofocusDelay"] }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i15.IsNilOrBlankPipe, name: "isNilOrBlank" }, { kind: "pipe", type: i15.IsNotNilOrBlankPipe, name: "isNotNilOrBlank" }, { kind: "pipe", type: i16.FormGetValuePipe, name: "formGetValue" }] });
93
96
  }
94
97
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NewTokenForm, decorators: [{
95
98
  type: Component,
96
- args: [{ selector: 'app-new-token-form', template: "<form class=\"form-container\" [formGroup]=\"form\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-form-field>\n <mat-label>{{ 'ACCOUNT.TOKENS.CREATE.NAME' | translate }}</mat-label>\n <input\n matInput\n [appAutofocus]=\"true\"\n [autofocusDelay]=\"500\"\n formControlName=\"name\"\n autocomplete=\"off\"\n required\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n />\n <mat-error *ngIf=\"form.controls.name.hasError('required') && form.controls.name.touched\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.name.hasError('notAlreadyExists') && form.controls.name.touched\" translate>\n ACCOUNT.TOKENS.CREATE.NAME_ALREADY_EXISTS\n </mat-error>\n </mat-form-field>\n </ion-col>\n </ion-row>\n @if (showScopes) {\n <ion-row>\n <ion-col>\n <mat-chips-field\n formControlName=\"scopes\"\n appearance=\"fill\"\n chipColor=\"primary\"\n [placeholder]=\"'ACCOUNT.TOKENS.CREATE.SCOPES' | translate\"\n [config]=\"tokenConfig\"\n [mobile]=\"mobile\"\n [debug]=\"false\"\n [required]=\"true\"\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n >\n <mat-error *ngIf=\"form.controls.name.hasError('notEmptyArray') && form.controls.name.touched\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-chips-field>\n </ion-col>\n </ion-row>\n }\n <ion-row>\n <ion-col>\n <mat-date-field\n formControlName=\"expirationDate\"\n [placeholder]=\"'ACCOUNT.TOKENS.CREATE.EXPIRATION_DATE' | translate\"\n [mobile]=\"mobile\"\n [required]=\"true\"\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n ></mat-date-field>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <ion-button\n *ngIf=\"form | formGetValue: 'token' | isNilOrBlank; else showToken\"\n [title]=\"'ACCOUNT.TOKENS.CREATE.BTN_GENERATE_TITLE' | translate\"\n (click)=\"generate($event)\"\n [disabled]=\"form.invalid\"\n >\n {{ 'ACCOUNT.TOKENS.CREATE.BTN_GENERATE' | translate }}\n </ion-button>\n <ng-template #showToken>\n <p><b translate>ACCOUNT.TOKENS.CREATE.COPY_HELP</b></p>\n <mat-form-field subscriptSizing=\"dynamic\">\n <textarea\n matInput\n formControlName=\"token\"\n readonly\n style=\"height: auto; background-color: lightgray\"\n rows=\"8\"\n ></textarea>\n <button\n matSuffix\n mat-icon-button\n [title]=\"'ACCOUNT.TOKENS.CREATE.BTN_COPY_TITLE' | translate\"\n (click)=\"copy($event)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </mat-form-field>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n</form>\n" }]
99
+ args: [{ selector: 'app-new-token-form', template: "<form class=\"form-container\" [formGroup]=\"form\">\n <ion-grid class=\"ion-no-padding\">\n <ion-row>\n <ion-col>\n <mat-form-field>\n <mat-label>{{ 'ACCOUNT.TOKENS.CREATE.NAME' | translate }}</mat-label>\n <input\n matInput\n [appAutofocus]=\"true\"\n [autofocusDelay]=\"500\"\n formControlName=\"name\"\n autocomplete=\"off\"\n required\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n />\n <mat-error *ngIf=\"form.controls.name.hasError('required') && form.controls.name.touched\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n <mat-error *ngIf=\"form.controls.name.hasError('notAlreadyExists') && form.controls.name.touched\" translate>\n ACCOUNT.TOKENS.CREATE.NAME_ALREADY_EXISTS\n </mat-error>\n </mat-form-field>\n </ion-col>\n </ion-row>\n @if (showScopes) {\n <ion-row>\n <ion-col>\n <mat-chips-field\n formControlName=\"scopes\"\n appearance=\"fill\"\n chipColor=\"primary\"\n [placeholder]=\"'ACCOUNT.TOKENS.CREATE.SCOPES' | translate\"\n [config]=\"tokenConfig\"\n [mobile]=\"mobile\"\n [debug]=\"false\"\n [required]=\"true\"\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n >\n <mat-error *ngIf=\"form.controls.name.hasError('notEmptyArray') && form.controls.name.touched\" translate>\n ERROR.FIELD_REQUIRED\n </mat-error>\n </mat-chips-field>\n </ion-col>\n </ion-row>\n }\n <ion-row>\n <ion-col>\n <mat-date-field\n formControlName=\"expirationDate\"\n [placeholder]=\"'ACCOUNT.TOKENS.CREATE.EXPIRATION_DATE' | translate\"\n [mobile]=\"mobile\"\n [required]=\"true\"\n [readonly]=\"form | formGetValue: 'token' | isNotNilOrBlank\"\n ></mat-date-field>\n </ion-col>\n </ion-row>\n <ion-row>\n <ion-col>\n <ion-button\n *ngIf=\"form | formGetValue: 'token' | isNilOrBlank; else showToken\"\n [title]=\"!showTooltip ? ('ACCOUNT.TOKENS.CREATE.BTN_GENERATE_TITLE' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('ACCOUNT.TOKENS.CREATE.BTN_GENERATE_TITLE' | translate) : ''\"\n (click)=\"generate($event)\"\n [disabled]=\"form.invalid\"\n >\n {{ 'ACCOUNT.TOKENS.CREATE.BTN_GENERATE' | translate }}\n </ion-button>\n <ng-template #showToken>\n <p><b translate>ACCOUNT.TOKENS.CREATE.COPY_HELP</b></p>\n <mat-form-field subscriptSizing=\"dynamic\">\n <textarea\n matInput\n formControlName=\"token\"\n readonly\n style=\"height: auto; background-color: lightgray\"\n rows=\"8\"\n ></textarea>\n <button\n matSuffix\n mat-icon-button\n [title]=\"!showTooltip ? ('ACCOUNT.TOKENS.CREATE.BTN_COPY_TITLE' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('ACCOUNT.TOKENS.CREATE.BTN_COPY_TITLE' | translate) : ''\"\n (click)=\"copy($event)\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n </mat-form-field>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n</form>\n" }]
97
100
  }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.UserTokenValidatorService }, { type: i2.AccountService }, { type: i0.ChangeDetectorRef }], propDecorators: { showScopes: [{
98
101
  type: Input
99
102
  }], tokenScopes: [{
@@ -103,4 +106,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
103
106
  }], mobile: [{
104
107
  type: Input
105
108
  }] } });
106
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3LXRva2VuLmZvcm0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvYWNjb3VudC9uZXctdG9rZW4uZm9ybS50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9hY2NvdW50L25ldy10b2tlbi5mb3JtLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFxQixTQUFTLEVBQVksS0FBSyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBR3RGLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFNdkUsTUFBTSxPQUFPLFlBQWEsU0FBUSxPQUFrQjtJQVd0QztJQUNBO0lBQ0E7SUFaRixXQUFXLENBQTZCO0lBQ3pDLFVBQVUsQ0FBVTtJQUNwQixXQUFXLENBQWU7SUFDMUIsYUFBYSxDQUFXO0lBQ3hCLE1BQU0sQ0FBVTtJQUVSLFFBQVEsQ0FBa0I7SUFFM0MsWUFDRSxRQUFrQixFQUNSLFNBQW9DLEVBQ3BDLGNBQThCLEVBQzlCLEVBQXFCO1FBRS9CLEtBQUssQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFKaEMsY0FBUyxHQUFULFNBQVMsQ0FBMkI7UUFDcEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBRy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsSUFBSSxLQUFLO1FBQ1AsT0FBTyxLQUFLLENBQUMsS0FBSyxJQUFJLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtB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ZW5TY29wZSwgVXNlclRva2VuIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvdG9rZW4ubW9kZWwnO1xuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgSW5qZWN0b3IsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFVzZXJUb2tlblZhbGlkYXRvclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy92YWxpZGF0b3IvdXNlci10b2tlbi52YWxpZGF0b3InO1xuaW1wb3J0IHsgTWF0QXV0b2NvbXBsZXRlRmllbGRDb25maWcgfSBmcm9tICcuLi8uLi9zaGFyZWQvbWF0ZXJpYWwvYXV0b2NvbXBsZXRlL21hdGVyaWFsLmF1dG9jb21wbGV0ZS5jb25maWcnO1xuaW1wb3J0IHsgQXBwRm9ybSB9IGZyb20gJy4uL2Zvcm0vZm9ybS5jbGFzcyc7XG5pbXBvcnQgeyBBY2NvdW50U2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2FjY291bnQuc2VydmljZSc7XG5pbXBvcnQgeyBQbGF0Zm9ybVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9wbGF0Zm9ybS5zZXJ2aWNlJztcbmltcG9ydCB7IGlzTmlsT3JCbGFuaywgaXNOb3ROaWxPckJsYW5rIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1uZXctdG9rZW4tZm9ybScsXG4gIHRlbXBsYXRlVXJsOiAnLi9uZXctdG9rZW4uZm9ybS5odG1sJyxcbn0pXG5leHBvcnQgY2xhc3MgTmV3VG9rZW5Gb3JtIGV4dGVuZHMgQXBwRm9ybTxVc2VyVG9rZW4+IGltcGxlbWVudHMgT25Jbml0IHtcbiAgcHJvdGVjdGVkIHRva2VuQ29uZmlnOiBNYXRBdXRvY29tcGxldGVGaWVsZENvbmZpZztcbiAgQElucHV0KCkgc2hvd1Njb3BlczogYm9vbGVhbjtcbiAgQElucHV0KCkgdG9rZW5TY29wZXM6IFRva2VuU2NvcGVbXTtcbiAgQElucHV0KCkgZXhpc3RpbmdOYW1lczogc3RyaW5nW107XG4gIEBJbnB1dCgpIG1vYmlsZTogYm9vbGVhbjtcblxuICBwcml2YXRlIHJlYWRvbmx5IHBsYXRmb3JtOiBQbGF0Zm9ybVNlcnZpY2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByb3RlY3RlZCB2YWxpZGF0b3I6IFVzZXJUb2tlblZhbGlkYXRvclNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGFjY291bnRTZXJ2aWNlOiBBY2NvdW50U2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmXG4gICkge1xuICAgIHN1cGVyKGluamVjdG9yLCB2YWxpZGF0b3IuZ2V0Rm9ybUdyb3VwKCkpO1xuICAgIHRoaXMucGxhdGZvcm0gPSBpbmplY3Rvci5nZXQoUGxhdGZvcm1TZXJ2aWNlKTtcbiAgfVxuXG4gIGdldCB2YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gc3VwZXIudmFsaWQgJiYgaXNOb3ROaWxPckJsYW5rKHRoaXMudmFsdWU/LnRva2VuKTtcbiAgfVxuXG4gIGdldCBpbnZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBzdXBlci5pbnZhbGlkIHx8IGlzTmlsT3JCbGFuayh0aGlzLnZhbHVlPy50b2tlbik7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgdGhpcy50b2tlbkNvbmZpZyA9IHtcbiAgICAgIGl0ZW1zOiB0aGlzLnRva2VuU2NvcGVzLnNsaWNlKCkubWFwKCh2YWx1ZSkgPT4ge1xuICAgICAgICB2YWx1ZS5uYW1lID0gdGhpcy50cmFuc2xhdGUuaW5zdGFudCh2YWx1ZS5uYW1lKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfSksXG4gICAgICBhdHRyaWJ1dGVzOiBbJ25hbWUnXSxcbiAgICB9O1xuXG4gICAgdGhpcy52YWxpZGF0b3IudXBkYXRlRm9ybUdyb3VwKHRoaXMuZm9ybSwgdGhpcy5leGlzdGluZ05hbWVzKTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlKGV2ZW50OiBVSUV2ZW50KSB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgdGhpcy5hY2NvdW50U2VydmljZS5nZW5lcmF0ZVRva2VuKHRoaXMuZ2V0RmxhZ3ModGhpcy52YWx1ZS5zY29wZXMpKTtcbiAgICAgIGlmICghdG9rZW4pIHtcbiAgICAgICAgdGhpcy5zZXRFcnJvcignTm8gdG9rZW4gZ2VuZXJhdGVkICEnKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyB0b2tlbiB9KTtcblxuICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLnNldEVycm9yKGUpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNvcHkoZXZlbnQ6IFVJRXZlbnQpIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgYXdhaXQgdGhpcy5wbGF0Zm9ybS5jb3B5VG9DbGlwYm9hcmQodGhpcy52YWx1ZS50b2tlbiwge1xuICAgICAgbWVzc2FnZTogJ0FDQ09VTlQuVE9LRU5TLkNSRUFURS5DT1BJRUQnLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZ2V0VmFsdWUoKTogUHJvbWlzZTxVc2VyVG9rZW4+IHtcbiAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHN1cGVyLmdldFZhbHVlKCk7XG5cbiAgICAvLyBTZXQgZmxhZ3MgZnJvbSBzY29wZXNcbiAgICB2YWx1ZS5mbGFncyA9IHRoaXMuZ2V0RmxhZ3ModmFsdWUuc2NvcGVzKTtcblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRGbGFncyhzY29wZXM6IFRva2VuU2NvcGVbXSk6IG51bWJlciB7XG4gICAgbGV0IGZsYWdzID0gMDtcbiAgICBzY29wZXMuZm9yRWFjaCgoc2NvcGUpID0+IHtcbiAgICAgIGZsYWdzICs9IHNjb3BlLmZsYWc7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZsYWdzO1xuICB9XG5cbiAgcHJvdGVjdGVkIG1hcmtGb3JDaGVjaygpIHtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8Zm9ybSBjbGFzcz1cImZvcm0tY29udGFpbmVyXCIgW2Zvcm1Hcm91cF09XCJmb3JtXCI+XG4gIDxpb24tZ3JpZCBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgPGlvbi1yb3c+XG4gICAgICA8aW9uLWNvbD5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDxtYXQtbGFiZWw+e3sgJ0FDQ09VTlQuVE9LRU5TLkNSRUFURS5OQU1FJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgIFthcHBBdXRvZm9jdXNdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbYXV0b2ZvY3VzRGVsYXldPVwiNTAwXCJcbiAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIlxuICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgIHJlcXVpcmVkXG4gICAgICAgICAgICBbcmVhZG9ubHldPVwiZm9ybSB8IGZvcm1HZXRWYWx1ZTogJ3Rva2VuJyB8IGlzTm90TmlsT3JCbGFua1wiXG4gICAgICAgICAgLz5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5uYW1lLmhhc0Vycm9yKCdyZXF1aXJlZCcpICYmIGZvcm0uY29udHJvbHMubmFtZS50b3VjaGVkXCIgdHJhbnNsYXRlPlxuICAgICAgICAgICAgRVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5uYW1lLmhhc0Vycm9yKCdub3RBbHJlYWR5RXhpc3RzJykgJiYgZm9ybS5jb250cm9scy5uYW1lLnRvdWNoZWRcIiB0cmFuc2xhdGU+XG4gICAgICAgICAgICBBQ0NPVU5ULlRPS0VOUy5DUkVBVEUuTkFNRV9BTFJFQURZX0VYSVNUU1xuICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgPC9pb24tY29sPlxuICAgIDwvaW9uLXJvdz5cbiAgICBAaWYgKHNob3dTY29wZXMpIHtcbiAgICAgIDxpb24tcm93PlxuICAgICAgICA8aW9uLWNvbD5cbiAgICAgICAgICA8bWF0LWNoaXBzLWZpZWxkXG4gICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJzY29wZXNcIlxuICAgICAgICAgICAgYXBwZWFyYW5jZT1cImZpbGxcIlxuICAgICAgICAgICAgY2hpcENvbG9yPVwicHJpbWFyeVwiXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0FDQ09VTlQuVE9LRU5TLkNSRUFURS5TQ09QRVMnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIFtjb25maWddPVwidG9rZW5Db25maWdcIlxuICAgICAgICAgICAgW21vYmlsZV09XCJtb2JpbGVcIlxuICAgICAgICAgICAgW2RlYnVnXT1cImZhbHNlXCJcbiAgICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtyZWFkb25seV09XCJmb3JtIHwgZm9ybUdldFZhbHVlOiAndG9rZW4nIHwgaXNOb3ROaWxPckJsYW5rXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5uYW1lLmhhc0Vycm9yKCdub3RFbXB0eUFycmF5JykgJiYgZm9ybS5jb250cm9scy5uYW1lLnRvdWNoZWRcIiB0cmFuc2xhdGU+XG4gICAgICAgICAgICAgIEVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1jaGlwcy1maWVsZD5cbiAgICAgICAgPC9pb24tY29sPlxuICAgICAgPC9pb24tcm93PlxuICAgIH1cbiAgICA8aW9uLXJvdz5cbiAgICAgIDxpb24tY29sPlxuICAgICAgICA8bWF0LWRhdGUtZmllbGRcbiAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJleHBpcmF0aW9uRGF0ZVwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidBQ0NPVU5ULlRPS0VOUy5DUkVBVEUuRVhQSVJBVElPTl9EQVRFJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgW21vYmlsZV09XCJtb2JpbGVcIlxuICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICBbcmVhZG9ubHldPVwiZm9ybSB8IGZvcm1HZXRWYWx1ZTogJ3Rva2VuJyB8IGlzTm90TmlsT3JCbGFua1wiXG4gICAgICAgID48L21hdC1kYXRlLWZpZWxkPlxuICAgICAgPC9pb24tY29sPlxuICAgIDwvaW9uLXJvdz5cbiAgICA8aW9uLXJvdz5cbiAgICAgIDxpb24tY29sPlxuICAgICAgICA8aW9uLWJ1dHRvblxuICAgICAgICAgICpuZ0lmPVwiZm9ybSB8IGZvcm1HZXRWYWx1ZTogJ3Rva2VuJyB8IGlzTmlsT3JCbGFuazsgZWxzZSBzaG93VG9rZW5cIlxuICAgICAgICAgIFt0aXRsZV09XCInQUNDT1VOVC5UT0tFTlMuQ1JFQVRFLkJUTl9HRU5FUkFURV9USVRMRScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgIChjbGljayk9XCJnZW5lcmF0ZSgkZXZlbnQpXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybS5pbnZhbGlkXCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7ICdBQ0NPVU5ULlRPS0VOUy5DUkVBVEUuQlROX0dFTkVSQVRFJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjc2hvd1Rva2VuPlxuICAgICAgICAgIDxwPjxiIHRyYW5zbGF0ZT5BQ0NPVU5ULlRPS0VOUy5DUkVBVEUuQ09QWV9IRUxQPC9iPjwvcD5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiPlxuICAgICAgICAgICAgPHRleHRhcmVhXG4gICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInRva2VuXCJcbiAgICAgICAgICAgICAgcmVhZG9ubHlcbiAgICAgICAgICAgICAgc3R5bGU9XCJoZWlnaHQ6IGF1dG87IGJhY2tncm91bmQtY29sb3I6IGxpZ2h0Z3JheVwiXG4gICAgICAgICAgICAgIHJvd3M9XCI4XCJcbiAgICAgICAgICAgID48L3RleHRhcmVhPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgIFt0aXRsZV09XCInQUNDT1VOVC5UT0tFTlMuQ1JFQVRFLkJUTl9DT1BZX1RJVExFJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJjb3B5KCRldmVudClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8bWF0LWljb24+Y29udGVudF9jb3B5PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L2lvbi1jb2w+XG4gICAgPC9pb24tcm93PlxuICA8L2lvbi1ncmlkPlxuPC9mb3JtPlxuIl19
109
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3LXRva2VuLmZvcm0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvYWNjb3VudC9uZXctdG9rZW4uZm9ybS50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9hY2NvdW50L25ldy10b2tlbi5mb3JtLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFxQixTQUFTLEVBQUUsTUFBTSxFQUFZLEtBQUssRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUc5RixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFN0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxZQUFZLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQU0xRCxNQUFNLE9BQU8sWUFBYSxTQUFRLE9BQWtCO0lBYXRDO0lBQ0E7SUFDQTtJQWRGLFdBQVcsQ0FBNkI7SUFDekMsVUFBVSxDQUFVO0lBQ3BCLFdBQVcsQ0FBZTtJQUMxQixhQUFhLENBQVc7SUFDeEIsTUFBTSxDQUFVO0lBRVIsUUFBUSxDQUFrQjtJQUUzQyxXQUFXLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFM0QsWUFDRSxRQUFrQixFQUNSLFNBQW9DLEVBQ3BDLGNBQThCLEVBQzlCLEVBQXFCO1FBRS9CLEtBQUssQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFKaEMsY0FBUyxHQUFULFNBQVMsQ0FBMkI7UUFDcEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBRy9CLElBQUksQ0FBQyxRQUFR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QUFvQjtrTEFLckIsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVG9rZW5TY29wZSwgVXNlclRva2VuIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvdG9rZW4ubW9kZWwnO1xuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgaW5qZWN0LCBJbmplY3RvciwgSW5wdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVXNlclRva2VuVmFsaWRhdG9yU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3ZhbGlkYXRvci91c2VyLXRva2VuLnZhbGlkYXRvcic7XG5pbXBvcnQgeyBNYXRBdXRvY29tcGxldGVGaWVsZENvbmZpZyB9IGZyb20gJy4uLy4uL3NoYXJlZC9tYXRlcmlhbC9hdXRvY29tcGxldGUvbWF0ZXJpYWwuYXV0b2NvbXBsZXRlLmNvbmZpZyc7XG5pbXBvcnQgeyBBcHBGb3JtIH0gZnJvbSAnLi4vZm9ybS9mb3JtLmNsYXNzJztcbmltcG9ydCB7IEFjY291bnRTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYWNjb3VudC5zZXJ2aWNlJztcbmltcG9ydCB7IFBsYXRmb3JtU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3BsYXRmb3JtLnNlcnZpY2UnO1xuaW1wb3J0IHsgaXNOaWxPckJsYW5rLCBpc05vdE5pbE9yQmxhbmsgfSBmcm9tICcuLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcblxuaW1wb3J0IHsgQVBQX1NIT1dfVE9PTFRJUCB9IGZyb20gJy4uLy4uL3NoYXJlZC9jb25zdGFudHMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtbmV3LXRva2VuLWZvcm0nLFxuICB0ZW1wbGF0ZVVybDogJy4vbmV3LXRva2VuLmZvcm0uaHRtbCcsXG59KVxuZXhwb3J0IGNsYXNzIE5ld1Rva2VuRm9ybSBleHRlbmRzIEFwcEZvcm08VXNlclRva2VuPiBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByb3RlY3RlZCB0b2tlbkNvbmZpZzogTWF0QXV0b2NvbXBsZXRlRmllbGRDb25maWc7XG4gIEBJbnB1dCgpIHNob3dTY29wZXM6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHRva2VuU2NvcGVzOiBUb2tlblNjb3BlW107XG4gIEBJbnB1dCgpIGV4aXN0aW5nTmFtZXM6IHN0cmluZ1tdO1xuICBASW5wdXQoKSBtb2JpbGU6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBwbGF0Zm9ybTogUGxhdGZvcm1TZXJ2aWNlO1xuXG4gIHNob3dUb29sdGlwID0gaW5qZWN0KEFQUF9TSE9XX1RPT0xUSVAsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgIHByb3RlY3RlZCB2YWxpZGF0b3I6IFVzZXJUb2tlblZhbGlkYXRvclNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGFjY291bnRTZXJ2aWNlOiBBY2NvdW50U2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY2Q6IENoYW5nZURldGVjdG9yUmVmXG4gICkge1xuICAgIHN1cGVyKGluamVjdG9yLCB2YWxpZGF0b3IuZ2V0Rm9ybUdyb3VwKCkpO1xuICAgIHRoaXMucGxhdGZvcm0gPSBpbmplY3Rvci5nZXQoUGxhdGZvcm1TZXJ2aWNlKTtcbiAgfVxuXG4gIGdldCB2YWxpZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gc3VwZXIudmFsaWQgJiYgaXNOb3ROaWxPckJsYW5rKHRoaXMudmFsdWU/LnRva2VuKTtcbiAgfVxuXG4gIGdldCBpbnZhbGlkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBzdXBlci5pbnZhbGlkIHx8IGlzTmlsT3JCbGFuayh0aGlzLnZhbHVlPy50b2tlbik7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xuXG4gICAgdGhpcy50b2tlbkNvbmZpZyA9IHtcbiAgICAgIGl0ZW1zOiB0aGlzLnRva2VuU2NvcGVzLnNsaWNlKCkubWFwKCh2YWx1ZSkgPT4ge1xuICAgICAgICB2YWx1ZS5uYW1lID0gdGhpcy50cmFuc2xhdGUuaW5zdGFudCh2YWx1ZS5uYW1lKTtcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgfSksXG4gICAgICBhdHRyaWJ1dGVzOiBbJ25hbWUnXSxcbiAgICB9O1xuXG4gICAgdGhpcy52YWxpZGF0b3IudXBkYXRlRm9ybUdyb3VwKHRoaXMuZm9ybSwgdGhpcy5leGlzdGluZ05hbWVzKTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlKGV2ZW50OiBVSUV2ZW50KSB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgdGhpcy5hY2NvdW50U2VydmljZS5nZW5lcmF0ZVRva2VuKHRoaXMuZ2V0RmxhZ3ModGhpcy52YWx1ZS5zY29wZXMpKTtcbiAgICAgIGlmICghdG9rZW4pIHtcbiAgICAgICAgdGhpcy5zZXRFcnJvcignTm8gdG9rZW4gZ2VuZXJhdGVkICEnKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5mb3JtLnBhdGNoVmFsdWUoeyB0b2tlbiB9KTtcblxuICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLnNldEVycm9yKGUpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNvcHkoZXZlbnQ6IFVJRXZlbnQpIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgYXdhaXQgdGhpcy5wbGF0Zm9ybS5jb3B5VG9DbGlwYm9hcmQodGhpcy52YWx1ZS50b2tlbiwge1xuICAgICAgbWVzc2FnZTogJ0FDQ09VTlQuVE9LRU5TLkNSRUFURS5DT1BJRUQnLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZ2V0VmFsdWUoKTogUHJvbWlzZTxVc2VyVG9rZW4+IHtcbiAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHN1cGVyLmdldFZhbHVlKCk7XG5cbiAgICAvLyBTZXQgZmxhZ3MgZnJvbSBzY29wZXNcbiAgICB2YWx1ZS5mbGFncyA9IHRoaXMuZ2V0RmxhZ3ModmFsdWUuc2NvcGVzKTtcblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRGbGFncyhzY29wZXM6IFRva2VuU2NvcGVbXSk6IG51bWJlciB7XG4gICAgbGV0IGZsYWdzID0gMDtcbiAgICBzY29wZXMuZm9yRWFjaCgoc2NvcGUpID0+IHtcbiAgICAgIGZsYWdzICs9IHNjb3BlLmZsYWc7XG4gICAgfSk7XG4gICAgcmV0dXJuIGZsYWdzO1xuICB9XG5cbiAgcHJvdGVjdGVkIG1hcmtGb3JDaGVjaygpIHtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8Zm9ybSBjbGFzcz1cImZvcm0tY29udGFpbmVyXCIgW2Zvcm1Hcm91cF09XCJmb3JtXCI+XG4gIDxpb24tZ3JpZCBjbGFzcz1cImlvbi1uby1wYWRkaW5nXCI+XG4gICAgPGlvbi1yb3c+XG4gICAgICA8aW9uLWNvbD5cbiAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgIDxtYXQtbGFiZWw+e3sgJ0FDQ09VTlQuVE9LRU5TLkNSRUFURS5OQU1FJyB8IHRyYW5zbGF0ZSB9fTwvbWF0LWxhYmVsPlxuICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgIFthcHBBdXRvZm9jdXNdPVwidHJ1ZVwiXG4gICAgICAgICAgICBbYXV0b2ZvY3VzRGVsYXldPVwiNTAwXCJcbiAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIlxuICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgIHJlcXVpcmVkXG4gICAgICAgICAgICBbcmVhZG9ubHldPVwiZm9ybSB8IGZvcm1HZXRWYWx1ZTogJ3Rva2VuJyB8IGlzTm90TmlsT3JCbGFua1wiXG4gICAgICAgICAgLz5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5uYW1lLmhhc0Vycm9yKCdyZXF1aXJlZCcpICYmIGZvcm0uY29udHJvbHMubmFtZS50b3VjaGVkXCIgdHJhbnNsYXRlPlxuICAgICAgICAgICAgRVJST1IuRklFTERfUkVRVUlSRURcbiAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5uYW1lLmhhc0Vycm9yKCdub3RBbHJlYWR5RXhpc3RzJykgJiYgZm9ybS5jb250cm9scy5uYW1lLnRvdWNoZWRcIiB0cmFuc2xhdGU+XG4gICAgICAgICAgICBBQ0NPVU5ULlRPS0VOUy5DUkVBVEUuTkFNRV9BTFJFQURZX0VYSVNUU1xuICAgICAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgPC9pb24tY29sPlxuICAgIDwvaW9uLXJvdz5cbiAgICBAaWYgKHNob3dTY29wZXMpIHtcbiAgICAgIDxpb24tcm93PlxuICAgICAgICA8aW9uLWNvbD5cbiAgICAgICAgICA8bWF0LWNoaXBzLWZpZWxkXG4gICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJzY29wZXNcIlxuICAgICAgICAgICAgYXBwZWFyYW5jZT1cImZpbGxcIlxuICAgICAgICAgICAgY2hpcENvbG9yPVwicHJpbWFyeVwiXG4gICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0FDQ09VTlQuVE9LRU5TLkNSRUFURS5TQ09QRVMnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIFtjb25maWddPVwidG9rZW5Db25maWdcIlxuICAgICAgICAgICAgW21vYmlsZV09XCJtb2JpbGVcIlxuICAgICAgICAgICAgW2RlYnVnXT1cImZhbHNlXCJcbiAgICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtyZWFkb25seV09XCJmb3JtIHwgZm9ybUdldFZhbHVlOiAndG9rZW4nIHwgaXNOb3ROaWxPckJsYW5rXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8bWF0LWVycm9yICpuZ0lmPVwiZm9ybS5jb250cm9scy5uYW1lLmhhc0Vycm9yKCdub3RFbXB0eUFycmF5JykgJiYgZm9ybS5jb250cm9scy5uYW1lLnRvdWNoZWRcIiB0cmFuc2xhdGU+XG4gICAgICAgICAgICAgIEVSUk9SLkZJRUxEX1JFUVVJUkVEXG4gICAgICAgICAgICA8L21hdC1lcnJvcj5cbiAgICAgICAgICA8L21hdC1jaGlwcy1maWVsZD5cbiAgICAgICAgPC9pb24tY29sPlxuICAgICAgPC9pb24tcm93PlxuICAgIH1cbiAgICA8aW9uLXJvdz5cbiAgICAgIDxpb24tY29sPlxuICAgICAgICA8bWF0LWRhdGUtZmllbGRcbiAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJleHBpcmF0aW9uRGF0ZVwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cIidBQ0NPVU5ULlRPS0VOUy5DUkVBVEUuRVhQSVJBVElPTl9EQVRFJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgW21vYmlsZV09XCJtb2JpbGVcIlxuICAgICAgICAgIFtyZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICBbcmVhZG9ubHldPVwiZm9ybSB8IGZvcm1HZXRWYWx1ZTogJ3Rva2VuJyB8IGlzTm90TmlsT3JCbGFua1wiXG4gICAgICAgID48L21hdC1kYXRlLWZpZWxkPlxuICAgICAgPC9pb24tY29sPlxuICAgIDwvaW9uLXJvdz5cbiAgICA8aW9uLXJvdz5cbiAgICAgIDxpb24tY29sPlxuICAgICAgICA8aW9uLWJ1dHRvblxuICAgICAgICAgICpuZ0lmPVwiZm9ybSB8IGZvcm1HZXRWYWx1ZTogJ3Rva2VuJyB8IGlzTmlsT3JCbGFuazsgZWxzZSBzaG93VG9rZW5cIlxuICAgICAgICAgIFt0aXRsZV09XCIhc2hvd1Rvb2x0aXAgPyAoJ0FDQ09VTlQuVE9LRU5TLkNSRUFURS5CVE5fR0VORVJBVEVfVElUTEUnIHwgdHJhbnNsYXRlKSA6ICcnXCJcbiAgICAgICAgICBbbWF0VG9vbHRpcF09XCJzaG93VG9vbHRpcCA/ICgnQUNDT1VOVC5UT0tFTlMuQ1JFQVRFLkJUTl9HRU5FUkFURV9USVRMRScgfCB0cmFuc2xhdGUpIDogJydcIlxuICAgICAgICAgIChjbGljayk9XCJnZW5lcmF0ZSgkZXZlbnQpXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybS5pbnZhbGlkXCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7ICdBQ0NPVU5ULlRPS0VOUy5DUkVBVEUuQlROX0dFTkVSQVRFJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2lvbi1idXR0b24+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjc2hvd1Rva2VuPlxuICAgICAgICAgIDxwPjxiIHRyYW5zbGF0ZT5BQ0NPVU5ULlRPS0VOUy5DUkVBVEUuQ09QWV9IRUxQPC9iPjwvcD5cbiAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgc3Vic2NyaXB0U2l6aW5nPVwiZHluYW1pY1wiPlxuICAgICAgICAgICAgPHRleHRhcmVhXG4gICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInRva2VuXCJcbiAgICAgICAgICAgICAgcmVhZG9ubHlcbiAgICAgICAgICAgICAgc3R5bGU9XCJoZWlnaHQ6IGF1dG87IGJhY2tncm91bmQtY29sb3I6IGxpZ2h0Z3JheVwiXG4gICAgICAgICAgICAgIHJvd3M9XCI4XCJcbiAgICAgICAgICAgID48L3RleHRhcmVhPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgIFt0aXRsZV09XCIhc2hvd1Rvb2x0aXAgPyAoJ0FDQ09VTlQuVE9LRU5TLkNSRUFURS5CVE5fQ09QWV9USVRMRScgfCB0cmFuc2xhdGUpIDogJydcIlxuICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJzaG93VG9vbHRpcCA/ICgnQUNDT1VOVC5UT0tFTlMuQ1JFQVRFLkJUTl9DT1BZX1RJVExFJyB8IHRyYW5zbGF0ZSkgOiAnJ1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJjb3B5KCRldmVudClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8bWF0LWljb24+Y29udGVudF9jb3B5PC9tYXQtaWNvbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L2lvbi1jb2w+XG4gICAgPC9pb24tcm93PlxuICA8L2lvbi1ncmlkPlxuPC9mb3JtPlxuIl19
@@ -1,4 +1,4 @@
1
- import { ChangeDetectionStrategy, Component, Inject, Input, Optional } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, inject, Inject, Input, Optional } from '@angular/core';
2
2
  import { ValidatorService } from '@e-is/ngx-material-table';
3
3
  import { UserTokenValidatorService } from '../services/validator/user-token.validator';
4
4
  import { UserToken } from '../services/model/token.model';
@@ -10,6 +10,7 @@ import { APP_USER_TOKEN_SCOPES } from '../services/account.service';
10
10
  import { NewTokenModal } from './new-token.modal';
11
11
  import { CORE_CONFIG_OPTIONS } from '../services/config/core.config';
12
12
  import { isNotEmptyArray, isNotNilOrBlank } from '../../shared/functions';
13
+ import { APP_SHOW_TOOLTIP } from '../../shared/constants';
13
14
  import * as i0 from "@angular/core";
14
15
  import * as i1 from "@e-is/ngx-material-table";
15
16
  import * as i2 from "../services/config.service";
@@ -23,18 +24,20 @@ import * as i9 from "@angular/material/toolbar";
23
24
  import * as i10 from "@angular/material/icon";
24
25
  import * as i11 from "@angular/material/button";
25
26
  import * as i12 from "@angular/cdk/a11y";
26
- import * as i13 from "../table/column/actions-column.component";
27
- import * as i14 from "../../shared/pipes/property.pipes";
28
- import * as i15 from "../../shared/pipes/date-format.pipe";
29
- import * as i16 from "../../shared/pipes/selection.pipes";
30
- import * as i17 from "../table/table.pipes";
31
- import * as i18 from "../../../environments/environment.class";
27
+ import * as i13 from "@angular/material/tooltip";
28
+ import * as i14 from "../table/column/actions-column.component";
29
+ import * as i15 from "../../shared/pipes/property.pipes";
30
+ import * as i16 from "../../shared/pipes/date-format.pipe";
31
+ import * as i17 from "../../shared/pipes/selection.pipes";
32
+ import * as i18 from "../table/table.pipes";
33
+ import * as i19 from "../../../environments/environment.class";
32
34
  export class UserTokenTable extends AppInMemoryTable {
33
35
  configService;
34
36
  useSticky = false;
35
37
  showScopes = false;
36
38
  defaultScope;
37
39
  tokenScopes;
40
+ showTooltip = inject(APP_SHOW_TOOLTIP, { optional: true });
38
41
  constructor(injector, validatorService, configService, environment, tokenScopes) {
39
42
  super(injector, [...RESERVED_START_COLUMNS, 'name', 'scopes', 'lastUsedDate', 'expirationDate', 'creationDate', ...RESERVED_END_COLUMNS], UserToken, new InMemoryEntitiesService(UserToken, undefined, {
40
43
  filterFnFactory: () => () => true,
@@ -138,12 +141,12 @@ export class UserTokenTable extends AppInMemoryTable {
138
141
  this.defaultScope = config.getProperty(CORE_CONFIG_OPTIONS.DEFAULT_AUTH_API_TOKEN_SCOPE);
139
142
  }
140
143
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserTokenTable, deps: [{ token: i0.Injector }, { token: i1.ValidatorService }, { token: i2.ConfigService }, { token: ENVIRONMENT }, { token: APP_USER_TOKEN_SCOPES, optional: true }], target: i0.ɵɵFactoryTarget.Component });
141
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: UserTokenTable, selector: "app-user-token-table", inputs: { useSticky: "useSticky" }, providers: [{ provide: ValidatorService, useClass: UserTokenValidatorService }], usesInheritance: true, ngImport: i0, template: "<mat-toolbar>\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\" [title]=\"'COMMON.BTN_REFRESH' | translate\" (click)=\"emitRefresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <ion-item *ngIf=\"!mobile && error; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n @if (selection | isEmptySelection) {\n <button\n mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"'COMMON.BTN_ADD' | translate\"\n (click)=\"addToken($event)\"\n >\n <mat-icon>add</mat-icon>\n </button>\n } @else {\n <button mat-icon-button [title]=\"'COMMON.BTN_DELETE' | translate\" (click)=\"deleteSelection($event)\">\n <mat-icon>delete_outline</mat-icon>\n </button>\n }\n</mat-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- table -->\n <div class=\"table-container\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n >\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (change)=\"$event ? masterToggle() : null\"\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n ></mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection | isSelected: row\"\n ></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id Column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"cdk-visually-hidden\">\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"cdk-visually-hidden\">{{ row.currentData.id }}</td>\n </ng-container>\n\n <!-- name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>{{ i18nColumnPrefix + 'NAME' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n {{ (row.currentData | propertyGet: 'name') || (i18nColumnPrefix + 'UNKNOWN' | translate) }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"scopes\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>{{ i18nColumnPrefix + 'SCOPES' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n {{ display(row.currentData | propertyGet: 'scopes') }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"creationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'CREATION_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'creationDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expirationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'EXPIRATION_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'expirationDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"lastUsedDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'LAST_USED_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'lastUsedDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"useSticky\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [canCancel]=\"false\"\n ></app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addToken($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".mat-cell-date-time{width:180px}.mat-column-id{width:90px}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i4.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { 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.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i4.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i4.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i8.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i9.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i12.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: i13.ActionsColumnComponent, selector: "app-actions-column", inputs: ["matColumnDef", "style", "showPendingSpinner", "stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplateStart", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i14.PropertyGetPipe, name: "propertyGet" }, { kind: "pipe", type: i15.DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: i16.IsSelectedPipe, name: "isSelected" }, { kind: "pipe", type: i16.IsEmptySelectionPipe, name: "isEmptySelection" }, { kind: "pipe", type: i17.IsAllSelectedPipe, name: "isAllSelected" }, { kind: "pipe", type: i17.IsNotAllSelectedPipe, name: "isNotAllSelected" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
144
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: UserTokenTable, selector: "app-user-token-table", inputs: { useSticky: "useSticky" }, providers: [{ provide: ValidatorService, useClass: UserTokenValidatorService }], usesInheritance: true, ngImport: i0, template: "<mat-toolbar>\n <!-- Refresh -->\n <button\n mat-icon-button\n *ngIf=\"!mobile\"\n [title]=\"!showTooltip ? ('COMMON.BTN_REFRESH' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('COMMON.BTN_REFRESH' | translate) : ''\"\n (click)=\"emitRefresh()\"\n >\n <mat-icon>refresh</mat-icon>\n </button>\n\n <ion-item *ngIf=\"!mobile && error; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n @if (selection | isEmptySelection) {\n <button\n mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"!showTooltip ? ('COMMON.BTN_ADD' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('COMMON.BTN_ADD' | translate) : ''\"\n (click)=\"addToken($event)\"\n >\n <mat-icon>add</mat-icon>\n </button>\n } @else {\n <button\n mat-icon-button\n [title]=\"!showTooltip ? ('COMMON.BTN_DELETE' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('COMMON.BTN_DELETE' | translate) : ''\"\n (click)=\"deleteSelection($event)\"\n >\n <mat-icon>delete_outline</mat-icon>\n </button>\n }\n</mat-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- table -->\n <div class=\"table-container\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n >\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (change)=\"$event ? masterToggle() : null\"\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n ></mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection | isSelected: row\"\n ></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id Column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"cdk-visually-hidden\">\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"cdk-visually-hidden\">{{ row.currentData.id }}</td>\n </ng-container>\n\n <!-- name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>{{ i18nColumnPrefix + 'NAME' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n {{ (row.currentData | propertyGet: 'name') || (i18nColumnPrefix + 'UNKNOWN' | translate) }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"scopes\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>{{ i18nColumnPrefix + 'SCOPES' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n {{ display(row.currentData | propertyGet: 'scopes') }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"creationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'CREATION_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'creationDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expirationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'EXPIRATION_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'expirationDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"lastUsedDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'LAST_USED_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'lastUsedDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"useSticky\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [canCancel]=\"false\"\n ></app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addToken($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".mat-cell-date-time{width:180px}.mat-column-id{width:90px}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.IonContent, selector: "ion-content", inputs: ["color", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: i4.IonFab, selector: "ion-fab", inputs: ["activated", "edge", "horizontal", "vertical"] }, { kind: "component", type: i4.IonFabButton, selector: "ion-fab-button", inputs: ["activated", "closeIcon", "color", "disabled", "download", "href", "mode", "rel", "routerAnimation", "routerDirection", "show", "size", "target", "translucent", "type"] }, { 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.IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: i4.IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: i4.IonSkeletonText, selector: "ion-skeleton-text", inputs: ["animated"] }, { kind: "component", type: i4.IonText, selector: "ion-text", inputs: ["color", "mode"] }, { kind: "directive", type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i7.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i7.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i8.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "component", type: i9.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i12.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: i13.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i14.ActionsColumnComponent, selector: "app-actions-column", inputs: ["matColumnDef", "style", "showPendingSpinner", "stickyEnd", "canCancel", "canConfirm", "canDelete", "canBackward", "canForward", "canConfirmAndAdd", "dirtyIcon", "optionsTitle", "class", "cellTemplateStart", "cellTemplate"], outputs: ["optionsClick", "cancelOrDeleteClick", "confirmEditCreateClick", "confirmAndAddClick", "backward", "forward"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }, { kind: "pipe", type: i15.PropertyGetPipe, name: "propertyGet" }, { kind: "pipe", type: i16.DateFormatPipe, name: "dateFormat" }, { kind: "pipe", type: i17.IsSelectedPipe, name: "isSelected" }, { kind: "pipe", type: i17.IsEmptySelectionPipe, name: "isEmptySelection" }, { kind: "pipe", type: i18.IsAllSelectedPipe, name: "isAllSelected" }, { kind: "pipe", type: i18.IsNotAllSelectedPipe, name: "isNotAllSelected" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
142
145
  }
143
146
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: UserTokenTable, decorators: [{
144
147
  type: Component,
145
- args: [{ selector: 'app-user-token-table', providers: [{ provide: ValidatorService, useClass: UserTokenValidatorService }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-toolbar>\n <!-- Refresh -->\n <button mat-icon-button *ngIf=\"!mobile\" [title]=\"'COMMON.BTN_REFRESH' | translate\" (click)=\"emitRefresh()\">\n <mat-icon>refresh</mat-icon>\n </button>\n\n <ion-item *ngIf=\"!mobile && error; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n @if (selection | isEmptySelection) {\n <button\n mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"'COMMON.BTN_ADD' | translate\"\n (click)=\"addToken($event)\"\n >\n <mat-icon>add</mat-icon>\n </button>\n } @else {\n <button mat-icon-button [title]=\"'COMMON.BTN_DELETE' | translate\" (click)=\"deleteSelection($event)\">\n <mat-icon>delete_outline</mat-icon>\n </button>\n }\n</mat-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- table -->\n <div class=\"table-container\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n >\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (change)=\"$event ? masterToggle() : null\"\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n ></mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection | isSelected: row\"\n ></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id Column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"cdk-visually-hidden\">\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"cdk-visually-hidden\">{{ row.currentData.id }}</td>\n </ng-container>\n\n <!-- name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>{{ i18nColumnPrefix + 'NAME' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n {{ (row.currentData | propertyGet: 'name') || (i18nColumnPrefix + 'UNKNOWN' | translate) }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"scopes\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>{{ i18nColumnPrefix + 'SCOPES' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n {{ display(row.currentData | propertyGet: 'scopes') }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"creationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'CREATION_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'creationDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expirationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'EXPIRATION_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'expirationDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"lastUsedDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'LAST_USED_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'lastUsedDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"useSticky\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [canCancel]=\"false\"\n ></app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addToken($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".mat-cell-date-time{width:180px}.mat-column-id{width:90px}\n"] }]
146
- }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.ValidatorService }, { type: i2.ConfigService }, { type: i18.Environment, decorators: [{
148
+ args: [{ selector: 'app-user-token-table', providers: [{ provide: ValidatorService, useClass: UserTokenValidatorService }], changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-toolbar>\n <!-- Refresh -->\n <button\n mat-icon-button\n *ngIf=\"!mobile\"\n [title]=\"!showTooltip ? ('COMMON.BTN_REFRESH' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('COMMON.BTN_REFRESH' | translate) : ''\"\n (click)=\"emitRefresh()\"\n >\n <mat-icon>refresh</mat-icon>\n </button>\n\n <ion-item *ngIf=\"!mobile && error; let error\" lines=\"none\">\n <ion-icon color=\"danger\" slot=\"start\" name=\"alert-circle\"></ion-icon>\n <ion-label color=\"danger\" [innerHTML]=\"error | translate\"></ion-label>\n </ion-item>\n\n <div class=\"toolbar-spacer\"></div>\n\n @if (selection | isEmptySelection) {\n <button\n mat-icon-button\n *ngIf=\"canEdit && !mobile\"\n [title]=\"!showTooltip ? ('COMMON.BTN_ADD' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('COMMON.BTN_ADD' | translate) : ''\"\n (click)=\"addToken($event)\"\n >\n <mat-icon>add</mat-icon>\n </button>\n } @else {\n <button\n mat-icon-button\n [title]=\"!showTooltip ? ('COMMON.BTN_DELETE' | translate) : ''\"\n [matTooltip]=\"showTooltip ? ('COMMON.BTN_DELETE' | translate) : ''\"\n (click)=\"deleteSelection($event)\"\n >\n <mat-icon>delete_outline</mat-icon>\n </button>\n }\n</mat-toolbar>\n\n<ion-content class=\"ion-no-padding\">\n <ion-refresher slot=\"fixed\" *ngIf=\"mobile\" (ionRefresh)=\"doRefresh($event)\">\n <ion-refresher-content></ion-refresher-content>\n </ion-refresher>\n\n <!-- table -->\n <div class=\"table-container\">\n <table\n #table\n mat-table\n matSort\n matSortDisableClear\n [dataSource]=\"dataSource\"\n [matSortActive]=\"defaultSortBy\"\n [matSortDirection]=\"defaultSortDirection\"\n [trackBy]=\"trackByFn\"\n >\n <ng-container matColumnDef=\"select\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (change)=\"$event ? masterToggle() : null\"\n [checked]=\"this | isAllSelected\"\n [indeterminate]=\"this | isNotAllSelected\"\n ></mat-checkbox>\n </th>\n <td mat-cell *matCellDef=\"let row\" [class.cdk-visually-hidden]=\"!canEdit\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? selection.toggle(row) : null\"\n [checked]=\"selection | isSelected: row\"\n ></mat-checkbox>\n </td>\n </ng-container>\n\n <!-- Id Column -->\n <ng-container matColumnDef=\"id\" [sticky]=\"useSticky\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"cdk-visually-hidden\">\n <ion-label>#</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"cdk-visually-hidden\">{{ row.currentData.id }}</td>\n </ng-container>\n\n <!-- name column -->\n <ng-container matColumnDef=\"name\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>{{ i18nColumnPrefix + 'NAME' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n {{ (row.currentData | propertyGet: 'name') || (i18nColumnPrefix + 'UNKNOWN' | translate) }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"scopes\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>\n <ion-label>{{ i18nColumnPrefix + 'SCOPES' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\">\n {{ display(row.currentData | propertyGet: 'scopes') }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"creationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'CREATION_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'creationDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"expirationDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'EXPIRATION_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'expirationDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"lastUsedDate\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"mat-cell-date-time\">\n <ion-label>{{ i18nColumnPrefix + 'LAST_USED_DATE' | translate }}</ion-label>\n </th>\n <td mat-cell *matCellDef=\"let row\" class=\"mat-cell-date-time\">\n {{ row.currentData | propertyGet: 'lastUsedDate' | dateFormat: { time: true } }}\n </td>\n </ng-container>\n\n <!-- Actions buttons column -->\n <app-actions-column\n [stickyEnd]=\"useSticky\"\n (optionsClick)=\"openSelectColumnsModal($event)\"\n (cancelOrDeleteClick)=\"cancelOrDelete($event.event, $event.row)\"\n (confirmAndAddClick)=\"confirmAndAdd($event.event, $event.row)\"\n (backward)=\"confirmAndBackward($event.event, $event.row)\"\n (forward)=\"confirmAndForward($event.event, $event.row)\"\n [canCancel]=\"false\"\n ></app-actions-column>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns; sticky: true\"></tr>\n <tr\n mat-row\n *matRowDef=\"let row; columns: displayedColumns\"\n [class.mat-row-selected]=\"row.editing\"\n [class.mat-row-error]=\"row.validator?.invalid\"\n [class.mat-row-dirty]=\"row.validator?.dirty\"\n (click)=\"clickRow($event, row)\"\n (keydown.escape)=\"escapeEditingRow($event)\"\n [cdkTrapFocus]=\"row.validator?.invalid\"\n ></tr>\n </table>\n\n <ng-container *ngIf=\"loadingSubject | async; else noResult\">\n <ion-item>\n <ion-skeleton-text animated></ion-skeleton-text>\n </ion-item>\n </ng-container>\n\n <ng-template #noResult>\n <ion-item *ngIf=\"totalRowCount === 0\">\n <ion-text color=\"danger\" class=\"text-italic\" translate>COMMON.NO_RESULT</ion-text>\n </ion-item>\n </ng-template>\n </div>\n</ion-content>\n\n<ion-fab slot=\"fixed\" vertical=\"bottom\" horizontal=\"end\" *ngIf=\"mobile\">\n <ion-fab-button color=\"tertiary\" (click)=\"addToken($event)\">\n <ion-icon name=\"add\"></ion-icon>\n </ion-fab-button>\n</ion-fab>\n", styles: [".mat-cell-date-time{width:180px}.mat-column-id{width:90px}\n"] }]
149
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: i1.ValidatorService }, { type: i2.ConfigService }, { type: i19.Environment, decorators: [{
147
150
  type: Inject,
148
151
  args: [ENVIRONMENT]
149
152
  }] }, { type: undefined, decorators: [{
@@ -154,4 +157,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
154
157
  }] }], propDecorators: { useSticky: [{
155
158
  type: Input
156
159
  }] } });
157
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4udGFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvYWNjb3VudC90b2tlbi50YWJsZS50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9hY2NvdW50L3Rva2VuLnRhYmxlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQVksS0FBSyxFQUFVLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5RyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM1RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUN2RixPQUFPLEVBQWMsU0FBUyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDL0QsT0FBTyxFQUFFLG9CQUFvQixFQUFFLHNCQUFzQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDcEYsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFDNUYsT0FBTyxFQUFlLFdBQVcsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ25GLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3BFLE9BQU8sRUFBb0IsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHcEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDckUsT0FBTyxFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFTMUUsTUFBTSxPQUFPLGNBQWUsU0FBUSxnQkFBMkI7SUFVakQ7SUFUSCxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBRWpCLFVBQVUsR0FBRyxLQUFLLENB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QUFXLGFBQ0MscUJBQXFCOzRGQVpoQyxjQUFjLG1GQUhkLENBQUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLHlCQUF5QixFQUFFLENBQUMsaURDbkJqRixzdU1BZ0tBOzs0RkQxSWEsY0FBYztrQkFQMUIsU0FBUzsrQkFDRSxzQkFBc0IsYUFHckIsQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUseUJBQXlCLEVBQUUsQ0FBQyxtQkFDOUQsdUJBQXVCLENBQUMsTUFBTTs7MEJBYTVDLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMscUJBQXFCO3lDQVhsQyxTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgSW5qZWN0LCBJbmplY3RvciwgSW5wdXQsIE9uSW5pdCwgT3B0aW9uYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFZhbGlkYXRvclNlcnZpY2UgfSBmcm9tICdAZS1pcy9uZ3gtbWF0ZXJpYWwtdGFibGUnO1xuaW1wb3J0IHsgVXNlclRva2VuVmFsaWRhdG9yU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3ZhbGlkYXRvci91c2VyLXRva2VuLnZhbGlkYXRvcic7XG5pbXBvcnQgeyBUb2tlblNjb3BlLCBVc2VyVG9rZW4gfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC90b2tlbi5tb2RlbCc7XG5pbXBvcnQgeyBBcHBJbk1lbW9yeVRhYmxlIH0gZnJvbSAnLi4vdGFibGUvbWVtb3J5LXRhYmxlLmNsYXNzJztcbmltcG9ydCB7IFJFU0VSVkVEX0VORF9DT0xVTU5TLCBSRVNFUlZFRF9TVEFSVF9DT0xVTU5TIH0gZnJvbSAnLi4vdGFibGUvdGFibGUubW9kZWwnO1xuaW1wb3J0IHsgSW5NZW1vcnlFbnRpdGllc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvc2VydmljZXMvbWVtb3J5LWVudGl0eS1zZXJ2aWNlLmNsYXNzJztcbmltcG9ydCB7IEVudmlyb25tZW50LCBFTlZJUk9OTUVOVCB9IGZyb20gJy4uLy4uLy4uL2Vudmlyb25tZW50cy9lbnZpcm9ubWVudC5jbGFzcyc7XG5pbXBvcnQgeyBBUFBfVVNFUl9UT0tFTl9TQ09QRVMgfSBmcm9tICcuLi9zZXJ2aWNlcy9hY2NvdW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgSU5ld1Rva2VuT3B0aW9ucywgTmV3VG9rZW5Nb2RhbCB9IGZyb20gJy4vbmV3LXRva2VuLm1vZGFsJztcbmltcG9ydCB7IENvbmZpZ1NlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBDb25maWd1cmF0aW9uIH0gZnJvbSAnLi4vc2VydmljZXMvbW9kZWwvY29uZmlnLm1vZGVsJztcbmltcG9ydCB7IENPUkVfQ09ORklHX09QVElPTlMgfSBmcm9tICcuLi9zZXJ2aWNlcy9jb25maWcvY29yZS5jb25maWcnO1xuaW1wb3J0IHsgaXNOb3RFbXB0eUFycmF5LCBpc05vdE5pbE9yQmxhbmsgfSBmcm9tICcuLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXVzZXItdG9rZW4tdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJ3Rva2VuLnRhYmxlLmh0bWwnLFxuICBzdHlsZVVybHM6IFsndG9rZW4udGFibGUuc2NzcyddLFxuICBwcm92aWRlcnM6IFt7IHByb3ZpZGU6IFZhbGlkYXRvclNlcnZpY2UsIHVzZUNsYXNzOiBVc2VyVG9rZW5WYWxpZGF0b3JTZXJ2aWNlIH1dLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgVXNlclRva2VuVGFibGUgZXh0ZW5kcyBBcHBJbk1lbW9yeVRhYmxlPFVzZXJUb2tlbj4gaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSB1c2VTdGlja3kgPSBmYWxzZTtcblxuICBwcm90ZWN0ZWQgc2hvd1Njb3BlcyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgZGVmYXVsdFNjb3BlOiBzdHJpbmc7XG4gIHByb3RlY3RlZCB0b2tlblNjb3BlczogVG9rZW5TY29wZVtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgICB2YWxpZGF0b3JTZXJ2aWNlOiBWYWxpZGF0b3JTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjb25maWdTZXJ2aWNlOiBDb25maWdTZXJ2aWNlLFxuICAgIEBJbmplY3QoRU5WSVJPTk1FTlQpIGVudmlyb25tZW50OiBFbnZpcm9ubWVudCxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFQUF9VU0VSX1RPS0VOX1NDT1BFUykgdG9rZW5TY29wZXM6IFRva2VuU2NvcGVbXVxuICApIHtcbiAgICBzdXBlcihcbiAgICAgIGluamVjdG9yLFxuICAgICAgWy4uLlJFU0VSVkVEX1NUQVJUX0NPTFVNTlMsICduYW1lJywgJ3Njb3BlcycsICdsYXN0VXNlZERhdGUnLCAnZXhwaXJhdGlvbkRhdGUnLCAnY3JlYXRpb25EYXRlJywgLi4uUkVTRVJWRURfRU5EX0NPTFVNTlNdLFxuICAgICAgVXNlclRva2VuLFxuICAgICAgbmV3IEluTWVtb3J5RW50aXRpZXNTZXJ2aWNlKFVzZXJUb2tlbiwgdW5kZWZpbmVkLCB7XG4gICAgICAgIGZpbHRlckZuRmFjdG9yeTogKCkgPT4gKCkgPT4gdHJ1ZSxcbiAgICAgICAgZXF1YWxzOiBVc2VyVG9rZW4uZXF1YWxzLFxuICAgICAgfSksXG4gICAgICB2YWxpZGF0b3JTZXJ2aWNlXG4gICAgKTtcblxuICAgIHRoaXMudG9rZW5TY29wZXMgPSB0b2tlblNjb3BlcyA/PyBbXTtcbiAgICB0aGlzLmlubGluZUVkaXRpb24gPSBmYWxzZTtcbiAgICB0aGlzLmFsbG93Um93RGV0YWlsID0gZmFsc2U7XG4gICAgdGhpcy5kZWZhdWx0U29ydEJ5ID0gJ2NyZWF0aW9uRGF0ZSc7XG4gICAgdGhpcy5kZWZhdWx0U29ydERpcmVjdGlvbiA9ICdhc2MnO1xuICAgIHRoaXMuaTE4bkNvbHVtblByZWZpeCA9ICdBQ0NPVU5ULlRPS0VOUy5UQUJMRS4nO1xuICAgIHRoaXMuZGVidWcgPSAhZW52aXJvbm1lbnQ/LnByb2R1Y3Rpb247XG5cbiAgICBpZiAoIXRva2VuU2NvcGVzKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ05vIFRva2VuU2NvcGVzIHByb3ZpZGVkLiBQbGVhc2UgcHJvdmlkZSB0aGUgdG9rZW4gQVBQX1VTRVJfVE9LRU5fU0NPUEVTIHdpdGggdmFsaWQgVG9rZW5TY29wZSBhcnJheScpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHN1cGVyLm5nT25Jbml0KCk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKHRoaXMuY29uZmlnU2VydmljZS5jb25maWcuc3Vic2NyaWJlKChjb25maWcpID0+IHRoaXMub25Db25maWdMb2FkZWQoY29uZmlnKSkpO1xuXG4gICAgdGhpcy5tYXJrQXNSZWFkeSgpO1xuICB9XG5cbiAgZ2V0IHZhbHVlKCk6IFVzZXJUb2tlbltdIHtcbiAgICByZXR1cm4gc3VwZXIudmFsdWUgfHwgW107XG4gIH1cblxuICBzZXQgdmFsdWUoZGF0YTogVXNlclRva2VuW10pIHtcbiAgICBzdXBlci52YWx1ZSA9IGRhdGE7XG4gIH1cblxuICBzZXRWYWx1ZSh2YWx1ZTogVXNlclRva2VuW10sIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIC8vIFNldCBzY29wZXMgZnJvbSBmbGFnc1xuICAgIHZhbHVlPy5mb3JFYWNoKCh1c2VyVG9rZW4pID0+IHtcbiAgICAgIGNvbnN0IHNjb3BlczogVG9rZW5TY29wZVtdID0gW107XG4gICAgICBpZiAodXNlclRva2VuLmZsYWdzKSB7XG4gICAgICAgIHRoaXMudG9rZW5TY29wZXMuZm9yRWFjaCgoc2NvcGUpID0+IHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgICAgICAgIGlmICh1c2VyVG9rZW4uZmxhZ3MgJiBzY29wZS5mbGFnKSB7XG4gICAgICAgICAgICBzY29wZXMucHVzaChzY29wZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHVzZXJUb2tlbi5zY29wZXMgPSBzY29wZXM7XG4gICAgfSk7XG5cbiAgICBzdXBlci5zZXRWYWx1ZSh2YWx1ZSwgb3B0cyk7XG4gIH1cblxuICBhc3luYyBhZGRUb2tlbihldmVudDogVUlFdmVudCkge1xuICAgIGlmIChldmVudD8uZGVmYXVsdFByZXZlbnRlZCkgcmV0dXJuOyAvLyBBdm9pZCBtdWx0aXBsZSBjYWxsXG5cbiAgICBldmVudD8ucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgbmV3VG9rZW4gPSBuZXcgVXNlclRva2VuKCk7XG4gICAgaWYgKGlzTm90TmlsT3JCbGFuayh0aGlzLmRlZmF1bHRTY29wZSkgJiYgaXNOb3RFbXB0eUFycmF5KHRoaXMudG9rZW5TY29wZXMpKSB7XG4gICAgICBjb25zdCBzY29wZSA9IHRoaXMudG9rZW5TY29wZXMuZmluZCgoc2NvcGUpID0+IHNjb3BlLmlkID09PSB0aGlzLmRlZmF1bHRTY29wZSk7XG4gICAgICBpZiAoIXNjb3BlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcIlt0b2tlbi10YWJsZV0gQ2Fubm90IGZvdW5kIHRoZSBkZWZhdWx0IHNjb3BlICcke3RoaXMuZGVmYXVsdFNjb3BlfScgaW4gdmFsdWVzIG9mIEFQUF9VU0VSX1RPS0VOX1NDT1BFUyFcIik7XG4gICAgICB9XG4gICAgICBuZXdUb2tlbi5zY29wZXMgPSBzY29wZSA/IFtzY29wZV0gOiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBtb2RhbCA9IGF3YWl0IHRoaXMubW9kYWxDdHJsLmNyZWF0ZSh7XG4gICAgICBjb21wb25lbnQ6IE5ld1Rva2VuTW9kYWwsXG4gICAgICBjb21wb25lbnRQcm9wczogPElOZXdUb2tlbk9wdGlvbnM+e1xuICAgICAgICBtb2JpbGU6IHRoaXMubW9iaWxlLFxuICAgICAgICBpc05ldzogdHJ1ZSxcbiAgICAgICAgZGF0YTogbmV3VG9rZW4sXG4gICAgICAgIHNob3dTY29wZXM6IHRoaXMuc2hvd1Njb3BlcyxcbiAgICAgICAgdG9rZW5TY29wZXM6IHRoaXMudG9rZW5TY29wZXMgfHwgW10sXG4gICAgICAgIGV4aXN0aW5nTmFtZXM6IHRoaXMudmFsdWU/Lm1hcCgodikgPT4gdi5uYW1lKSxcbiAgICAgIH0sXG4gICAgICBiYWNrZHJvcERpc21pc3M6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgYXdhaXQgbW9kYWwucHJlc2VudCgpO1xuICAgIGNvbnN0IHsgZGF0YSB9ID0gYXdhaXQgbW9kYWwub25EaWREaXNtaXNzKCk7XG5cbiAgICBpZiAoZGF0YT8ubmFtZSkge1xuICAgICAgLy8gQWRkIHRoaXMgdG9rZW4gaW4gdGhlIGxpc3RcbiAgICAgIGNvbnN0IHJvdyA9IGF3YWl0IHRoaXMuYWRkUm93VG9UYWJsZSh1bmRlZmluZWQsIHsgZWRpdGluZzogZmFsc2UgfSk7XG4gICAgICByb3cudmFsaWRhdG9yLnBhdGNoVmFsdWUoZGF0YSk7XG5cbiAgICAgIHRoaXMubWFya0FzRGlydHkoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICAvLyBhc3luYyByZXZvY2F0ZShldmVudDogVUlFdmVudCkge1xuICAvLyAgIGlmICh0aGlzLnNlbGVjdGlvbi5pc0VtcHR5KCkpIHJldHVybjtcbiAgLy9cbiAgLy8gICBjb25zdCBjb25maXJtZWQgPSBhd2FpdCBBbGVydHMuYXNrQ29uZmlybWF0aW9uKHRoaXMuaTE4bkNvbHVtblByZWZpeCArICdDT05GSVJNLlJFVk9DQVRFJywgdGhpcy5hbGVydEN0cmwsIHRoaXMudHJhbnNsYXRlKTtcbiAgLy8gICBpZiAoIWNvbmZpcm1lZCkgcmV0dXJuO1xuICAvL1xuICAvLyAgIGNvbnN0IG5vdyA9IG1vbWVudCgpO1xuICAvLyAgIHRoaXMuc2VsZWN0aW9uLnNlbGVjdGVkLmZvckVhY2gocm93ID0+IHtcbiAgLy8gICAgIHJvdy52YWxpZGF0b3IucGF0Y2hWYWx1ZSh7cmV2b2NhdGlvbkRhdGU6IG5vd30sIHtlbWl0RXZlbnQ6dHJ1ZX0pO1xuICAvLyAgICAgLy8gcm93LnZhbGlkYXRvci51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gIC8vICAgfSk7XG4gIC8vXG4gIC8vICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgLy8gICAvLyB0aGlzLm1hcmtBc0RpcnR5KCk7XG4gIC8vIH1cblxuICBkaXNwbGF5KHNjb3BlczogVG9rZW5TY29wZVtdKSB7XG4gICAgcmV0dXJuIHNjb3Blcz8ubWFwKCh2YWx1ZSkgPT4gdGhpcy50cmFuc2xhdGUuaW5zdGFudCh2YWx1ZS5uYW1lKSkuam9pbignLCAnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkNvbmZpZ0xvYWRlZChjb25maWc6IENvbmZpZ3VyYXRpb24pIHtcbiAgICB0aGlzLnNob3dTY29wZXMgPSBjb25maWcuZ2V0UHJvcGVydHlBc0Jvb2xlYW4oQ09SRV9DT05GSUdfT1BUSU9OUy5BVVRIX0FQSV9UT0tFTl9TQ09QRV9FTkFCTEVEKTtcbiAgICB0aGlzLnNldFNob3dDb2x1bW4oJ3Njb3BlcycsIHRoaXMuc2hvd1Njb3Blcyk7XG4gICAgdGhpcy5kZWZhdWx0U2NvcGUgPSBjb25maWcuZ2V0UHJvcGVydHkoQ09SRV9DT05GSUdfT1BUSU9OUy5ERUZBVUxUX0FVVEhfQVBJX1RPS0VOX1NDT1BFKTtcbiAgfVxufVxuIiwiPG1hdC10b29sYmFyPlxuICA8IS0tIFJlZnJlc2ggLS0+XG4gIDxidXR0b24gbWF0LWljb24tYnV0dG9uICpuZ0lmPVwiIW1vYmlsZVwiIFt0aXRsZV09XCInQ09NTU9OLkJUTl9SRUZSRVNIJyB8IHRyYW5zbGF0ZVwiIChjbGljayk9XCJlbWl0UmVmcmVzaCgpXCI+XG4gICAgPG1hdC1pY29uPnJlZnJlc2g8L21hdC1pY29uPlxuICA8L2J1dHRvbj5cblxuICA8aW9uLWl0ZW0gKm5nSWY9XCIhbW9iaWxlICYmIGVycm9yOyBsZXQgZXJyb3JcIiBsaW5lcz1cIm5vbmVcIj5cbiAgICA8aW9uLWljb24gY29sb3I9XCJkYW5nZXJcIiBzbG90PVwic3RhcnRcIiBuYW1lPVwiYWxlcnQtY2lyY2xlXCI+PC9pb24taWNvbj5cbiAgICA8aW9uLWxhYmVsIGNvbG9yPVwiZGFuZ2VyXCIgW2lubmVySFRNTF09XCJlcnJvciB8IHRyYW5zbGF0ZVwiPjwvaW9uLWxhYmVsPlxuICA8L2lvbi1pdGVtPlxuXG4gIDxkaXYgY2xhc3M9XCJ0b29sYmFyLXNwYWNlclwiPjwvZGl2PlxuXG4gIEBpZiAoc2VsZWN0aW9uIHwgaXNFbXB0eVNlbGVjdGlvbikge1xuICAgIDxidXR0b25cbiAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgKm5nSWY9XCJjYW5FZGl0ICYmICFtb2JpbGVcIlxuICAgICAgW3RpdGxlXT1cIidDT01NT04uQlROX0FERCcgfCB0cmFuc2xhdGVcIlxuICAgICAgKGNsaWNrKT1cImFkZFRva2VuKCRldmVudClcIlxuICAgID5cbiAgICAgIDxtYXQtaWNvbj5hZGQ8L21hdC1pY29uPlxuICAgIDwvYnV0dG9uPlxuICB9IEBlbHNlIHtcbiAgICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBbdGl0bGVdPVwiJ0NPTU1PTi5CVE5fREVMRVRFJyB8IHRyYW5zbGF0ZVwiIChjbGljayk9XCJkZWxldGVTZWxlY3Rpb24oJGV2ZW50KVwiPlxuICAgICAgPG1hdC1pY29uPmRlbGV0ZV9vdXRsaW5lPC9tYXQtaWNvbj5cbiAgICA8L2J1dHRvbj5cbiAgfVxuPC9tYXQtdG9vbGJhcj5cblxuPGlvbi1jb250ZW50IGNsYXNzPVwiaW9uLW5vLXBhZGRpbmdcIj5cbiAgPGlvbi1yZWZyZXNoZXIgc2xvdD1cImZpeGVkXCIgKm5nSWY9XCJtb2JpbGVcIiAoaW9uUmVmcmVzaCk9XCJkb1JlZnJlc2goJGV2ZW50KVwiPlxuICAgIDxpb24tcmVmcmVzaGVyLWNvbnRlbnQ+PC9pb24tcmVmcmVzaGVyLWNvbnRlbnQ+XG4gIDwvaW9uLXJlZnJlc2hlcj5cblxuICA8IS0tIHRhYmxlIC0tPlxuICA8ZGl2IGNsYXNzPVwidGFibGUtY29udGFpbmVyXCI+XG4gICAgPHRhYmxlXG4gICAgICAjdGFibGVcbiAgICAgIG1hdC10YWJsZVxuICAgICAgbWF0U29ydFxuICAgICAgbWF0U29ydERpc2FibGVDbGVhclxuICAgICAgW2RhdGFTb3VyY2VdPVwiZGF0YVNvdXJjZVwiXG4gICAgICBbbWF0U29ydEFjdGl2ZV09XCJkZWZhdWx0U29ydEJ5XCJcbiAgICAgIFttYXRTb3J0RGlyZWN0aW9uXT1cImRlZmF1bHRTb3J0RGlyZWN0aW9uXCJcbiAgICAgIFt0cmFja0J5XT1cInRyYWNrQnlGblwiXG4gICAgPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzZWxlY3RcIiBbc3RpY2t5XT1cInVzZVN0aWNreVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cIiFjYW5FZGl0XCI+XG4gICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgKGNoYW5nZSk9XCIkZXZlbnQgPyBtYXN0ZXJUb2dnbGUoKSA6IG51bGxcIlxuICAgICAgICAgICAgW2NoZWNrZWRdPVwidGhpcyB8IGlzQWxsU2VsZWN0ZWRcIlxuICAgICAgICAgICAgW2luZGV0ZXJtaW5hdGVdPVwidGhpcyB8IGlzTm90QWxsU2VsZWN0ZWRcIlxuICAgICAgICAgID48L21hdC1jaGVja2JveD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIFtjbGFzcy5jZGstdmlzdWFsbHktaGlkZGVuXT1cIiFjYW5FZGl0XCI+XG4gICAgICAgICAgPG1hdC1jaGVja2JveFxuICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cIiRldmVudCA/IHNlbGVjdGlvbi50b2dnbGUocm93KSA6IG51bGxcIlxuICAgICAgICAgICAgW2NoZWNrZWRdPVwic2VsZWN0aW9uIHwgaXNTZWxlY3RlZDogcm93XCJcbiAgICAgICAgICA+PC9tYXQtY2hlY2tib3g+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBJZCBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImlkXCIgW3N0aWNreV09XCJ1c2VTdGlja3lcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXIgY2xhc3M9XCJjZGstdmlzdWFsbHktaGlkZGVuXCI+XG4gICAgICAgICAgPGlvbi1sYWJlbD4jPC9pb24tbGFiZWw+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIiBjbGFzcz1cImNkay12aXN1YWxseS1oaWRkZW5cIj57eyByb3cuY3VycmVudERhdGEuaWQgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gbmFtZSBjb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIm5hbWVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+XG4gICAgICAgICAgPGlvbi1sYWJlbD57eyBpMThuQ29sdW1uUHJlZml4ICsgJ05BTUUnIHwgdHJhbnNsYXRlIH19PC9pb24tbGFiZWw+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIj5cbiAgICAgICAgICB7eyAocm93LmN1cnJlbnREYXRhIHwgcHJvcGVydHlHZXQ6ICduYW1lJykgfHwgKGkxOG5Db2x1bW5QcmVmaXggKyAnVU5LTk9XTicgfCB0cmFuc2xhdGUpIH19XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzY29wZXNcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+XG4gICAgICAgICAgPGlvbi1sYWJlbD57eyBpMThuQ29sdW1uUHJlZml4ICsgJ1NDT1BFUycgfCB0cmFuc2xhdGUgfX08L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiPlxuICAgICAgICAgIHt7IGRpc3BsYXkocm93LmN1cnJlbnREYXRhIHwgcHJvcGVydHlHZXQ6ICdzY29wZXMnKSB9fVxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiY3JlYXRpb25EYXRlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyIGNsYXNzPVwibWF0LWNlbGwtZGF0ZS10aW1lXCI+XG4gICAgICAgICAgPGlvbi1sYWJlbD57eyBpMThuQ29sdW1uUHJlZml4ICsgJ0NSRUFUSU9OX0RBVEUnIHwgdHJhbnNsYXRlIH19PC9pb24tbGFiZWw+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIiBjbGFzcz1cIm1hdC1jZWxsLWRhdGUtdGltZVwiPlxuICAgICAgICAgIHt7IHJvdy5jdXJyZW50RGF0YSB8IHByb3BlcnR5R2V0OiAnY3JlYXRpb25EYXRlJyB8IGRhdGVGb3JtYXQ6IHsgdGltZTogdHJ1ZSB9IH19XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJleHBpcmF0aW9uRGF0ZVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlciBjbGFzcz1cIm1hdC1jZWxsLWRhdGUtdGltZVwiPlxuICAgICAgICAgIDxpb24tbGFiZWw+e3sgaTE4bkNvbHVtblByZWZpeCArICdFWFBJUkFUSU9OX0RBVEUnIHwgdHJhbnNsYXRlIH19PC9pb24tbGFiZWw+XG4gICAgICAgIDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCByb3dcIiBjbGFzcz1cIm1hdC1jZWxsLWRhdGUtdGltZVwiPlxuICAgICAgICAgIHt7IHJvdy5jdXJyZW50RGF0YSB8IHByb3BlcnR5R2V0OiAnZXhwaXJhdGlvbkRhdGUnIHwgZGF0ZUZvcm1hdDogeyB0aW1lOiB0cnVlIH0gfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImxhc3RVc2VkRGF0ZVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlciBjbGFzcz1cIm1hdC1jZWxsLWRhdGUtdGltZVwiPlxuICAgICAgICAgIDxpb24tbGFiZWw+e3sgaTE4bkNvbHVtblByZWZpeCArICdMQVNUX1VTRURfREFURScgfCB0cmFuc2xhdGUgfX08L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIGNsYXNzPVwibWF0LWNlbGwtZGF0ZS10aW1lXCI+XG4gICAgICAgICAge3sgcm93LmN1cnJlbnREYXRhIHwgcHJvcGVydHlHZXQ6ICdsYXN0VXNlZERhdGUnIHwgZGF0ZUZvcm1hdDogeyB0aW1lOiB0cnVlIH0gfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIEFjdGlvbnMgYnV0dG9ucyBjb2x1bW4gLS0+XG4gICAgICA8YXBwLWFjdGlvbnMtY29sdW1uXG4gICAgICAgIFtzdGlja3lFbmRdPVwidXNlU3RpY2t5XCJcbiAgICAgICAgKG9wdGlvbnNDbGljayk9XCJvcGVuU2VsZWN0Q29sdW1uc01vZGFsKCRldmVudClcIlxuICAgICAgICAoY2FuY2VsT3JEZWxldGVDbGljayk9XCJjYW5jZWxPckRlbGV0ZSgkZXZlbnQuZXZlbnQsICRldmVudC5yb3cpXCJcbiAgICAgICAgKGNvbmZpcm1BbmRBZGRDbGljayk9XCJjb25maXJtQW5kQWRkKCRldmVudC5ldmVudCwgJGV2ZW50LnJvdylcIlxuICAgICAgICAoYmFja3dhcmQpPVwiY29uZmlybUFuZEJhY2t3YXJkKCRldmVudC5ldmVudCwgJGV2ZW50LnJvdylcIlxuICAgICAgICAoZm9yd2FyZCk9XCJjb25maXJtQW5kRm9yd2FyZCgkZXZlbnQuZXZlbnQsICRldmVudC5yb3cpXCJcbiAgICAgICAgW2NhbkNhbmNlbF09XCJmYWxzZVwiXG4gICAgICA+PC9hcHAtYWN0aW9ucy1jb2x1bW4+XG5cbiAgICAgIDx0ciBtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkQ29sdW1uczsgc3RpY2t5OiB0cnVlXCI+PC90cj5cbiAgICAgIDx0clxuICAgICAgICBtYXQtcm93XG4gICAgICAgICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBkaXNwbGF5ZWRDb2x1bW5zXCJcbiAgICAgICAgW2NsYXNzLm1hdC1yb3ctc2VsZWN0ZWRdPVwicm93LmVkaXRpbmdcIlxuICAgICAgICBbY2xhc3MubWF0LXJvdy1lcnJvcl09XCJyb3cudmFsaWRhdG9yPy5pbnZhbGlkXCJcbiAgICAgICAgW2NsYXNzLm1hdC1yb3ctZGlydHldPVwicm93LnZhbGlkYXRvcj8uZGlydHlcIlxuICAgICAgICAoY2xpY2spPVwiY2xpY2tSb3coJGV2ZW50LCByb3cpXCJcbiAgICAgICAgKGtleWRvd24uZXNjYXBlKT1cImVzY2FwZUVkaXRpbmdSb3coJGV2ZW50KVwiXG4gICAgICAgIFtjZGtUcmFwRm9jdXNdPVwicm93LnZhbGlkYXRvcj8uaW52YWxpZFwiXG4gICAgICA+PC90cj5cbiAgICA8L3RhYmxlPlxuXG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImxvYWRpbmdTdWJqZWN0IHwgYXN5bmM7IGVsc2Ugbm9SZXN1bHRcIj5cbiAgICAgIDxpb24taXRlbT5cbiAgICAgICAgPGlvbi1za2VsZXRvbi10ZXh0IGFuaW1hdGVkPjwvaW9uLXNrZWxldG9uLXRleHQ+XG4gICAgICA8L2lvbi1pdGVtPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPG5nLXRlbXBsYXRlICNub1Jlc3VsdD5cbiAgICAgIDxpb24taXRlbSAqbmdJZj1cInRvdGFsUm93Q291bnQgPT09IDBcIj5cbiAgICAgICAgPGlvbi10ZXh0IGNvbG9yPVwiZGFuZ2VyXCIgY2xhc3M9XCJ0ZXh0LWl0YWxpY1wiIHRyYW5zbGF0ZT5DT01NT04uTk9fUkVTVUxUPC9pb24tdGV4dD5cbiAgICAgIDwvaW9uLWl0ZW0+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC9kaXY+XG48L2lvbi1jb250ZW50PlxuXG48aW9uLWZhYiBzbG90PVwiZml4ZWRcIiB2ZXJ0aWNhbD1cImJvdHRvbVwiIGhvcml6b250YWw9XCJlbmRcIiAqbmdJZj1cIm1vYmlsZVwiPlxuICA8aW9uLWZhYi1idXR0b24gY29sb3I9XCJ0ZXJ0aWFyeVwiIChjbGljayk9XCJhZGRUb2tlbigkZXZlbnQpXCI+XG4gICAgPGlvbi1pY29uIG5hbWU9XCJhZGRcIj48L2lvbi1pY29uPlxuICA8L2lvbi1mYWItYnV0dG9uPlxuPC9pb24tZmFiPlxuIl19
160
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9rZW4udGFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL2NvcmUvYWNjb3VudC90b2tlbi50YWJsZS50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9hY2NvdW50L3Rva2VuLnRhYmxlLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFZLEtBQUssRUFBVSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEgsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDNUQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDdkYsT0FBTyxFQUFjLFNBQVMsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ3RFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBQzVGLE9BQU8sRUFBZSxXQUFXLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUNuRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNwRSxPQUFPLEVBQW9CLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBR3BFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFMUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVMxRCxNQUFNLE9BQU8sY0FBZSxTQUFRLGdCQUEy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QUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLDRCQUE0QixDQUFDLENBQUM7SUFDM0YsQ0FBQzt3R0ExSVUsY0FBYyx1R0FhZixXQUFXLGFBQ0MscUJBQXFCOzRGQWRoQyxjQUFjLG1GQUhkLENBQUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFFLHlCQUF5QixFQUFFLENBQUMsaURDckJqRiw4ak5BNEtBOzs0RkRwSmEsY0FBYztrQkFQMUIsU0FBUzsrQkFDRSxzQkFBc0IsYUFHckIsQ0FBQyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxRQUFRLEVBQUUseUJBQXlCLEVBQUUsQ0FBQyxtQkFDOUQsdUJBQXVCLENBQUMsTUFBTTs7MEJBZTVDLE1BQU07MkJBQUMsV0FBVzs7MEJBQ2xCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMscUJBQXFCO3lDQWJsQyxTQUFTO3NCQUFqQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgaW5qZWN0LCBJbmplY3QsIEluamVjdG9yLCBJbnB1dCwgT25Jbml0LCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVmFsaWRhdG9yU2VydmljZSB9IGZyb20gJ0BlLWlzL25neC1tYXRlcmlhbC10YWJsZSc7XG5pbXBvcnQgeyBVc2VyVG9rZW5WYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvdmFsaWRhdG9yL3VzZXItdG9rZW4udmFsaWRhdG9yJztcbmltcG9ydCB7IFRva2VuU2NvcGUsIFVzZXJUb2tlbiB9IGZyb20gJy4uL3NlcnZpY2VzL21vZGVsL3Rva2VuLm1vZGVsJztcbmltcG9ydCB7IEFwcEluTWVtb3J5VGFibGUgfSBmcm9tICcuLi90YWJsZS9tZW1vcnktdGFibGUuY2xhc3MnO1xuaW1wb3J0IHsgUkVTRVJWRURfRU5EX0NPTFVNTlMsIFJFU0VSVkVEX1NUQVJUX0NPTFVNTlMgfSBmcm9tICcuLi90YWJsZS90YWJsZS5tb2RlbCc7XG5pbXBvcnQgeyBJbk1lbW9yeUVudGl0aWVzU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC9zZXJ2aWNlcy9tZW1vcnktZW50aXR5LXNlcnZpY2UuY2xhc3MnO1xuaW1wb3J0IHsgRW52aXJvbm1lbnQsIEVOVklST05NRU5UIH0gZnJvbSAnLi4vLi4vLi4vZW52aXJvbm1lbnRzL2Vudmlyb25tZW50LmNsYXNzJztcbmltcG9ydCB7IEFQUF9VU0VSX1RPS0VOX1NDT1BFUyB9IGZyb20gJy4uL3NlcnZpY2VzL2FjY291bnQuc2VydmljZSc7XG5pbXBvcnQgeyBJTmV3VG9rZW5PcHRpb25zLCBOZXdUb2tlbk1vZGFsIH0gZnJvbSAnLi9uZXctdG9rZW4ubW9kYWwnO1xuaW1wb3J0IHsgQ29uZmlnU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2NvbmZpZy5zZXJ2aWNlJztcbmltcG9ydCB7IENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9zZXJ2aWNlcy9tb2RlbC9jb25maWcubW9kZWwnO1xuaW1wb3J0IHsgQ09SRV9DT05GSUdfT1BUSU9OUyB9IGZyb20gJy4uL3NlcnZpY2VzL2NvbmZpZy9jb3JlLmNvbmZpZyc7XG5pbXBvcnQgeyBpc05vdEVtcHR5QXJyYXksIGlzTm90TmlsT3JCbGFuayB9IGZyb20gJy4uLy4uL3NoYXJlZC9mdW5jdGlvbnMnO1xuXG5pbXBvcnQgeyBBUFBfU0hPV19UT09MVElQIH0gZnJvbSAnLi4vLi4vc2hhcmVkL2NvbnN0YW50cyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC11c2VyLXRva2VuLXRhYmxlJyxcbiAgdGVtcGxhdGVVcmw6ICd0b2tlbi50YWJsZS5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJ3Rva2VuLnRhYmxlLnNjc3MnXSxcbiAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBWYWxpZGF0b3JTZXJ2aWNlLCB1c2VDbGFzczogVXNlclRva2VuVmFsaWRhdG9yU2VydmljZSB9XSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFVzZXJUb2tlblRhYmxlIGV4dGVuZHMgQXBwSW5NZW1vcnlUYWJsZTxVc2VyVG9rZW4+IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgdXNlU3RpY2t5ID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIHNob3dTY29wZXMgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGRlZmF1bHRTY29wZTogc3RyaW5nO1xuICBwcm90ZWN0ZWQgdG9rZW5TY29wZXM6IFRva2VuU2NvcGVbXTtcblxuICBzaG93VG9vbHRpcCA9IGluamVjdChBUFBfU0hPV19UT09MVElQLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGluamVjdG9yOiBJbmplY3RvcixcbiAgICB2YWxpZGF0b3JTZXJ2aWNlOiBWYWxpZGF0b3JTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBjb25maWdTZXJ2aWNlOiBDb25maWdTZXJ2aWNlLFxuICAgIEBJbmplY3QoRU5WSVJPTk1FTlQpIGVudmlyb25tZW50OiBFbnZpcm9ubWVudCxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFQUF9VU0VSX1RPS0VOX1NDT1BFUykgdG9rZW5TY29wZXM6IFRva2VuU2NvcGVbXVxuICApIHtcbiAgICBzdXBlcihcbiAgICAgIGluamVjdG9yLFxuICAgICAgWy4uLlJFU0VSVkVEX1NUQVJUX0NPTFVNTlMsICduYW1lJywgJ3Njb3BlcycsICdsYXN0VXNlZERhdGUnLCAnZXhwaXJhdGlvbkRhdGUnLCAnY3JlYXRpb25EYXRlJywgLi4uUkVTRVJWRURfRU5EX0NPTFVNTlNdLFxuICAgICAgVXNlclRva2VuLFxuICAgICAgbmV3IEluTWVtb3J5RW50aXRpZXNTZXJ2aWNlKFVzZXJUb2tlbiwgdW5kZWZpbmVkLCB7XG4gICAgICAgIGZpbHRlckZuRmFjdG9yeTogKCkgPT4gKCkgPT4gdHJ1ZSxcbiAgICAgICAgZXF1YWxzOiBVc2VyVG9rZW4uZXF1YWxzLFxuICAgICAgfSksXG4gICAgICB2YWxpZGF0b3JTZXJ2aWNlXG4gICAgKTtcblxuICAgIHRoaXMudG9rZW5TY29wZXMgPSB0b2tlblNjb3BlcyA/PyBbXTtcbiAgICB0aGlzLmlubGluZUVkaXRpb24gPSBmYWxzZTtcbiAgICB0aGlzLmFsbG93Um93RGV0YWlsID0gZmFsc2U7XG4gICAgdGhpcy5kZWZhdWx0U29ydEJ5ID0gJ2NyZWF0aW9uRGF0ZSc7XG4gICAgdGhpcy5kZWZhdWx0U29ydERpcmVjdGlvbiA9ICdhc2MnO1xuICAgIHRoaXMuaTE4bkNvbHVtblByZWZpeCA9ICdBQ0NPVU5ULlRPS0VOUy5UQUJMRS4nO1xuICAgIHRoaXMuZGVidWcgPSAhZW52aXJvbm1lbnQ/LnByb2R1Y3Rpb247XG5cbiAgICBpZiAoIXRva2VuU2NvcGVzKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ05vIFRva2VuU2NvcGVzIHByb3ZpZGVkLiBQbGVhc2UgcHJvdmlkZSB0aGUgdG9rZW4gQVBQX1VTRVJfVE9LRU5fU0NPUEVTIHdpdGggdmFsaWQgVG9rZW5TY29wZSBhcnJheScpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHN1cGVyLm5nT25Jbml0KCk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyU3Vic2NyaXB0aW9uKHRoaXMuY29uZmlnU2VydmljZS5jb25maWcuc3Vic2NyaWJlKChjb25maWcpID0+IHRoaXMub25Db25maWdMb2FkZWQoY29uZmlnKSkpO1xuXG4gICAgdGhpcy5tYXJrQXNSZWFkeSgpO1xuICB9XG5cbiAgZ2V0IHZhbHVlKCk6IFVzZXJUb2tlbltdIHtcbiAgICByZXR1cm4gc3VwZXIudmFsdWUgfHwgW107XG4gIH1cblxuICBzZXQgdmFsdWUoZGF0YTogVXNlclRva2VuW10pIHtcbiAgICBzdXBlci52YWx1ZSA9IGRhdGE7XG4gIH1cblxuICBzZXRWYWx1ZSh2YWx1ZTogVXNlclRva2VuW10sIG9wdHM/OiB7IGVtaXRFdmVudD86IGJvb2xlYW4gfSkge1xuICAgIC8vIFNldCBzY29wZXMgZnJvbSBmbGFnc1xuICAgIHZhbHVlPy5mb3JFYWNoKCh1c2VyVG9rZW4pID0+IHtcbiAgICAgIGNvbnN0IHNjb3BlczogVG9rZW5TY29wZVtdID0gW107XG4gICAgICBpZiAodXNlclRva2VuLmZsYWdzKSB7XG4gICAgICAgIHRoaXMudG9rZW5TY29wZXMuZm9yRWFjaCgoc2NvcGUpID0+IHtcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tYml0d2lzZVxuICAgICAgICAgIGlmICh1c2VyVG9rZW4uZmxhZ3MgJiBzY29wZS5mbGFnKSB7XG4gICAgICAgICAgICBzY29wZXMucHVzaChzY29wZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHVzZXJUb2tlbi5zY29wZXMgPSBzY29wZXM7XG4gICAgfSk7XG5cbiAgICBzdXBlci5zZXRWYWx1ZSh2YWx1ZSwgb3B0cyk7XG4gIH1cblxuICBhc3luYyBhZGRUb2tlbihldmVudDogVUlFdmVudCkge1xuICAgIGlmIChldmVudD8uZGVmYXVsdFByZXZlbnRlZCkgcmV0dXJuOyAvLyBBdm9pZCBtdWx0aXBsZSBjYWxsXG5cbiAgICBldmVudD8ucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgbmV3VG9rZW4gPSBuZXcgVXNlclRva2VuKCk7XG4gICAgaWYgKGlzTm90TmlsT3JCbGFuayh0aGlzLmRlZmF1bHRTY29wZSkgJiYgaXNOb3RFbXB0eUFycmF5KHRoaXMudG9rZW5TY29wZXMpKSB7XG4gICAgICBjb25zdCBzY29wZSA9IHRoaXMudG9rZW5TY29wZXMuZmluZCgoc2NvcGUpID0+IHNjb3BlLmlkID09PSB0aGlzLmRlZmF1bHRTY29wZSk7XG4gICAgICBpZiAoIXNjb3BlKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcIlt0b2tlbi10YWJsZV0gQ2Fubm90IGZvdW5kIHRoZSBkZWZhdWx0IHNjb3BlICcke3RoaXMuZGVmYXVsdFNjb3BlfScgaW4gdmFsdWVzIG9mIEFQUF9VU0VSX1RPS0VOX1NDT1BFUyFcIik7XG4gICAgICB9XG4gICAgICBuZXdUb2tlbi5zY29wZXMgPSBzY29wZSA/IFtzY29wZV0gOiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBtb2RhbCA9IGF3YWl0IHRoaXMubW9kYWxDdHJsLmNyZWF0ZSh7XG4gICAgICBjb21wb25lbnQ6IE5ld1Rva2VuTW9kYWwsXG4gICAgICBjb21wb25lbnRQcm9wczogPElOZXdUb2tlbk9wdGlvbnM+e1xuICAgICAgICBtb2JpbGU6IHRoaXMubW9iaWxlLFxuICAgICAgICBpc05ldzogdHJ1ZSxcbiAgICAgICAgZGF0YTogbmV3VG9rZW4sXG4gICAgICAgIHNob3dTY29wZXM6IHRoaXMuc2hvd1Njb3BlcyxcbiAgICAgICAgdG9rZW5TY29wZXM6IHRoaXMudG9rZW5TY29wZXMgfHwgW10sXG4gICAgICAgIGV4aXN0aW5nTmFtZXM6IHRoaXMudmFsdWU/Lm1hcCgodikgPT4gdi5uYW1lKSxcbiAgICAgIH0sXG4gICAgICBiYWNrZHJvcERpc21pc3M6IGZhbHNlLFxuICAgIH0pO1xuXG4gICAgYXdhaXQgbW9kYWwucHJlc2VudCgpO1xuICAgIGNvbnN0IHsgZGF0YSB9ID0gYXdhaXQgbW9kYWwub25EaWREaXNtaXNzKCk7XG5cbiAgICBpZiAoZGF0YT8ubmFtZSkge1xuICAgICAgLy8gQWRkIHRoaXMgdG9rZW4gaW4gdGhlIGxpc3RcbiAgICAgIGNvbnN0IHJvdyA9IGF3YWl0IHRoaXMuYWRkUm93VG9UYWJsZSh1bmRlZmluZWQsIHsgZWRpdGluZzogZmFsc2UgfSk7XG4gICAgICByb3cudmFsaWRhdG9yLnBhdGNoVmFsdWUoZGF0YSk7XG5cbiAgICAgIHRoaXMubWFya0FzRGlydHkoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG4gIH1cblxuICAvLyBhc3luYyByZXZvY2F0ZShldmVudDogVUlFdmVudCkge1xuICAvLyAgIGlmICh0aGlzLnNlbGVjdGlvbi5pc0VtcHR5KCkpIHJldHVybjtcbiAgLy9cbiAgLy8gICBjb25zdCBjb25maXJtZWQgPSBhd2FpdCBBbGVydHMuYXNrQ29uZmlybWF0aW9uKHRoaXMuaTE4bkNvbHVtblByZWZpeCArICdDT05GSVJNLlJFVk9DQVRFJywgdGhpcy5hbGVydEN0cmwsIHRoaXMudHJhbnNsYXRlKTtcbiAgLy8gICBpZiAoIWNvbmZpcm1lZCkgcmV0dXJuO1xuICAvL1xuICAvLyAgIGNvbnN0IG5vdyA9IG1vbWVudCgpO1xuICAvLyAgIHRoaXMuc2VsZWN0aW9uLnNlbGVjdGVkLmZvckVhY2gocm93ID0+IHtcbiAgLy8gICAgIHJvdy52YWxpZGF0b3IucGF0Y2hWYWx1ZSh7cmV2b2NhdGlvbkRhdGU6IG5vd30sIHtlbWl0RXZlbnQ6dHJ1ZX0pO1xuICAvLyAgICAgLy8gcm93LnZhbGlkYXRvci51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KCk7XG4gIC8vICAgfSk7XG4gIC8vXG4gIC8vICAgdGhpcy5tYXJrRm9yQ2hlY2soKTtcbiAgLy8gICAvLyB0aGlzLm1hcmtBc0RpcnR5KCk7XG4gIC8vIH1cblxuICBkaXNwbGF5KHNjb3BlczogVG9rZW5TY29wZVtdKSB7XG4gICAgcmV0dXJuIHNjb3Blcz8ubWFwKCh2YWx1ZSkgPT4gdGhpcy50cmFuc2xhdGUuaW5zdGFudCh2YWx1ZS5uYW1lKSkuam9pbignLCAnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvbkNvbmZpZ0xvYWRlZChjb25maWc6IENvbmZpZ3VyYXRpb24pIHtcbiAgICB0aGlzLnNob3dTY29wZXMgPSBjb25maWcuZ2V0UHJvcGVydHlBc0Jvb2xlYW4oQ09SRV9DT05GSUdfT1BUSU9OUy5BVVRIX0FQSV9UT0tFTl9TQ09QRV9FTkFCTEVEKTtcbiAgICB0aGlzLnNldFNob3dDb2x1bW4oJ3Njb3BlcycsIHRoaXMuc2hvd1Njb3Blcyk7XG4gICAgdGhpcy5kZWZhdWx0U2NvcGUgPSBjb25maWcuZ2V0UHJvcGVydHkoQ09SRV9DT05GSUdfT1BUSU9OUy5ERUZBVUxUX0FVVEhfQVBJX1RPS0VOX1NDT1BFKTtcbiAgfVxufVxuIiwiPG1hdC10b29sYmFyPlxuICA8IS0tIFJlZnJlc2ggLS0+XG4gIDxidXR0b25cbiAgICBtYXQtaWNvbi1idXR0b25cbiAgICAqbmdJZj1cIiFtb2JpbGVcIlxuICAgIFt0aXRsZV09XCIhc2hvd1Rvb2x0aXAgPyAoJ0NPTU1PTi5CVE5fUkVGUkVTSCcgfCB0cmFuc2xhdGUpIDogJydcIlxuICAgIFttYXRUb29sdGlwXT1cInNob3dUb29sdGlwID8gKCdDT01NT04uQlROX1JFRlJFU0gnIHwgdHJhbnNsYXRlKSA6ICcnXCJcbiAgICAoY2xpY2spPVwiZW1pdFJlZnJlc2goKVwiXG4gID5cbiAgICA8bWF0LWljb24+cmVmcmVzaDwvbWF0LWljb24+XG4gIDwvYnV0dG9uPlxuXG4gIDxpb24taXRlbSAqbmdJZj1cIiFtb2JpbGUgJiYgZXJyb3I7IGxldCBlcnJvclwiIGxpbmVzPVwibm9uZVwiPlxuICAgIDxpb24taWNvbiBjb2xvcj1cImRhbmdlclwiIHNsb3Q9XCJzdGFydFwiIG5hbWU9XCJhbGVydC1jaXJjbGVcIj48L2lvbi1pY29uPlxuICAgIDxpb24tbGFiZWwgY29sb3I9XCJkYW5nZXJcIiBbaW5uZXJIVE1MXT1cImVycm9yIHwgdHJhbnNsYXRlXCI+PC9pb24tbGFiZWw+XG4gIDwvaW9uLWl0ZW0+XG5cbiAgPGRpdiBjbGFzcz1cInRvb2xiYXItc3BhY2VyXCI+PC9kaXY+XG5cbiAgQGlmIChzZWxlY3Rpb24gfCBpc0VtcHR5U2VsZWN0aW9uKSB7XG4gICAgPGJ1dHRvblxuICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAqbmdJZj1cImNhbkVkaXQgJiYgIW1vYmlsZVwiXG4gICAgICBbdGl0bGVdPVwiIXNob3dUb29sdGlwID8gKCdDT01NT04uQlROX0FERCcgfCB0cmFuc2xhdGUpIDogJydcIlxuICAgICAgW21hdFRvb2x0aXBdPVwic2hvd1Rvb2x0aXAgPyAoJ0NPTU1PTi5CVE5fQUREJyB8IHRyYW5zbGF0ZSkgOiAnJ1wiXG4gICAgICAoY2xpY2spPVwiYWRkVG9rZW4oJGV2ZW50KVwiXG4gICAgPlxuICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG4gIH0gQGVsc2Uge1xuICAgIDxidXR0b25cbiAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgW3RpdGxlXT1cIiFzaG93VG9vbHRpcCA/ICgnQ09NTU9OLkJUTl9ERUxFVEUnIHwgdHJhbnNsYXRlKSA6ICcnXCJcbiAgICAgIFttYXRUb29sdGlwXT1cInNob3dUb29sdGlwID8gKCdDT01NT04uQlROX0RFTEVURScgfCB0cmFuc2xhdGUpIDogJydcIlxuICAgICAgKGNsaWNrKT1cImRlbGV0ZVNlbGVjdGlvbigkZXZlbnQpXCJcbiAgICA+XG4gICAgICA8bWF0LWljb24+ZGVsZXRlX291dGxpbmU8L21hdC1pY29uPlxuICAgIDwvYnV0dG9uPlxuICB9XG48L21hdC10b29sYmFyPlxuXG48aW9uLWNvbnRlbnQgY2xhc3M9XCJpb24tbm8tcGFkZGluZ1wiPlxuICA8aW9uLXJlZnJlc2hlciBzbG90PVwiZml4ZWRcIiAqbmdJZj1cIm1vYmlsZVwiIChpb25SZWZyZXNoKT1cImRvUmVmcmVzaCgkZXZlbnQpXCI+XG4gICAgPGlvbi1yZWZyZXNoZXItY29udGVudD48L2lvbi1yZWZyZXNoZXItY29udGVudD5cbiAgPC9pb24tcmVmcmVzaGVyPlxuXG4gIDwhLS0gdGFibGUgLS0+XG4gIDxkaXYgY2xhc3M9XCJ0YWJsZS1jb250YWluZXJcIj5cbiAgICA8dGFibGVcbiAgICAgICN0YWJsZVxuICAgICAgbWF0LXRhYmxlXG4gICAgICBtYXRTb3J0XG4gICAgICBtYXRTb3J0RGlzYWJsZUNsZWFyXG4gICAgICBbZGF0YVNvdXJjZV09XCJkYXRhU291cmNlXCJcbiAgICAgIFttYXRTb3J0QWN0aXZlXT1cImRlZmF1bHRTb3J0QnlcIlxuICAgICAgW21hdFNvcnREaXJlY3Rpb25dPVwiZGVmYXVsdFNvcnREaXJlY3Rpb25cIlxuICAgICAgW3RyYWNrQnldPVwidHJhY2tCeUZuXCJcbiAgICA+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInNlbGVjdFwiIFtzdGlja3ldPVwidXNlU3RpY2t5XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIWNhbkVkaXRcIj5cbiAgICAgICAgICA8bWF0LWNoZWNrYm94XG4gICAgICAgICAgICAoY2hhbmdlKT1cIiRldmVudCA/IG1hc3RlclRvZ2dsZSgpIDogbnVsbFwiXG4gICAgICAgICAgICBbY2hlY2tlZF09XCJ0aGlzIHwgaXNBbGxTZWxlY3RlZFwiXG4gICAgICAgICAgICBbaW5kZXRlcm1pbmF0ZV09XCJ0aGlzIHwgaXNOb3RBbGxTZWxlY3RlZFwiXG4gICAgICAgICAgPjwvbWF0LWNoZWNrYm94PlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgW2NsYXNzLmNkay12aXN1YWxseS1oaWRkZW5dPVwiIWNhbkVkaXRcIj5cbiAgICAgICAgICA8bWF0LWNoZWNrYm94XG4gICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgIChjaGFuZ2UpPVwiJGV2ZW50ID8gc2VsZWN0aW9uLnRvZ2dsZShyb3cpIDogbnVsbFwiXG4gICAgICAgICAgICBbY2hlY2tlZF09XCJzZWxlY3Rpb24gfCBpc1NlbGVjdGVkOiByb3dcIlxuICAgICAgICAgID48L21hdC1jaGVja2JveD5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIElkIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiaWRcIiBbc3RpY2t5XT1cInVzZVN0aWNreVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlciBjbGFzcz1cImNkay12aXN1YWxseS1oaWRkZW5cIj5cbiAgICAgICAgICA8aW9uLWxhYmVsPiM8L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIGNsYXNzPVwiY2RrLXZpc3VhbGx5LWhpZGRlblwiPnt7IHJvdy5jdXJyZW50RGF0YS5pZCB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBuYW1lIGNvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwibmFtZVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5cbiAgICAgICAgICA8aW9uLWxhYmVsPnt7IGkxOG5Db2x1bW5QcmVmaXggKyAnTkFNRScgfCB0cmFuc2xhdGUgfX08L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiPlxuICAgICAgICAgIHt7IChyb3cuY3VycmVudERhdGEgfCBwcm9wZXJ0eUdldDogJ25hbWUnKSB8fCAoaTE4bkNvbHVtblByZWZpeCArICdVTktOT1dOJyB8IHRyYW5zbGF0ZSkgfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInNjb3Blc1wiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5cbiAgICAgICAgICA8aW9uLWxhYmVsPnt7IGkxOG5Db2x1bW5QcmVmaXggKyAnU0NPUEVTJyB8IHRyYW5zbGF0ZSB9fTwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCI+XG4gICAgICAgICAge3sgZGlzcGxheShyb3cuY3VycmVudERhdGEgfCBwcm9wZXJ0eUdldDogJ3Njb3BlcycpIH19XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJjcmVhdGlvbkRhdGVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXIgY2xhc3M9XCJtYXQtY2VsbC1kYXRlLXRpbWVcIj5cbiAgICAgICAgICA8aW9uLWxhYmVsPnt7IGkxOG5Db2x1bW5QcmVmaXggKyAnQ1JFQVRJT05fREFURScgfCB0cmFuc2xhdGUgfX08L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIGNsYXNzPVwibWF0LWNlbGwtZGF0ZS10aW1lXCI+XG4gICAgICAgICAge3sgcm93LmN1cnJlbnREYXRhIHwgcHJvcGVydHlHZXQ6ICdjcmVhdGlvbkRhdGUnIHwgZGF0ZUZvcm1hdDogeyB0aW1lOiB0cnVlIH0gfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImV4cGlyYXRpb25EYXRlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyIGNsYXNzPVwibWF0LWNlbGwtZGF0ZS10aW1lXCI+XG4gICAgICAgICAgPGlvbi1sYWJlbD57eyBpMThuQ29sdW1uUHJlZml4ICsgJ0VYUElSQVRJT05fREFURScgfCB0cmFuc2xhdGUgfX08L2lvbi1sYWJlbD5cbiAgICAgICAgPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHJvd1wiIGNsYXNzPVwibWF0LWNlbGwtZGF0ZS10aW1lXCI+XG4gICAgICAgICAge3sgcm93LmN1cnJlbnREYXRhIHwgcHJvcGVydHlHZXQ6ICdleHBpcmF0aW9uRGF0ZScgfCBkYXRlRm9ybWF0OiB7IHRpbWU6IHRydWUgfSB9fVxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwibGFzdFVzZWREYXRlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyIGNsYXNzPVwibWF0LWNlbGwtZGF0ZS10aW1lXCI+XG4gICAgICAgICAgPGlvbi1sYWJlbD57eyBpMThuQ29sdW1uUHJlZml4ICsgJ0xBU1RfVVNFRF9EQVRFJyB8IHRyYW5zbGF0ZSB9fTwvaW9uLWxhYmVsPlxuICAgICAgICA8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcm93XCIgY2xhc3M9XCJtYXQtY2VsbC1kYXRlLXRpbWVcIj5cbiAgICAgICAgICB7eyByb3cuY3VycmVudERhdGEgfCBwcm9wZXJ0eUdldDogJ2xhc3RVc2VkRGF0ZScgfCBkYXRlRm9ybWF0OiB7IHRpbWU6IHRydWUgfSB9fVxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gQWN0aW9ucyBidXR0b25zIGNvbHVtbiAtLT5cbiAgICAgIDxhcHAtYWN0aW9ucy1jb2x1bW5cbiAgICAgICAgW3N0aWNreUVuZF09XCJ1c2VTdGlja3lcIlxuICAgICAgICAob3B0aW9uc0NsaWNrKT1cIm9wZW5TZWxlY3RDb2x1bW5zTW9kYWwoJGV2ZW50KVwiXG4gICAgICAgIChjYW5jZWxPckRlbGV0ZUNsaWNrKT1cImNhbmNlbE9yRGVsZXRlKCRldmVudC5ldmVudCwgJGV2ZW50LnJvdylcIlxuICAgICAgICAoY29uZmlybUFuZEFkZENsaWNrKT1cImNvbmZpcm1BbmRBZGQoJGV2ZW50LmV2ZW50LCAkZXZlbnQucm93KVwiXG4gICAgICAgIChiYWNrd2FyZCk9XCJjb25maXJtQW5kQmFja3dhcmQoJGV2ZW50LmV2ZW50LCAkZXZlbnQucm93KVwiXG4gICAgICAgIChmb3J3YXJkKT1cImNvbmZpcm1BbmRGb3J3YXJkKCRldmVudC5ldmVudCwgJGV2ZW50LnJvdylcIlxuICAgICAgICBbY2FuQ2FuY2VsXT1cImZhbHNlXCJcbiAgICAgID48L2FwcC1hY3Rpb25zLWNvbHVtbj5cblxuICAgICAgPHRyIG1hdC1oZWFkZXItcm93ICptYXRIZWFkZXJSb3dEZWY9XCJkaXNwbGF5ZWRDb2x1bW5zOyBzdGlja3k6IHRydWVcIj48L3RyPlxuICAgICAgPHRyXG4gICAgICAgIG1hdC1yb3dcbiAgICAgICAgKm1hdFJvd0RlZj1cImxldCByb3c7IGNvbHVtbnM6IGRpc3BsYXllZENvbHVtbnNcIlxuICAgICAgICBbY2xhc3MubWF0LXJvdy1zZWxlY3RlZF09XCJyb3cuZWRpdGluZ1wiXG4gICAgICAgIFtjbGFzcy5tYXQtcm93LWVycm9yXT1cInJvdy52YWxpZGF0b3I/LmludmFsaWRcIlxuICAgICAgICBbY2xhc3MubWF0LXJvdy1kaXJ0eV09XCJyb3cudmFsaWRhdG9yPy5kaXJ0eVwiXG4gICAgICAgIChjbGljayk9XCJjbGlja1JvdygkZXZlbnQsIHJvdylcIlxuICAgICAgICAoa2V5ZG93bi5lc2NhcGUpPVwiZXNjYXBlRWRpdGluZ1JvdygkZXZlbnQpXCJcbiAgICAgICAgW2Nka1RyYXBGb2N1c109XCJyb3cudmFsaWRhdG9yPy5pbnZhbGlkXCJcbiAgICAgID48L3RyPlxuICAgIDwvdGFibGU+XG5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibG9hZGluZ1N1YmplY3QgfCBhc3luYzsgZWxzZSBub1Jlc3VsdFwiPlxuICAgICAgPGlvbi1pdGVtPlxuICAgICAgICA8aW9uLXNrZWxldG9uLXRleHQgYW5pbWF0ZWQ+PC9pb24tc2tlbGV0b24tdGV4dD5cbiAgICAgIDwvaW9uLWl0ZW0+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8bmctdGVtcGxhdGUgI25vUmVzdWx0PlxuICAgICAgPGlvbi1pdGVtICpuZ0lmPVwidG90YWxSb3dDb3VudCA9PT0gMFwiPlxuICAgICAgICA8aW9uLXRleHQgY29sb3I9XCJkYW5nZXJcIiBjbGFzcz1cInRleHQtaXRhbGljXCIgdHJhbnNsYXRlPkNPTU1PTi5OT19SRVNVTFQ8L2lvbi10ZXh0PlxuICAgICAgPC9pb24taXRlbT5cbiAgICA8L25nLXRlbXBsYXRlPlxuICA8L2Rpdj5cbjwvaW9uLWNvbnRlbnQ+XG5cbjxpb24tZmFiIHNsb3Q9XCJmaXhlZFwiIHZlcnRpY2FsPVwiYm90dG9tXCIgaG9yaXpvbnRhbD1cImVuZFwiICpuZ0lmPVwibW9iaWxlXCI+XG4gIDxpb24tZmFiLWJ1dHRvbiBjb2xvcj1cInRlcnRpYXJ5XCIgKGNsaWNrKT1cImFkZFRva2VuKCRldmVudClcIj5cbiAgICA8aW9uLWljb24gbmFtZT1cImFkZFwiPjwvaW9uLWljb24+XG4gIDwvaW9uLWZhYi1idXR0b24+XG48L2lvbi1mYWI+XG4iXX0=