ngx-dynamic-entity 0.0.1 → 1.0.0

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 (84) hide show
  1. package/README.md +139 -0
  2. package/esm2022/lib/field-types/array-field.component.mjs +160 -0
  3. package/esm2022/lib/field-types/boolean-field.component.mjs +100 -0
  4. package/esm2022/lib/field-types/checkbox-field.component.mjs +49 -41
  5. package/esm2022/lib/field-types/currency-field.component.mjs +101 -0
  6. package/esm2022/lib/field-types/date-field.component.mjs +47 -39
  7. package/esm2022/lib/field-types/dropdown-field.component.mjs +145 -54
  8. package/esm2022/lib/field-types/email-field.component.mjs +101 -0
  9. package/esm2022/lib/field-types/entity-ref-field.component.mjs +134 -70
  10. package/esm2022/lib/field-types/file-field.component.mjs +156 -0
  11. package/esm2022/lib/field-types/group-field.component.mjs +89 -0
  12. package/esm2022/lib/field-types/image-field.component.mjs +168 -0
  13. package/esm2022/lib/field-types/month-year-field.component.mjs +151 -0
  14. package/esm2022/lib/field-types/multi-select-field.component.mjs +110 -56
  15. package/esm2022/lib/field-types/number-field.component.mjs +84 -41
  16. package/esm2022/lib/field-types/password-field.component.mjs +109 -0
  17. package/esm2022/lib/field-types/radio-field.component.mjs +152 -0
  18. package/esm2022/lib/field-types/text-field.component.mjs +82 -42
  19. package/esm2022/lib/field-types/textarea-field.component.mjs +52 -41
  20. package/esm2022/lib/form/dynamic-field/dynamic-field.component.mjs +44 -26
  21. package/esm2022/lib/form/dynamic-form.component.mjs +501 -67
  22. package/esm2022/lib/form/dynamic-record-form.component.mjs +469 -0
  23. package/esm2022/lib/providers/provide-field-types.mjs +72 -0
  24. package/esm2022/lib/providers/provide-ngx-dynamic-entity.mjs +3 -5
  25. package/esm2022/lib/services/cascade-data.service.mjs +129 -0
  26. package/esm2022/lib/services/config-source.service.mjs +67 -0
  27. package/esm2022/lib/services/entity-ref-cache.mjs +20 -0
  28. package/esm2022/lib/services/entity-ref-registry.service.mjs +3 -3
  29. package/esm2022/lib/services/entity-ref-selection.service.mjs +27 -0
  30. package/esm2022/lib/services/entity-reference.service.mjs +168 -0
  31. package/esm2022/lib/services/field-registry.service.mjs +35 -30
  32. package/esm2022/lib/services/file-upload.service.mjs +89 -0
  33. package/esm2022/lib/services/lookup-registry.service.mjs +246 -0
  34. package/esm2022/lib/services/rbac.service.mjs +5 -11
  35. package/esm2022/lib/services/rules-evaluation.service.mjs +27 -0
  36. package/esm2022/lib/services/validator-registry.service.mjs +24 -7
  37. package/esm2022/lib/tokens/injection-tokens.mjs +88 -7
  38. package/esm2022/public-api.mjs +14 -5
  39. package/fesm2022/ngx-dynamic-entity.mjs +3985 -876
  40. package/fesm2022/ngx-dynamic-entity.mjs.map +1 -1
  41. package/lib/field-types/array-field.component.d.ts +22 -0
  42. package/lib/field-types/boolean-field.component.d.ts +18 -0
  43. package/lib/field-types/checkbox-field.component.d.ts +3 -2
  44. package/lib/field-types/currency-field.component.d.ts +17 -0
  45. package/lib/field-types/date-field.component.d.ts +3 -2
  46. package/lib/field-types/dropdown-field.component.d.ts +24 -4
  47. package/lib/field-types/email-field.component.d.ts +15 -0
  48. package/lib/field-types/entity-ref-field.component.d.ts +24 -11
  49. package/lib/field-types/file-field.component.d.ts +25 -0
  50. package/lib/field-types/group-field.component.d.ts +17 -0
  51. package/lib/field-types/image-field.component.d.ts +30 -0
  52. package/lib/field-types/month-year-field.component.d.ts +28 -0
  53. package/lib/field-types/multi-select-field.component.d.ts +18 -4
  54. package/lib/field-types/number-field.component.d.ts +5 -2
  55. package/lib/field-types/password-field.component.d.ts +17 -0
  56. package/lib/field-types/radio-field.component.d.ts +33 -0
  57. package/lib/field-types/text-field.component.d.ts +5 -3
  58. package/lib/field-types/textarea-field.component.d.ts +4 -2
  59. package/lib/form/dynamic-field/dynamic-field.component.d.ts +20 -7
  60. package/lib/form/dynamic-form.component.d.ts +111 -19
  61. package/lib/form/dynamic-record-form.component.d.ts +169 -0
  62. package/lib/providers/provide-field-types.d.ts +24 -0
  63. package/lib/providers/provide-ngx-dynamic-entity.d.ts +12 -7
  64. package/lib/services/cascade-data.service.d.ts +45 -0
  65. package/lib/services/config-source.service.d.ts +14 -0
  66. package/lib/services/entity-ref-cache.d.ts +27 -0
  67. package/lib/services/entity-ref-registry.service.d.ts +4 -3
  68. package/lib/services/entity-ref-selection.service.d.ts +24 -0
  69. package/lib/services/entity-reference.service.d.ts +49 -0
  70. package/lib/services/field-registry.service.d.ts +17 -7
  71. package/lib/services/file-upload.service.d.ts +27 -0
  72. package/lib/services/lookup-registry.service.d.ts +94 -0
  73. package/lib/services/rbac.service.d.ts +4 -9
  74. package/lib/services/rules-evaluation.service.d.ts +17 -0
  75. package/lib/services/validator-registry.service.d.ts +5 -4
  76. package/lib/tokens/injection-tokens.d.ts +90 -7
  77. package/package.json +14 -3
  78. package/public-api.d.ts +11 -4
  79. package/esm2022/lib/services/config.service.mjs +0 -58
  80. package/esm2022/lib/services/version.service.mjs +0 -40
  81. package/esm2022/lib/table/dynamic-table.component.mjs +0 -160
  82. package/lib/services/config.service.d.ts +0 -25
  83. package/lib/services/version.service.d.ts +0 -26
  84. package/lib/table/dynamic-table.component.d.ts +0 -56
@@ -1,35 +1,66 @@
1
1
  import { Component, Input } from '@angular/core';
2
2
  import { ReactiveFormsModule } from '@angular/forms';
3
+ import { resolveLabel } from '@dynamic-entity/core';
3
4
  import * as i0 from "@angular/core";
4
5
  import * as i1 from "@angular/forms";
5
- /** ADR-008: Shared field component contract — all 8 built-in types implement this. */
6
6
  export class TextFieldComponent {
7
7
  field;
8
8
  control;
9
9
  language = 'en';
10
10
  readonly = false;
11
11
  masked = false;
12
+ get label() {
13
+ return resolveLabel(this.field?.label, this.language);
14
+ }
15
+ get placeholder() {
16
+ return resolveLabel(this.field?.placeholder, this.language);
17
+ }
18
+ get errorMessage() {
19
+ if (!this.control || !this.control.errors || !this.control.touched)
20
+ return '';
21
+ const errs = this.control.errors;
22
+ if (errs['required'])
23
+ return 'This field is required.';
24
+ if (errs['email'])
25
+ return 'Please enter a valid email address.';
26
+ if (errs['minlength'])
27
+ return `Minimum ${errs['minlength'].requiredLength} characters required.`;
28
+ if (errs['maxlength'])
29
+ return `Maximum ${errs['maxlength'].requiredLength} characters allowed.`;
30
+ if (errs['pattern'])
31
+ return 'Invalid format.';
32
+ return 'Invalid value.';
33
+ }
12
34
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TextFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: TextFieldComponent, isStandalone: true, selector: "ngx-text-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
14
- <div class="ngx-field ngx-field--text" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
15
- <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
16
- @if (masked) {
17
- <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
18
- } @else if (readonly) {
19
- <span class="ngx-field__value">{{ control.value }}</span>
20
- } @else {
21
- <input
22
- class="ngx-field__input"
23
- type="text"
24
- [formControl]="$any(control)"
25
- [placeholder]="field.placeholder?.[language] || field.placeholder?.['en'] || ''"
26
- [attr.disabled]="field.disabled ? true : null"
27
- />
28
- @if (control.invalid && control.touched) {
29
- <span class="ngx-field__error">This field has an error</span>
30
- }
31
- }
32
- </div>
35
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: TextFieldComponent, isStandalone: true, selector: "ngx-text-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
36
+ <div
37
+ class="ngx-field ngx-field--text"
38
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type"
39
+ [class.ngx-field--readonly]="readonly"
40
+ [class.ngx-field--masked]="masked"
41
+ [class.ngx-field--invalid]="control && control.invalid && control.touched"
42
+ >
43
+ <label class="ngx-field__label" [attr.for]="field.id">{{ label }}@if (field.validators?.required) { <span class="ngx-field__req">*</span> }</label>
44
+ @if (masked) {
45
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
46
+ } @else if (readonly) {
47
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ control.value ?? '—' }}</span>
48
+ } @else {
49
+ <input
50
+ [id]="field.id"
51
+ type="text"
52
+ class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
53
+ [formControl]="$any(control)"
54
+ [placeholder]="placeholder"
55
+ [attr.disabled]="field.disabled ? true : null"
56
+ [attr.aria-invalid]="control.invalid && control.touched"
57
+ [attr.aria-describedby]="errorMessage ? field.id + '-error' : null"
58
+ />
59
+ @if (errorMessage) {
60
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'" [id]="field.id + '-error'" role="alert">{{ errorMessage }}</span>
61
+ }
62
+ }
63
+ </div>
33
64
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
34
65
  }
35
66
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TextFieldComponent, decorators: [{
@@ -38,26 +69,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
38
69
  selector: 'ngx-text-field',
39
70
  standalone: true,
40
71
  imports: [ReactiveFormsModule],
41
- template: `
42
- <div class="ngx-field ngx-field--text" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
43
- <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
44
- @if (masked) {
45
- <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
46
- } @else if (readonly) {
47
- <span class="ngx-field__value">{{ control.value }}</span>
48
- } @else {
49
- <input
50
- class="ngx-field__input"
51
- type="text"
52
- [formControl]="$any(control)"
53
- [placeholder]="field.placeholder?.[language] || field.placeholder?.['en'] || ''"
54
- [attr.disabled]="field.disabled ? true : null"
55
- />
56
- @if (control.invalid && control.touched) {
57
- <span class="ngx-field__error">This field has an error</span>
58
- }
59
- }
60
- </div>
72
+ template: `
73
+ <div
74
+ class="ngx-field ngx-field--text"
75
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type"
76
+ [class.ngx-field--readonly]="readonly"
77
+ [class.ngx-field--masked]="masked"
78
+ [class.ngx-field--invalid]="control && control.invalid && control.touched"
79
+ >
80
+ <label class="ngx-field__label" [attr.for]="field.id">{{ label }}@if (field.validators?.required) { <span class="ngx-field__req">*</span> }</label>
81
+ @if (masked) {
82
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
83
+ } @else if (readonly) {
84
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ control.value ?? '—' }}</span>
85
+ } @else {
86
+ <input
87
+ [id]="field.id"
88
+ type="text"
89
+ class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
90
+ [formControl]="$any(control)"
91
+ [placeholder]="placeholder"
92
+ [attr.disabled]="field.disabled ? true : null"
93
+ [attr.aria-invalid]="control.invalid && control.touched"
94
+ [attr.aria-describedby]="errorMessage ? field.id + '-error' : null"
95
+ />
96
+ @if (errorMessage) {
97
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'" [id]="field.id + '-error'" role="alert">{{ errorMessage }}</span>
98
+ }
99
+ }
100
+ </div>
61
101
  `,
62
102
  }]
63
103
  }], propDecorators: { field: [{
@@ -71,4 +111,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
71
111
  }], masked: [{
72
112
  type: Input
73
113
  }] } });
74
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2ZpZWxkLXR5cGVzL3RleHQtZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pELE9BQU8sRUFBbUIsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBR3RFLHNGQUFzRjtBQTJCdEYsTUFBTSxPQUFPLGtCQUFrQjtJQUNwQixLQUFLLENBQWU7SUFDcEIsT0FBTyxDQUFtQjtJQUMxQixRQUFRLEdBQVcsSUFBSSxDQUFDO0lBQ3hCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsTUFBTSxHQUFZLEtBQUssQ0FBQzt3R0FMdEIsa0JBQWtCOzRGQUFsQixrQkFBa0Isd0xBdEJuQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQlQsMkRBckJTLG1CQUFtQjs7NEZBdUJsQixrQkFBa0I7a0JBMUI5QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztvQkFDOUIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CVDtpQkFDRjs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgdHlwZSB7IEZpZWxkQ29uZmlnIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xuXG4vKiogQURSLTAwODogU2hhcmVkIGZpZWxkIGNvbXBvbmVudCBjb250cmFjdCDigJQgYWxsIDggYnVpbHQtaW4gdHlwZXMgaW1wbGVtZW50IHRoaXMuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtdGV4dC1maWVsZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwibmd4LWZpZWxkIG5neC1maWVsZC0tdGV4dFwiIFtjbGFzcy5uZ3gtZmllbGQtLXJlYWRvbmx5XT1cInJlYWRvbmx5XCIgW2NsYXNzLm5neC1maWVsZC0tbWFza2VkXT1cIm1hc2tlZFwiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwibmd4LWZpZWxkX19sYWJlbFwiPnt7IGZpZWxkLmxhYmVsW2xhbmd1YWdlXSB8fCBmaWVsZC5sYWJlbFsnZW4nXSB9fTwvbGFiZWw+XG4gICAgICBAaWYgKG1hc2tlZCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWUgbmd4LWZpZWxkX192YWx1ZS0tbWFza2VkXCI+WFhYWFhYWFhYPC9zcGFuPlxuICAgICAgfSBAZWxzZSBpZiAocmVhZG9ubHkpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCI+e3sgY29udHJvbC52YWx1ZSB9fTwvc3Bhbj5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBjbGFzcz1cIm5neC1maWVsZF9faW5wdXRcIlxuICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiJGFueShjb250cm9sKVwiXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cImZpZWxkLnBsYWNlaG9sZGVyPy5bbGFuZ3VhZ2VdIHx8IGZpZWxkLnBsYWNlaG9sZGVyPy5bJ2VuJ10gfHwgJydcIlxuICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cImZpZWxkLmRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIlxuICAgICAgICAvPlxuICAgICAgICBAaWYgKGNvbnRyb2wuaW52YWxpZCAmJiBjb250cm9sLnRvdWNoZWQpIHtcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fZXJyb3JcIj5UaGlzIGZpZWxkIGhhcyBhbiBlcnJvcjwvc3Bhbj5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBUZXh0RmllbGRDb21wb25lbnQge1xuICBASW5wdXQoKSBmaWVsZCE6IEZpZWxkQ29uZmlnO1xuICBASW5wdXQoKSBjb250cm9sITogQWJzdHJhY3RDb250cm9sO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgbWFza2VkOiBib29sZWFuID0gZmFsc2U7XG59XG4iXX0=
114
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dC1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2ZpZWxkLXR5cGVzL3RleHQtZmllbGQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pELE9BQU8sRUFBbUIsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7OztBQXFDcEQsTUFBTSxPQUFPLGtCQUFrQjtJQUNwQixLQUFLLENBQXFCO0lBQzFCLE9BQU8sQ0FBbUI7SUFDMUIsUUFBUSxHQUFXLElBQUksQ0FBQztJQUN4QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLE1BQU0sR0FBWSxLQUFLLENBQUM7SUFFakMsSUFBSSxLQUFLO1FBQ1AsT0FBTyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRCxJQUFJLFdBQVc7UUFDYixPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVELElBQUksWUFBWTtRQUNkLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU87WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUM5RSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUNqQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUM7WUFBRSxPQUFPLHlCQUF5QixDQUFDO1FBQ3ZELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUFFLE9BQU8scUNBQXFDLENBQUM7UUFDaEUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQUUsT0FBTyxXQUFXLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxjQUFjLHVCQUF1QixDQUFDO1FBQ2pHLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUFFLE9BQU8sV0FBVyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsY0FBYyxzQkFBc0IsQ0FBQztRQUNoRyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUM7WUFBRSxPQUFPLGlCQUFpQixDQUFDO1FBQzlDLE9BQU8sZ0JBQWdCLENBQUM7SUFDMUIsQ0FBQzt3R0F4QlUsa0JBQWtCOzRGQUFsQixrQkFBa0Isd0xBL0JuQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2QlQsMkRBOUJTLG1CQUFtQjs7NEZBZ0NsQixrQkFBa0I7a0JBbkM5QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztvQkFDOUIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZCVDtpQkFDRjs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHR5cGUgeyBOZXN0ZWRGaWVsZENvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcclxuaW1wb3J0IHsgcmVzb2x2ZUxhYmVsIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduZ3gtdGV4dC1maWVsZCcsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbUmVhY3RpdmVGb3Jtc01vZHVsZV0sXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxkaXZcclxuICAgICAgY2xhc3M9XCJuZ3gtZmllbGQgbmd4LWZpZWxkLS10ZXh0XCJcclxuICAgICAgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZFwiIFthdHRyLmRhdGEtZmllbGQtdHlwZV09XCJmaWVsZC50eXBlXCJcclxuICAgICAgW2NsYXNzLm5neC1maWVsZC0tcmVhZG9ubHldPVwicmVhZG9ubHlcIlxyXG4gICAgICBbY2xhc3Mubmd4LWZpZWxkLS1tYXNrZWRdPVwibWFza2VkXCJcclxuICAgICAgW2NsYXNzLm5neC1maWVsZC0taW52YWxpZF09XCJjb250cm9sICYmIGNvbnRyb2wuaW52YWxpZCAmJiBjb250cm9sLnRvdWNoZWRcIlxyXG4gICAgPlxyXG4gICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX2xhYmVsXCIgW2F0dHIuZm9yXT1cImZpZWxkLmlkXCI+e3sgbGFiZWwgfX1AaWYgKGZpZWxkLnZhbGlkYXRvcnM/LnJlcXVpcmVkKSB7IDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX19yZXFcIj4qPC9zcGFuPiB9PC9sYWJlbD5cclxuICAgICAgQGlmIChtYXNrZWQpIHtcclxuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWUgbmd4LWZpZWxkX192YWx1ZS0tbWFza2VkXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctbWFza2VkJ1wiPlhYWFhYWFhYWDwvc3Bhbj5cclxuICAgICAgfSBAZWxzZSBpZiAocmVhZG9ubHkpIHtcclxuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWVcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy12YWx1ZSdcIj57eyBjb250cm9sLnZhbHVlID8/ICfigJQnIH19PC9zcGFuPlxyXG4gICAgICB9IEBlbHNlIHtcclxuICAgICAgICA8aW5wdXRcclxuICAgICAgICAgIFtpZF09XCJmaWVsZC5pZFwiXHJcbiAgICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgICBjbGFzcz1cIm5neC1maWVsZF9faW5wdXRcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy1pbnB1dCdcIlxyXG4gICAgICAgICAgW2Zvcm1Db250cm9sXT1cIiRhbnkoY29udHJvbClcIlxyXG4gICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcclxuICAgICAgICAgIFthdHRyLmRpc2FibGVkXT1cImZpZWxkLmRpc2FibGVkID8gdHJ1ZSA6IG51bGxcIlxyXG4gICAgICAgICAgW2F0dHIuYXJpYS1pbnZhbGlkXT1cImNvbnRyb2wuaW52YWxpZCAmJiBjb250cm9sLnRvdWNoZWRcIlxyXG4gICAgICAgICAgW2F0dHIuYXJpYS1kZXNjcmliZWRieV09XCJlcnJvck1lc3NhZ2UgPyBmaWVsZC5pZCArICctZXJyb3InIDogbnVsbFwiXHJcbiAgICAgICAgLz5cclxuICAgICAgICBAaWYgKGVycm9yTWVzc2FnZSkge1xyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCIgW2F0dHIuZGF0YS10ZXN0aWRdPVwiJ2ZpZWxkLScgKyBmaWVsZC5pZCArICctZXJyb3InXCIgW2lkXT1cImZpZWxkLmlkICsgJy1lcnJvcidcIiByb2xlPVwiYWxlcnRcIj57eyBlcnJvck1lc3NhZ2UgfX08L3NwYW4+XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICBgLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVGV4dEZpZWxkQ29tcG9uZW50IHtcclxuICBASW5wdXQoKSBmaWVsZCE6IE5lc3RlZEZpZWxkQ29uZmlnO1xyXG4gIEBJbnB1dCgpIGNvbnRyb2whOiBBYnN0cmFjdENvbnRyb2w7XHJcbiAgQElucHV0KCkgbGFuZ3VhZ2U6IHN0cmluZyA9ICdlbic7XHJcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBtYXNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgZ2V0IGxhYmVsKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gcmVzb2x2ZUxhYmVsKHRoaXMuZmllbGQ/LmxhYmVsLCB0aGlzLmxhbmd1YWdlKTtcclxuICB9XHJcblxyXG4gIGdldCBwbGFjZWhvbGRlcigpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHJlc29sdmVMYWJlbCh0aGlzLmZpZWxkPy5wbGFjZWhvbGRlciwgdGhpcy5sYW5ndWFnZSk7XHJcbiAgfVxyXG5cclxuICBnZXQgZXJyb3JNZXNzYWdlKCk6IHN0cmluZyB7XHJcbiAgICBpZiAoIXRoaXMuY29udHJvbCB8fCAhdGhpcy5jb250cm9sLmVycm9ycyB8fCAhdGhpcy5jb250cm9sLnRvdWNoZWQpIHJldHVybiAnJztcclxuICAgIGNvbnN0IGVycnMgPSB0aGlzLmNvbnRyb2wuZXJyb3JzO1xyXG4gICAgaWYgKGVycnNbJ3JlcXVpcmVkJ10pIHJldHVybiAnVGhpcyBmaWVsZCBpcyByZXF1aXJlZC4nO1xyXG4gICAgaWYgKGVycnNbJ2VtYWlsJ10pIHJldHVybiAnUGxlYXNlIGVudGVyIGEgdmFsaWQgZW1haWwgYWRkcmVzcy4nO1xyXG4gICAgaWYgKGVycnNbJ21pbmxlbmd0aCddKSByZXR1cm4gYE1pbmltdW0gJHtlcnJzWydtaW5sZW5ndGgnXS5yZXF1aXJlZExlbmd0aH0gY2hhcmFjdGVycyByZXF1aXJlZC5gO1xyXG4gICAgaWYgKGVycnNbJ21heGxlbmd0aCddKSByZXR1cm4gYE1heGltdW0gJHtlcnJzWydtYXhsZW5ndGgnXS5yZXF1aXJlZExlbmd0aH0gY2hhcmFjdGVycyBhbGxvd2VkLmA7XHJcbiAgICBpZiAoZXJyc1sncGF0dGVybiddKSByZXR1cm4gJ0ludmFsaWQgZm9ybWF0Lic7XHJcbiAgICByZXR1cm4gJ0ludmFsaWQgdmFsdWUuJztcclxuICB9XHJcbn1cclxuIl19
@@ -1,5 +1,6 @@
1
1
  import { Component, Input } from '@angular/core';
2
2
  import { ReactiveFormsModule } from '@angular/forms';
3
+ import { resolveLabel } from '@dynamic-entity/core';
3
4
  import * as i0 from "@angular/core";
4
5
  import * as i1 from "@angular/forms";
5
6
  export class TextareaFieldComponent {
@@ -8,27 +9,35 @@ export class TextareaFieldComponent {
8
9
  language = 'en';
9
10
  readonly = false;
10
11
  masked = false;
12
+ get label() {
13
+ return resolveLabel(this.field?.label, this.language);
14
+ }
15
+ get placeholder() {
16
+ return resolveLabel(this.field?.placeholder, this.language);
17
+ }
11
18
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TextareaFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: TextareaFieldComponent, isStandalone: true, selector: "ngx-textarea-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
13
- <div class="ngx-field ngx-field--textarea" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
14
- <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
15
- @if (masked) {
16
- <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
17
- } @else if (readonly) {
18
- <span class="ngx-field__value">{{ control.value }}</span>
19
- } @else {
20
- <textarea
21
- class="ngx-field__input"
22
- [formControl]="$any(control)"
23
- [placeholder]="field.placeholder?.[language] || field.placeholder?.['en'] || ''"
24
- [attr.disabled]="field.disabled ? true : null"
25
- rows="3"
26
- ></textarea>
27
- @if (control.invalid && control.touched) {
28
- <span class="ngx-field__error">This field has an error</span>
29
- }
30
- }
31
- </div>
19
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: TextareaFieldComponent, isStandalone: true, selector: "ngx-textarea-field", inputs: { field: "field", control: "control", language: "language", readonly: "readonly", masked: "masked" }, ngImport: i0, template: `
20
+ <div class="ngx-field ngx-field--textarea"
21
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
22
+ <label class="ngx-field__label" [attr.for]="field.id">{{ label }}</label>
23
+ @if (masked) {
24
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
25
+ } @else if (readonly) {
26
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ control.value }}</span>
27
+ } @else {
28
+ <textarea
29
+ [id]="field.id"
30
+ class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
31
+ [formControl]="$any(control)"
32
+ [placeholder]="placeholder"
33
+ [attr.disabled]="field.disabled ? true : null"
34
+ rows="3"
35
+ ></textarea>
36
+ @if (control.invalid && control.touched) {
37
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">This field has an error</span>
38
+ }
39
+ }
40
+ </div>
32
41
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
33
42
  }
34
43
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TextareaFieldComponent, decorators: [{
@@ -37,26 +46,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
37
46
  selector: 'ngx-textarea-field',
38
47
  standalone: true,
39
48
  imports: [ReactiveFormsModule],
40
- template: `
41
- <div class="ngx-field ngx-field--textarea" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
42
- <label class="ngx-field__label">{{ field.label[language] || field.label['en'] }}</label>
43
- @if (masked) {
44
- <span class="ngx-field__value ngx-field__value--masked">XXXXXXXXX</span>
45
- } @else if (readonly) {
46
- <span class="ngx-field__value">{{ control.value }}</span>
47
- } @else {
48
- <textarea
49
- class="ngx-field__input"
50
- [formControl]="$any(control)"
51
- [placeholder]="field.placeholder?.[language] || field.placeholder?.['en'] || ''"
52
- [attr.disabled]="field.disabled ? true : null"
53
- rows="3"
54
- ></textarea>
55
- @if (control.invalid && control.touched) {
56
- <span class="ngx-field__error">This field has an error</span>
57
- }
58
- }
59
- </div>
49
+ template: `
50
+ <div class="ngx-field ngx-field--textarea"
51
+ [attr.data-testid]="'field-' + field.id" [attr.data-field-type]="field.type" [class.ngx-field--readonly]="readonly" [class.ngx-field--masked]="masked">
52
+ <label class="ngx-field__label" [attr.for]="field.id">{{ label }}</label>
53
+ @if (masked) {
54
+ <span class="ngx-field__value ngx-field__value--masked" [attr.data-testid]="'field-' + field.id + '-masked'">XXXXXXXXX</span>
55
+ } @else if (readonly) {
56
+ <span class="ngx-field__value" [attr.data-testid]="'field-' + field.id + '-value'">{{ control.value }}</span>
57
+ } @else {
58
+ <textarea
59
+ [id]="field.id"
60
+ class="ngx-field__input" [attr.data-testid]="'field-' + field.id + '-input'"
61
+ [formControl]="$any(control)"
62
+ [placeholder]="placeholder"
63
+ [attr.disabled]="field.disabled ? true : null"
64
+ rows="3"
65
+ ></textarea>
66
+ @if (control.invalid && control.touched) {
67
+ <span class="ngx-field__error" [attr.data-testid]="'field-' + field.id + '-error'">This field has an error</span>
68
+ }
69
+ }
70
+ </div>
60
71
  `,
61
72
  }]
62
73
  }], propDecorators: { field: [{
@@ -70,4 +81,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
70
81
  }], masked: [{
71
82
  type: Input
72
83
  }] } });
73
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dGFyZWEtZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9maWVsZC10eXBlcy90ZXh0YXJlYS1maWVsZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFtQixtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7QUE2QnRFLE1BQU0sT0FBTyxzQkFBc0I7SUFDeEIsS0FBSyxDQUFlO0lBQ3BCLE9BQU8sQ0FBbUI7SUFDMUIsUUFBUSxHQUFXLElBQUksQ0FBQztJQUN4QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLE1BQU0sR0FBWSxLQUFLLENBQUM7d0dBTHRCLHNCQUFzQjs0RkFBdEIsc0JBQXNCLDRMQXRCdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JULDJEQXJCUyxtQkFBbUI7OzRGQXVCbEIsc0JBQXNCO2tCQTFCbEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsb0JBQW9CO29CQUM5QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLENBQUMsbUJBQW1CLENBQUM7b0JBQzlCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQlQ7aUJBQ0Y7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHR5cGUgeyBGaWVsZENvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LXRleHRhcmVhLWZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1JlYWN0aXZlRm9ybXNNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJuZ3gtZmllbGQgbmd4LWZpZWxkLS10ZXh0YXJlYVwiIFtjbGFzcy5uZ3gtZmllbGQtLXJlYWRvbmx5XT1cInJlYWRvbmx5XCIgW2NsYXNzLm5neC1maWVsZC0tbWFza2VkXT1cIm1hc2tlZFwiPlxuICAgICAgPGxhYmVsIGNsYXNzPVwibmd4LWZpZWxkX19sYWJlbFwiPnt7IGZpZWxkLmxhYmVsW2xhbmd1YWdlXSB8fCBmaWVsZC5sYWJlbFsnZW4nXSB9fTwvbGFiZWw+XG4gICAgICBAaWYgKG1hc2tlZCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fdmFsdWUgbmd4LWZpZWxkX192YWx1ZS0tbWFza2VkXCI+WFhYWFhYWFhYPC9zcGFuPlxuICAgICAgfSBAZWxzZSBpZiAocmVhZG9ubHkpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX3ZhbHVlXCI+e3sgY29udHJvbC52YWx1ZSB9fTwvc3Bhbj5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8dGV4dGFyZWFcbiAgICAgICAgICBjbGFzcz1cIm5neC1maWVsZF9faW5wdXRcIlxuICAgICAgICAgIFtmb3JtQ29udHJvbF09XCIkYW55KGNvbnRyb2wpXCJcbiAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiZmllbGQucGxhY2Vob2xkZXI/LltsYW5ndWFnZV0gfHwgZmllbGQucGxhY2Vob2xkZXI/LlsnZW4nXSB8fCAnJ1wiXG4gICAgICAgICAgW2F0dHIuZGlzYWJsZWRdPVwiZmllbGQuZGlzYWJsZWQgPyB0cnVlIDogbnVsbFwiXG4gICAgICAgICAgcm93cz1cIjNcIlxuICAgICAgICA+PC90ZXh0YXJlYT5cbiAgICAgICAgQGlmIChjb250cm9sLmludmFsaWQgJiYgY29udHJvbC50b3VjaGVkKSB7XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZ3gtZmllbGRfX2Vycm9yXCI+VGhpcyBmaWVsZCBoYXMgYW4gZXJyb3I8L3NwYW4+XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbn0pXG5leHBvcnQgY2xhc3MgVGV4dGFyZWFGaWVsZENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGZpZWxkITogRmllbGRDb25maWc7XG4gIEBJbnB1dCgpIGNvbnRyb2whOiBBYnN0cmFjdENvbnRyb2w7XG4gIEBJbnB1dCgpIGxhbmd1YWdlOiBzdHJpbmcgPSAnZW4nO1xuICBASW5wdXQoKSByZWFkb25seTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBtYXNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbn1cbiJdfQ==
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4dGFyZWEtZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9maWVsZC10eXBlcy90ZXh0YXJlYS1maWVsZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakQsT0FBTyxFQUFtQixtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXRFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7O0FBOEJwRCxNQUFNLE9BQU8sc0JBQXNCO0lBQ3hCLEtBQUssQ0FBcUI7SUFDMUIsT0FBTyxDQUFtQjtJQUMxQixRQUFRLEdBQVcsSUFBSSxDQUFDO0lBQ3hCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsTUFBTSxHQUFZLEtBQUssQ0FBQztJQUVqQyxJQUFJLEtBQUs7UUFDUCxPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELElBQUksV0FBVztRQUNiLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5RCxDQUFDO3dHQWJVLHNCQUFzQjs0RkFBdEIsc0JBQXNCLDRMQXhCdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQlQsMkRBdkJTLG1CQUFtQjs7NEZBeUJsQixzQkFBc0I7a0JBNUJsQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxvQkFBb0I7b0JBQzlCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixPQUFPLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztvQkFDOUIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JUO2lCQUNGOzhCQUVVLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgdHlwZSB7IE5lc3RlZEZpZWxkQ29uZmlnIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xyXG5pbXBvcnQgeyByZXNvbHZlTGFiZWwgfSBmcm9tICdAZHluYW1pYy1lbnRpdHkvY29yZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25neC10ZXh0YXJlYS1maWVsZCcsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbUmVhY3RpdmVGb3Jtc01vZHVsZV0sXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxkaXYgY2xhc3M9XCJuZ3gtZmllbGQgbmd4LWZpZWxkLS10ZXh0YXJlYVwiXHJcbiAgICAgIFthdHRyLmRhdGEtdGVzdGlkXT1cIidmaWVsZC0nICsgZmllbGQuaWRcIiBbYXR0ci5kYXRhLWZpZWxkLXR5cGVdPVwiZmllbGQudHlwZVwiIFtjbGFzcy5uZ3gtZmllbGQtLXJlYWRvbmx5XT1cInJlYWRvbmx5XCIgW2NsYXNzLm5neC1maWVsZC0tbWFza2VkXT1cIm1hc2tlZFwiPlxyXG4gICAgICA8bGFiZWwgY2xhc3M9XCJuZ3gtZmllbGRfX2xhYmVsXCIgW2F0dHIuZm9yXT1cImZpZWxkLmlkXCI+e3sgbGFiZWwgfX08L2xhYmVsPlxyXG4gICAgICBAaWYgKG1hc2tlZCkge1xyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZSBuZ3gtZmllbGRfX3ZhbHVlLS1tYXNrZWRcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy1tYXNrZWQnXCI+WFhYWFhYWFhYPC9zcGFuPlxyXG4gICAgICB9IEBlbHNlIGlmIChyZWFkb25seSkge1xyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwibmd4LWZpZWxkX192YWx1ZVwiIFthdHRyLmRhdGEtdGVzdGlkXT1cIidmaWVsZC0nICsgZmllbGQuaWQgKyAnLXZhbHVlJ1wiPnt7IGNvbnRyb2wudmFsdWUgfX08L3NwYW4+XHJcbiAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgIDx0ZXh0YXJlYVxyXG4gICAgICAgICAgW2lkXT1cImZpZWxkLmlkXCJcclxuICAgICAgICAgIGNsYXNzPVwibmd4LWZpZWxkX19pbnB1dFwiIFthdHRyLmRhdGEtdGVzdGlkXT1cIidmaWVsZC0nICsgZmllbGQuaWQgKyAnLWlucHV0J1wiXHJcbiAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiJGFueShjb250cm9sKVwiXHJcbiAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxyXG4gICAgICAgICAgW2F0dHIuZGlzYWJsZWRdPVwiZmllbGQuZGlzYWJsZWQgPyB0cnVlIDogbnVsbFwiXHJcbiAgICAgICAgICByb3dzPVwiM1wiXHJcbiAgICAgICAgPjwvdGV4dGFyZWE+XHJcbiAgICAgICAgQGlmIChjb250cm9sLmludmFsaWQgJiYgY29udHJvbC50b3VjaGVkKSB7XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1maWVsZF9fZXJyb3JcIiBbYXR0ci5kYXRhLXRlc3RpZF09XCInZmllbGQtJyArIGZpZWxkLmlkICsgJy1lcnJvcidcIj5UaGlzIGZpZWxkIGhhcyBhbiBlcnJvcjwvc3Bhbj5cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIDwvZGl2PlxyXG4gIGAsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUZXh0YXJlYUZpZWxkQ29tcG9uZW50IHtcclxuICBASW5wdXQoKSBmaWVsZCE6IE5lc3RlZEZpZWxkQ29uZmlnO1xyXG4gIEBJbnB1dCgpIGNvbnRyb2whOiBBYnN0cmFjdENvbnRyb2w7XHJcbiAgQElucHV0KCkgbGFuZ3VhZ2U6IHN0cmluZyA9ICdlbic7XHJcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSBtYXNrZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgZ2V0IGxhYmVsKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gcmVzb2x2ZUxhYmVsKHRoaXMuZmllbGQ/LmxhYmVsLCB0aGlzLmxhbmd1YWdlKTtcclxuICB9XHJcblxyXG4gIGdldCBwbGFjZWhvbGRlcigpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHJlc29sdmVMYWJlbCh0aGlzLmZpZWxkPy5wbGFjZWhvbGRlciwgdGhpcy5sYW5ndWFnZSk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
@@ -1,9 +1,10 @@
1
- import { Component, Input, ViewChild, ViewContainerRef, inject, } from '@angular/core';
1
+ import { Component, Input, ViewChild, ViewContainerRef, inject, isDevMode, } from '@angular/core';
2
+ import { findTab } from '@dynamic-entity/core';
2
3
  import { FieldRegistryService } from '../../services/field-registry.service';
3
4
  import { RbacService } from '../../services/rbac.service';
4
5
  import * as i0 from "@angular/core";
5
6
  /**
6
- * DynamicFieldComponent — mounts the correct field component for a given FieldConfig.
7
+ * DynamicFieldComponent — mounts the correct field component for a given NestedFieldConfig.
7
8
  * Uses ViewContainerRef.createComponent() and passes inputs via setInput() (ADR-008).
8
9
  * Never add field-type-specific logic here — this component must remain generic.
9
10
  *
@@ -14,13 +15,14 @@ export class DynamicFieldComponent {
14
15
  field;
15
16
  control;
16
17
  config;
18
+ currentTabId;
17
19
  language = 'en';
18
20
  readonly = false;
19
21
  userRoles = [];
20
22
  fieldHost;
21
23
  fieldRegistry = inject(FieldRegistryService);
22
24
  rbacService = inject(RbacService);
23
- mountedComponent = null;
25
+ componentRef = null;
24
26
  ngOnChanges(_changes) {
25
27
  this.mountField();
26
28
  }
@@ -28,37 +30,51 @@ export class DynamicFieldComponent {
28
30
  if (!this.field || !this.control)
29
31
  return;
30
32
  const ComponentClass = this.fieldRegistry.resolve(this.field.type);
31
- if (!ComponentClass)
33
+ if (!ComponentClass) {
34
+ this.warnUnresolved(this.field.type);
32
35
  return; // Unknown field type — render nothing
36
+ }
33
37
  // Determine masking for this specific field
34
- const tab = (this.config?.tabs || []).find(t => t.id === this.field.tab);
35
- const masked = this.rbacService.shouldMaskField(this.field, tab, this.config, this.userRoles);
38
+ const tab = this.currentTabId ? findTab(this.config?.tabs, this.currentTabId) : null;
39
+ const masked = this.rbacService.shouldMaskField(this.field, tab ?? undefined, this.config, this.userRoles);
36
40
  // Re-use existing component if same type, otherwise recreate
37
- if (this.mountedComponent && this.mountedComponent instanceof ComponentClass) {
38
- this.setInputs(this.mountedComponent, masked);
41
+ if (this.componentRef && this.componentRef.instance instanceof ComponentClass) {
42
+ this.setInputs(this.componentRef, masked);
39
43
  return;
40
44
  }
41
45
  this.fieldHost.clear();
42
- const ref = this.fieldHost.createComponent(ComponentClass);
43
- this.mountedComponent = ref.instance;
44
- this.setInputs(ref.instance, masked);
45
- ref.changeDetectorRef.markForCheck();
46
+ this.componentRef = this.fieldHost.createComponent(ComponentClass);
47
+ this.setInputs(this.componentRef, masked);
48
+ this.componentRef.changeDetectorRef.markForCheck();
49
+ }
50
+ /**
51
+ * Field types are opt-in (see `provideFieldTypes` / `provideBuiltInFieldTypes`), so an
52
+ * unregistered type renders nothing. Say so once per type in dev builds rather than
53
+ * leaving a silently blank slot.
54
+ */
55
+ warnUnresolved(type) {
56
+ if (!isDevMode() || DynamicFieldComponent.warnedTypes.has(type))
57
+ return;
58
+ DynamicFieldComponent.warnedTypes.add(type);
59
+ console.warn(`[ngx-dynamic-entity] No component registered for field type "${type}" — the field was not rendered. ` +
60
+ `Register it with provideFieldTypes({ '${type}': MyComponent }) or provideBuiltInFieldTypes().`);
46
61
  }
47
- /** Pass all 5 contract inputs via setInput() — uniform for all types (ADR-008) */
48
- setInputs(instance, masked) {
49
- if ('field' in instance)
50
- instance.field = this.field;
51
- if ('control' in instance)
52
- instance.control = this.control;
53
- if ('language' in instance)
54
- instance.language = this.language;
55
- if ('readonly' in instance)
56
- instance.readonly = this.readonly || !!this.field.readonly;
57
- if ('masked' in instance)
58
- instance.masked = masked;
62
+ static warnedTypes = new Set();
63
+ /**
64
+ * Pass all 5 contract inputs via ComponentRef.setInput() — uniform for all types (ADR-008).
65
+ * Must use setInput(), not property assignment: the field components declare inputs with
66
+ * definite assignment and no initializer, and the lib compiles with
67
+ * useDefineForClassFields:false, so `'field' in instance` is false until first set.
68
+ */
69
+ setInputs(ref, masked) {
70
+ ref.setInput('field', this.field);
71
+ ref.setInput('control', this.control);
72
+ ref.setInput('language', this.language);
73
+ ref.setInput('readonly', this.readonly || !!this.field.readonly);
74
+ ref.setInput('masked', masked);
59
75
  }
60
76
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
61
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DynamicFieldComponent, isStandalone: true, selector: "ngx-dynamic-field", inputs: { field: "field", control: "control", config: "config", language: "language", readonly: "readonly", userRoles: "userRoles" }, viewQueries: [{ propertyName: "fieldHost", first: true, predicate: ["fieldHost"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `<ng-container #fieldHost></ng-container>`, isInline: true });
77
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DynamicFieldComponent, isStandalone: true, selector: "ngx-dynamic-field", inputs: { field: "field", control: "control", config: "config", currentTabId: "currentTabId", language: "language", readonly: "readonly", userRoles: "userRoles" }, viewQueries: [{ propertyName: "fieldHost", first: true, predicate: ["fieldHost"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `<ng-container #fieldHost></ng-container>`, isInline: true });
62
78
  }
63
79
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicFieldComponent, decorators: [{
64
80
  type: Component,
@@ -73,6 +89,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
73
89
  type: Input
74
90
  }], config: [{
75
91
  type: Input
92
+ }], currentTabId: [{
93
+ type: Input
76
94
  }], language: [{
77
95
  type: Input
78
96
  }], readonly: [{
@@ -83,4 +101,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
83
101
  type: ViewChild,
84
102
  args: ['fieldHost', { read: ViewContainerRef, static: true }]
85
103
  }] } });
86
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2Zvcm0vZHluYW1pYy1maWVsZC9keW5hbWljLWZpZWxkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFHTCxTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2hCLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7O0FBRTFEOzs7Ozs7O0dBT0c7QUFNSCxNQUFNLE9BQU8scUJBQXFCO0lBQ3ZCLEtBQUssQ0FBZTtJQUNwQixPQUFPLENBQW1CO0lBQzFCLE1BQU0sQ0FBZ0I7SUFDdEIsUUFBUSxHQUFXLElBQUksQ0FBQztJQUN4QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLFNBQVMsR0FBYSxFQUFFLENBQUM7SUFHakIsU0FBUyxDQUFvQjtJQUU3QixhQUFhLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDN0MsV0FBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUUzQyxnQkFBZ0IsR0FBUSxJQUFJLENBQUM7SUFFckMsV0FBVyxDQUFDLFFBQXVCO1FBQ2pDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRU8sVUFBVTtRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUV6QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxjQUFjO1lBQUUsT0FBTyxDQUFDLHNDQUFzQztRQUVuRSw0Q0FBNEM7UUFDNUMsTUFBTSxHQUFHLEdBQTBCLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2hHLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTlGLDZEQUE2RDtRQUM3RCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLFlBQVksY0FBYyxFQUFFLENBQUM7WUFDN0UsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDOUMsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNyQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdkMsQ0FBQztJQUVELGtGQUFrRjtJQUMxRSxTQUFTLENBQUMsUUFBYSxFQUFFLE1BQWU7UUFDOUMsSUFBSSxPQUFPLElBQUksUUFBUTtZQUFFLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNyRCxJQUFJLFNBQVMsSUFBSSxRQUFRO1lBQUUsUUFBUSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQzNELElBQUksVUFBVSxJQUFJLFFBQVE7WUFBRSxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUQsSUFBSSxVQUFVLElBQUksUUFBUTtZQUFFLFFBQVEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUM7UUFDdkYsSUFBSSxRQUFRLElBQUksUUFBUTtZQUFFLFFBQVEsQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3JELENBQUM7d0dBbERVLHFCQUFxQjs0RkFBckIscUJBQXFCLHNTQVFBLGdCQUFnQixnRUFWdEMsMENBQTBDOzs0RkFFekMscUJBQXFCO2tCQUxqQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxtQkFBbUI7b0JBQzdCLFVBQVUsRUFBRSxJQUFJO29CQUNoQixRQUFRLEVBQUUsMENBQTBDO2lCQUNyRDs4QkFFVSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFHVyxTQUFTO3NCQUR6QixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdDb250YWluZXJSZWYsXG4gIGluamVjdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgdHlwZSB7IEZpZWxkQ29uZmlnLCBFbnRpdHlDb25maWcsIFRhYkNvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcbmltcG9ydCB7IEZpZWxkUmVnaXN0cnlTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZmllbGQtcmVnaXN0cnkuc2VydmljZSc7XG5pbXBvcnQgeyBSYmFjU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JiYWMuc2VydmljZSc7XG5cbi8qKlxuICogRHluYW1pY0ZpZWxkQ29tcG9uZW50IOKAlCBtb3VudHMgdGhlIGNvcnJlY3QgZmllbGQgY29tcG9uZW50IGZvciBhIGdpdmVuIEZpZWxkQ29uZmlnLlxuICogVXNlcyBWaWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudCgpIGFuZCBwYXNzZXMgaW5wdXRzIHZpYSBzZXRJbnB1dCgpIChBRFItMDA4KS5cbiAqIE5ldmVyIGFkZCBmaWVsZC10eXBlLXNwZWNpZmljIGxvZ2ljIGhlcmUg4oCUIHRoaXMgY29tcG9uZW50IG11c3QgcmVtYWluIGdlbmVyaWMuXG4gKlxuICogVGhlIDUgaW5wdXRzIChmaWVsZCwgY29udHJvbCwgbGFuZ3VhZ2UsIHJlYWRvbmx5LCBtYXNrZWQpIGFyZSBwYXNzZWQgdG8gZXZlcnkgbW91bnRlZFxuICogY29tcG9uZW50IHVuaWZvcm1seSDigJQgbm8gc3BlY2lhbC1jYXNpbmcgcGVyIHR5cGUuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1keW5hbWljLWZpZWxkJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgdGVtcGxhdGU6IGA8bmctY29udGFpbmVyICNmaWVsZEhvc3Q+PC9uZy1jb250YWluZXI+YCxcbn0pXG5leHBvcnQgY2xhc3MgRHluYW1pY0ZpZWxkQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgZmllbGQhOiBGaWVsZENvbmZpZztcbiAgQElucHV0KCkgY29udHJvbCE6IEFic3RyYWN0Q29udHJvbDtcbiAgQElucHV0KCkgY29uZmlnITogRW50aXR5Q29uZmlnO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgdXNlclJvbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIEBWaWV3Q2hpbGQoJ2ZpZWxkSG9zdCcsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgcmVhZG9ubHkgZmllbGRIb3N0ITogVmlld0NvbnRhaW5lclJlZjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGZpZWxkUmVnaXN0cnkgPSBpbmplY3QoRmllbGRSZWdpc3RyeVNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJiYWNTZXJ2aWNlID0gaW5qZWN0KFJiYWNTZXJ2aWNlKTtcblxuICBwcml2YXRlIG1vdW50ZWRDb21wb25lbnQ6IGFueSA9IG51bGw7XG5cbiAgbmdPbkNoYW5nZXMoX2NoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICB0aGlzLm1vdW50RmllbGQoKTtcbiAgfVxuXG4gIHByaXZhdGUgbW91bnRGaWVsZCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZmllbGQgfHwgIXRoaXMuY29udHJvbCkgcmV0dXJuO1xuXG4gICAgY29uc3QgQ29tcG9uZW50Q2xhc3MgPSB0aGlzLmZpZWxkUmVnaXN0cnkucmVzb2x2ZSh0aGlzLmZpZWxkLnR5cGUpO1xuICAgIGlmICghQ29tcG9uZW50Q2xhc3MpIHJldHVybjsgLy8gVW5rbm93biBmaWVsZCB0eXBlIOKAlCByZW5kZXIgbm90aGluZ1xuXG4gICAgLy8gRGV0ZXJtaW5lIG1hc2tpbmcgZm9yIHRoaXMgc3BlY2lmaWMgZmllbGRcbiAgICBjb25zdCB0YWI6IFRhYkNvbmZpZyB8IHVuZGVmaW5lZCA9ICh0aGlzLmNvbmZpZz8udGFicyB8fCBbXSkuZmluZCh0ID0+IHQuaWQgPT09IHRoaXMuZmllbGQudGFiKTtcbiAgICBjb25zdCBtYXNrZWQgPSB0aGlzLnJiYWNTZXJ2aWNlLnNob3VsZE1hc2tGaWVsZCh0aGlzLmZpZWxkLCB0YWIsIHRoaXMuY29uZmlnLCB0aGlzLnVzZXJSb2xlcyk7XG5cbiAgICAvLyBSZS11c2UgZXhpc3RpbmcgY29tcG9uZW50IGlmIHNhbWUgdHlwZSwgb3RoZXJ3aXNlIHJlY3JlYXRlXG4gICAgaWYgKHRoaXMubW91bnRlZENvbXBvbmVudCAmJiB0aGlzLm1vdW50ZWRDb21wb25lbnQgaW5zdGFuY2VvZiBDb21wb25lbnRDbGFzcykge1xuICAgICAgdGhpcy5zZXRJbnB1dHModGhpcy5tb3VudGVkQ29tcG9uZW50LCBtYXNrZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZmllbGRIb3N0LmNsZWFyKCk7XG4gICAgY29uc3QgcmVmID0gdGhpcy5maWVsZEhvc3QuY3JlYXRlQ29tcG9uZW50KENvbXBvbmVudENsYXNzKTtcbiAgICB0aGlzLm1vdW50ZWRDb21wb25lbnQgPSByZWYuaW5zdGFuY2U7XG4gICAgdGhpcy5zZXRJbnB1dHMocmVmLmluc3RhbmNlLCBtYXNrZWQpO1xuICAgIHJlZi5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKiBQYXNzIGFsbCA1IGNvbnRyYWN0IGlucHV0cyB2aWEgc2V0SW5wdXQoKSDigJQgdW5pZm9ybSBmb3IgYWxsIHR5cGVzIChBRFItMDA4KSAqL1xuICBwcml2YXRlIHNldElucHV0cyhpbnN0YW5jZTogYW55LCBtYXNrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAoJ2ZpZWxkJyBpbiBpbnN0YW5jZSkgaW5zdGFuY2UuZmllbGQgPSB0aGlzLmZpZWxkO1xuICAgIGlmICgnY29udHJvbCcgaW4gaW5zdGFuY2UpIGluc3RhbmNlLmNvbnRyb2wgPSB0aGlzLmNvbnRyb2w7XG4gICAgaWYgKCdsYW5ndWFnZScgaW4gaW5zdGFuY2UpIGluc3RhbmNlLmxhbmd1YWdlID0gdGhpcy5sYW5ndWFnZTtcbiAgICBpZiAoJ3JlYWRvbmx5JyBpbiBpbnN0YW5jZSkgaW5zdGFuY2UucmVhZG9ubHkgPSB0aGlzLnJlYWRvbmx5IHx8ICEhdGhpcy5maWVsZC5yZWFkb25seTtcbiAgICBpZiAoJ21hc2tlZCcgaW4gaW5zdGFuY2UpIGluc3RhbmNlLm1hc2tlZCA9IG1hc2tlZDtcbiAgfVxufVxuIl19
104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2Zvcm0vZHluYW1pYy1maWVsZC9keW5hbWljLWZpZWxkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULEtBQUssRUFHTCxTQUFTLEVBQ1QsZ0JBQWdCLEVBQ2hCLE1BQU0sRUFDTixTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7QUFFMUQ7Ozs7Ozs7R0FPRztBQU1ILE1BQU0sT0FBTyxxQkFBcUI7SUFDdkIsS0FBSyxDQUFxQjtJQUMxQixPQUFPLENBQW1CO0lBQzFCLE1BQU0sQ0FBb0I7SUFDMUIsWUFBWSxDQUFVO0lBQ3RCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixTQUFTLEdBQWEsRUFBRSxDQUFDO0lBR2pCLFNBQVMsQ0FBb0I7SUFFN0IsYUFBYSxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQzdDLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFM0MsWUFBWSxHQUFpQyxJQUFJLENBQUM7SUFFMUQsV0FBVyxDQUFDLFFBQXVCO1FBQ2pDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRU8sVUFBVTtRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUV6QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckMsT0FBTyxDQUFDLHNDQUFzQztRQUNoRCxDQUFDO1FBRUQsNENBQTRDO1FBQzVDLE1BQU0sR0FBRyxHQUEyQixJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDN0csTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLElBQUksU0FBUyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTNHLDZEQUE2RDtRQUM3RCxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLFlBQVksY0FBYyxFQUFFLENBQUM7WUFDOUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3JELENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssY0FBYyxDQUFDLElBQVk7UUFDakMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQUUsT0FBTztRQUN4RSxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxJQUFJLENBQ1YsZ0VBQWdFLElBQUksa0NBQWtDO1lBQ3BHLHlDQUF5QyxJQUFJLGtEQUFrRCxDQUNsRyxDQUFDO0lBQ0osQ0FBQztJQUVPLE1BQU0sQ0FBVSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUV4RDs7Ozs7T0FLRztJQUNLLFNBQVMsQ0FBQyxHQUEwQixFQUFFLE1BQWU7UUFDM0QsR0FBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLEdBQUcsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN0QyxHQUFHLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRSxHQUFHLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNqQyxDQUFDO3dHQTFFVSxxQkFBcUI7NEZBQXJCLHFCQUFxQixvVUFTQSxnQkFBZ0IsZ0VBWHRDLDBDQUEwQzs7NEZBRXpDLHFCQUFxQjtrQkFMakMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsbUJBQW1CO29CQUM3QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsUUFBUSxFQUFFLDBDQUEwQztpQkFDckQ7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFHVyxTQUFTO3NCQUR6QixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsXHJcbiAgQ29tcG9uZW50UmVmLFxyXG4gIElucHV0LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIFZpZXdDaGlsZCxcclxuICBWaWV3Q29udGFpbmVyUmVmLFxyXG4gIGluamVjdCxcclxuICBpc0Rldk1vZGUsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHR5cGUgeyBOZXN0ZWRGaWVsZENvbmZpZywgRW50aXR5Rm9ybUNvbmZpZywgTmVzdGVkVGFiQ29uZmlnIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xyXG5pbXBvcnQgeyBmaW5kVGFiIH0gZnJvbSAnQGR5bmFtaWMtZW50aXR5L2NvcmUnO1xyXG5pbXBvcnQgeyBGaWVsZFJlZ2lzdHJ5U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2ZpZWxkLXJlZ2lzdHJ5LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBSYmFjU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JiYWMuc2VydmljZSc7XHJcblxyXG4vKipcclxuICogRHluYW1pY0ZpZWxkQ29tcG9uZW50IOKAlCBtb3VudHMgdGhlIGNvcnJlY3QgZmllbGQgY29tcG9uZW50IGZvciBhIGdpdmVuIE5lc3RlZEZpZWxkQ29uZmlnLlxyXG4gKiBVc2VzIFZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KCkgYW5kIHBhc3NlcyBpbnB1dHMgdmlhIHNldElucHV0KCkgKEFEUi0wMDgpLlxyXG4gKiBOZXZlciBhZGQgZmllbGQtdHlwZS1zcGVjaWZpYyBsb2dpYyBoZXJlIOKAlCB0aGlzIGNvbXBvbmVudCBtdXN0IHJlbWFpbiBnZW5lcmljLlxyXG4gKlxyXG4gKiBUaGUgNSBpbnB1dHMgKGZpZWxkLCBjb250cm9sLCBsYW5ndWFnZSwgcmVhZG9ubHksIG1hc2tlZCkgYXJlIHBhc3NlZCB0byBldmVyeSBtb3VudGVkXHJcbiAqIGNvbXBvbmVudCB1bmlmb3JtbHkg4oCUIG5vIHNwZWNpYWwtY2FzaW5nIHBlciB0eXBlLlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduZ3gtZHluYW1pYy1maWVsZCcsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICB0ZW1wbGF0ZTogYDxuZy1jb250YWluZXIgI2ZpZWxkSG9zdD48L25nLWNvbnRhaW5lcj5gLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRHluYW1pY0ZpZWxkQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcclxuICBASW5wdXQoKSBmaWVsZCE6IE5lc3RlZEZpZWxkQ29uZmlnO1xyXG4gIEBJbnB1dCgpIGNvbnRyb2whOiBBYnN0cmFjdENvbnRyb2w7XHJcbiAgQElucHV0KCkgY29uZmlnITogRW50aXR5Rm9ybUNvbmZpZztcclxuICBASW5wdXQoKSBjdXJyZW50VGFiSWQ/OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgbGFuZ3VhZ2U6IHN0cmluZyA9ICdlbic7XHJcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSB1c2VyUm9sZXM6IHN0cmluZ1tdID0gW107XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2ZpZWxkSG9zdCcsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pXHJcbiAgcHJpdmF0ZSByZWFkb25seSBmaWVsZEhvc3QhOiBWaWV3Q29udGFpbmVyUmVmO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IGZpZWxkUmVnaXN0cnkgPSBpbmplY3QoRmllbGRSZWdpc3RyeVNlcnZpY2UpO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgcmJhY1NlcnZpY2UgPSBpbmplY3QoUmJhY1NlcnZpY2UpO1xyXG5cclxuICBwcml2YXRlIGNvbXBvbmVudFJlZjogQ29tcG9uZW50UmVmPHVua25vd24+IHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIG5nT25DaGFuZ2VzKF9jaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICB0aGlzLm1vdW50RmllbGQoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbW91bnRGaWVsZCgpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5maWVsZCB8fCAhdGhpcy5jb250cm9sKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgQ29tcG9uZW50Q2xhc3MgPSB0aGlzLmZpZWxkUmVnaXN0cnkucmVzb2x2ZSh0aGlzLmZpZWxkLnR5cGUpO1xyXG4gICAgaWYgKCFDb21wb25lbnRDbGFzcykge1xyXG4gICAgICB0aGlzLndhcm5VbnJlc29sdmVkKHRoaXMuZmllbGQudHlwZSk7XHJcbiAgICAgIHJldHVybjsgLy8gVW5rbm93biBmaWVsZCB0eXBlIOKAlCByZW5kZXIgbm90aGluZ1xyXG4gICAgfVxyXG5cclxuICAgIC8vIERldGVybWluZSBtYXNraW5nIGZvciB0aGlzIHNwZWNpZmljIGZpZWxkXHJcbiAgICBjb25zdCB0YWI6IE5lc3RlZFRhYkNvbmZpZyB8IG51bGwgPSB0aGlzLmN1cnJlbnRUYWJJZCA/IGZpbmRUYWIodGhpcy5jb25maWc/LnRhYnMsIHRoaXMuY3VycmVudFRhYklkKSA6IG51bGw7XHJcbiAgICBjb25zdCBtYXNrZWQgPSB0aGlzLnJiYWNTZXJ2aWNlLnNob3VsZE1hc2tGaWVsZCh0aGlzLmZpZWxkLCB0YWIgPz8gdW5kZWZpbmVkLCB0aGlzLmNvbmZpZywgdGhpcy51c2VyUm9sZXMpO1xyXG5cclxuICAgIC8vIFJlLXVzZSBleGlzdGluZyBjb21wb25lbnQgaWYgc2FtZSB0eXBlLCBvdGhlcndpc2UgcmVjcmVhdGVcclxuICAgIGlmICh0aGlzLmNvbXBvbmVudFJlZiAmJiB0aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZSBpbnN0YW5jZW9mIENvbXBvbmVudENsYXNzKSB7XHJcbiAgICAgIHRoaXMuc2V0SW5wdXRzKHRoaXMuY29tcG9uZW50UmVmLCBtYXNrZWQpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5maWVsZEhvc3QuY2xlYXIoKTtcclxuICAgIHRoaXMuY29tcG9uZW50UmVmID0gdGhpcy5maWVsZEhvc3QuY3JlYXRlQ29tcG9uZW50KENvbXBvbmVudENsYXNzKTtcclxuICAgIHRoaXMuc2V0SW5wdXRzKHRoaXMuY29tcG9uZW50UmVmLCBtYXNrZWQpO1xyXG4gICAgdGhpcy5jb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGaWVsZCB0eXBlcyBhcmUgb3B0LWluIChzZWUgYHByb3ZpZGVGaWVsZFR5cGVzYCAvIGBwcm92aWRlQnVpbHRJbkZpZWxkVHlwZXNgKSwgc28gYW5cclxuICAgKiB1bnJlZ2lzdGVyZWQgdHlwZSByZW5kZXJzIG5vdGhpbmcuIFNheSBzbyBvbmNlIHBlciB0eXBlIGluIGRldiBidWlsZHMgcmF0aGVyIHRoYW5cclxuICAgKiBsZWF2aW5nIGEgc2lsZW50bHkgYmxhbmsgc2xvdC5cclxuICAgKi9cclxuICBwcml2YXRlIHdhcm5VbnJlc29sdmVkKHR5cGU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgaWYgKCFpc0Rldk1vZGUoKSB8fCBEeW5hbWljRmllbGRDb21wb25lbnQud2FybmVkVHlwZXMuaGFzKHR5cGUpKSByZXR1cm47XHJcbiAgICBEeW5hbWljRmllbGRDb21wb25lbnQud2FybmVkVHlwZXMuYWRkKHR5cGUpO1xyXG4gICAgY29uc29sZS53YXJuKFxyXG4gICAgICBgW25neC1keW5hbWljLWVudGl0eV0gTm8gY29tcG9uZW50IHJlZ2lzdGVyZWQgZm9yIGZpZWxkIHR5cGUgXCIke3R5cGV9XCIg4oCUIHRoZSBmaWVsZCB3YXMgbm90IHJlbmRlcmVkLiBgICtcclxuICAgICAgICBgUmVnaXN0ZXIgaXQgd2l0aCBwcm92aWRlRmllbGRUeXBlcyh7ICcke3R5cGV9JzogTXlDb21wb25lbnQgfSkgb3IgcHJvdmlkZUJ1aWx0SW5GaWVsZFR5cGVzKCkuYCxcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSB3YXJuZWRUeXBlcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xyXG5cclxuICAvKipcclxuICAgKiBQYXNzIGFsbCA1IGNvbnRyYWN0IGlucHV0cyB2aWEgQ29tcG9uZW50UmVmLnNldElucHV0KCkg4oCUIHVuaWZvcm0gZm9yIGFsbCB0eXBlcyAoQURSLTAwOCkuXHJcbiAgICogTXVzdCB1c2Ugc2V0SW5wdXQoKSwgbm90IHByb3BlcnR5IGFzc2lnbm1lbnQ6IHRoZSBmaWVsZCBjb21wb25lbnRzIGRlY2xhcmUgaW5wdXRzIHdpdGhcclxuICAgKiBkZWZpbml0ZSBhc3NpZ25tZW50IGFuZCBubyBpbml0aWFsaXplciwgYW5kIHRoZSBsaWIgY29tcGlsZXMgd2l0aFxyXG4gICAqIHVzZURlZmluZUZvckNsYXNzRmllbGRzOmZhbHNlLCBzbyBgJ2ZpZWxkJyBpbiBpbnN0YW5jZWAgaXMgZmFsc2UgdW50aWwgZmlyc3Qgc2V0LlxyXG4gICAqL1xyXG4gIHByaXZhdGUgc2V0SW5wdXRzKHJlZjogQ29tcG9uZW50UmVmPHVua25vd24+LCBtYXNrZWQ6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIHJlZi5zZXRJbnB1dCgnZmllbGQnLCB0aGlzLmZpZWxkKTtcclxuICAgIHJlZi5zZXRJbnB1dCgnY29udHJvbCcsIHRoaXMuY29udHJvbCk7XHJcbiAgICByZWYuc2V0SW5wdXQoJ2xhbmd1YWdlJywgdGhpcy5sYW5ndWFnZSk7XHJcbiAgICByZWYuc2V0SW5wdXQoJ3JlYWRvbmx5JywgdGhpcy5yZWFkb25seSB8fCAhIXRoaXMuZmllbGQucmVhZG9ubHkpO1xyXG4gICAgcmVmLnNldElucHV0KCdtYXNrZWQnLCBtYXNrZWQpO1xyXG4gIH1cclxufVxyXG4iXX0=