ngx-dynamic-entity 1.3.0 → 1.4.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 (91) hide show
  1. package/README.md +14 -0
  2. package/fesm2022/ngx-dynamic-entity.mjs +228 -150
  3. package/fesm2022/ngx-dynamic-entity.mjs.map +1 -1
  4. package/package.json +6 -7
  5. package/types/ngx-dynamic-entity.d.ts +1719 -0
  6. package/esm2022/lib/field-types/array-field.component.mjs +0 -168
  7. package/esm2022/lib/field-types/boolean-field.component.mjs +0 -101
  8. package/esm2022/lib/field-types/checkbox-field.component.mjs +0 -82
  9. package/esm2022/lib/field-types/currency-field.component.mjs +0 -102
  10. package/esm2022/lib/field-types/date-field.component.mjs +0 -91
  11. package/esm2022/lib/field-types/date-time-field.component.mjs +0 -138
  12. package/esm2022/lib/field-types/dropdown-field.component.mjs +0 -176
  13. package/esm2022/lib/field-types/email-field.component.mjs +0 -102
  14. package/esm2022/lib/field-types/entity-ref-field.component.mjs +0 -195
  15. package/esm2022/lib/field-types/field-component.contract.mjs +0 -2
  16. package/esm2022/lib/field-types/file-field.component.mjs +0 -157
  17. package/esm2022/lib/field-types/group-field.component.mjs +0 -89
  18. package/esm2022/lib/field-types/image-field.component.mjs +0 -169
  19. package/esm2022/lib/field-types/month-year-field.component.mjs +0 -152
  20. package/esm2022/lib/field-types/multi-select-field.component.mjs +0 -146
  21. package/esm2022/lib/field-types/number-field.component.mjs +0 -112
  22. package/esm2022/lib/field-types/password-field.component.mjs +0 -110
  23. package/esm2022/lib/field-types/radio-field.component.mjs +0 -153
  24. package/esm2022/lib/field-types/text-field.component.mjs +0 -121
  25. package/esm2022/lib/field-types/textarea-field.component.mjs +0 -85
  26. package/esm2022/lib/field-types/time-field.component.mjs +0 -96
  27. package/esm2022/lib/form/dynamic-field/dynamic-field.component.mjs +0 -152
  28. package/esm2022/lib/form/dynamic-form.component.mjs +0 -899
  29. package/esm2022/lib/form/dynamic-record-form.component.mjs +0 -531
  30. package/esm2022/lib/providers/provide-field-types.mjs +0 -75
  31. package/esm2022/lib/providers/provide-ngx-dynamic-entity.mjs +0 -27
  32. package/esm2022/lib/services/cascade-data.service.mjs +0 -129
  33. package/esm2022/lib/services/config-source.service.mjs +0 -67
  34. package/esm2022/lib/services/entity-ref-cache.mjs +0 -20
  35. package/esm2022/lib/services/entity-ref-registry.service.mjs +0 -31
  36. package/esm2022/lib/services/entity-ref-selection.service.mjs +0 -27
  37. package/esm2022/lib/services/entity-reference.service.mjs +0 -168
  38. package/esm2022/lib/services/field-registry.service.mjs +0 -55
  39. package/esm2022/lib/services/file-upload.service.mjs +0 -89
  40. package/esm2022/lib/services/hook-registry.service.mjs +0 -26
  41. package/esm2022/lib/services/lookup-registry.service.mjs +0 -246
  42. package/esm2022/lib/services/rbac.service.mjs +0 -46
  43. package/esm2022/lib/services/rules-evaluation.service.mjs +0 -27
  44. package/esm2022/lib/services/validation-messages.service.mjs +0 -56
  45. package/esm2022/lib/services/validator-registry.service.mjs +0 -99
  46. package/esm2022/lib/tokens/injection-tokens.mjs +0 -126
  47. package/esm2022/ngx-dynamic-entity.mjs +0 -5
  48. package/esm2022/public-api.mjs +0 -58
  49. package/index.d.ts +0 -5
  50. package/lib/field-types/array-field.component.d.ts +0 -28
  51. package/lib/field-types/boolean-field.component.d.ts +0 -18
  52. package/lib/field-types/checkbox-field.component.d.ts +0 -13
  53. package/lib/field-types/currency-field.component.d.ts +0 -17
  54. package/lib/field-types/date-field.component.d.ts +0 -15
  55. package/lib/field-types/date-time-field.component.d.ts +0 -30
  56. package/lib/field-types/dropdown-field.component.d.ts +0 -34
  57. package/lib/field-types/email-field.component.d.ts +0 -15
  58. package/lib/field-types/entity-ref-field.component.d.ts +0 -49
  59. package/lib/field-types/field-component.contract.d.ts +0 -49
  60. package/lib/field-types/file-field.component.d.ts +0 -25
  61. package/lib/field-types/group-field.component.d.ts +0 -17
  62. package/lib/field-types/image-field.component.d.ts +0 -30
  63. package/lib/field-types/month-year-field.component.d.ts +0 -28
  64. package/lib/field-types/multi-select-field.component.d.ts +0 -27
  65. package/lib/field-types/number-field.component.d.ts +0 -16
  66. package/lib/field-types/password-field.component.d.ts +0 -17
  67. package/lib/field-types/radio-field.component.d.ts +0 -33
  68. package/lib/field-types/text-field.component.d.ts +0 -23
  69. package/lib/field-types/textarea-field.component.d.ts +0 -14
  70. package/lib/field-types/time-field.component.d.ts +0 -27
  71. package/lib/form/dynamic-field/dynamic-field.component.d.ts +0 -78
  72. package/lib/form/dynamic-form.component.d.ts +0 -293
  73. package/lib/form/dynamic-record-form.component.d.ts +0 -199
  74. package/lib/providers/provide-field-types.d.ts +0 -24
  75. package/lib/providers/provide-ngx-dynamic-entity.d.ts +0 -56
  76. package/lib/services/cascade-data.service.d.ts +0 -45
  77. package/lib/services/config-source.service.d.ts +0 -14
  78. package/lib/services/entity-ref-cache.d.ts +0 -27
  79. package/lib/services/entity-ref-registry.service.d.ts +0 -21
  80. package/lib/services/entity-ref-selection.service.d.ts +0 -24
  81. package/lib/services/entity-reference.service.d.ts +0 -49
  82. package/lib/services/field-registry.service.d.ts +0 -32
  83. package/lib/services/file-upload.service.d.ts +0 -27
  84. package/lib/services/hook-registry.service.d.ts +0 -12
  85. package/lib/services/lookup-registry.service.d.ts +0 -94
  86. package/lib/services/rbac.service.d.ts +0 -27
  87. package/lib/services/rules-evaluation.service.d.ts +0 -17
  88. package/lib/services/validation-messages.service.d.ts +0 -43
  89. package/lib/services/validator-registry.service.d.ts +0 -32
  90. package/lib/tokens/injection-tokens.d.ts +0 -134
  91. package/public-api.d.ts +0 -42
@@ -1,152 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, Injector, Input, ViewChild, ViewContainerRef, inject, isDevMode, } from '@angular/core';
2
- import { findTab } from '@dynamic-entity/core';
3
- import { FieldRegistryService } from '../../services/field-registry.service';
4
- import { RbacService } from '../../services/rbac.service';
5
- import * as i0 from "@angular/core";
6
- /**
7
- * DynamicFieldComponent — mounts the correct field component for a given NestedFieldConfig.
8
- * Uses ViewContainerRef.createComponent() and passes inputs via setInput(); see
9
- * DynamicFieldComponentContract for the five inputs every field component receives.
10
- * Never add field-type-specific logic here — this component must remain generic.
11
- *
12
- * The 5 inputs (field, control, language, readonly, masked) are passed to every mounted
13
- * component uniformly — no special-casing per type.
14
- */
15
- export class DynamicFieldComponent {
16
- field;
17
- control;
18
- config;
19
- currentTabId;
20
- language = 'en';
21
- readonly = false;
22
- userRoles = [];
23
- fieldHost;
24
- fieldRegistry = inject(FieldRegistryService);
25
- rbacService = inject(RbacService);
26
- /**
27
- * Passed into `createComponent` so a hosted field sees this host's injector — including
28
- * `DynamicFormComponent`'s scoped `EntityRefSelectionService`. Without it, a standalone
29
- * field resolves the root bus and `autoPatch` never runs.
30
- */
31
- injector = inject(Injector);
32
- componentRef = null;
33
- ngOnChanges(_changes) {
34
- this.mountField();
35
- }
36
- mountField() {
37
- if (!this.field || !this.control)
38
- return;
39
- const ComponentClass = this.fieldRegistry.resolve(this.field.type);
40
- if (!ComponentClass) {
41
- this.warnUnresolved(this.field.type);
42
- return; // Unknown field type — render nothing
43
- }
44
- // Determine masking for this specific field
45
- const tab = this.currentTabId ? findTab(this.config?.tabs, this.currentTabId) : null;
46
- const masked = this.rbacService.shouldMaskField(this.field, tab ?? undefined, this.config, this.userRoles);
47
- // Re-use existing component if same type, otherwise recreate
48
- if (this.componentRef && this.componentRef.instance instanceof ComponentClass) {
49
- this.setInputs(this.componentRef, masked);
50
- return;
51
- }
52
- this.fieldHost.clear();
53
- this.componentRef = this.fieldHost.createComponent(ComponentClass, {
54
- injector: this.injector,
55
- });
56
- this.setInputs(this.componentRef, masked);
57
- this.watchControl();
58
- this.componentRef.changeDetectorRef.detectChanges();
59
- }
60
- /**
61
- * Field types are opt-in (see `provideFieldTypes` / `provideBuiltInFieldTypes`), so an
62
- * unregistered type renders nothing. Say so once per type in dev builds rather than
63
- * leaving a silently blank slot.
64
- */
65
- warnUnresolved(type) {
66
- if (!isDevMode() || DynamicFieldComponent.warnedTypes.has(type))
67
- return;
68
- DynamicFieldComponent.warnedTypes.add(type);
69
- console.warn(`[ngx-dynamic-entity] No component registered for field type "${type}" — the field was not rendered. ` +
70
- `Register it with provideFieldTypes({ '${type}': MyComponent }) or provideBuiltInFieldTypes().`);
71
- }
72
- static warnedTypes = new Set();
73
- /**
74
- * Re-check the hosted field component.
75
- *
76
- * The field components are OnPush, so they re-render on an input change, an event from
77
- * their own template, or a signal they read. `form.markAllAsTouched()` is none of those —
78
- * it flips `touched` from outside, and every field's error message depends on it. Without
79
- * this, a blocked submit would mark the form touched and no error would appear.
80
- */
81
- refresh() {
82
- this.componentRef?.changeDetectorRef.detectChanges();
83
- }
84
- /**
85
- * Re-check the hosted component whenever its control changes from outside.
86
- *
87
- * The field components are OnPush, so they re-render on an input change or an event from
88
- * their own template. A control mutated externally is neither — and that is not an edge
89
- * case: patchForm, reset, autoPatch and patchOnTrue all do exactly that. Without this, a
90
- * field patched from a record would keep rendering its previous value.
91
- *
92
- * `detectChanges()` rather than `markForCheck()`: a selection that arrives from a native
93
- * `change` event (or Playwright) may not be followed by another Angular tick, so a dirty
94
- * flag would never be flushed. Running CD on the hosted component now is the copy showing up.
95
- *
96
- * Done here rather than in each of the eighteen field components: the host owns the
97
- * component reference, so one subscription covers every type including custom ones.
98
- */
99
- watchControl() {
100
- this.controlSub?.unsubscribe();
101
- if (!this.control)
102
- return;
103
- this.controlSub = this.control.valueChanges.subscribe(() => this.refresh());
104
- }
105
- controlSub;
106
- ngOnDestroy() {
107
- this.controlSub?.unsubscribe();
108
- }
109
- /**
110
- * Pass all 5 contract inputs via ComponentRef.setInput() — uniform for all types.
111
- * The public shape is DynamicFieldComponentContract.
112
- * Must use setInput(), not property assignment: the field components declare inputs with
113
- * definite assignment and no initializer, and the lib compiles with
114
- * useDefineForClassFields:false, so `'field' in instance` is false until first set.
115
- */
116
- setInputs(ref, masked) {
117
- ref.setInput('field', this.field);
118
- ref.setInput('control', this.control);
119
- ref.setInput('language', this.language);
120
- ref.setInput('readonly', this.readonly || !!this.field.readonly);
121
- ref.setInput('masked', masked);
122
- }
123
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
124
- 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, changeDetection: i0.ChangeDetectionStrategy.OnPush });
125
- }
126
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DynamicFieldComponent, decorators: [{
127
- type: Component,
128
- args: [{
129
- changeDetection: ChangeDetectionStrategy.OnPush,
130
- selector: 'ngx-dynamic-field',
131
- standalone: true,
132
- template: `<ng-container #fieldHost></ng-container>`,
133
- }]
134
- }], propDecorators: { field: [{
135
- type: Input
136
- }], control: [{
137
- type: Input
138
- }], config: [{
139
- type: Input
140
- }], currentTabId: [{
141
- type: Input
142
- }], language: [{
143
- type: Input
144
- }], readonly: [{
145
- type: Input
146
- }], userRoles: [{
147
- type: Input
148
- }], fieldHost: [{
149
- type: ViewChild,
150
- args: ['fieldHost', { read: ViewContainerRef, static: true }]
151
- }] } });
152
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1maWVsZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL2Zvcm0vZHluYW1pYy1maWVsZC9keW5hbWljLWZpZWxkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFFVCxRQUFRLEVBQ1IsS0FBSyxFQUdMLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUl2QixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDL0MsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDZCQUE2QixDQUFDOztBQUUxRDs7Ozs7Ozs7R0FRRztBQU9ILE1BQU0sT0FBTyxxQkFBcUI7SUFDdkIsS0FBSyxDQUFxQjtJQUMxQixPQUFPLENBQW1CO0lBQzFCLE1BQU0sQ0FBb0I7SUFDMUIsWUFBWSxDQUFVO0lBQ3RCLFFBQVEsR0FBVyxJQUFJLENBQUM7SUFDeEIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixTQUFTLEdBQWEsRUFBRSxDQUFDO0lBR2pCLFNBQVMsQ0FBb0I7SUFFN0IsYUFBYSxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQzdDLFdBQVcsR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDbkQ7Ozs7T0FJRztJQUNjLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7SUFFckMsWUFBWSxHQUFpQyxJQUFJLENBQUM7SUFFMUQsV0FBVyxDQUFDLFFBQXVCO1FBQ2pDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNwQixDQUFDO0lBRU8sVUFBVTtRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUV6QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckMsT0FBTyxDQUFDLHNDQUFzQztRQUNoRCxDQUFDO1FBRUQsNENBQTRDO1FBQzVDLE1BQU0sR0FBRyxHQUEyQixJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDN0csTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLElBQUksU0FBUyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRTNHLDZEQUE2RDtRQUM3RCxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLFlBQVksY0FBYyxFQUFFLENBQUM7WUFDOUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzFDLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLGNBQWMsRUFBRTtZQUNqRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7U0FDeEIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3RELENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssY0FBYyxDQUFDLElBQVk7UUFDakMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQUUsT0FBTztRQUN4RSxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxJQUFJLENBQ1YsZ0VBQWdFLElBQUksa0NBQWtDO1lBQ3BHLHlDQUF5QyxJQUFJLGtEQUFrRCxDQUNsRyxDQUFDO0lBQ0osQ0FBQztJQUVPLE1BQU0sQ0FBVSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUV4RDs7Ozs7OztPQU9HO0lBQ0gsT0FBTztRQUNMLElBQUksQ0FBQyxZQUFZLEVBQUUsaUJBQWlCLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDdkQsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0ssWUFBWTtRQUNsQixJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU87UUFFMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUVPLFVBQVUsQ0FBZ0I7SUFFbEMsV0FBVztRQUNULElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDakMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLFNBQVMsQ0FBQyxHQUEwQixFQUFFLE1BQWU7UUFDM0QsR0FBRyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLEdBQUcsQ0FBQyxRQUFRLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN0QyxHQUFHLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqRSxHQUFHLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNqQyxDQUFDO3dHQTVIVSxxQkFBcUI7NEZBQXJCLHFCQUFxQixvVUFTQSxnQkFBZ0IsZ0VBWHRDLDBDQUEwQzs7NEZBRXpDLHFCQUFxQjtrQkFOakMsU0FBUzttQkFBQztvQkFDVCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsUUFBUSxFQUFFLG1CQUFtQjtvQkFDN0IsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLFFBQVEsRUFBRSwwQ0FBMEM7aUJBQ3JEOzhCQUVVLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR1csU0FBUztzQkFEekIsU0FBUzt1QkFBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIENvbXBvbmVudFJlZixcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsIE9uRGVzdHJveSxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxuICBpbmplY3QsXG4gIGlzRGV2TW9kZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB0eXBlIHsgTmVzdGVkRmllbGRDb25maWcsIEVudGl0eUZvcm1Db25maWcsIE5lc3RlZFRhYkNvbmZpZyB9IGZyb20gJ0BkeW5hbWljLWVudGl0eS9jb3JlJztcbmltcG9ydCB7IGZpbmRUYWIgfSBmcm9tICdAZHluYW1pYy1lbnRpdHkvY29yZSc7XG5pbXBvcnQgeyBGaWVsZFJlZ2lzdHJ5U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2ZpZWxkLXJlZ2lzdHJ5LnNlcnZpY2UnO1xuaW1wb3J0IHsgUmJhY1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yYmFjLnNlcnZpY2UnO1xuXG4vKipcbiAqIER5bmFtaWNGaWVsZENvbXBvbmVudCDigJQgbW91bnRzIHRoZSBjb3JyZWN0IGZpZWxkIGNvbXBvbmVudCBmb3IgYSBnaXZlbiBOZXN0ZWRGaWVsZENvbmZpZy5cbiAqIFVzZXMgVmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQoKSBhbmQgcGFzc2VzIGlucHV0cyB2aWEgc2V0SW5wdXQoKTsgc2VlXG4gKiBEeW5hbWljRmllbGRDb21wb25lbnRDb250cmFjdCBmb3IgdGhlIGZpdmUgaW5wdXRzIGV2ZXJ5IGZpZWxkIGNvbXBvbmVudCByZWNlaXZlcy5cbiAqIE5ldmVyIGFkZCBmaWVsZC10eXBlLXNwZWNpZmljIGxvZ2ljIGhlcmUg4oCUIHRoaXMgY29tcG9uZW50IG11c3QgcmVtYWluIGdlbmVyaWMuXG4gKlxuICogVGhlIDUgaW5wdXRzIChmaWVsZCwgY29udHJvbCwgbGFuZ3VhZ2UsIHJlYWRvbmx5LCBtYXNrZWQpIGFyZSBwYXNzZWQgdG8gZXZlcnkgbW91bnRlZFxuICogY29tcG9uZW50IHVuaWZvcm1seSDigJQgbm8gc3BlY2lhbC1jYXNpbmcgcGVyIHR5cGUuXG4gKi9cbkBDb21wb25lbnQoe1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc2VsZWN0b3I6ICduZ3gtZHluYW1pYy1maWVsZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHRlbXBsYXRlOiBgPG5nLWNvbnRhaW5lciAjZmllbGRIb3N0PjwvbmctY29udGFpbmVyPmAsXG59KVxuZXhwb3J0IGNsYXNzIER5bmFtaWNGaWVsZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgQElucHV0KCkgZmllbGQhOiBOZXN0ZWRGaWVsZENvbmZpZztcbiAgQElucHV0KCkgY29udHJvbCE6IEFic3RyYWN0Q29udHJvbDtcbiAgQElucHV0KCkgY29uZmlnITogRW50aXR5Rm9ybUNvbmZpZztcbiAgQElucHV0KCkgY3VycmVudFRhYklkPzogc3RyaW5nO1xuICBASW5wdXQoKSBsYW5ndWFnZTogc3RyaW5nID0gJ2VuJztcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgdXNlclJvbGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIEBWaWV3Q2hpbGQoJ2ZpZWxkSG9zdCcsIHsgcmVhZDogVmlld0NvbnRhaW5lclJlZiwgc3RhdGljOiB0cnVlIH0pXG4gIHByaXZhdGUgcmVhZG9ubHkgZmllbGRIb3N0ITogVmlld0NvbnRhaW5lclJlZjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGZpZWxkUmVnaXN0cnkgPSBpbmplY3QoRmllbGRSZWdpc3RyeVNlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJiYWNTZXJ2aWNlID0gaW5qZWN0KFJiYWNTZXJ2aWNlKTtcbiAgLyoqXG4gICAqIFBhc3NlZCBpbnRvIGBjcmVhdGVDb21wb25lbnRgIHNvIGEgaG9zdGVkIGZpZWxkIHNlZXMgdGhpcyBob3N0J3MgaW5qZWN0b3Ig4oCUIGluY2x1ZGluZ1xuICAgKiBgRHluYW1pY0Zvcm1Db21wb25lbnRgJ3Mgc2NvcGVkIGBFbnRpdHlSZWZTZWxlY3Rpb25TZXJ2aWNlYC4gV2l0aG91dCBpdCwgYSBzdGFuZGFsb25lXG4gICAqIGZpZWxkIHJlc29sdmVzIHRoZSByb290IGJ1cyBhbmQgYGF1dG9QYXRjaGAgbmV2ZXIgcnVucy5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5qZWN0b3IgPSBpbmplY3QoSW5qZWN0b3IpO1xuXG4gIHByaXZhdGUgY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8dW5rbm93bj4gfCBudWxsID0gbnVsbDtcblxuICBuZ09uQ2hhbmdlcyhfY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIHRoaXMubW91bnRGaWVsZCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBtb3VudEZpZWxkKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5maWVsZCB8fCAhdGhpcy5jb250cm9sKSByZXR1cm47XG5cbiAgICBjb25zdCBDb21wb25lbnRDbGFzcyA9IHRoaXMuZmllbGRSZWdpc3RyeS5yZXNvbHZlKHRoaXMuZmllbGQudHlwZSk7XG4gICAgaWYgKCFDb21wb25lbnRDbGFzcykge1xuICAgICAgdGhpcy53YXJuVW5yZXNvbHZlZCh0aGlzLmZpZWxkLnR5cGUpO1xuICAgICAgcmV0dXJuOyAvLyBVbmtub3duIGZpZWxkIHR5cGUg4oCUIHJlbmRlciBub3RoaW5nXG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lIG1hc2tpbmcgZm9yIHRoaXMgc3BlY2lmaWMgZmllbGRcbiAgICBjb25zdCB0YWI6IE5lc3RlZFRhYkNvbmZpZyB8IG51bGwgPSB0aGlzLmN1cnJlbnRUYWJJZCA/IGZpbmRUYWIodGhpcy5jb25maWc/LnRhYnMsIHRoaXMuY3VycmVudFRhYklkKSA6IG51bGw7XG4gICAgY29uc3QgbWFza2VkID0gdGhpcy5yYmFjU2VydmljZS5zaG91bGRNYXNrRmllbGQodGhpcy5maWVsZCwgdGFiID8/IHVuZGVmaW5lZCwgdGhpcy5jb25maWcsIHRoaXMudXNlclJvbGVzKTtcblxuICAgIC8vIFJlLXVzZSBleGlzdGluZyBjb21wb25lbnQgaWYgc2FtZSB0eXBlLCBvdGhlcndpc2UgcmVjcmVhdGVcbiAgICBpZiAodGhpcy5jb21wb25lbnRSZWYgJiYgdGhpcy5jb21wb25lbnRSZWYuaW5zdGFuY2UgaW5zdGFuY2VvZiBDb21wb25lbnRDbGFzcykge1xuICAgICAgdGhpcy5zZXRJbnB1dHModGhpcy5jb21wb25lbnRSZWYsIG1hc2tlZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5maWVsZEhvc3QuY2xlYXIoKTtcbiAgICB0aGlzLmNvbXBvbmVudFJlZiA9IHRoaXMuZmllbGRIb3N0LmNyZWF0ZUNvbXBvbmVudChDb21wb25lbnRDbGFzcywge1xuICAgICAgaW5qZWN0b3I6IHRoaXMuaW5qZWN0b3IsXG4gICAgfSk7XG4gICAgdGhpcy5zZXRJbnB1dHModGhpcy5jb21wb25lbnRSZWYsIG1hc2tlZCk7XG4gICAgdGhpcy53YXRjaENvbnRyb2woKTtcbiAgICB0aGlzLmNvbXBvbmVudFJlZi5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKipcbiAgICogRmllbGQgdHlwZXMgYXJlIG9wdC1pbiAoc2VlIGBwcm92aWRlRmllbGRUeXBlc2AgLyBgcHJvdmlkZUJ1aWx0SW5GaWVsZFR5cGVzYCksIHNvIGFuXG4gICAqIHVucmVnaXN0ZXJlZCB0eXBlIHJlbmRlcnMgbm90aGluZy4gU2F5IHNvIG9uY2UgcGVyIHR5cGUgaW4gZGV2IGJ1aWxkcyByYXRoZXIgdGhhblxuICAgKiBsZWF2aW5nIGEgc2lsZW50bHkgYmxhbmsgc2xvdC5cbiAgICovXG4gIHByaXZhdGUgd2FyblVucmVzb2x2ZWQodHlwZTogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCFpc0Rldk1vZGUoKSB8fCBEeW5hbWljRmllbGRDb21wb25lbnQud2FybmVkVHlwZXMuaGFzKHR5cGUpKSByZXR1cm47XG4gICAgRHluYW1pY0ZpZWxkQ29tcG9uZW50Lndhcm5lZFR5cGVzLmFkZCh0eXBlKTtcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgW25neC1keW5hbWljLWVudGl0eV0gTm8gY29tcG9uZW50IHJlZ2lzdGVyZWQgZm9yIGZpZWxkIHR5cGUgXCIke3R5cGV9XCIg4oCUIHRoZSBmaWVsZCB3YXMgbm90IHJlbmRlcmVkLiBgICtcbiAgICAgICAgYFJlZ2lzdGVyIGl0IHdpdGggcHJvdmlkZUZpZWxkVHlwZXMoeyAnJHt0eXBlfSc6IE15Q29tcG9uZW50IH0pIG9yIHByb3ZpZGVCdWlsdEluRmllbGRUeXBlcygpLmAsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IHdhcm5lZFR5cGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgLyoqXG4gICAqIFJlLWNoZWNrIHRoZSBob3N0ZWQgZmllbGQgY29tcG9uZW50LlxuICAgKlxuICAgKiBUaGUgZmllbGQgY29tcG9uZW50cyBhcmUgT25QdXNoLCBzbyB0aGV5IHJlLXJlbmRlciBvbiBhbiBpbnB1dCBjaGFuZ2UsIGFuIGV2ZW50IGZyb21cbiAgICogdGhlaXIgb3duIHRlbXBsYXRlLCBvciBhIHNpZ25hbCB0aGV5IHJlYWQuIGBmb3JtLm1hcmtBbGxBc1RvdWNoZWQoKWAgaXMgbm9uZSBvZiB0aG9zZSDigJRcbiAgICogaXQgZmxpcHMgYHRvdWNoZWRgIGZyb20gb3V0c2lkZSwgYW5kIGV2ZXJ5IGZpZWxkJ3MgZXJyb3IgbWVzc2FnZSBkZXBlbmRzIG9uIGl0LiBXaXRob3V0XG4gICAqIHRoaXMsIGEgYmxvY2tlZCBzdWJtaXQgd291bGQgbWFyayB0aGUgZm9ybSB0b3VjaGVkIGFuZCBubyBlcnJvciB3b3VsZCBhcHBlYXIuXG4gICAqL1xuICByZWZyZXNoKCk6IHZvaWQge1xuICAgIHRoaXMuY29tcG9uZW50UmVmPy5jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvKipcbiAgICogUmUtY2hlY2sgdGhlIGhvc3RlZCBjb21wb25lbnQgd2hlbmV2ZXIgaXRzIGNvbnRyb2wgY2hhbmdlcyBmcm9tIG91dHNpZGUuXG4gICAqXG4gICAqIFRoZSBmaWVsZCBjb21wb25lbnRzIGFyZSBPblB1c2gsIHNvIHRoZXkgcmUtcmVuZGVyIG9uIGFuIGlucHV0IGNoYW5nZSBvciBhbiBldmVudCBmcm9tXG4gICAqIHRoZWlyIG93biB0ZW1wbGF0ZS4gQSBjb250cm9sIG11dGF0ZWQgZXh0ZXJuYWxseSBpcyBuZWl0aGVyIOKAlCBhbmQgdGhhdCBpcyBub3QgYW4gZWRnZVxuICAgKiBjYXNlOiBwYXRjaEZvcm0sIHJlc2V0LCBhdXRvUGF0Y2ggYW5kIHBhdGNoT25UcnVlIGFsbCBkbyBleGFjdGx5IHRoYXQuIFdpdGhvdXQgdGhpcywgYVxuICAgKiBmaWVsZCBwYXRjaGVkIGZyb20gYSByZWNvcmQgd291bGQga2VlcCByZW5kZXJpbmcgaXRzIHByZXZpb3VzIHZhbHVlLlxuICAgKlxuICAgKiBgZGV0ZWN0Q2hhbmdlcygpYCByYXRoZXIgdGhhbiBgbWFya0ZvckNoZWNrKClgOiBhIHNlbGVjdGlvbiB0aGF0IGFycml2ZXMgZnJvbSBhIG5hdGl2ZVxuICAgKiBgY2hhbmdlYCBldmVudCAob3IgUGxheXdyaWdodCkgbWF5IG5vdCBiZSBmb2xsb3dlZCBieSBhbm90aGVyIEFuZ3VsYXIgdGljaywgc28gYSBkaXJ0eVxuICAgKiBmbGFnIHdvdWxkIG5ldmVyIGJlIGZsdXNoZWQuIFJ1bm5pbmcgQ0Qgb24gdGhlIGhvc3RlZCBjb21wb25lbnQgbm93IGlzIHRoZSBjb3B5IHNob3dpbmcgdXAuXG4gICAqXG4gICAqIERvbmUgaGVyZSByYXRoZXIgdGhhbiBpbiBlYWNoIG9mIHRoZSBlaWdodGVlbiBmaWVsZCBjb21wb25lbnRzOiB0aGUgaG9zdCBvd25zIHRoZVxuICAgKiBjb21wb25lbnQgcmVmZXJlbmNlLCBzbyBvbmUgc3Vic2NyaXB0aW9uIGNvdmVycyBldmVyeSB0eXBlIGluY2x1ZGluZyBjdXN0b20gb25lcy5cbiAgICovXG4gIHByaXZhdGUgd2F0Y2hDb250cm9sKCk6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICBpZiAoIXRoaXMuY29udHJvbCkgcmV0dXJuO1xuXG4gICAgdGhpcy5jb250cm9sU3ViID0gdGhpcy5jb250cm9sLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4gdGhpcy5yZWZyZXNoKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb250cm9sU3ViPzogU3Vic2NyaXB0aW9uO1xuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXNzIGFsbCA1IGNvbnRyYWN0IGlucHV0cyB2aWEgQ29tcG9uZW50UmVmLnNldElucHV0KCkg4oCUIHVuaWZvcm0gZm9yIGFsbCB0eXBlcy5cbiAgICogVGhlIHB1YmxpYyBzaGFwZSBpcyBEeW5hbWljRmllbGRDb21wb25lbnRDb250cmFjdC5cbiAgICogTXVzdCB1c2Ugc2V0SW5wdXQoKSwgbm90IHByb3BlcnR5IGFzc2lnbm1lbnQ6IHRoZSBmaWVsZCBjb21wb25lbnRzIGRlY2xhcmUgaW5wdXRzIHdpdGhcbiAgICogZGVmaW5pdGUgYXNzaWdubWVudCBhbmQgbm8gaW5pdGlhbGl6ZXIsIGFuZCB0aGUgbGliIGNvbXBpbGVzIHdpdGhcbiAgICogdXNlRGVmaW5lRm9yQ2xhc3NGaWVsZHM6ZmFsc2UsIHNvIGAnZmllbGQnIGluIGluc3RhbmNlYCBpcyBmYWxzZSB1bnRpbCBmaXJzdCBzZXQuXG4gICAqL1xuICBwcml2YXRlIHNldElucHV0cyhyZWY6IENvbXBvbmVudFJlZjx1bmtub3duPiwgbWFza2VkOiBib29sZWFuKTogdm9pZCB7XG4gICAgcmVmLnNldElucHV0KCdmaWVsZCcsIHRoaXMuZmllbGQpO1xuICAgIHJlZi5zZXRJbnB1dCgnY29udHJvbCcsIHRoaXMuY29udHJvbCk7XG4gICAgcmVmLnNldElucHV0KCdsYW5ndWFnZScsIHRoaXMubGFuZ3VhZ2UpO1xuICAgIHJlZi5zZXRJbnB1dCgncmVhZG9ubHknLCB0aGlzLnJlYWRvbmx5IHx8ICEhdGhpcy5maWVsZC5yZWFkb25seSk7XG4gICAgcmVmLnNldElucHV0KCdtYXNrZWQnLCBtYXNrZWQpO1xuICB9XG59XG4iXX0=