@mediusinc/mng-commons 5.3.0-rc.0 → 5.3.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/core/components/pages/error/error.page.component.d.ts +3 -0
  2. package/core/components/pages/not-found/not-found.page.component.d.ts +3 -0
  3. package/core/data-list/filter-metadata.model.d.ts +20 -0
  4. package/core/enum/enum-helpers.d.ts +5 -0
  5. package/core/helpers/number.d.ts +5 -0
  6. package/core/helpers/type-helpers.d.ts +1 -0
  7. package/core/index.d.ts +3 -1
  8. package/core/provide.d.ts +3 -2
  9. package/core/services/{local-storage-config.service.d.ts → commons-storage.service.d.ts} +4 -3
  10. package/core/services/commons.service.d.ts +24 -0
  11. package/core/services/tokens/module-config.token.d.ts +30 -8
  12. package/esm2022/core/components/pages/error/error.page.component.mjs +4 -1
  13. package/esm2022/core/components/pages/not-found/not-found.page.component.mjs +4 -1
  14. package/esm2022/core/data-list/data-list-params-helpers.mjs +3 -1
  15. package/esm2022/core/data-list/filter-metadata.model.mjs +2 -0
  16. package/esm2022/core/enum/enum-helpers.mjs +10 -1
  17. package/esm2022/core/helpers/date.mjs +2 -2
  18. package/esm2022/core/helpers/number.mjs +19 -0
  19. package/esm2022/core/helpers/type-helpers.mjs +1 -1
  20. package/esm2022/core/index.mjs +4 -2
  21. package/esm2022/core/pipes/boolean.pipe.mjs +7 -1
  22. package/esm2022/core/pipes/enum.pipe.mjs +16 -5
  23. package/esm2022/core/provide.mjs +6 -5
  24. package/esm2022/core/router/route-builder.mjs +8 -1
  25. package/esm2022/core/security/permission.guard.mjs +2 -2
  26. package/esm2022/core/security/permission.service.mjs +2 -2
  27. package/esm2022/core/services/commons-storage.service.mjs +31 -0
  28. package/esm2022/core/services/commons.service.mjs +25 -1
  29. package/esm2022/core/services/tokens/module-config.token.mjs +1 -1
  30. package/esm2022/filter/descriptors/filter-lookup.descriptor.mjs +2 -3
  31. package/esm2022/filter/descriptors/filter.descriptor.mjs +76 -31
  32. package/esm2022/filter/models/filter.model.mjs +6 -1
  33. package/esm2022/form/components/date-range/date-range.component.mjs +45 -14
  34. package/esm2022/form/components/dropdown/dropdown.component.mjs +77 -93
  35. package/esm2022/form/components/number-range/number-range.component.mjs +29 -12
  36. package/esm2022/table/api/descriptors/column.descriptor.mjs +2 -1
  37. package/esm2022/table/api/descriptors/table.descriptor.mjs +11 -20
  38. package/esm2022/table/api/models/table-columns.model.mjs +1 -1
  39. package/esm2022/table/api/models/table.model.mjs +1 -1
  40. package/esm2022/table/components/column-filter/column-filter.component.mjs +396 -0
  41. package/esm2022/table/components/filter/filter-active-tag/filter-active-tag.component.mjs +52 -0
  42. package/esm2022/table/components/filter/filter-form/filter-form.component.mjs +197 -0
  43. package/esm2022/table/components/filter/filter-overlay-with-tag/filter-overlay-with-tag.component.mjs +135 -0
  44. package/esm2022/table/components/table/table.component.mjs +39 -30
  45. package/esm2022/table/helpers/filters.mjs +297 -0
  46. package/esm2022/table/index.mjs +13 -2
  47. package/esm2022/table/models/filter.model.mjs +2 -0
  48. package/esm2022/table/pipes/filter-value.pipe.mjs +77 -0
  49. package/esm2022/table/provide.mjs +19 -0
  50. package/esm2022/table/services/data-list.service.mjs +1 -1
  51. package/esm2022/table/services/table-feature-config.token.mjs +3 -0
  52. package/esm2022/tableview/action/components/editor/injector-context/action-editor-injector-context.component.mjs +2 -2
  53. package/esm2022/tableview/action/components/localization/data-language-dropdown.component.mjs +2 -2
  54. package/esm2022/tableview/api/editor/descriptors/field.descriptor.mjs +1 -1
  55. package/esm2022/tableview/api/editor/models/editor-fields.model.mjs +1 -1
  56. package/esm2022/tableview/api/tableview/descriptors/tableview.descriptor.mjs +11 -13
  57. package/esm2022/tableview/editor/components/formly/fields/formly-field-dropdown/formly-field-dropdown.component.mjs +2 -2
  58. package/esm2022/tableview/tableview/components/tableview/tableview.component.mjs +3 -4
  59. package/fesm2022/mediusinc-mng-commons-core.mjs +103 -17
  60. package/fesm2022/mediusinc-mng-commons-core.mjs.map +1 -1
  61. package/fesm2022/mediusinc-mng-commons-filter.mjs +81 -32
  62. package/fesm2022/mediusinc-mng-commons-filter.mjs.map +1 -1
  63. package/fesm2022/mediusinc-mng-commons-form.mjs +149 -117
  64. package/fesm2022/mediusinc-mng-commons-form.mjs.map +1 -1
  65. package/fesm2022/mediusinc-mng-commons-table-api.mjs +11 -19
  66. package/fesm2022/mediusinc-mng-commons-table-api.mjs.map +1 -1
  67. package/fesm2022/mediusinc-mng-commons-table.mjs +836 -363
  68. package/fesm2022/mediusinc-mng-commons-table.mjs.map +1 -1
  69. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs +10 -12
  70. package/fesm2022/mediusinc-mng-commons-tableview-api.mjs.map +1 -1
  71. package/fesm2022/mediusinc-mng-commons-tableview.mjs +5 -5
  72. package/fesm2022/mediusinc-mng-commons-tableview.mjs.map +1 -1
  73. package/filter/descriptors/filter.descriptor.d.ts +60 -16
  74. package/filter/models/filter.model.d.ts +4 -0
  75. package/form/components/date-range/date-range.component.d.ts +9 -3
  76. package/form/components/dropdown/dropdown.component.d.ts +6 -7
  77. package/form/components/number-range/number-range.component.d.ts +8 -4
  78. package/i18n/en.json +40 -0
  79. package/i18n/sl.json +40 -0
  80. package/package.json +7 -7
  81. package/table/api/descriptors/table.descriptor.d.ts +7 -7
  82. package/table/api/models/table-columns.model.d.ts +3 -3
  83. package/table/api/models/table.model.d.ts +0 -12
  84. package/table/components/{column-filter-full/column-filter-full.component.d.ts → column-filter/column-filter.component.d.ts} +23 -38
  85. package/table/components/filter/filter-active-tag/filter-active-tag.component.d.ts +20 -0
  86. package/table/components/filter/filter-form/filter-form.component.d.ts +53 -0
  87. package/table/components/filter/filter-overlay-with-tag/filter-overlay-with-tag.component.d.ts +35 -0
  88. package/table/components/table/table.component.d.ts +11 -8
  89. package/table/helpers/filters.d.ts +31 -0
  90. package/table/index.d.ts +10 -1
  91. package/table/models/filter.model.d.ts +24 -0
  92. package/table/pipes/filter-value.pipe.d.ts +19 -0
  93. package/table/provide.d.ts +8 -0
  94. package/table/services/data-list.service.d.ts +3 -2
  95. package/table/services/table-feature-config.token.d.ts +6 -0
  96. package/tableview/api/editor/descriptors/field.descriptor.d.ts +3 -3
  97. package/tableview/api/editor/models/editor-fields.model.d.ts +4 -4
  98. package/tableview/api/tableview/descriptors/tableview.descriptor.d.ts +8 -6
  99. package/version-info.json +5 -5
  100. package/esm2022/core/services/local-storage-config.service.mjs +0 -29
  101. package/esm2022/table/components/column-filter-full/column-filter-full.component.mjs +0 -655
@@ -0,0 +1,52 @@
1
+ import { AsyncPipe } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';
3
+ import { TranslateModule } from '@ngx-translate/core';
4
+ import { TagModule } from 'primeng/tag';
5
+ import { FilterMatchMode, getI18nTypePropertyKey } from '@mediusinc/mng-commons/core';
6
+ import { FilterValuePipe } from '../../../pipes/filter-value.pipe';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@ngx-translate/core";
9
+ import * as i2 from "primeng/tag";
10
+ export class FilterActiveTagComponent {
11
+ constructor() {
12
+ this.FilterMatchMode = FilterMatchMode;
13
+ this.model = input.required();
14
+ this.filter = input.required();
15
+ this.edit = output();
16
+ this.remove = output();
17
+ this.label = computed(() => this.getPropertyLabelKey(this.filter().descriptor));
18
+ this.matchMode = computed(() => this.filter().displayMatchMode);
19
+ this.matchModeSymbol = computed(() => `mngFilterActiveTag.matchMode.${this.matchMode()}`);
20
+ this.value = computed(() => this.filter().displayValue);
21
+ }
22
+ onRemove(event) {
23
+ event.stopPropagation();
24
+ this.remove.emit({
25
+ filter: this.filter(),
26
+ event: event
27
+ });
28
+ }
29
+ onEdit(event) {
30
+ this.edit.emit({
31
+ filter: this.filter(),
32
+ event: event
33
+ });
34
+ }
35
+ getPropertyLabelKey(filterDescriptor) {
36
+ let labelKey;
37
+ if (filterDescriptor.title !== undefined) {
38
+ labelKey = filterDescriptor.title;
39
+ }
40
+ else {
41
+ labelKey = getI18nTypePropertyKey(this.model().i18nBaseKey, filterDescriptor.property);
42
+ }
43
+ return labelKey;
44
+ }
45
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FilterActiveTagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
46
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: FilterActiveTagComponent, isStandalone: true, selector: "mng-filter-active-tag", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { edit: "edit", remove: "remove" }, ngImport: i0, template: "<p-tag severity=\"secondary\" styleClass=\"mr-1 p-tag-outlined\">\n <div class=\"flex align-items-center gap-2 p-1 cursor-pointer\" (click)=\"onEdit($event)\">\n <span>{{ label() | translate }}</span>\n @if (matchMode() === FilterMatchMode.Between) {\n <span class=\"font-semibold\">{{ value()?.[0] | mngFilterValue: filter().descriptor | async }}</span>\n <span class=\"text-primary\">{{ matchModeSymbol() | translate }}</span>\n <span class=\"font-semibold\">{{ value()?.[1] | mngFilterValue: filter().descriptor | async }}</span>\n } @else {\n <span class=\"text-primary\">{{ matchModeSymbol() | translate }}</span>\n <span class=\"font-semibold\">{{ value() | mngFilterValue: filter().descriptor | async }}</span>\n @if (filter().caseSensitive) {\n <small class=\"border-solid border-1 border-round-sm px-1 text-primary-400\">Aa</small>\n }\n }\n <span class=\"pi pi-times text-xs\" (click)=\"onRemove($event)\"></span>\n </div>\n</p-tag>\n", dependencies: [{ kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i1.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i2.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }, { kind: "pipe", type: FilterValuePipe, name: "mngFilterValue" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
47
+ }
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FilterActiveTagComponent, decorators: [{
49
+ type: Component,
50
+ args: [{ standalone: true, selector: 'mng-filter-active-tag', imports: [TranslateModule, TagModule, FilterValuePipe, AsyncPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-tag severity=\"secondary\" styleClass=\"mr-1 p-tag-outlined\">\n <div class=\"flex align-items-center gap-2 p-1 cursor-pointer\" (click)=\"onEdit($event)\">\n <span>{{ label() | translate }}</span>\n @if (matchMode() === FilterMatchMode.Between) {\n <span class=\"font-semibold\">{{ value()?.[0] | mngFilterValue: filter().descriptor | async }}</span>\n <span class=\"text-primary\">{{ matchModeSymbol() | translate }}</span>\n <span class=\"font-semibold\">{{ value()?.[1] | mngFilterValue: filter().descriptor | async }}</span>\n } @else {\n <span class=\"text-primary\">{{ matchModeSymbol() | translate }}</span>\n <span class=\"font-semibold\">{{ value() | mngFilterValue: filter().descriptor | async }}</span>\n @if (filter().caseSensitive) {\n <small class=\"border-solid border-1 border-round-sm px-1 text-primary-400\">Aa</small>\n }\n }\n <span class=\"pi pi-times text-xs\" (click)=\"onRemove($event)\"></span>\n </div>\n</p-tag>\n" }]
51
+ }] });
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLWFjdGl2ZS10YWcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvZmlsdGVyL2ZpbHRlci1hY3RpdmUtdGFnL2ZpbHRlci1hY3RpdmUtdGFnLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3RhYmxlL3NyYy9jb21wb25lbnRzL2ZpbHRlci9maWx0ZXItYWN0aXZlLXRhZy9maWx0ZXItYWN0aXZlLXRhZy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUFDLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUUxRixPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUV0QyxPQUFPLEVBQUMsZUFBZSxFQUFFLHNCQUFzQixFQUFDLE1BQU0sNkJBQTZCLENBQUM7QUFLcEYsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGtDQUFrQyxDQUFDOzs7O0FBU2pFLE1BQU0sT0FBTyx3QkFBd0I7SUFQckM7UUFRb0Isb0JBQWUsR0FBRyxlQUFlLENBQUM7UUFFM0MsVUFBSyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQTZCLENBQUM7UUFDcEQsV0FBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQXVDLENBQUM7UUFFL0QsU0FBSSxHQUFHLE1BQU0sRUFBd0IsQ0FBQztRQUN0QyxXQUFNLEdBQUcsTUFBTSxFQUF3QixDQUFDO1FBRXhDLFVBQUssR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQzNFLGNBQVMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDM0Qsb0JBQWUsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsZ0NBQWdDLElBQUksQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDckYsVUFBSyxHQUFHLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDLENBQUM7S0EwQjdEO0lBeEJHLFFBQVEsQ0FBQyxLQUFZO1FBQ2pCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztZQUNiLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ3JCLEtBQUssRUFBRSxLQUFLO1NBQ2YsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFZO1FBQ2YsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDWCxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNyQixLQUFLLEVBQUUsS0FBSztTQUNmLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyxtQkFBbUIsQ0FBQyxnQkFBNEM7UUFDcEUsSUFBSSxRQUFnQixDQUFDO1FBQ3JCLElBQUksZ0JBQWdCLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3ZDLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUM7UUFDdEMsQ0FBQzthQUFNLENBQUM7WUFDSixRQUFRLEdBQUcsc0JBQXNCLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMzRixDQUFDO1FBQ0QsT0FBTyxRQUFRLENBQUM7SUFDcEIsQ0FBQzs4R0FyQ1Esd0JBQXdCO2tHQUF4Qix3QkFBd0IsMlhDcEJyQyx1akNBaUJBLDJDREFjLGVBQWUsMkZBQUUsU0FBUywySkFBRSxlQUFlLGtEQUFFLFNBQVM7OzJGQUd2RCx3QkFBd0I7a0JBUHBDLFNBQVM7aUNBQ00sSUFBSSxZQUNOLHVCQUF1QixXQUV4QixDQUFDLGVBQWUsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLFNBQVMsQ0FBQyxtQkFDaEQsdUJBQXVCLENBQUMsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QXN5bmNQaXBlfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBjb21wdXRlZCwgaW5wdXQsIG91dHB1dH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7VHJhbnNsYXRlTW9kdWxlfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7VGFnTW9kdWxlfSBmcm9tICdwcmltZW5nL3RhZyc7XG5cbmltcG9ydCB7RmlsdGVyTWF0Y2hNb2RlLCBnZXRJMThuVHlwZVByb3BlcnR5S2V5fSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL2NvcmUnO1xuaW1wb3J0IHtGaWx0ZXJEZXNjcmlwdG9yfSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL2ZpbHRlcic7XG5pbXBvcnQge01vZGVsRGVzY3JpcHRvcn0gZnJvbSAnQG1lZGl1c2luYy9tbmctY29tbW9ucy9tb2RlbCc7XG5cbmltcG9ydCB7Q29tbW9uc0ZpbHRlck1ldGFkYXRhV2l0aERlc2NyaXB0b3IsIEZpbHRlckFjdGl2ZVRhZ0V2ZW50fSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvZmlsdGVyLm1vZGVsJztcbmltcG9ydCB7RmlsdGVyVmFsdWVQaXBlfSBmcm9tICcuLi8uLi8uLi9waXBlcy9maWx0ZXItdmFsdWUucGlwZSc7XG5cbkBDb21wb25lbnQoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdtbmctZmlsdGVyLWFjdGl2ZS10YWcnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9maWx0ZXItYWN0aXZlLXRhZy5jb21wb25lbnQuaHRtbCcsXG4gICAgaW1wb3J0czogW1RyYW5zbGF0ZU1vZHVsZSwgVGFnTW9kdWxlLCBGaWx0ZXJWYWx1ZVBpcGUsIEFzeW5jUGlwZV0sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgRmlsdGVyQWN0aXZlVGFnQ29tcG9uZW50IHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgRmlsdGVyTWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlO1xuXG4gICAgcHVibGljIG1vZGVsID0gaW5wdXQucmVxdWlyZWQ8TW9kZWxEZXNjcmlwdG9yPGFueSwgYW55Pj4oKTtcbiAgICBwdWJsaWMgZmlsdGVyID0gaW5wdXQucmVxdWlyZWQ8Q29tbW9uc0ZpbHRlck1ldGFkYXRhV2l0aERlc2NyaXB0b3I+KCk7XG5cbiAgICBwdWJsaWMgZWRpdCA9IG91dHB1dDxGaWx0ZXJBY3RpdmVUYWdFdmVudD4oKTtcbiAgICBwdWJsaWMgcmVtb3ZlID0gb3V0cHV0PEZpbHRlckFjdGl2ZVRhZ0V2ZW50PigpO1xuXG4gICAgcHVibGljIGxhYmVsID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5nZXRQcm9wZXJ0eUxhYmVsS2V5KHRoaXMuZmlsdGVyKCkuZGVzY3JpcHRvcikpO1xuICAgIHB1YmxpYyBtYXRjaE1vZGUgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmZpbHRlcigpLmRpc3BsYXlNYXRjaE1vZGUpO1xuICAgIHB1YmxpYyBtYXRjaE1vZGVTeW1ib2wgPSBjb21wdXRlZCgoKSA9PiBgbW5nRmlsdGVyQWN0aXZlVGFnLm1hdGNoTW9kZS4ke3RoaXMubWF0Y2hNb2RlKCl9YCk7XG4gICAgcHVibGljIHZhbHVlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5maWx0ZXIoKS5kaXNwbGF5VmFsdWUpO1xuXG4gICAgb25SZW1vdmUoZXZlbnQ6IEV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB0aGlzLnJlbW92ZS5lbWl0KHtcbiAgICAgICAgICAgIGZpbHRlcjogdGhpcy5maWx0ZXIoKSxcbiAgICAgICAgICAgIGV2ZW50OiBldmVudFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBvbkVkaXQoZXZlbnQ6IEV2ZW50KSB7XG4gICAgICAgIHRoaXMuZWRpdC5lbWl0KHtcbiAgICAgICAgICAgIGZpbHRlcjogdGhpcy5maWx0ZXIoKSxcbiAgICAgICAgICAgIGV2ZW50OiBldmVudFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFByb3BlcnR5TGFiZWxLZXkoZmlsdGVyRGVzY3JpcHRvcjogRmlsdGVyRGVzY3JpcHRvcjxhbnksIGFueT4pIHtcbiAgICAgICAgbGV0IGxhYmVsS2V5OiBzdHJpbmc7XG4gICAgICAgIGlmIChmaWx0ZXJEZXNjcmlwdG9yLnRpdGxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxhYmVsS2V5ID0gZmlsdGVyRGVzY3JpcHRvci50aXRsZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxhYmVsS2V5ID0gZ2V0STE4blR5cGVQcm9wZXJ0eUtleSh0aGlzLm1vZGVsKCkuaTE4bkJhc2VLZXksIGZpbHRlckRlc2NyaXB0b3IucHJvcGVydHkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsYWJlbEtleTtcbiAgICB9XG59XG4iLCI8cC10YWcgc2V2ZXJpdHk9XCJzZWNvbmRhcnlcIiBzdHlsZUNsYXNzPVwibXItMSBwLXRhZy1vdXRsaW5lZFwiPlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMiBwLTEgY3Vyc29yLXBvaW50ZXJcIiAoY2xpY2spPVwib25FZGl0KCRldmVudClcIj5cbiAgICAgICAgPHNwYW4+e3sgbGFiZWwoKSB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgQGlmIChtYXRjaE1vZGUoKSA9PT0gRmlsdGVyTWF0Y2hNb2RlLkJldHdlZW4pIHtcbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZm9udC1zZW1pYm9sZFwiPnt7IHZhbHVlKCk/LlswXSB8IG1uZ0ZpbHRlclZhbHVlOiBmaWx0ZXIoKS5kZXNjcmlwdG9yIHwgYXN5bmMgfX08L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtcHJpbWFyeVwiPnt7IG1hdGNoTW9kZVN5bWJvbCgpIHwgdHJhbnNsYXRlIH19PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb250LXNlbWlib2xkXCI+e3sgdmFsdWUoKT8uWzFdIHwgbW5nRmlsdGVyVmFsdWU6IGZpbHRlcigpLmRlc2NyaXB0b3IgfCBhc3luYyB9fTwvc3Bhbj5cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtcHJpbWFyeVwiPnt7IG1hdGNoTW9kZVN5bWJvbCgpIHwgdHJhbnNsYXRlIH19PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmb250LXNlbWlib2xkXCI+e3sgdmFsdWUoKSB8IG1uZ0ZpbHRlclZhbHVlOiBmaWx0ZXIoKS5kZXNjcmlwdG9yIHwgYXN5bmMgfX08L3NwYW4+XG4gICAgICAgICAgICBAaWYgKGZpbHRlcigpLmNhc2VTZW5zaXRpdmUpIHtcbiAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJib3JkZXItc29saWQgYm9yZGVyLTEgYm9yZGVyLXJvdW5kLXNtIHB4LTEgdGV4dC1wcmltYXJ5LTQwMFwiPkFhPC9zbWFsbD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICA8c3BhbiBjbGFzcz1cInBpIHBpLXRpbWVzIHRleHQteHNcIiAoY2xpY2spPVwib25SZW1vdmUoJGV2ZW50KVwiPjwvc3Bhbj5cbiAgICA8L2Rpdj5cbjwvcC10YWc+XG4iXX0=
@@ -0,0 +1,197 @@
1
+ import { NgClass, NgTemplateOutlet } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, ElementRef, computed, effect, inject, input, output, signal, untracked, viewChild } from '@angular/core';
3
+ import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
4
+ import { FormsModule } from '@angular/forms';
5
+ import { TranslateModule, TranslateService } from '@ngx-translate/core';
6
+ import { PrimeNGConfig } from 'primeng/api';
7
+ import { CalendarModule } from 'primeng/calendar';
8
+ import { CheckboxModule } from 'primeng/checkbox';
9
+ import { InputNumberModule } from 'primeng/inputnumber';
10
+ import { InputTextModule } from 'primeng/inputtext';
11
+ import { MessagesModule } from 'primeng/messages';
12
+ import { NEVER, switchMap } from 'rxjs';
13
+ import { COMMONS_MODULE_CONFIG_IT, FilterMatchMode, getI18nTypePropertyKey } from '@mediusinc/mng-commons/core';
14
+ import { FilterLookupTypeEnum, FilterTypeEnum } from '@mediusinc/mng-commons/filter';
15
+ import { AutocompleteComponent, DateRangeComponent, DropdownComponent, InputTrimDirective, NumberRangeComponent } from '@mediusinc/mng-commons/form';
16
+ import { filterAdjustDisplayValueOnMatchModeChange, filterApplySerializationConfigToCmp, filterGetDateConfig, filterGetDefaultMatchMode, filterGetNumberConfig, generateMatchModeOptions } from '../../../helpers/filters';
17
+ import * as i0 from "@angular/core";
18
+ import * as i1 from "@angular/forms";
19
+ import * as i2 from "@ngx-translate/core";
20
+ import * as i3 from "primeng/inputnumber";
21
+ import * as i4 from "primeng/calendar";
22
+ import * as i5 from "primeng/button";
23
+ import * as i6 from "primeng/checkbox";
24
+ import * as i7 from "primeng/messages";
25
+ import * as i8 from "primeng/inputtext";
26
+ export class FilterFormComponent {
27
+ constructor() {
28
+ this.lookupTypeDropdown = FilterLookupTypeEnum.Dropdown;
29
+ this.lookupTypeAutocomplete = FilterLookupTypeEnum.Autocomplete;
30
+ this.FilterTypeEnum = FilterTypeEnum;
31
+ this.FilterMatchMode = FilterMatchMode;
32
+ this.elementRef = inject(ElementRef);
33
+ this.moduleConfig = inject(COMMONS_MODULE_CONFIG_IT, { optional: true });
34
+ this.primeConfig = inject(PrimeNGConfig);
35
+ this.translate = inject(TranslateService);
36
+ this.title = input();
37
+ this.descriptors = input.required();
38
+ this.model = input.required();
39
+ this.filter = input();
40
+ this.overlay = input();
41
+ this.disabledProperties = input([]);
42
+ this.apply = output();
43
+ this.propertyOptionsWithTranslations = computed(() => {
44
+ const disabledProperties = this.disabledProperties();
45
+ const filter = this.filter();
46
+ return this.descriptors()?.map(d => ({ property: d.property, label: this.getPropertyLabelKey(d), disabled: !filter && disabledProperties.includes(d.property) }));
47
+ });
48
+ this.selectedDescriptor = computed(() => {
49
+ const property = this.propertyModel();
50
+ return this.descriptors().find(filterDescriptor => filterDescriptor.property === property);
51
+ });
52
+ this.selectedDescriptorAsLookup = computed(() => {
53
+ const filterDescriptor = this.selectedDescriptor();
54
+ return filterDescriptor !== undefined && (filterDescriptor.filterType === FilterTypeEnum.Lookup || filterDescriptor.filterType === FilterTypeEnum.LookupEnum)
55
+ ? filterDescriptor
56
+ : undefined;
57
+ });
58
+ this.matchModeOptions = computed(() => {
59
+ return generateMatchModeOptions(this.primeConfig, this.selectedDescriptor(), this.serializationCfg);
60
+ });
61
+ this.isEdit = computed(() => this.filter() != null);
62
+ this.formSubmitted = signal(false);
63
+ this.formErrorMessage = signal([]);
64
+ // display configs
65
+ this.dateConfig = computed(() => filterGetDateConfig(this.selectedDescriptor(), this.serializationCfg));
66
+ this.numberConfig = computed(() => filterGetNumberConfig(this.selectedDescriptor()));
67
+ // UI utilities
68
+ this.filterForm = viewChild.required('filterForm');
69
+ // Filter form model and form utilities
70
+ this.propertyModel = signal(null);
71
+ this.matchModeModel = signal(null);
72
+ this.valueModel = signal(null);
73
+ this.caseSensitiveModel = signal(false);
74
+ this.serializationCfg = {};
75
+ filterApplySerializationConfigToCmp(this.moduleConfig, this.serializationCfg);
76
+ effect(() => {
77
+ const edit = this.filter();
78
+ if (edit) {
79
+ this.resetForm({
80
+ property: edit.descriptor.property,
81
+ matchMode: edit.displayMatchMode ?? edit.matchMode ?? null,
82
+ value: edit.displayValue ?? edit.value,
83
+ caseSensitive: edit.caseSensitive ?? false
84
+ });
85
+ }
86
+ else {
87
+ this.resetForm();
88
+ }
89
+ }, { allowSignalWrites: true });
90
+ effect(() => {
91
+ const descriptor = this.selectedDescriptor();
92
+ const value = untracked(() => this.valueModel());
93
+ if (value != null) {
94
+ // reset value if filter type and value type mismatch
95
+ if ((descriptor?.filterType === FilterTypeEnum.String &&
96
+ (value === true || value === false || value === 'true' || value === 'false' || value instanceof Date)) ||
97
+ (descriptor?.filterType === FilterTypeEnum.Number && typeof value !== 'number' && isNaN(+value)) ||
98
+ (descriptor?.filterType === FilterTypeEnum.Date && !(value instanceof Date)) ||
99
+ descriptor?.filterType === FilterTypeEnum.Lookup ||
100
+ descriptor?.filterType === FilterTypeEnum.LookupEnum) {
101
+ this.valueModel.set(null);
102
+ }
103
+ else if (descriptor?.filterType === FilterTypeEnum.Boolean && typeof value !== 'boolean') {
104
+ this.valueModel.set(false);
105
+ }
106
+ }
107
+ }, { allowSignalWrites: true });
108
+ effect(() => {
109
+ const matchModeOptions = this.matchModeOptions();
110
+ const matchMode = untracked(() => this.matchModeModel());
111
+ const filterForm = untracked(() => this.filterForm());
112
+ if (matchModeOptions.length > 0 &&
113
+ (!matchMode || filterForm.controls['matchMode']?.pristine || filterForm.controls['matchMode']?.untouched || !matchModeOptions.find(o => o.value === matchMode))) {
114
+ this.matchModeModel.set(filterGetDefaultMatchMode(this.selectedDescriptor(), matchModeOptions));
115
+ }
116
+ }, { allowSignalWrites: true });
117
+ effect(() => {
118
+ const currentValue = untracked(() => this.valueModel());
119
+ this.valueModel.set(filterAdjustDisplayValueOnMatchModeChange(this.matchModeModel() ?? undefined, currentValue));
120
+ }, { allowSignalWrites: true });
121
+ toObservable(this.overlay)
122
+ .pipe(switchMap(o => (o ? o.onShow : NEVER)), takeUntilDestroyed())
123
+ .subscribe(() => {
124
+ const formFields = this.elementRef.nativeElement.querySelectorAll('input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [role="combobox"]:not([disabled])');
125
+ const activeEl = document.activeElement;
126
+ const activeInputIdx = activeEl ? [...formFields].findIndex(el => activeEl.isEqualNode(el)) : 0;
127
+ if (activeInputIdx <= 0) {
128
+ formFields[0].focus();
129
+ }
130
+ });
131
+ }
132
+ onFormSubmit(form) {
133
+ this.formSubmitted.set(true);
134
+ // mark all as dirty
135
+ for (const key in form.controls) {
136
+ form.controls[key].markAsDirty();
137
+ }
138
+ const property = this.propertyModel();
139
+ const matchMode = this.matchModeModel();
140
+ if (form.invalid || !property || !matchMode) {
141
+ this.formErrorMessage.set([
142
+ {
143
+ severity: 'warn',
144
+ summary: this.translate.instant('mngFilter.messages.invalidFormTitle'),
145
+ detail: this.translate.instant('mngFilter.messages.invalidFormMessage')
146
+ }
147
+ ]);
148
+ return;
149
+ }
150
+ this.apply.emit({
151
+ property: property,
152
+ matchMode: matchMode,
153
+ value: this.valueModel(),
154
+ caseSensitive: this.caseSensitiveModel()
155
+ });
156
+ }
157
+ resetForm(value) {
158
+ this.filterForm().resetForm(value);
159
+ // somehow have to set case sensitivity manually
160
+ this.caseSensitiveModel.set(value?.caseSensitive ?? false);
161
+ this.formSubmitted.set(false);
162
+ }
163
+ getPropertyLabelKey(filterDescriptor) {
164
+ let labelKey;
165
+ if (filterDescriptor.title !== undefined) {
166
+ labelKey = filterDescriptor.title;
167
+ }
168
+ else {
169
+ labelKey = getI18nTypePropertyKey(this.model().i18nBaseKey, filterDescriptor.property);
170
+ }
171
+ return labelKey;
172
+ }
173
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FilterFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
174
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: FilterFormComponent, isStandalone: true, selector: "mng-filter-form", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, descriptors: { classPropertyName: "descriptors", publicName: "descriptors", isSignal: true, isRequired: true, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, overlay: { classPropertyName: "overlay", publicName: "overlay", isSignal: true, isRequired: false, transformFunction: null }, disabledProperties: { classPropertyName: "disabledProperties", publicName: "disabledProperties", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { apply: "apply" }, host: { classAttribute: "flex flex-grow-1" }, viewQueries: [{ propertyName: "filterForm", first: true, predicate: ["filterForm"], descendants: true, isSignal: true }], ngImport: i0, template: "<div>\n <div>\n <h5>{{ filter() ? ('mngFilter.titleEdit' | translate) : ('mngFilter.titleAdd' | translate) }}</h5>\n </div>\n <form #filterForm=\"ngForm\" (ngSubmit)=\"onFormSubmit(filterForm)\" class=\"flex flex-column align-items-center lg:flex-row gap-3\">\n <div class=\"w-full lg:w-auto\">\n <mng-dropdown\n name=\"property\"\n id=\"property\"\n tabindex=\"1\"\n #propertyControl=\"ngModel\"\n [(ngModel)]=\"propertyModel\"\n [options]=\"propertyOptionsWithTranslations()\"\n optionsValueProperty=\"property\"\n optionsDisabledProperty=\"disabled\"\n optionsLabelProperty=\"label\"\n [placeholder]=\"'mngFilter.property' | translate\"\n optionsLabelTranslate=\"true\"\n required=\"true\"\n className=\"w-full\"\n [disabled]=\"isEdit()\"\n [appendTo]=\"null\" />\n </div>\n <div class=\"w-full lg:w-auto\">\n <mng-dropdown\n name=\"matchMode\"\n id=\"matchMode\"\n [(ngModel)]=\"matchModeModel\"\n className=\"w-full\"\n [options]=\"matchModeOptions()\"\n [placeholder]=\"'mngFilter.matchMode' | translate\"\n [disabled]=\"!propertyControl.value\"\n class=\"align-self-end\"\n required=\"true\"\n [appendTo]=\"null\" />\n </div>\n @if (!(matchModeModel() === FilterMatchMode.Exists || matchModeModel() === FilterMatchMode.DoesNotExist)) {\n <div class=\"w-full lg:w-auto flex flex-column\">\n @switch (selectedDescriptor()?.filterType) {\n @case (FilterTypeEnum.Number) {\n @if (matchModeModel() === FilterMatchMode.Between) {\n <mng-number-range\n className=\"mng-column-filter-number-input\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [useGrouping]=\"selectedDescriptor()?.numberUseGrouping ?? false\"\n [minFractionDigits]=\"numberConfig()?.fractionsMin\"\n [maxFractionDigits]=\"numberConfig()?.fractionsMax\"\n required=\"true\" />\n } @else {\n <p-inputNumber\n inputStyleClass=\"mng-column-filter-number-input\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [styleClass]=\"'w-full'\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [useGrouping]=\"selectedDescriptor()?.numberUseGrouping\"\n [minFractionDigits]=\"numberConfig()?.fractionsMin\"\n [maxFractionDigits]=\"numberConfig()?.fractionsMax\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\" />\n }\n }\n\n @case (FilterTypeEnum.Boolean) {\n <p-checkbox [(ngModel)]=\"valueModel\" [disabled]=\"!matchModeModel()\" name=\"value\" binary=\"true\" required=\"true\" />\n }\n @case (FilterTypeEnum.Date) {\n @if (matchModeModel() === FilterMatchMode.Between) {\n <mng-date-range\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [showTime]=\"dateConfig()?.showTime ?? false\"\n [showSeconds]=\"dateConfig()?.showSeconds ?? false\"\n [dateFormat]=\"dateConfig()?.format\"\n [placeholder]=\"'mngFilter.value' | translate\"\n required=\"true\"></mng-date-range>\n } @else {\n <p-calendar\n appendTo=\"body\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [styleClass]=\"'w-full'\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [showIcon]=\"true\"\n [showTime]=\"dateConfig()?.showTime ?? false\"\n [showSeconds]=\"dateConfig()?.showSeconds ?? false\"\n [dateFormat]=\"dateConfig()?.format\"\n [firstDayOfWeek]=\"1\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\">\n </p-calendar>\n }\n }\n @case (FilterTypeEnum.Lookup) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\"></ng-container>\n }\n @case (FilterTypeEnum.LookupEnum) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\"></ng-container>\n }\n @default {\n <input\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n type=\"text\"\n pInputText\n class=\"mng-column-filter-string-input w-full\"\n [attr.placeholder]=\"'mngFilter.value' | translate\"\n [mngInputTrim]=\"selectedDescriptor()?.trimOption!\"\n [disabled]=\"!matchModeModel()\"\n [placeholder]=\"'mngFilter.value' | translate\"\n required=\"true\" />\n }\n }\n <ng-template #lookupFilter>\n @if (selectedDescriptorAsLookup(); as lookupFilterDescriptor) {\n @switch (lookupFilterDescriptor.lookupType) {\n @case (lookupTypeAutocomplete) {\n <mng-autocomplete\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"lookupFilterDescriptor.dataProvider\"\n [optionsTrackProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsValueProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupFilterDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupFilterDescriptor.optionsLabelTranslate\"\n [multiselect]=\"lookupFilterDescriptor.multiselect\"\n [autoClear]=\"lookupFilterDescriptor.autocompleteAutoClear ?? false\"\n [openOnFocus]=\"lookupFilterDescriptor.autocompleteAutoClear ?? true\"\n [inlineSearch]=\"lookupFilterDescriptor.autocompleteInlineSearch ?? false\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [className]=\"lookupFilterDescriptor.className\"\n [dropdownClassName]=\"lookupFilterDescriptor.dropdownClassName\"\n [searchTrim]=\"selectedDescriptor()?.trimOption!\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\">\n </mng-autocomplete>\n }\n @case (lookupTypeDropdown) {\n <mng-dropdown\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"lookupFilterDescriptor.dataProvider\"\n [optionsValueProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupFilterDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupFilterDescriptor.optionsLabelTranslate\"\n [multiselect]=\"lookupFilterDescriptor.multiselect\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [className]=\"lookupFilterDescriptor.className + ' w-full'\"\n [dropdownClassName]=\"lookupFilterDescriptor.dropdownClassName\"\n [showClear]=\"false\"\n [disabled]=\"!matchModeModel()\"\n [appendTo]=\"null\"\n required=\"true\">\n </mng-dropdown>\n }\n }\n }\n </ng-template>\n </div>\n }\n @if (selectedDescriptor()?.filterType === FilterTypeEnum.String && matchModeModel() !== FilterMatchMode.Exists && matchModeModel() !== FilterMatchMode.DoesNotExist) {\n <div class=\"flex align-items-center gap-2\">\n <p-checkbox [(ngModel)]=\"caseSensitiveModel\" name=\"caseSensitive\" binary=\"true\" id=\"caseSensitive\" />\n <label for=\"caseSensitive\">{{ 'mngFilter.caseSensitive' | translate }}</label>\n </div>\n }\n <div class=\"flex justify-content-end\">\n <button pButton type=\"submit\" class=\"align-self-end\">\n {{ (filter() ? 'general.apply' : 'general.add') | translate }}\n </button>\n </div>\n </form>\n @if (formSubmitted() && filterForm.invalid) {\n <p-messages [value]=\"formErrorMessage()\" class=\"w-full\"></p-messages>\n }\n</div>\n", dependencies: [{ kind: "component", type: DropdownComponent, selector: "mng-dropdown", inputs: ["dataProvider", "options", "optionsTrackProperty", "optionsLabelProperty", "optionsLabelTranslate", "optionsValueProperty", "optionsDisabledProperty", "multiselect", "placeholder", "showClear", "selectFirstItem", "className", "dropdownClassName", "changeValueOnBlur", "loading", "disabled", "appendTo"], outputs: ["valueChange", "blur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "directive", type: InputTrimDirective, selector: "[mngInputTrim]", inputs: ["mngInputTrim"] }, { kind: "component", type: NumberRangeComponent, selector: "mng-number-range", inputs: ["placeholder", "useGrouping", "minFractionDigits", "maxFractionDigits", "required", "disabled"], outputs: ["keyDown"] }, { kind: "ngmodule", type: InputNumberModule }, { kind: "component", type: i3.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "component", type: DateRangeComponent, selector: "mng-date-range", inputs: ["placeholder", "showTime", "showSeconds", "dateFormat", "className", "required", "disabled"] }, { kind: "ngmodule", type: CalendarModule }, { kind: "component", type: i4.Calendar, selector: "p-calendar", inputs: ["iconDisplay", "style", "styleClass", "inputStyle", "inputId", "name", "inputStyleClass", "placeholder", "ariaLabelledBy", "ariaLabel", "iconAriaLabel", "disabled", "dateFormat", "multipleSeparator", "rangeSeparator", "inline", "showOtherMonths", "selectOtherMonths", "showIcon", "icon", "appendTo", "readonlyInput", "shortYearCutoff", "monthNavigator", "yearNavigator", "hourFormat", "timeOnly", "stepYearPicker", "stepHour", "stepMinute", "stepSecond", "showSeconds", "required", "showOnFocus", "showWeek", "startWeekFromFirstDayOfYear", "showClear", "dataType", "selectionMode", "maxDateCount", "showButtonBar", "todayButtonStyleClass", "clearButtonStyleClass", "autofocus", "autoZIndex", "baseZIndex", "panelStyleClass", "panelStyle", "keepInvalid", "hideOnDateTimeSelect", "touchUI", "timeSeparator", "focusTrap", "showTransitionOptions", "hideTransitionOptions", "tabindex", "variant", "minDate", "maxDate", "disabledDates", "disabledDays", "yearRange", "showTime", "responsiveOptions", "numberOfMonths", "firstDayOfWeek", "locale", "view", "defaultDate"], outputs: ["onFocus", "onBlur", "onClose", "onSelect", "onClear", "onInput", "onTodayClick", "onClearClick", "onMonthChange", "onYearChange", "onClickOutside", "onShow"] }, { kind: "directive", type: i5.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain"] }, { kind: "component", type: AutocompleteComponent, selector: "mng-autocomplete", inputs: ["dataProvider", "optionsTrackProperty", "optionsValueProperty", "optionsLabelProperty", "optionsLabelTranslate", "inlineSearch", "openOnFocus", "multiselect", "placeholder", "className", "dropdownClassName", "showClear", "autoClear", "selectFirst", "searchTrim", "disabled"], outputs: ["valueChange", "blur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i6.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessagesModule }, { kind: "component", type: i7.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i8.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
175
+ }
176
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FilterFormComponent, decorators: [{
177
+ type: Component,
178
+ args: [{ standalone: true, selector: 'mng-filter-form', imports: [
179
+ DropdownComponent,
180
+ FormsModule,
181
+ NgClass,
182
+ TranslateModule,
183
+ InputTrimDirective,
184
+ NumberRangeComponent,
185
+ InputNumberModule,
186
+ DateRangeComponent,
187
+ CalendarModule,
188
+ AutocompleteComponent,
189
+ CheckboxModule,
190
+ MessagesModule,
191
+ InputTextModule,
192
+ NgTemplateOutlet
193
+ ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
194
+ class: 'flex flex-grow-1'
195
+ }, template: "<div>\n <div>\n <h5>{{ filter() ? ('mngFilter.titleEdit' | translate) : ('mngFilter.titleAdd' | translate) }}</h5>\n </div>\n <form #filterForm=\"ngForm\" (ngSubmit)=\"onFormSubmit(filterForm)\" class=\"flex flex-column align-items-center lg:flex-row gap-3\">\n <div class=\"w-full lg:w-auto\">\n <mng-dropdown\n name=\"property\"\n id=\"property\"\n tabindex=\"1\"\n #propertyControl=\"ngModel\"\n [(ngModel)]=\"propertyModel\"\n [options]=\"propertyOptionsWithTranslations()\"\n optionsValueProperty=\"property\"\n optionsDisabledProperty=\"disabled\"\n optionsLabelProperty=\"label\"\n [placeholder]=\"'mngFilter.property' | translate\"\n optionsLabelTranslate=\"true\"\n required=\"true\"\n className=\"w-full\"\n [disabled]=\"isEdit()\"\n [appendTo]=\"null\" />\n </div>\n <div class=\"w-full lg:w-auto\">\n <mng-dropdown\n name=\"matchMode\"\n id=\"matchMode\"\n [(ngModel)]=\"matchModeModel\"\n className=\"w-full\"\n [options]=\"matchModeOptions()\"\n [placeholder]=\"'mngFilter.matchMode' | translate\"\n [disabled]=\"!propertyControl.value\"\n class=\"align-self-end\"\n required=\"true\"\n [appendTo]=\"null\" />\n </div>\n @if (!(matchModeModel() === FilterMatchMode.Exists || matchModeModel() === FilterMatchMode.DoesNotExist)) {\n <div class=\"w-full lg:w-auto flex flex-column\">\n @switch (selectedDescriptor()?.filterType) {\n @case (FilterTypeEnum.Number) {\n @if (matchModeModel() === FilterMatchMode.Between) {\n <mng-number-range\n className=\"mng-column-filter-number-input\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [useGrouping]=\"selectedDescriptor()?.numberUseGrouping ?? false\"\n [minFractionDigits]=\"numberConfig()?.fractionsMin\"\n [maxFractionDigits]=\"numberConfig()?.fractionsMax\"\n required=\"true\" />\n } @else {\n <p-inputNumber\n inputStyleClass=\"mng-column-filter-number-input\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [styleClass]=\"'w-full'\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [useGrouping]=\"selectedDescriptor()?.numberUseGrouping\"\n [minFractionDigits]=\"numberConfig()?.fractionsMin\"\n [maxFractionDigits]=\"numberConfig()?.fractionsMax\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\" />\n }\n }\n\n @case (FilterTypeEnum.Boolean) {\n <p-checkbox [(ngModel)]=\"valueModel\" [disabled]=\"!matchModeModel()\" name=\"value\" binary=\"true\" required=\"true\" />\n }\n @case (FilterTypeEnum.Date) {\n @if (matchModeModel() === FilterMatchMode.Between) {\n <mng-date-range\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [showTime]=\"dateConfig()?.showTime ?? false\"\n [showSeconds]=\"dateConfig()?.showSeconds ?? false\"\n [dateFormat]=\"dateConfig()?.format\"\n [placeholder]=\"'mngFilter.value' | translate\"\n required=\"true\"></mng-date-range>\n } @else {\n <p-calendar\n appendTo=\"body\"\n name=\"value\"\n [(ngModel)]=\"valueModel\"\n [styleClass]=\"'w-full'\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [showIcon]=\"true\"\n [showTime]=\"dateConfig()?.showTime ?? false\"\n [showSeconds]=\"dateConfig()?.showSeconds ?? false\"\n [dateFormat]=\"dateConfig()?.format\"\n [firstDayOfWeek]=\"1\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\">\n </p-calendar>\n }\n }\n @case (FilterTypeEnum.Lookup) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\"></ng-container>\n }\n @case (FilterTypeEnum.LookupEnum) {\n <ng-container *ngTemplateOutlet=\"lookupFilter\"></ng-container>\n }\n @default {\n <input\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n type=\"text\"\n pInputText\n class=\"mng-column-filter-string-input w-full\"\n [attr.placeholder]=\"'mngFilter.value' | translate\"\n [mngInputTrim]=\"selectedDescriptor()?.trimOption!\"\n [disabled]=\"!matchModeModel()\"\n [placeholder]=\"'mngFilter.value' | translate\"\n required=\"true\" />\n }\n }\n <ng-template #lookupFilter>\n @if (selectedDescriptorAsLookup(); as lookupFilterDescriptor) {\n @switch (lookupFilterDescriptor.lookupType) {\n @case (lookupTypeAutocomplete) {\n <mng-autocomplete\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"lookupFilterDescriptor.dataProvider\"\n [optionsTrackProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsValueProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupFilterDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupFilterDescriptor.optionsLabelTranslate\"\n [multiselect]=\"lookupFilterDescriptor.multiselect\"\n [autoClear]=\"lookupFilterDescriptor.autocompleteAutoClear ?? false\"\n [openOnFocus]=\"lookupFilterDescriptor.autocompleteAutoClear ?? true\"\n [inlineSearch]=\"lookupFilterDescriptor.autocompleteInlineSearch ?? false\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [className]=\"lookupFilterDescriptor.className\"\n [dropdownClassName]=\"lookupFilterDescriptor.dropdownClassName\"\n [searchTrim]=\"selectedDescriptor()?.trimOption!\"\n [disabled]=\"!matchModeModel()\"\n required=\"true\">\n </mng-autocomplete>\n }\n @case (lookupTypeDropdown) {\n <mng-dropdown\n [(ngModel)]=\"valueModel\"\n name=\"value\"\n [dataProvider]=\"lookupFilterDescriptor.dataProvider\"\n [optionsValueProperty]=\"lookupFilterDescriptor.optionsValueProperty\"\n [optionsLabelProperty]=\"lookupFilterDescriptor.optionsLabelProperty\"\n [optionsLabelTranslate]=\"lookupFilterDescriptor.optionsLabelTranslate\"\n [multiselect]=\"lookupFilterDescriptor.multiselect\"\n [placeholder]=\"'mngFilter.value' | translate\"\n [className]=\"lookupFilterDescriptor.className + ' w-full'\"\n [dropdownClassName]=\"lookupFilterDescriptor.dropdownClassName\"\n [showClear]=\"false\"\n [disabled]=\"!matchModeModel()\"\n [appendTo]=\"null\"\n required=\"true\">\n </mng-dropdown>\n }\n }\n }\n </ng-template>\n </div>\n }\n @if (selectedDescriptor()?.filterType === FilterTypeEnum.String && matchModeModel() !== FilterMatchMode.Exists && matchModeModel() !== FilterMatchMode.DoesNotExist) {\n <div class=\"flex align-items-center gap-2\">\n <p-checkbox [(ngModel)]=\"caseSensitiveModel\" name=\"caseSensitive\" binary=\"true\" id=\"caseSensitive\" />\n <label for=\"caseSensitive\">{{ 'mngFilter.caseSensitive' | translate }}</label>\n </div>\n }\n <div class=\"flex justify-content-end\">\n <button pButton type=\"submit\" class=\"align-self-end\">\n {{ (filter() ? 'general.apply' : 'general.add') | translate }}\n </button>\n </div>\n </form>\n @if (formSubmitted() && filterForm.invalid) {\n <p-messages [value]=\"formErrorMessage()\" class=\"w-full\"></p-messages>\n }\n</div>\n" }]
196
+ }], ctorParameters: () => [] });
197
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLWZvcm0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvZmlsdGVyL2ZpbHRlci1mb3JtL2ZpbHRlci1mb3JtLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3RhYmxlL3NyYy9jb21wb25lbnRzL2ZpbHRlci9maWx0ZXItZm9ybS9maWx0ZXItZm9ybS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsT0FBTyxFQUFFLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDMUQsT0FBTyxFQUFDLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNwSixPQUFPLEVBQUMsa0JBQWtCLEVBQUUsWUFBWSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDNUUsT0FBTyxFQUFDLFdBQVcsRUFBUyxNQUFNLGdCQUFnQixDQUFDO0FBRW5ELE9BQU8sRUFBQyxlQUFlLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RSxPQUFPLEVBQUMsYUFBYSxFQUFhLE1BQU0sYUFBYSxDQUFDO0FBQ3RELE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUVoRCxPQUFPLEVBQUMsS0FBSyxF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QUNQLGVBQWU7d0JBQ2Ysa0JBQWtCO3dCQUNsQixvQkFBb0I7d0JBQ3BCLGlCQUFpQjt3QkFDakIsa0JBQWtCO3dCQUNsQixjQUFjO3dCQUNkLHFCQUFxQjt3QkFDckIsY0FBYzt3QkFDZCxjQUFjO3dCQUNkLGVBQWU7d0JBQ2YsZ0JBQWdCO3FCQUNuQixtQkFDZ0IsdUJBQXVCLENBQUMsTUFBTSxRQUN6Qzt3QkFDRixLQUFLLEVBQUUsa0JBQWtCO3FCQUM1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TmdDbGFzcywgTmdUZW1wbGF0ZU91dGxldH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7Q2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRWxlbWVudFJlZiwgY29tcHV0ZWQsIGVmZmVjdCwgaW5qZWN0LCBpbnB1dCwgb3V0cHV0LCBzaWduYWwsIHVudHJhY2tlZCwgdmlld0NoaWxkfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7dGFrZVVudGlsRGVzdHJveWVkLCB0b09ic2VydmFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7Rm9ybXNNb2R1bGUsIE5nRm9ybX0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQge1RyYW5zbGF0ZU1vZHVsZSwgVHJhbnNsYXRlU2VydmljZX0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQge1ByaW1lTkdDb25maWcsIFNlbGVjdEl0ZW19IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7Q2FsZW5kYXJNb2R1bGV9IGZyb20gJ3ByaW1lbmcvY2FsZW5kYXInO1xuaW1wb3J0IHtDaGVja2JveE1vZHVsZX0gZnJvbSAncHJpbWVuZy9jaGVja2JveCc7XG5pbXBvcnQge0lucHV0TnVtYmVyTW9kdWxlfSBmcm9tICdwcmltZW5nL2lucHV0bnVtYmVyJztcbmltcG9ydCB7SW5wdXRUZXh0TW9kdWxlfSBmcm9tICdwcmltZW5nL2lucHV0dGV4dCc7XG5pbXBvcnQge01lc3NhZ2VzTW9kdWxlfSBmcm9tICdwcmltZW5nL21lc3NhZ2VzJztcbmltcG9ydCB7T3ZlcmxheVBhbmVsfSBmcm9tICdwcmltZW5nL292ZXJsYXlwYW5lbCc7XG5pbXBvcnQge05FVkVSLCBzd2l0Y2hNYXB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge0NPTU1PTlNfTU9EVUxFX0NPTkZJR19JVCwgQ29tbW9uc1NlcmlhbGl6YXRpb25Db25maWcsIEZpbHRlck1hdGNoTW9kZSwgRmlsdGVyTWF0Y2hNb2RlRXh0ZW5kZWRUeXBlLCBnZXRJMThuVHlwZVByb3BlcnR5S2V5fSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL2NvcmUnO1xuaW1wb3J0IHtGaWx0ZXJEZXNjcmlwdG9yLCBGaWx0ZXJMb29rdXBEZXNjcmlwdG9yLCBGaWx0ZXJMb29rdXBUeXBlRW51bSwgRmlsdGVyVHlwZUVudW19IGZyb20gJ0BtZWRpdXNpbmMvbW5nLWNvbW1vbnMvZmlsdGVyJztcbmltcG9ydCB7QXV0b2NvbXBsZXRlQ29tcG9uZW50LCBEYXRlUmFuZ2VDb21wb25lbnQsIERyb3Bkb3duQ29tcG9uZW50LCBJbnB1dFRyaW1EaXJlY3RpdmUsIE51bWJlclJhbmdlQ29tcG9uZW50fSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL2Zvcm0nO1xuaW1wb3J0IHtNb2RlbERlc2NyaXB0b3J9IGZyb20gJ0BtZWRpdXNpbmMvbW5nLWNvbW1vbnMvbW9kZWwnO1xuXG5pbXBvcnQge1xuICAgIGZpbHRlckFkanVzdERpc3BsYXlWYWx1ZU9uTWF0Y2hNb2RlQ2hhbmdlLFxuICAgIGZpbHRlckFwcGx5U2VyaWFsaXphdGlvbkNvbmZpZ1RvQ21wLFxuICAgIGZpbHRlckdldERhdGVDb25maWcsXG4gICAgZmlsdGVyR2V0RGVmYXVsdE1hdGNoTW9kZSxcbiAgICBmaWx0ZXJHZXROdW1iZXJDb25maWcsXG4gICAgZ2VuZXJhdGVNYXRjaE1vZGVPcHRpb25zXG59IGZyb20gJy4uLy4uLy4uL2hlbHBlcnMvZmlsdGVycyc7XG5pbXBvcnQge0NvbW1vbnNGaWx0ZXJNZXRhZGF0YVdpdGhEZXNjcmlwdG9yLCBGaWx0ZXJGb3JtRW1pdEV2ZW50fSBmcm9tICcuLi8uLi8uLi9tb2RlbHMvZmlsdGVyLm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBzZWxlY3RvcjogJ21uZy1maWx0ZXItZm9ybScsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2ZpbHRlci1mb3JtLmNvbXBvbmVudC5odG1sJyxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIERyb3Bkb3duQ29tcG9uZW50LFxuICAgICAgICBGb3Jtc01vZHVsZSxcbiAgICAgICAgTmdDbGFzcyxcbiAgICAgICAgVHJhbnNsYXRlTW9kdWxlLFxuICAgICAgICBJbnB1dFRyaW1EaXJlY3RpdmUsXG4gICAgICAgIE51bWJlclJhbmdlQ29tcG9uZW50LFxuICAgICAgICBJbnB1dE51bWJlck1vZHVsZSxcbiAgICAgICAgRGF0ZVJhbmdlQ29tcG9uZW50LFxuICAgICAgICBDYWxlbmRhck1vZHVsZSxcbiAgICAgICAgQXV0b2NvbXBsZXRlQ29tcG9uZW50LFxuICAgICAgICBDaGVja2JveE1vZHVsZSxcbiAgICAgICAgTWVzc2FnZXNNb2R1bGUsXG4gICAgICAgIElucHV0VGV4dE1vZHVsZSxcbiAgICAgICAgTmdUZW1wbGF0ZU91dGxldFxuICAgIF0sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgaG9zdDoge1xuICAgICAgICBjbGFzczogJ2ZsZXggZmxleC1ncm93LTEnXG4gICAgfVxufSlcbmV4cG9ydCBjbGFzcyBGaWx0ZXJGb3JtQ29tcG9uZW50IHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgbG9va3VwVHlwZURyb3Bkb3duOiBGaWx0ZXJMb29rdXBUeXBlRW51bSA9IEZpbHRlckxvb2t1cFR5cGVFbnVtLkRyb3Bkb3duO1xuICAgIHB1YmxpYyByZWFkb25seSBsb29rdXBUeXBlQXV0b2NvbXBsZXRlOiBGaWx0ZXJMb29rdXBUeXBlRW51bSA9IEZpbHRlckxvb2t1cFR5cGVFbnVtLkF1dG9jb21wbGV0ZTtcbiAgICBwdWJsaWMgcmVhZG9ubHkgRmlsdGVyVHlwZUVudW0gPSBGaWx0ZXJUeXBlRW51bTtcbiAgICBwdWJsaWMgcmVhZG9ubHkgRmlsdGVyTWF0Y2hNb2RlID0gRmlsdGVyTWF0Y2hNb2RlO1xuXG4gICAgcHJpdmF0ZSByZWFkb25seSBlbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbW9kdWxlQ29uZmlnID0gaW5qZWN0KENPTU1PTlNfTU9EVUxFX0NPTkZJR19JVCwge29wdGlvbmFsOiB0cnVlfSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBwcmltZUNvbmZpZyA9IGluamVjdChQcmltZU5HQ29uZmlnKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zbGF0ZSA9IGluamVjdChUcmFuc2xhdGVTZXJ2aWNlKTtcblxuICAgIHB1YmxpYyB0aXRsZSA9IGlucHV0PHN0cmluZz4oKTtcbiAgICBwdWJsaWMgZGVzY3JpcHRvcnMgPSBpbnB1dC5yZXF1aXJlZDxGaWx0ZXJEZXNjcmlwdG9yPGFueSwgYW55PltdPigpO1xuICAgIHB1YmxpYyBtb2RlbCA9IGlucHV0LnJlcXVpcmVkPE1vZGVsRGVzY3JpcHRvcjxhbnk+PigpO1xuICAgIHB1YmxpYyBmaWx0ZXIgPSBpbnB1dDxDb21tb25zRmlsdGVyTWV0YWRhdGFXaXRoRGVzY3JpcHRvcj4oKTtcbiAgICBwdWJsaWMgb3ZlcmxheSA9IGlucHV0PE92ZXJsYXlQYW5lbD4oKTtcbiAgICBwdWJsaWMgZGlzYWJsZWRQcm9wZXJ0aWVzID0gaW5wdXQ8c3RyaW5nW10+KFtdKTtcblxuICAgIHB1YmxpYyBhcHBseSA9IG91dHB1dDxGaWx0ZXJGb3JtRW1pdEV2ZW50PigpO1xuXG4gICAgcHVibGljIHByb3BlcnR5T3B0aW9uc1dpdGhUcmFuc2xhdGlvbnMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGRpc2FibGVkUHJvcGVydGllcyA9IHRoaXMuZGlzYWJsZWRQcm9wZXJ0aWVzKCk7XG4gICAgICAgIGNvbnN0IGZpbHRlciA9IHRoaXMuZmlsdGVyKCk7XG4gICAgICAgIHJldHVybiB0aGlzLmRlc2NyaXB0b3JzKCk/Lm1hcChkID0+ICh7cHJvcGVydHk6IGQucHJvcGVydHksIGxhYmVsOiB0aGlzLmdldFByb3BlcnR5TGFiZWxLZXkoZCksIGRpc2FibGVkOiAhZmlsdGVyICYmIGRpc2FibGVkUHJvcGVydGllcy5pbmNsdWRlcyhkLnByb3BlcnR5KX0pKTtcbiAgICB9KTtcblxuICAgIHB1YmxpYyBzZWxlY3RlZERlc2NyaXB0b3IgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb3BlcnR5ID0gdGhpcy5wcm9wZXJ0eU1vZGVsKCk7XG4gICAgICAgIHJldHVybiB0aGlzLmRlc2NyaXB0b3JzKCkuZmluZChmaWx0ZXJEZXNjcmlwdG9yID0+IGZpbHRlckRlc2NyaXB0b3IucHJvcGVydHkgPT09IHByb3BlcnR5KTtcbiAgICB9KTtcbiAgICBwdWJsaWMgc2VsZWN0ZWREZXNjcmlwdG9yQXNMb29rdXAgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpbHRlckRlc2NyaXB0b3IgPSB0aGlzLnNlbGVjdGVkRGVzY3JpcHRvcigpO1xuICAgICAgICByZXR1cm4gZmlsdGVyRGVzY3JpcHRvciAhPT0gdW5kZWZpbmVkICYmIChmaWx0ZXJEZXNjcmlwdG9yLmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLkxvb2t1cCB8fCBmaWx0ZXJEZXNjcmlwdG9yLmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLkxvb2t1cEVudW0pXG4gICAgICAgICAgICA/IChmaWx0ZXJEZXNjcmlwdG9yIGFzIEZpbHRlckxvb2t1cERlc2NyaXB0b3I8YW55LCBhbnk+KVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgcHVibGljIG1hdGNoTW9kZU9wdGlvbnMgPSBjb21wdXRlZDxTZWxlY3RJdGVtW10+KCgpID0+IHtcbiAgICAgICAgcmV0dXJuIGdlbmVyYXRlTWF0Y2hNb2RlT3B0aW9ucyh0aGlzLnByaW1lQ29uZmlnLCB0aGlzLnNlbGVjdGVkRGVzY3JpcHRvcigpLCB0aGlzLnNlcmlhbGl6YXRpb25DZmcpO1xuICAgIH0pO1xuXG4gICAgcHVibGljIGlzRWRpdCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZmlsdGVyKCkgIT0gbnVsbCk7XG4gICAgcHVibGljIGZvcm1TdWJtaXR0ZWQgPSBzaWduYWwoZmFsc2UpO1xuICAgIHB1YmxpYyBmb3JtRXJyb3JNZXNzYWdlID0gc2lnbmFsPGFueT4oW10pO1xuXG4gICAgLy8gZGlzcGxheSBjb25maWdzXG4gICAgcHVibGljIGRhdGVDb25maWcgPSBjb21wdXRlZCgoKSA9PiBmaWx0ZXJHZXREYXRlQ29uZmlnKHRoaXMuc2VsZWN0ZWREZXNjcmlwdG9yKCksIHRoaXMuc2VyaWFsaXphdGlvbkNmZykpO1xuICAgIHB1YmxpYyBudW1iZXJDb25maWcgPSBjb21wdXRlZCgoKSA9PiBmaWx0ZXJHZXROdW1iZXJDb25maWcodGhpcy5zZWxlY3RlZERlc2NyaXB0b3IoKSkpO1xuXG4gICAgLy8gVUkgdXRpbGl0aWVzXG4gICAgcHJpdmF0ZSBmaWx0ZXJGb3JtID0gdmlld0NoaWxkLnJlcXVpcmVkPE5nRm9ybT4oJ2ZpbHRlckZvcm0nKTtcblxuICAgIC8vIEZpbHRlciBmb3JtIG1vZGVsIGFuZCBmb3JtIHV0aWxpdGllc1xuICAgIHB1YmxpYyBwcm9wZXJ0eU1vZGVsID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAgIHB1YmxpYyBtYXRjaE1vZGVNb2RlbCA9IHNpZ25hbDxGaWx0ZXJNYXRjaE1vZGVFeHRlbmRlZFR5cGUgfCBudWxsPihudWxsKTtcbiAgICBwdWJsaWMgdmFsdWVNb2RlbCA9IHNpZ25hbDxhbnkgfCBhbnlbXSB8IG51bGw+KG51bGwpO1xuICAgIHB1YmxpYyBjYXNlU2Vuc2l0aXZlTW9kZWwgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gICAgcHJpdmF0ZSBzZXJpYWxpemF0aW9uQ2ZnOiBDb21tb25zU2VyaWFsaXphdGlvbkNvbmZpZyA9IHt9O1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIGZpbHRlckFwcGx5U2VyaWFsaXphdGlvbkNvbmZpZ1RvQ21wKHRoaXMubW9kdWxlQ29uZmlnLCB0aGlzLnNlcmlhbGl6YXRpb25DZmcpO1xuXG4gICAgICAgIGVmZmVjdChcbiAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBlZGl0ID0gdGhpcy5maWx0ZXIoKTtcbiAgICAgICAgICAgICAgICBpZiAoZWRpdCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlc2V0Rm9ybSh7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eTogZWRpdC5kZXNjcmlwdG9yLnByb3BlcnR5LFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hNb2RlOiBlZGl0LmRpc3BsYXlNYXRjaE1vZGUgPz8gZWRpdC5tYXRjaE1vZGUgPz8gbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBlZGl0LmRpc3BsYXlWYWx1ZSA/PyBlZGl0LnZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZVNlbnNpdGl2ZTogZWRpdC5jYXNlU2Vuc2l0aXZlID8/IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVzZXRGb3JtKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcblxuICAgICAgICBlZmZlY3QoXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHRoaXMuc2VsZWN0ZWREZXNjcmlwdG9yKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSB1bnRyYWNrZWQoKCkgPT4gdGhpcy52YWx1ZU1vZGVsKCkpO1xuXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gcmVzZXQgdmFsdWUgaWYgZmlsdGVyIHR5cGUgYW5kIHZhbHVlIHR5cGUgbWlzbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgKGRlc2NyaXB0b3I/LmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLlN0cmluZyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gZmFsc2UgfHwgdmFsdWUgPT09ICd0cnVlJyB8fCB2YWx1ZSA9PT0gJ2ZhbHNlJyB8fCB2YWx1ZSBpbnN0YW5jZW9mIERhdGUpKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgKGRlc2NyaXB0b3I/LmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLk51bWJlciAmJiB0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInICYmIGlzTmFOKCt2YWx1ZSkpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAoZGVzY3JpcHRvcj8uZmlsdGVyVHlwZSA9PT0gRmlsdGVyVHlwZUVudW0uRGF0ZSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdG9yPy5maWx0ZXJUeXBlID09PSBGaWx0ZXJUeXBlRW51bS5Mb29rdXAgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0b3I/LmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLkxvb2t1cEVudW1cbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlTW9kZWwuc2V0KG51bGwpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRlc2NyaXB0b3I/LmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLkJvb2xlYW4gJiYgdHlwZW9mIHZhbHVlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWVNb2RlbC5zZXQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHthbGxvd1NpZ25hbFdyaXRlczogdHJ1ZX1cbiAgICAgICAgKTtcblxuICAgICAgICBlZmZlY3QoXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgbWF0Y2hNb2RlT3B0aW9ucyA9IHRoaXMubWF0Y2hNb2RlT3B0aW9ucygpO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoTW9kZSA9IHVudHJhY2tlZCgoKSA9PiB0aGlzLm1hdGNoTW9kZU1vZGVsKCkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlckZvcm0gPSB1bnRyYWNrZWQoKCkgPT4gdGhpcy5maWx0ZXJGb3JtKCkpO1xuXG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICBtYXRjaE1vZGVPcHRpb25zLmxlbmd0aCA+IDAgJiZcbiAgICAgICAgICAgICAgICAgICAgKCFtYXRjaE1vZGUgfHwgZmlsdGVyRm9ybS5jb250cm9sc1snbWF0Y2hNb2RlJ10/LnByaXN0aW5lIHx8IGZpbHRlckZvcm0uY29udHJvbHNbJ21hdGNoTW9kZSddPy51bnRvdWNoZWQgfHwgIW1hdGNoTW9kZU9wdGlvbnMuZmluZChvID0+IG8udmFsdWUgPT09IG1hdGNoTW9kZSkpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWF0Y2hNb2RlTW9kZWwuc2V0KGZpbHRlckdldERlZmF1bHRNYXRjaE1vZGUodGhpcy5zZWxlY3RlZERlc2NyaXB0b3IoKSwgbWF0Y2hNb2RlT3B0aW9ucykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7YWxsb3dTaWduYWxXcml0ZXM6IHRydWV9XG4gICAgICAgICk7XG5cbiAgICAgICAgZWZmZWN0KFxuICAgICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHVudHJhY2tlZCgoKSA9PiB0aGlzLnZhbHVlTW9kZWwoKSk7XG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZU1vZGVsLnNldChmaWx0ZXJBZGp1c3REaXNwbGF5VmFsdWVPbk1hdGNoTW9kZUNoYW5nZSh0aGlzLm1hdGNoTW9kZU1vZGVsKCkgPz8gdW5kZWZpbmVkLCBjdXJyZW50VmFsdWUpKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7YWxsb3dTaWduYWxXcml0ZXM6IHRydWV9XG4gICAgICAgICk7XG5cbiAgICAgICAgdG9PYnNlcnZhYmxlKHRoaXMub3ZlcmxheSlcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcChvID0+IChvID8gby5vblNob3cgOiBORVZFUikpLFxuICAgICAgICAgICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCgpXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtRmllbGRzID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChcbiAgICAgICAgICAgICAgICAgICAgJ2lucHV0Om5vdChbZGlzYWJsZWRdKSwgc2VsZWN0Om5vdChbZGlzYWJsZWRdKSwgdGV4dGFyZWE6bm90KFtkaXNhYmxlZF0pLCBbcm9sZT1cImNvbWJvYm94XCJdOm5vdChbZGlzYWJsZWRdKSdcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUVsID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmVJbnB1dElkeCA9IGFjdGl2ZUVsID8gWy4uLmZvcm1GaWVsZHNdLmZpbmRJbmRleChlbCA9PiBhY3RpdmVFbC5pc0VxdWFsTm9kZShlbCkpIDogMDtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aXZlSW5wdXRJZHggPD0gMCkge1xuICAgICAgICAgICAgICAgICAgICBmb3JtRmllbGRzWzBdLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb25Gb3JtU3VibWl0KGZvcm06IE5nRm9ybSkge1xuICAgICAgICB0aGlzLmZvcm1TdWJtaXR0ZWQuc2V0KHRydWUpO1xuXG4gICAgICAgIC8vIG1hcmsgYWxsIGFzIGRpcnR5XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGZvcm0uY29udHJvbHMpIHtcbiAgICAgICAgICAgIGZvcm0uY29udHJvbHNba2V5XS5tYXJrQXNEaXJ0eSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJvcGVydHkgPSB0aGlzLnByb3BlcnR5TW9kZWwoKTtcbiAgICAgICAgY29uc3QgbWF0Y2hNb2RlID0gdGhpcy5tYXRjaE1vZGVNb2RlbCgpO1xuICAgICAgICBpZiAoZm9ybS5pbnZhbGlkIHx8ICFwcm9wZXJ0eSB8fCAhbWF0Y2hNb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmZvcm1FcnJvck1lc3NhZ2Uuc2V0KFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHNldmVyaXR5OiAnd2FybicsXG4gICAgICAgICAgICAgICAgICAgIHN1bW1hcnk6IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ21uZ0ZpbHRlci5tZXNzYWdlcy5pbnZhbGlkRm9ybVRpdGxlJyksXG4gICAgICAgICAgICAgICAgICAgIGRldGFpbDogdGhpcy50cmFuc2xhdGUuaW5zdGFudCgnbW5nRmlsdGVyLm1lc3NhZ2VzLmludmFsaWRGb3JtTWVzc2FnZScpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmFwcGx5LmVtaXQoe1xuICAgICAgICAgICAgcHJvcGVydHk6IHByb3BlcnR5LFxuICAgICAgICAgICAgbWF0Y2hNb2RlOiBtYXRjaE1vZGUsXG4gICAgICAgICAgICB2YWx1ZTogdGhpcy52YWx1ZU1vZGVsKCksXG4gICAgICAgICAgICBjYXNlU2Vuc2l0aXZlOiB0aGlzLmNhc2VTZW5zaXRpdmVNb2RlbCgpXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgcmVzZXRGb3JtKHZhbHVlPzogRmlsdGVyRm9ybU1vZGVsKSB7XG4gICAgICAgIHRoaXMuZmlsdGVyRm9ybSgpLnJlc2V0Rm9ybSh2YWx1ZSk7XG4gICAgICAgIC8vIHNvbWVob3cgaGF2ZSB0byBzZXQgY2FzZSBzZW5zaXRpdml0eSBtYW51YWxseVxuICAgICAgICB0aGlzLmNhc2VTZW5zaXRpdmVNb2RlbC5zZXQodmFsdWU/LmNhc2VTZW5zaXRpdmUgPz8gZmFsc2UpO1xuICAgICAgICB0aGlzLmZvcm1TdWJtaXR0ZWQuc2V0KGZhbHNlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFByb3BlcnR5TGFiZWxLZXkoZmlsdGVyRGVzY3JpcHRvcjogRmlsdGVyRGVzY3JpcHRvcjxhbnksIGFueT4pIHtcbiAgICAgICAgbGV0IGxhYmVsS2V5OiBzdHJpbmc7XG4gICAgICAgIGlmIChmaWx0ZXJEZXNjcmlwdG9yLnRpdGxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxhYmVsS2V5ID0gZmlsdGVyRGVzY3JpcHRvci50aXRsZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxhYmVsS2V5ID0gZ2V0STE4blR5cGVQcm9wZXJ0eUtleSh0aGlzLm1vZGVsKCkuaTE4bkJhc2VLZXksIGZpbHRlckRlc2NyaXB0b3IucHJvcGVydHkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBsYWJlbEtleTtcbiAgICB9XG59XG5cbmludGVyZmFjZSBGaWx0ZXJGb3JtTW9kZWwge1xuICAgIHByb3BlcnR5OiBzdHJpbmcgfCBudWxsO1xuICAgIG1hdGNoTW9kZTogRmlsdGVyTWF0Y2hNb2RlRXh0ZW5kZWRUeXBlIHwgbnVsbDtcbiAgICB2YWx1ZTogYW55IHwgbnVsbDtcbiAgICBjYXNlU2Vuc2l0aXZlOiBib29sZWFuO1xufVxuIiwiPGRpdj5cbiAgICA8ZGl2PlxuICAgICAgICA8aDU+e3sgZmlsdGVyKCkgPyAoJ21uZ0ZpbHRlci50aXRsZUVkaXQnIHwgdHJhbnNsYXRlKSA6ICgnbW5nRmlsdGVyLnRpdGxlQWRkJyB8IHRyYW5zbGF0ZSkgfX08L2g1PlxuICAgIDwvZGl2PlxuICAgIDxmb3JtICNmaWx0ZXJGb3JtPVwibmdGb3JtXCIgKG5nU3VibWl0KT1cIm9uRm9ybVN1Ym1pdChmaWx0ZXJGb3JtKVwiIGNsYXNzPVwiZmxleCBmbGV4LWNvbHVtbiBhbGlnbi1pdGVtcy1jZW50ZXIgbGc6ZmxleC1yb3cgZ2FwLTNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbCBsZzp3LWF1dG9cIj5cbiAgICAgICAgICAgIDxtbmctZHJvcGRvd25cbiAgICAgICAgICAgICAgICBuYW1lPVwicHJvcGVydHlcIlxuICAgICAgICAgICAgICAgIGlkPVwicHJvcGVydHlcIlxuICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMVwiXG4gICAgICAgICAgICAgICAgI3Byb3BlcnR5Q29udHJvbD1cIm5nTW9kZWxcIlxuICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicHJvcGVydHlNb2RlbFwiXG4gICAgICAgICAgICAgICAgW29wdGlvbnNdPVwicHJvcGVydHlPcHRpb25zV2l0aFRyYW5zbGF0aW9ucygpXCJcbiAgICAgICAgICAgICAgICBvcHRpb25zVmFsdWVQcm9wZXJ0eT1cInByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICBvcHRpb25zRGlzYWJsZWRQcm9wZXJ0eT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICBvcHRpb25zTGFiZWxQcm9wZXJ0eT1cImxhYmVsXCJcbiAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ21uZ0ZpbHRlci5wcm9wZXJ0eScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgIG9wdGlvbnNMYWJlbFRyYW5zbGF0ZT1cInRydWVcIlxuICAgICAgICAgICAgICAgIHJlcXVpcmVkPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwidy1mdWxsXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNFZGl0KClcIlxuICAgICAgICAgICAgICAgIFthcHBlbmRUb109XCJudWxsXCIgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgbGc6dy1hdXRvXCI+XG4gICAgICAgICAgICA8bW5nLWRyb3Bkb3duXG4gICAgICAgICAgICAgICAgbmFtZT1cIm1hdGNoTW9kZVwiXG4gICAgICAgICAgICAgICAgaWQ9XCJtYXRjaE1vZGVcIlxuICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwibWF0Y2hNb2RlTW9kZWxcIlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cInctZnVsbFwiXG4gICAgICAgICAgICAgICAgW29wdGlvbnNdPVwibWF0Y2hNb2RlT3B0aW9ucygpXCJcbiAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ21uZ0ZpbHRlci5tYXRjaE1vZGUnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIXByb3BlcnR5Q29udHJvbC52YWx1ZVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJhbGlnbi1zZWxmLWVuZFwiXG4gICAgICAgICAgICAgICAgcmVxdWlyZWQ9XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICBbYXBwZW5kVG9dPVwibnVsbFwiIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICBAaWYgKCEobWF0Y2hNb2RlTW9kZWwoKSA9PT0gRmlsdGVyTWF0Y2hNb2RlLkV4aXN0cyB8fCBtYXRjaE1vZGVNb2RlbCgpID09PSBGaWx0ZXJNYXRjaE1vZGUuRG9lc05vdEV4aXN0KSkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInctZnVsbCBsZzp3LWF1dG8gZmxleCBmbGV4LWNvbHVtblwiPlxuICAgICAgICAgICAgICAgIEBzd2l0Y2ggKHNlbGVjdGVkRGVzY3JpcHRvcigpPy5maWx0ZXJUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlIChGaWx0ZXJUeXBlRW51bS5OdW1iZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAobWF0Y2hNb2RlTW9kZWwoKSA9PT0gRmlsdGVyTWF0Y2hNb2RlLkJldHdlZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bW5nLW51bWJlci1yYW5nZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJtbmctY29sdW1uLWZpbHRlci1udW1iZXItaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInZhbHVlTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ21uZ0ZpbHRlci52YWx1ZScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdXNlR3JvdXBpbmddPVwic2VsZWN0ZWREZXNjcmlwdG9yKCk/Lm51bWJlclVzZUdyb3VwaW5nID8/IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21pbkZyYWN0aW9uRGlnaXRzXT1cIm51bWJlckNvbmZpZygpPy5mcmFjdGlvbnNNaW5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF4RnJhY3Rpb25EaWdpdHNdPVwibnVtYmVyQ29uZmlnKCk/LmZyYWN0aW9uc01heFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVpcmVkPVwidHJ1ZVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cC1pbnB1dE51bWJlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dFN0eWxlQ2xhc3M9XCJtbmctY29sdW1uLWZpbHRlci1udW1iZXItaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInZhbHVlTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGVDbGFzc109XCIndy1mdWxsJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInbW5nRmlsdGVyLnZhbHVlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt1c2VHcm91cGluZ109XCJzZWxlY3RlZERlc2NyaXB0b3IoKT8ubnVtYmVyVXNlR3JvdXBpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWluRnJhY3Rpb25EaWdpdHNdPVwibnVtYmVyQ29uZmlnKCk/LmZyYWN0aW9uc01pblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXhGcmFjdGlvbkRpZ2l0c109XCJudW1iZXJDb25maWcoKT8uZnJhY3Rpb25zTWF4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFtYXRjaE1vZGVNb2RlbCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ9XCJ0cnVlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIEBjYXNlIChGaWx0ZXJUeXBlRW51bS5Cb29sZWFuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8cC1jaGVja2JveCBbKG5nTW9kZWwpXT1cInZhbHVlTW9kZWxcIiBbZGlzYWJsZWRdPVwiIW1hdGNoTW9kZU1vZGVsKClcIiBuYW1lPVwidmFsdWVcIiBiaW5hcnk9XCJ0cnVlXCIgcmVxdWlyZWQ9XCJ0cnVlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoRmlsdGVyVHlwZUVudW0uRGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChtYXRjaE1vZGVNb2RlbCgpID09PSBGaWx0ZXJNYXRjaE1vZGUuQmV0d2Vlbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtbmctZGF0ZS1yYW5nZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInZhbHVlTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwidmFsdWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd1RpbWVdPVwiZGF0ZUNvbmZpZygpPy5zaG93VGltZSA/PyBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U2Vjb25kc109XCJkYXRlQ29uZmlnKCk/LnNob3dTZWNvbmRzID8/IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2RhdGVGb3JtYXRdPVwiZGF0ZUNvbmZpZygpPy5mb3JtYXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ21uZ0ZpbHRlci52YWx1ZScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD1cInRydWVcIj48L21uZy1kYXRlLXJhbmdlPlxuICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAtY2FsZW5kYXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ2YWx1ZU1vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlQ2xhc3NdPVwiJ3ctZnVsbCdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ21uZ0ZpbHRlci52YWx1ZScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd0ljb25dPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93VGltZV09XCJkYXRlQ29uZmlnKCk/LnNob3dUaW1lID8/IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Nob3dTZWNvbmRzXT1cImRhdGVDb25maWcoKT8uc2hvd1NlY29uZHMgPz8gZmFsc2VcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0ZUZvcm1hdF09XCJkYXRlQ29uZmlnKCk/LmZvcm1hdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmaXJzdERheU9mV2Vla109XCIxXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFtYXRjaE1vZGVNb2RlbCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ9XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9wLWNhbGVuZGFyPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlIChGaWx0ZXJUeXBlRW51bS5Mb29rdXApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJsb29rdXBGaWx0ZXJcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoRmlsdGVyVHlwZUVudW0uTG9va3VwRW51bSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImxvb2t1cEZpbHRlclwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBkZWZhdWx0IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidmFsdWVNb2RlbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcElucHV0VGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwibW5nLWNvbHVtbi1maWx0ZXItc3RyaW5nLWlucHV0IHctZnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIucGxhY2Vob2xkZXJdPVwiJ21uZ0ZpbHRlci52YWx1ZScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttbmdJbnB1dFRyaW1dPVwic2VsZWN0ZWREZXNjcmlwdG9yKCk/LnRyaW1PcHRpb24hXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIW1hdGNoTW9kZU1vZGVsKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInbW5nRmlsdGVyLnZhbHVlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ9XCJ0cnVlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2xvb2t1cEZpbHRlcj5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChzZWxlY3RlZERlc2NyaXB0b3JBc0xvb2t1cCgpOyBhcyBsb29rdXBGaWx0ZXJEZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBAc3dpdGNoIChsb29rdXBGaWx0ZXJEZXNjcmlwdG9yLmxvb2t1cFR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAY2FzZSAobG9va3VwVHlwZUF1dG9jb21wbGV0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bW5nLWF1dG9jb21wbGV0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ2YWx1ZU1vZGVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ2YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YVByb3ZpZGVyXT1cImxvb2t1cEZpbHRlckRlc2NyaXB0b3IuZGF0YVByb3ZpZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zVHJhY2tQcm9wZXJ0eV09XCJsb29rdXBGaWx0ZXJEZXNjcmlwdG9yLm9wdGlvbnNWYWx1ZVByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zVmFsdWVQcm9wZXJ0eV09XCJsb29rdXBGaWx0ZXJEZXNjcmlwdG9yLm9wdGlvbnNWYWx1ZVByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zTGFiZWxQcm9wZXJ0eV09XCJsb29rdXBGaWx0ZXJEZXNjcmlwdG9yLm9wdGlvbnNMYWJlbFByb3BlcnR5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtvcHRpb25zTGFiZWxUcmFuc2xhdGVdPVwibG9va3VwRmlsdGVyRGVzY3JpcHRvci5vcHRpb25zTGFiZWxUcmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW211bHRpc2VsZWN0XT1cImxvb2t1cEZpbHRlckRlc2NyaXB0b3IubXVsdGlzZWxlY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F1dG9DbGVhcl09XCJsb29rdXBGaWx0ZXJEZXNjcmlwdG9yLmF1dG9jb21wbGV0ZUF1dG9DbGVhciA/PyBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbb3Blbk9uRm9jdXNdPVwibG9va3VwRmlsdGVyRGVzY3JpcHRvci5hdXRvY29tcGxldGVBdXRvQ2xlYXIgPz8gdHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5saW5lU2VhcmNoXT1cImxvb2t1cEZpbHRlckRlc2NyaXB0b3IuYXV0b2NvbXBsZXRlSW5saW5lU2VhcmNoID8/IGZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCInbW5nRmlsdGVyLnZhbHVlJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3NOYW1lXT1cImxvb2t1cEZpbHRlckRlc2NyaXB0b3IuY2xhc3NOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkcm9wZG93bkNsYXNzTmFtZV09XCJsb29rdXBGaWx0ZXJEZXNjcmlwdG9yLmRyb3Bkb3duQ2xhc3NOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzZWFyY2hUcmltXT1cInNlbGVjdGVkRGVzY3JpcHRvcigpPy50cmltT3B0aW9uIVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIW1hdGNoTW9kZU1vZGVsKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWQ9XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbW5nLWF1dG9jb21wbGV0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQGNhc2UgKGxvb2t1cFR5cGVEcm9wZG93bikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bW5nLWRyb3Bkb3duXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInZhbHVlTW9kZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkYXRhUHJvdmlkZXJdPVwibG9va3VwRmlsdGVyRGVzY3JpcHRvci5kYXRhUHJvdmlkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNWYWx1ZVByb3BlcnR5XT1cImxvb2t1cEZpbHRlckRlc2NyaXB0b3Iub3B0aW9uc1ZhbHVlUHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNMYWJlbFByb3BlcnR5XT1cImxvb2t1cEZpbHRlckRlc2NyaXB0b3Iub3B0aW9uc0xhYmVsUHJvcGVydHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW29wdGlvbnNMYWJlbFRyYW5zbGF0ZV09XCJsb29rdXBGaWx0ZXJEZXNjcmlwdG9yLm9wdGlvbnNMYWJlbFRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbXVsdGlzZWxlY3RdPVwibG9va3VwRmlsdGVyRGVzY3JpcHRvci5tdWx0aXNlbGVjdFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ21uZ0ZpbHRlci52YWx1ZScgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzTmFtZV09XCJsb29rdXBGaWx0ZXJEZXNjcmlwdG9yLmNsYXNzTmFtZSArICcgdy1mdWxsJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZHJvcGRvd25DbGFzc05hbWVdPVwibG9va3VwRmlsdGVyRGVzY3JpcHRvci5kcm9wZG93bkNsYXNzTmFtZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2hvd0NsZWFyXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhbWF0Y2hNb2RlTW9kZWwoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXBwZW5kVG9dPVwibnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZD1cInRydWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tbmctZHJvcGRvd24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIEBpZiAoc2VsZWN0ZWREZXNjcmlwdG9yKCk/LmZpbHRlclR5cGUgPT09IEZpbHRlclR5cGVFbnVtLlN0cmluZyAmJiBtYXRjaE1vZGVNb2RlbCgpICE9PSBGaWx0ZXJNYXRjaE1vZGUuRXhpc3RzICYmIG1hdGNoTW9kZU1vZGVsKCkgIT09IEZpbHRlck1hdGNoTW9kZS5Eb2VzTm90RXhpc3QpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMlwiPlxuICAgICAgICAgICAgICAgIDxwLWNoZWNrYm94IFsobmdNb2RlbCldPVwiY2FzZVNlbnNpdGl2ZU1vZGVsXCIgbmFtZT1cImNhc2VTZW5zaXRpdmVcIiBiaW5hcnk9XCJ0cnVlXCIgaWQ9XCJjYXNlU2Vuc2l0aXZlXCIgLz5cbiAgICAgICAgICAgICAgICA8bGFiZWwgZm9yPVwiY2FzZVNlbnNpdGl2ZVwiPnt7ICdtbmdGaWx0ZXIuY2FzZVNlbnNpdGl2ZScgfCB0cmFuc2xhdGUgfX08L2xhYmVsPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgganVzdGlmeS1jb250ZW50LWVuZFwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBwQnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBjbGFzcz1cImFsaWduLXNlbGYtZW5kXCI+XG4gICAgICAgICAgICAgICAge3sgKGZpbHRlcigpID8gJ2dlbmVyYWwuYXBwbHknIDogJ2dlbmVyYWwuYWRkJykgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Zvcm0+XG4gICAgQGlmIChmb3JtU3VibWl0dGVkKCkgJiYgZmlsdGVyRm9ybS5pbnZhbGlkKSB7XG4gICAgICAgIDxwLW1lc3NhZ2VzIFt2YWx1ZV09XCJmb3JtRXJyb3JNZXNzYWdlKClcIiBjbGFzcz1cInctZnVsbFwiPjwvcC1tZXNzYWdlcz5cbiAgICB9XG48L2Rpdj5cbiJdfQ==
@@ -0,0 +1,135 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, computed, contentChildren, inject, input, signal, viewChild } from '@angular/core';
3
+ import { TranslateModule } from '@ngx-translate/core';
4
+ import { Button } from 'primeng/button';
5
+ import { OverlayPanel, OverlayPanelModule } from 'primeng/overlaypanel';
6
+ import { Table } from 'primeng/table';
7
+ import { TagModule } from 'primeng/tag';
8
+ import { COMMONS_MODULE_CONFIG_IT, FilterMatchMode, TemplateDirective, findTemplateByName } from '@mediusinc/mng-commons/core';
9
+ import { filterApplySerializationConfigToCmp, filterGetDateConfig, filterSetMetadataOnChange, filterSetMetadataOnDisplayChange } from '../../../helpers/filters';
10
+ import { DataListService } from '../../../services/data-list.service';
11
+ import { FilterActiveTagComponent } from '../filter-active-tag/filter-active-tag.component';
12
+ import { FilterFormComponent } from '../filter-form/filter-form.component';
13
+ import * as i0 from "@angular/core";
14
+ import * as i1 from "primeng/overlaypanel";
15
+ export class FilterOverlayWithTagComponent {
16
+ constructor() {
17
+ this.primeTable = inject(Table);
18
+ this.dataListService = inject((DataListService));
19
+ this.moduleConfig = inject(COMMONS_MODULE_CONFIG_IT, { optional: true });
20
+ this.descriptors = input.required();
21
+ this.model = input.required();
22
+ this.filterOverlay = viewChild.required(OverlayPanel);
23
+ this.templates = contentChildren(TemplateDirective);
24
+ this.titleTemplate = computed(() => findTemplateByName([...this.templates()], 'title'));
25
+ this.filters = computed(() => {
26
+ return this.setInitialFilters(this.dataListService.filterMeta());
27
+ });
28
+ this.activeFilters = computed(() => {
29
+ const filterEntry = this.filters();
30
+ return this.descriptors()
31
+ .filter(d => {
32
+ const filter = filterEntry[d.property];
33
+ return (filter &&
34
+ filter.matchMode !== undefined &&
35
+ filter.displayMatchMode !== undefined &&
36
+ (filter.matchMode === FilterMatchMode.Exists ||
37
+ filter.matchMode === FilterMatchMode.DoesNotExist ||
38
+ (filter.value !== undefined && filter.displayValue !== undefined)));
39
+ })
40
+ .map(d => filterEntry[d.property]);
41
+ });
42
+ this.activeFilterProperties = computed(() => this.activeFilters().map(f => f.descriptor.property));
43
+ this.filterEdit = signal(undefined);
44
+ this.serializationCfg = {};
45
+ // UI utilities
46
+ this.clickedOnFilterEvent = undefined;
47
+ filterApplySerializationConfigToCmp(this.moduleConfig, this.serializationCfg);
48
+ }
49
+ onFilterFormApply(event) {
50
+ const descriptor = this.descriptors().find(d => d.property === event.property);
51
+ if (!descriptor) {
52
+ return;
53
+ }
54
+ this.updatePrimeTableFilter({
55
+ ...filterSetMetadataOnDisplayChange({ caseSensitive: event.caseSensitive }, event.matchMode, event.value, descriptor.filterType, filterGetDateConfig(descriptor, this.serializationCfg)),
56
+ descriptor: descriptor
57
+ });
58
+ // Resetting the form is done in the onOverlayHide callback because resetting the
59
+ // values here renders empty inputs for a split second before closing the overlay
60
+ this.filterOverlay().hide();
61
+ }
62
+ onFilterRemove(event) {
63
+ this.updatePrimeTableFilter({
64
+ ...this.filters()[event.filter.descriptor.property],
65
+ matchMode: undefined,
66
+ displayMatchMode: undefined,
67
+ value: undefined,
68
+ displayValue: undefined
69
+ });
70
+ }
71
+ onFilterEdit(event) {
72
+ this.onFilterAddOrEdit(event.filter, event.event);
73
+ }
74
+ onFilterAdd(event) {
75
+ this.onFilterAddOrEdit(undefined, event);
76
+ }
77
+ onOverlayHide() {
78
+ if (this.clickedOnFilterEvent) {
79
+ // show the overlay again if the user clicked another filter
80
+ setTimeout(() => {
81
+ this.filterOverlay().show(this.clickedOnFilterEvent);
82
+ this.clickedOnFilterEvent = undefined;
83
+ }, 0);
84
+ return;
85
+ }
86
+ else {
87
+ // clean state
88
+ this.filterEdit.set(undefined);
89
+ }
90
+ }
91
+ onFilterAddOrEdit(filter, event) {
92
+ // If user clicks on the same filter or add that is already open, close the overlay
93
+ if (this.filterOverlay().overlayVisible && this.filterEdit()?.descriptor.property === filter?.descriptor.property) {
94
+ this.filterOverlay().hide();
95
+ this.filterEdit.set(undefined);
96
+ return;
97
+ }
98
+ this.filterEdit.set(filter);
99
+ if (this.filterOverlay().overlayVisible) {
100
+ // In case the user clicks another filter, 're-showing' the overlay in
101
+ // the new position is done in the onOverlayHide callback
102
+ this.clickedOnFilterEvent = event;
103
+ this.filterOverlay().hide();
104
+ }
105
+ else {
106
+ this.filterOverlay().show(event);
107
+ }
108
+ }
109
+ setInitialFilters(filtersInit) {
110
+ const filtersResult = {};
111
+ for (const property in filtersInit) {
112
+ const filterInit = filtersInit[property];
113
+ const descriptor = this.descriptors().find(filterDescriptor => filterDescriptor.property === property);
114
+ if (!descriptor) {
115
+ continue;
116
+ }
117
+ filtersResult[property] = {
118
+ ...filterSetMetadataOnChange(filterInit, filterInit.matchMode, filterInit.value, descriptor.filterType, filterGetDateConfig(descriptor, this.serializationCfg)),
119
+ descriptor: descriptor
120
+ };
121
+ }
122
+ return filtersResult;
123
+ }
124
+ updatePrimeTableFilter(filter) {
125
+ this.primeTable.filters[filter.descriptor.property] = { ...filter };
126
+ this.primeTable._filter();
127
+ }
128
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FilterOverlayWithTagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
129
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.5", type: FilterOverlayWithTagComponent, isStandalone: true, selector: "mng-filter-overlay-with-tag", inputs: { descriptors: { classPropertyName: "descriptors", publicName: "descriptors", isSignal: true, isRequired: true, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null } }, queries: [{ propertyName: "templates", predicate: TemplateDirective, isSignal: true }], viewQueries: [{ propertyName: "filterOverlay", first: true, predicate: OverlayPanel, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex align-items-center flex-grow-1\">\n @if (titleTemplate()) {\n <ng-container *ngTemplateOutlet=\"titleTemplate()\"></ng-container>\n }\n <p-button\n icon=\"pi pi-filter\"\n [rounded]=\"true\"\n [severity]=\"activeFilters().length > 0 ? 'primary' : 'secondary'\"\n size=\"small\"\n (click)=\"onFilterAdd($event)\"\n [styleClass]=\"'my-1 mr-2' + (titleTemplate() ? ' ml-3' : '')\">\n </p-button>\n</div>\n@if (activeFilters().length > 0) {\n <div class=\"flex align-items-center flex-wrap mt-2\">\n @for (filter of activeFilters(); track filter.descriptor.property) {\n <mng-filter-active-tag [model]=\"model()\" [filter]=\"filter\" (edit)=\"onFilterEdit($event)\" (remove)=\"onFilterRemove($event)\" />\n }\n </div>\n}\n<p-overlayPanel #op [showCloseIcon]=\"true\" (onHide)=\"onOverlayHide()\" appendTo=\"body\">\n <mng-filter-form\n [model]=\"model()\"\n [descriptors]=\"descriptors()\"\n [filter]=\"filterEdit()\"\n [disabledProperties]=\"activeFilterProperties()\"\n [overlay]=\"op\"\n (apply)=\"onFilterFormApply($event)\" />\n</p-overlayPanel>\n", dependencies: [{ kind: "ngmodule", type: OverlayPanelModule }, { kind: "component", type: i1.OverlayPanel, selector: "p-overlayPanel", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "showCloseIcon", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: FilterFormComponent, selector: "mng-filter-form", inputs: ["title", "descriptors", "model", "filter", "overlay", "disabledProperties"], outputs: ["apply"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: FilterActiveTagComponent, selector: "mng-filter-active-tag", inputs: ["model", "filter"], outputs: ["edit", "remove"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
130
+ }
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.5", ngImport: i0, type: FilterOverlayWithTagComponent, decorators: [{
132
+ type: Component,
133
+ args: [{ standalone: true, selector: 'mng-filter-overlay-with-tag', imports: [OverlayPanelModule, TranslateModule, TagModule, FilterFormComponent, Button, FilterActiveTagComponent, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex align-items-center flex-grow-1\">\n @if (titleTemplate()) {\n <ng-container *ngTemplateOutlet=\"titleTemplate()\"></ng-container>\n }\n <p-button\n icon=\"pi pi-filter\"\n [rounded]=\"true\"\n [severity]=\"activeFilters().length > 0 ? 'primary' : 'secondary'\"\n size=\"small\"\n (click)=\"onFilterAdd($event)\"\n [styleClass]=\"'my-1 mr-2' + (titleTemplate() ? ' ml-3' : '')\">\n </p-button>\n</div>\n@if (activeFilters().length > 0) {\n <div class=\"flex align-items-center flex-wrap mt-2\">\n @for (filter of activeFilters(); track filter.descriptor.property) {\n <mng-filter-active-tag [model]=\"model()\" [filter]=\"filter\" (edit)=\"onFilterEdit($event)\" (remove)=\"onFilterRemove($event)\" />\n }\n </div>\n}\n<p-overlayPanel #op [showCloseIcon]=\"true\" (onHide)=\"onOverlayHide()\" appendTo=\"body\">\n <mng-filter-form\n [model]=\"model()\"\n [descriptors]=\"descriptors()\"\n [filter]=\"filterEdit()\"\n [disabledProperties]=\"activeFilterProperties()\"\n [overlay]=\"op\"\n (apply)=\"onFilterFormApply($event)\" />\n</p-overlayPanel>\n" }]
134
+ }], ctorParameters: () => [] });
135
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLW92ZXJsYXktd2l0aC10YWcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGFibGUvc3JjL2NvbXBvbmVudHMvZmlsdGVyL2ZpbHRlci1vdmVybGF5LXdpdGgtdGFnL2ZpbHRlci1vdmVybGF5LXdpdGgtdGFnLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3RhYmxlL3NyYy9jb21wb25lbnRzL2ZpbHRlci9maWx0ZXItb3ZlcmxheS13aXRoLXRhZy9maWx0ZXItb3ZlcmxheS13aXRoLXRhZy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsU0FBUyxFQUF1QixRQUFRLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUVuSixPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sRUFBQyxZQUFZLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUN0RSxPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3BDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxhQUFhLENBQUM7QUFFdEMsT0FBTyxFQUFDLHdCQUF3QixFQUFxRCxlQUFlLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUMsTUFBTSw2QkFBNkIsQ0FBQztBQUloTCxPQUFPLEVBQUMsbUNBQW1DLEVBQUUsbUJBQW1CLEVBQUUseUJBQXlCLEVBQUUsZ0NBQWdDLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUUvSixPQUFPLEVBQUMsZUFBZSxFQUFDLE1B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LHdCQUF3QixFQUFFLGdCQUFnQixDQUFDLG1CQUNqSCx1QkFBdUIsQ0FBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtOZ1RlbXBsYXRlT3V0bGV0fSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBTaWduYWwsIFRlbXBsYXRlUmVmLCBjb21wdXRlZCwgY29udGVudENoaWxkcmVuLCBpbmplY3QsIGlucHV0LCBzaWduYWwsIHZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7VHJhbnNsYXRlTW9kdWxlfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7QnV0dG9ufSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQge092ZXJsYXlQYW5lbCwgT3ZlcmxheVBhbmVsTW9kdWxlfSBmcm9tICdwcmltZW5nL292ZXJsYXlwYW5lbCc7XG5pbXBvcnQge1RhYmxlfSBmcm9tICdwcmltZW5nL3RhYmxlJztcbmltcG9ydCB7VGFnTW9kdWxlfSBmcm9tICdwcmltZW5nL3RhZyc7XG5cbmltcG9ydCB7Q09NTU9OU19NT0RVTEVfQ09ORklHX0lULCBDb21tb25zRmlsdGVyTWV0YWRhdGEsIENvbW1vbnNTZXJpYWxpemF0aW9uQ29uZmlnLCBGaWx0ZXJNYXRjaE1vZGUsIFRlbXBsYXRlRGlyZWN0aXZlLCBmaW5kVGVtcGxhdGVCeU5hbWV9IGZyb20gJ0BtZWRpdXNpbmMvbW5nLWNvbW1vbnMvY29yZSc7XG5pbXBvcnQge0ZpbHRlckRlc2NyaXB0b3J9IGZyb20gJ0BtZWRpdXNpbmMvbW5nLWNvbW1vbnMvZmlsdGVyJztcbmltcG9ydCB7TW9kZWxEZXNjcmlwdG9yfSBmcm9tICdAbWVkaXVzaW5jL21uZy1jb21tb25zL21vZGVsJztcblxuaW1wb3J0IHtmaWx0ZXJBcHBseVNlcmlhbGl6YXRpb25Db25maWdUb0NtcCwgZmlsdGVyR2V0RGF0ZUNvbmZpZywgZmlsdGVyU2V0TWV0YWRhdGFPbkNoYW5nZSwgZmlsdGVyU2V0TWV0YWRhdGFPbkRpc3BsYXlDaGFuZ2V9IGZyb20gJy4uLy4uLy4uL2hlbHBlcnMvZmlsdGVycyc7XG5pbXBvcnQge0NvbW1vbnNGaWx0ZXJNZXRhZGF0YVdpdGhEZXNjcmlwdG9yLCBGaWx0ZXJBY3RpdmVUYWdFdmVudCwgRmlsdGVyRm9ybUVtaXRFdmVudH0gZnJvbSAnLi4vLi4vLi4vbW9kZWxzL2ZpbHRlci5tb2RlbCc7XG5pbXBvcnQge0RhdGFMaXN0U2VydmljZX0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvZGF0YS1saXN0LnNlcnZpY2UnO1xuaW1wb3J0IHtGaWx0ZXJBY3RpdmVUYWdDb21wb25lbnR9IGZyb20gJy4uL2ZpbHRlci1hY3RpdmUtdGFnL2ZpbHRlci1hY3RpdmUtdGFnLmNvbXBvbmVudCc7XG5pbXBvcnQge0ZpbHRlckZvcm1Db21wb25lbnR9IGZyb20gJy4uL2ZpbHRlci1mb3JtL2ZpbHRlci1mb3JtLmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgc2VsZWN0b3I6ICdtbmctZmlsdGVyLW92ZXJsYXktd2l0aC10YWcnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9maWx0ZXItb3ZlcmxheS13aXRoLXRhZy5jb21wb25lbnQuaHRtbCcsXG4gICAgaW1wb3J0czogW092ZXJsYXlQYW5lbE1vZHVsZSwgVHJhbnNsYXRlTW9kdWxlLCBUYWdNb2R1bGUsIEZpbHRlckZvcm1Db21wb25lbnQsIEJ1dHRvbiwgRmlsdGVyQWN0aXZlVGFnQ29tcG9uZW50LCBOZ1RlbXBsYXRlT3V0bGV0XSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBGaWx0ZXJPdmVybGF5V2l0aFRhZ0NvbXBvbmVudCB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBwcmltZVRhYmxlID0gaW5qZWN0KFRhYmxlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRhdGFMaXN0U2VydmljZSA9IGluamVjdChEYXRhTGlzdFNlcnZpY2U8YW55Pik7XG4gICAgcHJpdmF0ZSByZWFkb25seSBtb2R1bGVDb25maWcgPSBpbmplY3QoQ09NTU9OU19NT0RVTEVfQ09ORklHX0lULCB7b3B0aW9uYWw6IHRydWV9KTtcblxuICAgIHB1YmxpYyBkZXNjcmlwdG9ycyA9IGlucHV0LnJlcXVpcmVkPEZpbHRlckRlc2NyaXB0b3I8YW55LCBhbnk+W10+KCk7XG4gICAgcHVibGljIG1vZGVsID0gaW5wdXQucmVxdWlyZWQ8TW9kZWxEZXNjcmlwdG9yPGFueT4+KCk7XG5cbiAgICBwcml2YXRlIGZpbHRlck92ZXJsYXkgPSB2aWV3Q2hpbGQucmVxdWlyZWQoT3ZlcmxheVBhbmVsKTtcblxuICAgIHB1YmxpYyB0ZW1wbGF0ZXMgPSBjb250ZW50Q2hpbGRyZW4oVGVtcGxhdGVEaXJlY3RpdmUpO1xuICAgIHB1YmxpYyB0aXRsZVRlbXBsYXRlOiBTaWduYWw8VGVtcGxhdGVSZWY8YW55PiB8IG51bGw+ID0gY29tcHV0ZWQoKCkgPT4gZmluZFRlbXBsYXRlQnlOYW1lKFsuLi50aGlzLnRlbXBsYXRlcygpXSwgJ3RpdGxlJykpO1xuXG4gICAgcHVibGljIGZpbHRlcnMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnNldEluaXRpYWxGaWx0ZXJzKHRoaXMuZGF0YUxpc3RTZXJ2aWNlLmZpbHRlck1ldGEoKSk7XG4gICAgfSk7XG5cbiAgICBwdWJsaWMgYWN0aXZlRmlsdGVycyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICAgICAgY29uc3QgZmlsdGVyRW50cnkgPSB0aGlzLmZpbHRlcnMoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGVzY3JpcHRvcnMoKVxuICAgICAgICAgICAgLmZpbHRlcihkID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBmaWx0ZXJFbnRyeVtkLnByb3BlcnR5XTtcbiAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgJiZcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyLm1hdGNoTW9kZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlci5kaXNwbGF5TWF0Y2hNb2RlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgICAgICAgICAgKGZpbHRlci5tYXRjaE1vZGUgPT09IEZpbHRlck1hdGNoTW9kZS5FeGlzdHMgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlci5tYXRjaE1vZGUgPT09IEZpbHRlck1hdGNoTW9kZS5Eb2VzTm90RXhpc3QgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChmaWx0ZXIudmFsdWUgIT09IHVuZGVmaW5lZCAmJiBmaWx0ZXIuZGlzcGxheVZhbHVlICE9PSB1bmRlZmluZWQpKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm1hcChkID0+IGZpbHRlckVudHJ5W2QucHJvcGVydHldISk7XG4gICAgfSk7XG4gICAgcHVibGljIGFjdGl2ZUZpbHRlclByb3BlcnRpZXMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmFjdGl2ZUZpbHRlcnMoKS5tYXAoZiA9PiBmLmRlc2NyaXB0b3IucHJvcGVydHkpKTtcbiAgICBwdWJsaWMgZmlsdGVyRWRpdCA9IHNpZ25hbDxDb21tb25zRmlsdGVyTWV0YWRhdGFXaXRoRGVzY3JpcHRvciB8IHVuZGVmaW5lZD4odW5kZWZpbmVkKTtcblxuICAgIHByaXZhdGUgc2VyaWFsaXphdGlvbkNmZzogQ29tbW9uc1NlcmlhbGl6YXRpb25Db25maWcgPSB7fTtcblxuICAgIC8vIFVJIHV0aWxpdGllc1xuICAgIHByaXZhdGUgY2xpY2tlZE9uRmlsdGVyRXZlbnQ6IEV2ZW50IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIGZpbHRlckFwcGx5U2VyaWFsaXphdGlvbkNvbmZpZ1RvQ21wKHRoaXMubW9kdWxlQ29uZmlnLCB0aGlzLnNlcmlhbGl6YXRpb25DZmcpO1xuICAgIH1cblxuICAgIG9uRmlsdGVyRm9ybUFwcGx5KGV2ZW50OiBGaWx0ZXJGb3JtRW1pdEV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB0aGlzLmRlc2NyaXB0b3JzKCkuZmluZChkID0+IGQucHJvcGVydHkgPT09IGV2ZW50LnByb3BlcnR5KTtcbiAgICAgICAgaWYgKCFkZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnVwZGF0ZVByaW1lVGFibGVGaWx0ZXIoe1xuICAgICAgICAgICAgLi4uZmlsdGVyU2V0TWV0YWRhdGFPbkRpc3BsYXlDaGFuZ2UoXG4gICAgICAgICAgICAgICAge2Nhc2VTZW5zaXRpdmU6IGV2ZW50LmNhc2VTZW5zaXRpdmV9LFxuICAgICAgICAgICAgICAgIGV2ZW50Lm1hdGNoTW9kZSxcbiAgICAgICAgICAgICAgICBldmVudC52YWx1ZSxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdG9yLmZpbHRlclR5cGUsXG4gICAgICAgICAgICAgICAgZmlsdGVyR2V0RGF0ZUNvbmZpZyhkZXNjcmlwdG9yLCB0aGlzLnNlcmlhbGl6YXRpb25DZmcpXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgZGVzY3JpcHRvcjogZGVzY3JpcHRvclxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBSZXNldHRpbmcgdGhlIGZvcm0gaXMgZG9uZSBpbiB0aGUgb25PdmVybGF5SGlkZSBjYWxsYmFjayBiZWNhdXNlIHJlc2V0dGluZyB0aGVcbiAgICAgICAgLy8gdmFsdWVzIGhlcmUgcmVuZGVycyBlbXB0eSBpbnB1dHMgZm9yIGEgc3BsaXQgc2Vjb25kIGJlZm9yZSBjbG9zaW5nIHRoZSBvdmVybGF5XG4gICAgICAgIHRoaXMuZmlsdGVyT3ZlcmxheSgpLmhpZGUoKTtcbiAgICB9XG5cbiAgICBvbkZpbHRlclJlbW92ZShldmVudDogRmlsdGVyQWN0aXZlVGFnRXZlbnQpIHtcbiAgICAgICAgdGhpcy51cGRhdGVQcmltZVRhYmxlRmlsdGVyKHtcbiAgICAgICAgICAgIC4uLnRoaXMuZmlsdGVycygpW2V2ZW50LmZpbHRlci5kZXNjcmlwdG9yLnByb3BlcnR5XSxcbiAgICAgICAgICAgIG1hdGNoTW9kZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgZGlzcGxheU1hdGNoTW9kZTogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdmFsdWU6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGRpc3BsYXlWYWx1ZTogdW5kZWZpbmVkXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIG9uRmlsdGVyRWRpdChldmVudDogRmlsdGVyQWN0aXZlVGFnRXZlbnQpIHtcbiAgICAgICAgdGhpcy5vbkZpbHRlckFkZE9yRWRpdChldmVudC5maWx0ZXIsIGV2ZW50LmV2ZW50KTtcbiAgICB9XG5cbiAgICBvbkZpbHRlckFkZChldmVudDogRXZlbnQpIHtcbiAgICAgICAgdGhpcy5vbkZpbHRlckFkZE9yRWRpdCh1bmRlZmluZWQsIGV2ZW50KTtcbiAgICB9XG5cbiAgICBvbk92ZXJsYXlIaWRlKCkge1xuICAgICAgICBpZiAodGhpcy5jbGlja2VkT25GaWx0ZXJFdmVudCkge1xuICAgICAgICAgICAgLy8gc2hvdyB0aGUgb3ZlcmxheSBhZ2FpbiBpZiB0aGUgdXNlciBjbGlja2VkIGFub3RoZXIgZmlsdGVyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmZpbHRlck92ZXJsYXkoKS5zaG93KHRoaXMuY2xpY2tlZE9uRmlsdGVyRXZlbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xpY2tlZE9uRmlsdGVyRXZlbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGNsZWFuIHN0YXRlXG4gICAgICAgICAgICB0aGlzLmZpbHRlckVkaXQuc2V0KHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG9uRmlsdGVyQWRkT3JFZGl0KGZpbHRlcj86IENvbW1vbnNGaWx0ZXJNZXRhZGF0YVdpdGhEZXNjcmlwdG9yLCBldmVudD86IEV2ZW50KSB7XG4gICAgICAgIC8vIElmIHVzZXIgY2xpY2tzIG9uIHRoZSBzYW1lIGZpbHRlciBvciBhZGQgdGhhdCBpcyBhbHJlYWR5IG9wZW4sIGNsb3NlIHRoZSBvdmVybGF5XG4gICAgICAgIGlmICh0aGlzLmZpbHRlck92ZXJsYXkoKS5vdmVybGF5VmlzaWJsZSAmJiB0aGlzLmZpbHRlckVkaXQoKT8uZGVzY3JpcHRvci5wcm9wZXJ0eSA9PT0gZmlsdGVyPy5kZXNjcmlwdG9yLnByb3BlcnR5KSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlck92ZXJsYXkoKS5oaWRlKCk7XG4gICAgICAgICAgICB0aGlzLmZpbHRlckVkaXQuc2V0KHVuZGVmaW5lZCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZpbHRlckVkaXQuc2V0KGZpbHRlcik7XG4gICAgICAgIGlmICh0aGlzLmZpbHRlck92ZXJsYXkoKS5vdmVybGF5VmlzaWJsZSkge1xuICAgICAgICAgICAgLy8gSW4gY2FzZSB0aGUgdXNlciBjbGlja3MgYW5vdGhlciBmaWx0ZXIsICdyZS1zaG93aW5nJyB0aGUgb3ZlcmxheSBpblxuICAgICAgICAgICAgLy8gdGhlIG5ldyBwb3NpdGlvbiBpcyBkb25lIGluIHRoZSBvbk92ZXJsYXlIaWRlIGNhbGxiYWNrXG4gICAgICAgICAgICB0aGlzLmNsaWNrZWRPbkZpbHRlckV2ZW50ID0gZXZlbnQ7XG4gICAgICAgICAgICB0aGlzLmZpbHRlck92ZXJsYXkoKS5oaWRlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlck92ZXJsYXkoKS5zaG93KGV2ZW50KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2V0SW5pdGlhbEZpbHRlcnMoZmlsdGVyc0luaXQ6IFJlY29yZDxzdHJpbmcsIENvbW1vbnNGaWx0ZXJNZXRhZGF0YT4pIHtcbiAgICAgICAgY29uc3QgZmlsdGVyc1Jlc3VsdDoge1twOiBzdHJpbmddOiBDb21tb25zRmlsdGVyTWV0YWRhdGFXaXRoRGVzY3JpcHRvcn0gPSB7fTtcblxuICAgICAgICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIGZpbHRlcnNJbml0KSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJJbml0ID0gZmlsdGVyc0luaXRbcHJvcGVydHldO1xuXG4gICAgICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gdGhpcy5kZXNjcmlwdG9ycygpLmZpbmQoZmlsdGVyRGVzY3JpcHRvciA9PiBmaWx0ZXJEZXNjcmlwdG9yLnByb3BlcnR5ID09PSBwcm9wZXJ0eSk7XG4gICAgICAgICAgICBpZiAoIWRlc2NyaXB0b3IpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZmlsdGVyc1Jlc3VsdFtwcm9wZXJ0eV0gPSB7XG4gICAgICAgICAgICAgICAgLi4uZmlsdGVyU2V0TWV0YWRhdGFPbkNoYW5nZShmaWx0ZXJJbml0LCBmaWx0ZXJJbml0Lm1hdGNoTW9kZSwgZmlsdGVySW5pdC52YWx1ZSwgZGVzY3JpcHRvci5maWx0ZXJUeXBlLCBmaWx0ZXJHZXREYXRlQ29uZmlnKGRlc2NyaXB0b3IsIHRoaXMuc2VyaWFsaXphdGlvbkNmZykpLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0b3I6IGRlc2NyaXB0b3JcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmlsdGVyc1Jlc3VsdDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVByaW1lVGFibGVGaWx0ZXIoZmlsdGVyOiBDb21tb25zRmlsdGVyTWV0YWRhdGFXaXRoRGVzY3JpcHRvcikge1xuICAgICAgICB0aGlzLnByaW1lVGFibGUuZmlsdGVyc1tmaWx0ZXIuZGVzY3JpcHRvci5wcm9wZXJ0eV0gPSB7Li4uZmlsdGVyfTtcbiAgICAgICAgdGhpcy5wcmltZVRhYmxlLl9maWx0ZXIoKTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZmxleC1ncm93LTFcIj5cbiAgICBAaWYgKHRpdGxlVGVtcGxhdGUoKSkge1xuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGl0bGVUZW1wbGF0ZSgpXCI+PC9uZy1jb250YWluZXI+XG4gICAgfVxuICAgIDxwLWJ1dHRvblxuICAgICAgICBpY29uPVwicGkgcGktZmlsdGVyXCJcbiAgICAgICAgW3JvdW5kZWRdPVwidHJ1ZVwiXG4gICAgICAgIFtzZXZlcml0eV09XCJhY3RpdmVGaWx0ZXJzKCkubGVuZ3RoID4gMCA/ICdwcmltYXJ5JyA6ICdzZWNvbmRhcnknXCJcbiAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgKGNsaWNrKT1cIm9uRmlsdGVyQWRkKCRldmVudClcIlxuICAgICAgICBbc3R5bGVDbGFzc109XCInbXktMSBtci0yJyArICh0aXRsZVRlbXBsYXRlKCkgPyAnIG1sLTMnIDogJycpXCI+XG4gICAgPC9wLWJ1dHRvbj5cbjwvZGl2PlxuQGlmIChhY3RpdmVGaWx0ZXJzKCkubGVuZ3RoID4gMCkge1xuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBmbGV4LXdyYXAgbXQtMlwiPlxuICAgICAgICBAZm9yIChmaWx0ZXIgb2YgYWN0aXZlRmlsdGVycygpOyB0cmFjayBmaWx0ZXIuZGVzY3JpcHRvci5wcm9wZXJ0eSkge1xuICAgICAgICAgICAgPG1uZy1maWx0ZXItYWN0aXZlLXRhZyBbbW9kZWxdPVwibW9kZWwoKVwiIFtmaWx0ZXJdPVwiZmlsdGVyXCIgKGVkaXQpPVwib25GaWx0ZXJFZGl0KCRldmVudClcIiAocmVtb3ZlKT1cIm9uRmlsdGVyUmVtb3ZlKCRldmVudClcIiAvPlxuICAgICAgICB9XG4gICAgPC9kaXY+XG59XG48cC1vdmVybGF5UGFuZWwgI29wIFtzaG93Q2xvc2VJY29uXT1cInRydWVcIiAob25IaWRlKT1cIm9uT3ZlcmxheUhpZGUoKVwiIGFwcGVuZFRvPVwiYm9keVwiPlxuICAgIDxtbmctZmlsdGVyLWZvcm1cbiAgICAgICAgW21vZGVsXT1cIm1vZGVsKClcIlxuICAgICAgICBbZGVzY3JpcHRvcnNdPVwiZGVzY3JpcHRvcnMoKVwiXG4gICAgICAgIFtmaWx0ZXJdPVwiZmlsdGVyRWRpdCgpXCJcbiAgICAgICAgW2Rpc2FibGVkUHJvcGVydGllc109XCJhY3RpdmVGaWx0ZXJQcm9wZXJ0aWVzKClcIlxuICAgICAgICBbb3ZlcmxheV09XCJvcFwiXG4gICAgICAgIChhcHBseSk9XCJvbkZpbHRlckZvcm1BcHBseSgkZXZlbnQpXCIgLz5cbjwvcC1vdmVybGF5UGFuZWw+XG4iXX0=