bways-report 0.1.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.
- package/LICENSE +26 -0
- package/README.md +477 -0
- package/esm2022/bways-report.mjs +5 -0
- package/esm2022/lib/core/errors/index.mjs +2 -0
- package/esm2022/lib/core/errors/reporting-errors.mjs +65 -0
- package/esm2022/lib/core/index.mjs +8 -0
- package/esm2022/lib/core/models/component-event.model.mjs +8 -0
- package/esm2022/lib/core/models/index.mjs +5 -0
- package/esm2022/lib/core/models/report-component.model.mjs +10 -0
- package/esm2022/lib/core/models/report-datasource.model.mjs +9 -0
- package/esm2022/lib/core/models/report-definition.model.mjs +13 -0
- package/esm2022/lib/core/models/report-grid.model.mjs +10 -0
- package/esm2022/lib/core/models/report-layout.model.mjs +9 -0
- package/esm2022/lib/core/models/report-parameter.model.mjs +9 -0
- package/esm2022/lib/core/models/validation.model.mjs +8 -0
- package/esm2022/lib/core/registry/component-category.mjs +8 -0
- package/esm2022/lib/core/registry/component-registry.mjs +90 -0
- package/esm2022/lib/core/registry/index.mjs +2 -0
- package/esm2022/lib/core/registry/property-definition.model.mjs +10 -0
- package/esm2022/lib/core/services/dynamic-form-builder.service.mjs +55 -0
- package/esm2022/lib/core/services/index.mjs +3 -0
- package/esm2022/lib/core/services/report-session-context.service.mjs +314 -0
- package/esm2022/lib/core/tokens/index.mjs +3 -0
- package/esm2022/lib/core/tokens/reporting-config.token.mjs +26 -0
- package/esm2022/lib/core/tokens/session-context.token.mjs +18 -0
- package/esm2022/lib/core/utilities/id-generator.mjs +17 -0
- package/esm2022/lib/core/utilities/index.mjs +3 -0
- package/esm2022/lib/core/utilities/schema-migration.mjs +38 -0
- package/esm2022/lib/core/utils/identifier-humanizer.mjs +88 -0
- package/esm2022/lib/core/validation/index.mjs +2 -0
- package/esm2022/lib/core/validation/validation-factory.mjs +70 -0
- package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +107 -0
- package/esm2022/lib/data-access/adapters/http-schema-discovery.adapter.mjs +119 -0
- package/esm2022/lib/data-access/adapters/index.mjs +3 -0
- package/esm2022/lib/data-access/contracts/data-source.contract.mjs +28 -0
- package/esm2022/lib/data-access/contracts/index.mjs +7 -0
- package/esm2022/lib/data-access/contracts/lookup.contract.mjs +6 -0
- package/esm2022/lib/data-access/contracts/master-data.provider.mjs +24 -0
- package/esm2022/lib/data-access/contracts/report-persistence.contract.mjs +25 -0
- package/esm2022/lib/data-access/contracts/schema-discovery.contract.mjs +7 -0
- package/esm2022/lib/data-access/contracts/translation.contract.mjs +9 -0
- package/esm2022/lib/data-access/index.mjs +3 -0
- package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +542 -0
- package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +843 -0
- package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +556 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +845 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +185 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +452 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +350 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +175 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +137 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +608 -0
- package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +225 -0
- package/esm2022/lib/features/designer/designer.component.mjs +285 -0
- package/esm2022/lib/features/designer/index.mjs +7 -0
- package/esm2022/lib/features/designer/services/designer-state.service.mjs +310 -0
- package/esm2022/lib/features/designer/services/index.mjs +2 -0
- package/esm2022/lib/features/designer/utilities/canvas-layout.util.mjs +124 -0
- package/esm2022/lib/features/export/index.mjs +2 -0
- package/esm2022/lib/features/export/models/export.models.mjs +2 -0
- package/esm2022/lib/features/export/services/report-export.service.mjs +107 -0
- package/esm2022/lib/features/index.mjs +6 -0
- package/esm2022/lib/features/persistence/index.mjs +2 -0
- package/esm2022/lib/features/persistence/services/index.mjs +4 -0
- package/esm2022/lib/features/persistence/services/report-store.service.mjs +183 -0
- package/esm2022/lib/features/persistence/services/report-versioning.service.mjs +81 -0
- package/esm2022/lib/features/persistence/services/schema-validator.service.mjs +102 -0
- package/esm2022/lib/features/routing/components/routed-report-designer.component.mjs +156 -0
- package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +163 -0
- package/esm2022/lib/features/routing/index.mjs +6 -0
- package/esm2022/lib/features/routing/models/report-route.models.mjs +2 -0
- package/esm2022/lib/features/routing/report-routes.mjs +49 -0
- package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +22 -0
- package/esm2022/lib/features/routing/services/report-menu.service.mjs +77 -0
- package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +222 -0
- package/esm2022/lib/features/runtime/index.mjs +4 -0
- package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +409 -0
- package/esm2022/lib/features/runtime/report-runtime.component.mjs +147 -0
- package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +88 -0
- package/esm2022/lib/primitives/components/chart-bridge/report-chart-bridge.component.mjs +361 -0
- package/esm2022/lib/primitives/components/checkbox/rpt-checkbox.component.mjs +86 -0
- package/esm2022/lib/primitives/components/date/rpt-date.component.mjs +91 -0
- package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +204 -0
- package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +476 -0
- package/esm2022/lib/primitives/components/index.mjs +10 -0
- package/esm2022/lib/primitives/components/input/rpt-input.component.mjs +88 -0
- package/esm2022/lib/primitives/components/kpi-card/rpt-kpi-card.component.mjs +197 -0
- package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +110 -0
- package/esm2022/lib/primitives/index.mjs +3 -0
- package/esm2022/lib/primitives/register-builtins.mjs +328 -0
- package/esm2022/lib/provide-reporting.mjs +92 -0
- package/esm2022/public-api.mjs +9 -0
- package/fesm2022/bways-report.mjs +10360 -0
- package/fesm2022/bways-report.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/core/errors/index.d.ts +1 -0
- package/lib/core/errors/reporting-errors.d.ts +42 -0
- package/lib/core/index.d.ts +7 -0
- package/lib/core/models/component-event.model.d.ts +37 -0
- package/lib/core/models/index.d.ts +11 -0
- package/lib/core/models/report-component.model.d.ts +95 -0
- package/lib/core/models/report-datasource.model.d.ts +39 -0
- package/lib/core/models/report-definition.model.d.ts +100 -0
- package/lib/core/models/report-grid.model.d.ts +73 -0
- package/lib/core/models/report-layout.model.d.ts +43 -0
- package/lib/core/models/report-parameter.model.d.ts +22 -0
- package/lib/core/models/validation.model.d.ts +30 -0
- package/lib/core/registry/component-category.d.ts +16 -0
- package/lib/core/registry/component-registry.d.ts +101 -0
- package/lib/core/registry/index.d.ts +4 -0
- package/lib/core/registry/property-definition.model.d.ts +38 -0
- package/lib/core/services/dynamic-form-builder.service.d.ts +30 -0
- package/lib/core/services/index.d.ts +3 -0
- package/lib/core/services/report-session-context.service.d.ts +87 -0
- package/lib/core/tokens/index.d.ts +4 -0
- package/lib/core/tokens/reporting-config.token.d.ts +42 -0
- package/lib/core/tokens/session-context.token.d.ts +36 -0
- package/lib/core/utilities/id-generator.d.ts +9 -0
- package/lib/core/utilities/index.d.ts +3 -0
- package/lib/core/utilities/schema-migration.d.ts +10 -0
- package/lib/core/utils/identifier-humanizer.d.ts +22 -0
- package/lib/core/validation/index.d.ts +1 -0
- package/lib/core/validation/validation-factory.d.ts +31 -0
- package/lib/data-access/adapters/http-lookup.adapter.d.ts +19 -0
- package/lib/data-access/adapters/http-schema-discovery.adapter.d.ts +20 -0
- package/lib/data-access/adapters/index.d.ts +2 -0
- package/lib/data-access/contracts/data-source.contract.d.ts +37 -0
- package/lib/data-access/contracts/index.d.ts +9 -0
- package/lib/data-access/contracts/lookup.contract.d.ts +32 -0
- package/lib/data-access/contracts/master-data.provider.d.ts +54 -0
- package/lib/data-access/contracts/report-persistence.contract.d.ts +36 -0
- package/lib/data-access/contracts/schema-discovery.contract.d.ts +52 -0
- package/lib/data-access/contracts/translation.contract.d.ts +16 -0
- package/lib/data-access/index.d.ts +2 -0
- package/lib/features/designer/components/component-palette/component-palette.component.d.ts +39 -0
- package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +42 -0
- package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +36 -0
- package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +68 -0
- package/lib/features/designer/components/property-editor/property-editor-general.component.d.ts +20 -0
- package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +20 -0
- package/lib/features/designer/components/property-editor/property-editor-layout.component.d.ts +18 -0
- package/lib/features/designer/components/property-editor/property-editor-report.component.d.ts +15 -0
- package/lib/features/designer/components/property-editor/property-editor-validation.component.d.ts +12 -0
- package/lib/features/designer/components/property-editor/property-editor.component.d.ts +44 -0
- package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +18 -0
- package/lib/features/designer/designer.component.d.ts +36 -0
- package/lib/features/designer/index.d.ts +7 -0
- package/lib/features/designer/services/designer-state.service.d.ts +103 -0
- package/lib/features/designer/services/index.d.ts +2 -0
- package/lib/features/designer/utilities/canvas-layout.util.d.ts +55 -0
- package/lib/features/export/index.d.ts +2 -0
- package/lib/features/export/models/export.models.d.ts +16 -0
- package/lib/features/export/services/report-export.service.d.ts +27 -0
- package/lib/features/index.d.ts +5 -0
- package/lib/features/persistence/index.d.ts +1 -0
- package/lib/features/persistence/services/index.d.ts +5 -0
- package/lib/features/persistence/services/report-store.service.d.ts +53 -0
- package/lib/features/persistence/services/report-versioning.service.d.ts +29 -0
- package/lib/features/persistence/services/schema-validator.service.d.ts +34 -0
- package/lib/features/routing/components/routed-report-designer.component.d.ts +18 -0
- package/lib/features/routing/components/routed-report-runtime.component.d.ts +18 -0
- package/lib/features/routing/index.d.ts +6 -0
- package/lib/features/routing/models/report-route.models.d.ts +41 -0
- package/lib/features/routing/report-routes.d.ts +16 -0
- package/lib/features/routing/resolvers/report.resolver.d.ts +7 -0
- package/lib/features/routing/services/report-menu.service.d.ts +30 -0
- package/lib/features/runtime/dynamic-renderer.component.d.ts +30 -0
- package/lib/features/runtime/index.d.ts +3 -0
- package/lib/features/runtime/report-grid-bridge.component.d.ts +94 -0
- package/lib/features/runtime/report-runtime.component.d.ts +26 -0
- package/lib/primitives/components/button/rpt-button.component.d.ts +19 -0
- package/lib/primitives/components/chart-bridge/report-chart-bridge.component.d.ts +45 -0
- package/lib/primitives/components/checkbox/rpt-checkbox.component.d.ts +14 -0
- package/lib/primitives/components/date/rpt-date.component.d.ts +17 -0
- package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +32 -0
- package/lib/primitives/components/icon/rpt-icon.component.d.ts +41 -0
- package/lib/primitives/components/index.d.ts +12 -0
- package/lib/primitives/components/input/rpt-input.component.d.ts +16 -0
- package/lib/primitives/components/kpi-card/rpt-kpi-card.component.d.ts +43 -0
- package/lib/primitives/components/number/rpt-number.component.d.ts +20 -0
- package/lib/primitives/index.d.ts +2 -0
- package/lib/primitives/register-builtins.d.ts +11 -0
- package/lib/provide-reporting.d.ts +75 -0
- package/package.json +55 -0
- package/public-api.d.ts +5 -0
package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs
ADDED
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, inject, signal, } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { DesignerStateService } from '../../services/designer-state.service';
|
|
4
|
+
import { ComponentRegistry } from '../../../../core/registry/component-registry';
|
|
5
|
+
import { RptIconComponent } from '../../../../primitives/components/icon/rpt-icon.component';
|
|
6
|
+
import { PropertyEditorGeneralComponent } from './property-editor-general.component';
|
|
7
|
+
import { PropertyEditorLayoutComponent } from './property-editor-layout.component';
|
|
8
|
+
import { PropertyEditorValidationComponent } from './property-editor-validation.component';
|
|
9
|
+
import { PropertyEditorGridComponent } from './property-editor-grid.component';
|
|
10
|
+
import { PropertyEditorReportComponent } from './property-editor-report.component';
|
|
11
|
+
import { PropertyEditorDatasourceComponent } from './property-editor-datasource.component';
|
|
12
|
+
import * as i0 from "@angular/core";
|
|
13
|
+
/**
|
|
14
|
+
* Property Editor coordinator component.
|
|
15
|
+
*
|
|
16
|
+
* Decomposed into focused child presentational components per Rule 18 & 19 (Composition Over Giant Components)
|
|
17
|
+
* and Rule 32 (Avoid God Components).
|
|
18
|
+
*/
|
|
19
|
+
export class PropertyEditorComponent {
|
|
20
|
+
designerState = inject(DesignerStateService);
|
|
21
|
+
registry = inject(ComponentRegistry);
|
|
22
|
+
definition = this.designerState.definition;
|
|
23
|
+
activeTab = this.designerState.activeTab;
|
|
24
|
+
selectedComponent = this.designerState.selectedComponent;
|
|
25
|
+
maxColumns = computed(() => this.definition().layout.columns || 12);
|
|
26
|
+
allComponents = computed(() => this.definition().components);
|
|
27
|
+
propertySchema = computed(() => {
|
|
28
|
+
const comp = this.selectedComponent();
|
|
29
|
+
if (!comp)
|
|
30
|
+
return [];
|
|
31
|
+
const meta = this.registry.resolve(comp.type);
|
|
32
|
+
return meta?.propertySchema ?? [];
|
|
33
|
+
});
|
|
34
|
+
setTab(tab) {
|
|
35
|
+
this.designerState.setActiveTab(tab);
|
|
36
|
+
}
|
|
37
|
+
updateCompDataSource(id, dataSource) {
|
|
38
|
+
this.designerState.updateComponent(id, { dataSource });
|
|
39
|
+
}
|
|
40
|
+
deselect() {
|
|
41
|
+
this.designerState.selectComponent(null);
|
|
42
|
+
}
|
|
43
|
+
updateComp(field, value) {
|
|
44
|
+
const comp = this.selectedComponent();
|
|
45
|
+
if (comp) {
|
|
46
|
+
this.designerState.updateComponent(comp.id, { [field]: value });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
updateProp(id, key, value) {
|
|
50
|
+
this.designerState.updateComponentProperty(id, key, value);
|
|
51
|
+
}
|
|
52
|
+
updateLayout(key, value) {
|
|
53
|
+
const comp = this.selectedComponent();
|
|
54
|
+
if (comp) {
|
|
55
|
+
this.designerState.updateComponentLayout(comp.id, { [key]: value });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
updateComponentHeight(val) {
|
|
59
|
+
const comp = this.selectedComponent();
|
|
60
|
+
if (!comp)
|
|
61
|
+
return;
|
|
62
|
+
const height = !val || val === 'auto' || !val.trim() ? undefined : val.trim();
|
|
63
|
+
this.designerState.updateComponentLayout(comp.id, {
|
|
64
|
+
height,
|
|
65
|
+
minHeight: height,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
resetComponentDimensions(id, type) {
|
|
69
|
+
const defaultSpan = type === 'button' ? 2 : 4;
|
|
70
|
+
this.designerState.updateComponentLayout(id, {
|
|
71
|
+
columnSpan: defaultSpan,
|
|
72
|
+
height: undefined,
|
|
73
|
+
minHeight: undefined,
|
|
74
|
+
width: undefined,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
updateValidation(key, value) {
|
|
78
|
+
const comp = this.selectedComponent();
|
|
79
|
+
if (comp) {
|
|
80
|
+
const nextValidation = { ...(comp.validation ?? {}), [key]: value };
|
|
81
|
+
this.designerState.updateComponent(comp.id, { validation: nextValidation });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
updateReport(key, value) {
|
|
85
|
+
this.designerState.updateReportSettings({ [key]: value });
|
|
86
|
+
}
|
|
87
|
+
updateLayoutProp(key, value) {
|
|
88
|
+
const currentLayout = this.definition().layout;
|
|
89
|
+
this.designerState.updateReportSettings({
|
|
90
|
+
layout: { ...currentLayout, [key]: value },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
addColumn() {
|
|
94
|
+
const current = this.definition().grid ?? {
|
|
95
|
+
dataSourceId: 'default',
|
|
96
|
+
columns: [],
|
|
97
|
+
};
|
|
98
|
+
const colCount = current.columns.length + 1;
|
|
99
|
+
const newCol = {
|
|
100
|
+
field: `field_${colCount}`,
|
|
101
|
+
label: `Column ${colCount}`,
|
|
102
|
+
dataType: 'string',
|
|
103
|
+
sortable: true,
|
|
104
|
+
align: 'left',
|
|
105
|
+
};
|
|
106
|
+
this.designerState.updateGridSettings({
|
|
107
|
+
...current,
|
|
108
|
+
columns: [...current.columns, newCol],
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
removeColumn(index) {
|
|
112
|
+
const current = this.definition().grid;
|
|
113
|
+
if (!current)
|
|
114
|
+
return;
|
|
115
|
+
const nextCols = [...current.columns];
|
|
116
|
+
nextCols.splice(index, 1);
|
|
117
|
+
this.designerState.updateGridSettings({
|
|
118
|
+
...current,
|
|
119
|
+
columns: nextCols,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
updateColumn(index, field, value) {
|
|
123
|
+
const current = this.definition().grid;
|
|
124
|
+
if (!current)
|
|
125
|
+
return;
|
|
126
|
+
const nextCols = current.columns.map((c, idx) => {
|
|
127
|
+
if (idx === index) {
|
|
128
|
+
return { ...c, [field]: value };
|
|
129
|
+
}
|
|
130
|
+
return c;
|
|
131
|
+
});
|
|
132
|
+
this.designerState.updateGridSettings({
|
|
133
|
+
...current,
|
|
134
|
+
columns: nextCols,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
updateGridOption(field, value) {
|
|
138
|
+
const current = this.definition().grid ?? {
|
|
139
|
+
dataSourceId: 'default',
|
|
140
|
+
columns: [],
|
|
141
|
+
};
|
|
142
|
+
const nextOptions = { ...(current.options ?? {}), [field]: value };
|
|
143
|
+
this.designerState.updateGridSettings({
|
|
144
|
+
...current,
|
|
145
|
+
options: nextOptions,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
expandedSections = signal({
|
|
149
|
+
datasource: true,
|
|
150
|
+
general: true,
|
|
151
|
+
layout: false,
|
|
152
|
+
validation: false,
|
|
153
|
+
});
|
|
154
|
+
toggleSection(section) {
|
|
155
|
+
this.expandedSections.update((prev) => ({
|
|
156
|
+
...prev,
|
|
157
|
+
[section]: !prev[section],
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
isSectionExpanded(section) {
|
|
161
|
+
return !!this.expandedSections()[section];
|
|
162
|
+
}
|
|
163
|
+
getDatasourceBadge(comp) {
|
|
164
|
+
const ds = comp.dataSource;
|
|
165
|
+
if (!ds || ds.sourceType === 'static')
|
|
166
|
+
return 'Static List';
|
|
167
|
+
if (ds.sourceType === 'table' || ds.entityName) {
|
|
168
|
+
return ds.entityName ? `Table: ${ds.entityName}` : 'Table / View';
|
|
169
|
+
}
|
|
170
|
+
if (ds.sourceType === 'procedure') {
|
|
171
|
+
return ds.entityName ? `SP: ${ds.entityName}` : 'Stored Proc';
|
|
172
|
+
}
|
|
173
|
+
return 'Static List';
|
|
174
|
+
}
|
|
175
|
+
getLayoutBadge(comp) {
|
|
176
|
+
const span = comp.layout?.columnSpan || (comp.type === 'button' ? 2 : 4);
|
|
177
|
+
return `${span}/${this.maxColumns()} cols`;
|
|
178
|
+
}
|
|
179
|
+
getValidationBadge(comp) {
|
|
180
|
+
return comp.validation?.required ? 'Required' : 'Optional';
|
|
181
|
+
}
|
|
182
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PropertyEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
183
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PropertyEditorComponent, isStandalone: true, selector: "rpt-property-editor", ngImport: i0, template: `
|
|
184
|
+
<div class="editor-container">
|
|
185
|
+
<!-- Editor Header & Tabs -->
|
|
186
|
+
<div class="editor-tabs">
|
|
187
|
+
<button
|
|
188
|
+
type="button"
|
|
189
|
+
class="tab-btn"
|
|
190
|
+
[class.active]="activeTab() === 'properties'"
|
|
191
|
+
(click)="setTab('properties')"
|
|
192
|
+
[disabled]="!selectedComponent()"
|
|
193
|
+
>
|
|
194
|
+
<rpt-icon name="edit" [size]="13" />
|
|
195
|
+
<span>Properties</span>
|
|
196
|
+
</button>
|
|
197
|
+
<button
|
|
198
|
+
type="button"
|
|
199
|
+
class="tab-btn"
|
|
200
|
+
[class.active]="activeTab() === 'report'"
|
|
201
|
+
(click)="setTab('report')"
|
|
202
|
+
>
|
|
203
|
+
<rpt-icon name="design" [size]="13" />
|
|
204
|
+
<span>Layout</span>
|
|
205
|
+
</button>
|
|
206
|
+
<button
|
|
207
|
+
type="button"
|
|
208
|
+
class="tab-btn"
|
|
209
|
+
[class.active]="activeTab() === 'grid'"
|
|
210
|
+
(click)="setTab('grid')"
|
|
211
|
+
>
|
|
212
|
+
<rpt-icon name="table" [size]="13" />
|
|
213
|
+
<span>Grid</span>
|
|
214
|
+
</button>
|
|
215
|
+
</div>
|
|
216
|
+
|
|
217
|
+
<!-- Editor Body -->
|
|
218
|
+
<div class="editor-body">
|
|
219
|
+
<!-- 1. COMPONENT PROPERTIES TAB -->
|
|
220
|
+
@if (activeTab() === 'properties') {
|
|
221
|
+
@if (selectedComponent(); as comp) {
|
|
222
|
+
<div class="component-sections-wrapper">
|
|
223
|
+
<!-- Component Identifier Header (Pinned at Top) -->
|
|
224
|
+
<div class="comp-badge-header">
|
|
225
|
+
<div class="badge-title">
|
|
226
|
+
<span class="badge-type">{{ comp.type }}</span>
|
|
227
|
+
<span class="badge-id">{{ comp.id }}</span>
|
|
228
|
+
</div>
|
|
229
|
+
<button type="button" class="btn-deselect" (click)="deselect()" title="Deselect component">
|
|
230
|
+
<rpt-icon name="close" [size]="13" />
|
|
231
|
+
</button>
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<!-- Accordion Container -->
|
|
235
|
+
<div class="property-accordion">
|
|
236
|
+
<!-- 1. OPTIONS DATA SOURCE ACCORDION (FIRST for Dropdown) -->
|
|
237
|
+
@if (comp.type === 'dropdown') {
|
|
238
|
+
<div class="accordion-item" [class.is-expanded]="isSectionExpanded('datasource')">
|
|
239
|
+
<button
|
|
240
|
+
type="button"
|
|
241
|
+
class="accordion-header"
|
|
242
|
+
(click)="toggleSection('datasource')"
|
|
243
|
+
title="Toggle Options Data Source section"
|
|
244
|
+
>
|
|
245
|
+
<div class="header-left">
|
|
246
|
+
<rpt-icon name="database" [size]="14" />
|
|
247
|
+
<span class="header-title">Options Data Source</span>
|
|
248
|
+
<span class="header-badge">{{ getDatasourceBadge(comp) }}</span>
|
|
249
|
+
</div>
|
|
250
|
+
<div class="header-right">
|
|
251
|
+
<rpt-icon name="chevron-down" [size]="13" class="accordion-chevron" />
|
|
252
|
+
</div>
|
|
253
|
+
</button>
|
|
254
|
+
@if (isSectionExpanded('datasource')) {
|
|
255
|
+
<div class="accordion-content">
|
|
256
|
+
<rpt-property-editor-datasource
|
|
257
|
+
[comp]="comp"
|
|
258
|
+
[allComponents]="allComponents()"
|
|
259
|
+
(updateDataSource)="updateCompDataSource(comp.id, $event)"
|
|
260
|
+
(updateProperty)="updateProp(comp.id, $event.key, $event.value)"
|
|
261
|
+
/>
|
|
262
|
+
</div>
|
|
263
|
+
}
|
|
264
|
+
</div>
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
<!-- 2. GENERAL PROPERTIES ACCORDION -->
|
|
268
|
+
<div class="accordion-item" [class.is-expanded]="isSectionExpanded('general')">
|
|
269
|
+
<button
|
|
270
|
+
type="button"
|
|
271
|
+
class="accordion-header"
|
|
272
|
+
(click)="toggleSection('general')"
|
|
273
|
+
title="Toggle General Properties section"
|
|
274
|
+
>
|
|
275
|
+
<div class="header-left">
|
|
276
|
+
<rpt-icon name="edit" [size]="14" />
|
|
277
|
+
<span class="header-title">General Properties</span>
|
|
278
|
+
@if (comp.label) {
|
|
279
|
+
<span class="header-badge">{{ comp.label }}</span>
|
|
280
|
+
}
|
|
281
|
+
</div>
|
|
282
|
+
<div class="header-right">
|
|
283
|
+
<rpt-icon name="chevron-down" [size]="13" class="accordion-chevron" />
|
|
284
|
+
</div>
|
|
285
|
+
</button>
|
|
286
|
+
@if (isSectionExpanded('general')) {
|
|
287
|
+
<div class="accordion-content">
|
|
288
|
+
<rpt-property-editor-general
|
|
289
|
+
[comp]="comp"
|
|
290
|
+
[propertySchema]="propertySchema()"
|
|
291
|
+
(update)="updateComp($event.field, $event.value)"
|
|
292
|
+
(updateProperty)="updateProp(comp.id, $event.key, $event.value)"
|
|
293
|
+
(deselect)="deselect()"
|
|
294
|
+
/>
|
|
295
|
+
</div>
|
|
296
|
+
}
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
<!-- 3. LAYOUT & GRID ACCORDION -->
|
|
300
|
+
<div class="accordion-item" [class.is-expanded]="isSectionExpanded('layout')">
|
|
301
|
+
<button
|
|
302
|
+
type="button"
|
|
303
|
+
class="accordion-header"
|
|
304
|
+
(click)="toggleSection('layout')"
|
|
305
|
+
title="Toggle Layout & Dimensions section"
|
|
306
|
+
>
|
|
307
|
+
<div class="header-left">
|
|
308
|
+
<rpt-icon name="design" [size]="14" />
|
|
309
|
+
<span class="header-title">Layout & Grid</span>
|
|
310
|
+
<span class="header-badge">{{ getLayoutBadge(comp) }}</span>
|
|
311
|
+
</div>
|
|
312
|
+
<div class="header-right">
|
|
313
|
+
<rpt-icon name="chevron-down" [size]="13" class="accordion-chevron" />
|
|
314
|
+
</div>
|
|
315
|
+
</button>
|
|
316
|
+
@if (isSectionExpanded('layout')) {
|
|
317
|
+
<div class="accordion-content">
|
|
318
|
+
<rpt-property-editor-layout
|
|
319
|
+
[comp]="comp"
|
|
320
|
+
[maxColumns]="maxColumns()"
|
|
321
|
+
(updateLayout)="updateLayout($event.key, $event.value)"
|
|
322
|
+
(updateHeight)="updateComponentHeight($event)"
|
|
323
|
+
(resetDimensions)="resetComponentDimensions(comp.id, comp.type)"
|
|
324
|
+
/>
|
|
325
|
+
</div>
|
|
326
|
+
}
|
|
327
|
+
</div>
|
|
328
|
+
|
|
329
|
+
<!-- 4. VALIDATION ACCORDION -->
|
|
330
|
+
<div class="accordion-item" [class.is-expanded]="isSectionExpanded('validation')">
|
|
331
|
+
<button
|
|
332
|
+
type="button"
|
|
333
|
+
class="accordion-header"
|
|
334
|
+
(click)="toggleSection('validation')"
|
|
335
|
+
title="Toggle Validation Rules section"
|
|
336
|
+
>
|
|
337
|
+
<div class="header-left">
|
|
338
|
+
<rpt-icon name="check" [size]="14" />
|
|
339
|
+
<span class="header-title">Validation Rules</span>
|
|
340
|
+
<span class="header-badge">{{ getValidationBadge(comp) }}</span>
|
|
341
|
+
</div>
|
|
342
|
+
<div class="header-right">
|
|
343
|
+
<rpt-icon name="chevron-down" [size]="13" class="accordion-chevron" />
|
|
344
|
+
</div>
|
|
345
|
+
</button>
|
|
346
|
+
@if (isSectionExpanded('validation')) {
|
|
347
|
+
<div class="accordion-content">
|
|
348
|
+
<rpt-property-editor-validation
|
|
349
|
+
[comp]="comp"
|
|
350
|
+
(updateValidation)="updateValidation($event.key, $event.value)"
|
|
351
|
+
/>
|
|
352
|
+
</div>
|
|
353
|
+
}
|
|
354
|
+
</div>
|
|
355
|
+
</div>
|
|
356
|
+
</div>
|
|
357
|
+
} @else {
|
|
358
|
+
<div class="empty-selection">
|
|
359
|
+
<div class="empty-icon-wrap">
|
|
360
|
+
<rpt-icon name="cursor" [size]="24" color="#64748b" />
|
|
361
|
+
</div>
|
|
362
|
+
<p class="empty-text">Select a component on the canvas to configure its properties.</p>
|
|
363
|
+
</div>
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
<!-- 2. REPORT SETTINGS TAB -->
|
|
368
|
+
@if (activeTab() === 'report') {
|
|
369
|
+
<rpt-property-editor-report
|
|
370
|
+
[definition]="definition()"
|
|
371
|
+
(updateReport)="updateReport($event.field, $event.value)"
|
|
372
|
+
(updateLayout)="updateLayoutProp($event.field, $event.value)"
|
|
373
|
+
/>
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
<!-- 3. RESULT GRID SETTINGS TAB -->
|
|
377
|
+
@if (activeTab() === 'grid') {
|
|
378
|
+
<rpt-property-editor-grid
|
|
379
|
+
[grid]="definition().grid"
|
|
380
|
+
(addColumn)="addColumn()"
|
|
381
|
+
(removeColumn)="removeColumn($event)"
|
|
382
|
+
(updateColumn)="updateColumn($event.index, $event.field, $event.value)"
|
|
383
|
+
(updateOption)="updateGridOption($event.field, $event.value)"
|
|
384
|
+
/>
|
|
385
|
+
}
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
`, isInline: true, styles: [":host{display:block;height:100%;background:#fff;border-left:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;font-family:var(--rpt-font-family, inherit)}.editor-container{display:flex;flex-direction:column;height:100%}.editor-tabs{display:flex;flex-shrink:0;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);background:var(--rpt-color-surface, #f8fafc)}.tab-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:12px 8px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:transparent;border:none;border-bottom:2px solid transparent;cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease}.tab-btn:hover:not(:disabled){color:var(--rpt-color-text, #0f172a)}.tab-btn.active{color:var(--rpt-color-primary, #2563eb);border-bottom-color:var(--rpt-color-primary, #2563eb);background:#fff}.tab-btn:disabled{opacity:.4;cursor:not-allowed}.editor-body{flex:1;overflow-y:auto;padding:12px 14px}.component-sections-wrapper{display:flex;flex-direction:column;gap:12px}.comp-badge-header{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--rpt-color-surface, #f8fafc);border-radius:6px;border:1px solid var(--rpt-color-border, #e2e8f0)}.badge-title{display:flex;align-items:center}.badge-type{font-size:.75rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);text-transform:uppercase;margin-right:8px}.badge-id{font-size:.7rem;color:var(--rpt-color-text-muted, #94a3b8);font-family:monospace}.btn-deselect{background:none;border:none;display:flex;align-items:center;justify-content:center;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;padding:3px;border-radius:4px;transition:all .15s ease}.btn-deselect:hover{color:var(--rpt-color-danger, #ef4444);background:#fee2e2}.property-accordion{display:flex;flex-direction:column;gap:10px}.accordion-item{border:1px solid var(--rpt-color-border, #e2e8f0);border-radius:6px;background:#fff;overflow:hidden;transition:all .15s ease}.accordion-item.is-expanded{border-color:#cbd5e1;box-shadow:0 1px 3px #0000000a}.accordion-header{width:100%;display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:var(--rpt-color-surface, #f8fafc);border:none;cursor:pointer;text-align:left;-webkit-user-select:none;user-select:none;transition:background .15s ease}.accordion-header:hover{background:#f1f5f9}.accordion-item.is-expanded .accordion-header{background:#f8fafc;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.header-left{display:flex;align-items:center;gap:8px;min-width:0;flex:1}.header-title{font-size:.72rem;font-weight:700;color:var(--rpt-color-text, #0f172a);text-transform:uppercase;letter-spacing:.03em;white-space:nowrap}.header-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px}.header-right{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);margin-left:8px}.accordion-chevron{transition:transform .2s ease}.accordion-item.is-expanded .accordion-chevron{transform:rotate(180deg)}.accordion-content{padding:12px;display:flex;flex-direction:column;gap:12px}::ng-deep .accordion-content .group-title{display:none}::ng-deep .accordion-content .comp-badge-header{display:none}.empty-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;box-sizing:border-box}.empty-icon-wrap{display:inline-flex;align-items:center;justify-content:center;width:52px;height:52px;border-radius:50%;background:#f1f5f9;margin-bottom:16px;box-shadow:0 1px 3px #0000000a}.empty-text{font-size:.8125rem;line-height:1.5;max-width:220px;margin:0;color:var(--rpt-color-text-muted, #64748b)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: RptIconComponent, selector: "rpt-icon", inputs: ["name", "size", "color", "strokeWidth"] }, { kind: "component", type: PropertyEditorGeneralComponent, selector: "rpt-property-editor-general", inputs: ["comp", "propertySchema"], outputs: ["update", "updateProperty", "deselect"] }, { kind: "component", type: PropertyEditorLayoutComponent, selector: "rpt-property-editor-layout", inputs: ["comp", "maxColumns"], outputs: ["updateLayout", "updateHeight", "resetDimensions"] }, { kind: "component", type: PropertyEditorValidationComponent, selector: "rpt-property-editor-validation", inputs: ["comp"], outputs: ["updateValidation"] }, { kind: "component", type: PropertyEditorGridComponent, selector: "rpt-property-editor-grid", inputs: ["grid"], outputs: ["addColumn", "removeColumn", "updateColumn", "updateOption"] }, { kind: "component", type: PropertyEditorReportComponent, selector: "rpt-property-editor-report", inputs: ["definition"], outputs: ["updateReport", "updateLayout"] }, { kind: "component", type: PropertyEditorDatasourceComponent, selector: "rpt-property-editor-datasource", inputs: ["comp", "allComponents"], outputs: ["updateDataSource", "updateProperty"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
389
|
+
}
|
|
390
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PropertyEditorComponent, decorators: [{
|
|
391
|
+
type: Component,
|
|
392
|
+
args: [{ selector: 'rpt-property-editor', standalone: true, imports: [
|
|
393
|
+
CommonModule,
|
|
394
|
+
RptIconComponent,
|
|
395
|
+
PropertyEditorGeneralComponent,
|
|
396
|
+
PropertyEditorLayoutComponent,
|
|
397
|
+
PropertyEditorValidationComponent,
|
|
398
|
+
PropertyEditorGridComponent,
|
|
399
|
+
PropertyEditorReportComponent,
|
|
400
|
+
PropertyEditorDatasourceComponent,
|
|
401
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
402
|
+
<div class="editor-container">
|
|
403
|
+
<!-- Editor Header & Tabs -->
|
|
404
|
+
<div class="editor-tabs">
|
|
405
|
+
<button
|
|
406
|
+
type="button"
|
|
407
|
+
class="tab-btn"
|
|
408
|
+
[class.active]="activeTab() === 'properties'"
|
|
409
|
+
(click)="setTab('properties')"
|
|
410
|
+
[disabled]="!selectedComponent()"
|
|
411
|
+
>
|
|
412
|
+
<rpt-icon name="edit" [size]="13" />
|
|
413
|
+
<span>Properties</span>
|
|
414
|
+
</button>
|
|
415
|
+
<button
|
|
416
|
+
type="button"
|
|
417
|
+
class="tab-btn"
|
|
418
|
+
[class.active]="activeTab() === 'report'"
|
|
419
|
+
(click)="setTab('report')"
|
|
420
|
+
>
|
|
421
|
+
<rpt-icon name="design" [size]="13" />
|
|
422
|
+
<span>Layout</span>
|
|
423
|
+
</button>
|
|
424
|
+
<button
|
|
425
|
+
type="button"
|
|
426
|
+
class="tab-btn"
|
|
427
|
+
[class.active]="activeTab() === 'grid'"
|
|
428
|
+
(click)="setTab('grid')"
|
|
429
|
+
>
|
|
430
|
+
<rpt-icon name="table" [size]="13" />
|
|
431
|
+
<span>Grid</span>
|
|
432
|
+
</button>
|
|
433
|
+
</div>
|
|
434
|
+
|
|
435
|
+
<!-- Editor Body -->
|
|
436
|
+
<div class="editor-body">
|
|
437
|
+
<!-- 1. COMPONENT PROPERTIES TAB -->
|
|
438
|
+
@if (activeTab() === 'properties') {
|
|
439
|
+
@if (selectedComponent(); as comp) {
|
|
440
|
+
<div class="component-sections-wrapper">
|
|
441
|
+
<!-- Component Identifier Header (Pinned at Top) -->
|
|
442
|
+
<div class="comp-badge-header">
|
|
443
|
+
<div class="badge-title">
|
|
444
|
+
<span class="badge-type">{{ comp.type }}</span>
|
|
445
|
+
<span class="badge-id">{{ comp.id }}</span>
|
|
446
|
+
</div>
|
|
447
|
+
<button type="button" class="btn-deselect" (click)="deselect()" title="Deselect component">
|
|
448
|
+
<rpt-icon name="close" [size]="13" />
|
|
449
|
+
</button>
|
|
450
|
+
</div>
|
|
451
|
+
|
|
452
|
+
<!-- Accordion Container -->
|
|
453
|
+
<div class="property-accordion">
|
|
454
|
+
<!-- 1. OPTIONS DATA SOURCE ACCORDION (FIRST for Dropdown) -->
|
|
455
|
+
@if (comp.type === 'dropdown') {
|
|
456
|
+
<div class="accordion-item" [class.is-expanded]="isSectionExpanded('datasource')">
|
|
457
|
+
<button
|
|
458
|
+
type="button"
|
|
459
|
+
class="accordion-header"
|
|
460
|
+
(click)="toggleSection('datasource')"
|
|
461
|
+
title="Toggle Options Data Source section"
|
|
462
|
+
>
|
|
463
|
+
<div class="header-left">
|
|
464
|
+
<rpt-icon name="database" [size]="14" />
|
|
465
|
+
<span class="header-title">Options Data Source</span>
|
|
466
|
+
<span class="header-badge">{{ getDatasourceBadge(comp) }}</span>
|
|
467
|
+
</div>
|
|
468
|
+
<div class="header-right">
|
|
469
|
+
<rpt-icon name="chevron-down" [size]="13" class="accordion-chevron" />
|
|
470
|
+
</div>
|
|
471
|
+
</button>
|
|
472
|
+
@if (isSectionExpanded('datasource')) {
|
|
473
|
+
<div class="accordion-content">
|
|
474
|
+
<rpt-property-editor-datasource
|
|
475
|
+
[comp]="comp"
|
|
476
|
+
[allComponents]="allComponents()"
|
|
477
|
+
(updateDataSource)="updateCompDataSource(comp.id, $event)"
|
|
478
|
+
(updateProperty)="updateProp(comp.id, $event.key, $event.value)"
|
|
479
|
+
/>
|
|
480
|
+
</div>
|
|
481
|
+
}
|
|
482
|
+
</div>
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
<!-- 2. GENERAL PROPERTIES ACCORDION -->
|
|
486
|
+
<div class="accordion-item" [class.is-expanded]="isSectionExpanded('general')">
|
|
487
|
+
<button
|
|
488
|
+
type="button"
|
|
489
|
+
class="accordion-header"
|
|
490
|
+
(click)="toggleSection('general')"
|
|
491
|
+
title="Toggle General Properties section"
|
|
492
|
+
>
|
|
493
|
+
<div class="header-left">
|
|
494
|
+
<rpt-icon name="edit" [size]="14" />
|
|
495
|
+
<span class="header-title">General Properties</span>
|
|
496
|
+
@if (comp.label) {
|
|
497
|
+
<span class="header-badge">{{ comp.label }}</span>
|
|
498
|
+
}
|
|
499
|
+
</div>
|
|
500
|
+
<div class="header-right">
|
|
501
|
+
<rpt-icon name="chevron-down" [size]="13" class="accordion-chevron" />
|
|
502
|
+
</div>
|
|
503
|
+
</button>
|
|
504
|
+
@if (isSectionExpanded('general')) {
|
|
505
|
+
<div class="accordion-content">
|
|
506
|
+
<rpt-property-editor-general
|
|
507
|
+
[comp]="comp"
|
|
508
|
+
[propertySchema]="propertySchema()"
|
|
509
|
+
(update)="updateComp($event.field, $event.value)"
|
|
510
|
+
(updateProperty)="updateProp(comp.id, $event.key, $event.value)"
|
|
511
|
+
(deselect)="deselect()"
|
|
512
|
+
/>
|
|
513
|
+
</div>
|
|
514
|
+
}
|
|
515
|
+
</div>
|
|
516
|
+
|
|
517
|
+
<!-- 3. LAYOUT & GRID ACCORDION -->
|
|
518
|
+
<div class="accordion-item" [class.is-expanded]="isSectionExpanded('layout')">
|
|
519
|
+
<button
|
|
520
|
+
type="button"
|
|
521
|
+
class="accordion-header"
|
|
522
|
+
(click)="toggleSection('layout')"
|
|
523
|
+
title="Toggle Layout & Dimensions section"
|
|
524
|
+
>
|
|
525
|
+
<div class="header-left">
|
|
526
|
+
<rpt-icon name="design" [size]="14" />
|
|
527
|
+
<span class="header-title">Layout & Grid</span>
|
|
528
|
+
<span class="header-badge">{{ getLayoutBadge(comp) }}</span>
|
|
529
|
+
</div>
|
|
530
|
+
<div class="header-right">
|
|
531
|
+
<rpt-icon name="chevron-down" [size]="13" class="accordion-chevron" />
|
|
532
|
+
</div>
|
|
533
|
+
</button>
|
|
534
|
+
@if (isSectionExpanded('layout')) {
|
|
535
|
+
<div class="accordion-content">
|
|
536
|
+
<rpt-property-editor-layout
|
|
537
|
+
[comp]="comp"
|
|
538
|
+
[maxColumns]="maxColumns()"
|
|
539
|
+
(updateLayout)="updateLayout($event.key, $event.value)"
|
|
540
|
+
(updateHeight)="updateComponentHeight($event)"
|
|
541
|
+
(resetDimensions)="resetComponentDimensions(comp.id, comp.type)"
|
|
542
|
+
/>
|
|
543
|
+
</div>
|
|
544
|
+
}
|
|
545
|
+
</div>
|
|
546
|
+
|
|
547
|
+
<!-- 4. VALIDATION ACCORDION -->
|
|
548
|
+
<div class="accordion-item" [class.is-expanded]="isSectionExpanded('validation')">
|
|
549
|
+
<button
|
|
550
|
+
type="button"
|
|
551
|
+
class="accordion-header"
|
|
552
|
+
(click)="toggleSection('validation')"
|
|
553
|
+
title="Toggle Validation Rules section"
|
|
554
|
+
>
|
|
555
|
+
<div class="header-left">
|
|
556
|
+
<rpt-icon name="check" [size]="14" />
|
|
557
|
+
<span class="header-title">Validation Rules</span>
|
|
558
|
+
<span class="header-badge">{{ getValidationBadge(comp) }}</span>
|
|
559
|
+
</div>
|
|
560
|
+
<div class="header-right">
|
|
561
|
+
<rpt-icon name="chevron-down" [size]="13" class="accordion-chevron" />
|
|
562
|
+
</div>
|
|
563
|
+
</button>
|
|
564
|
+
@if (isSectionExpanded('validation')) {
|
|
565
|
+
<div class="accordion-content">
|
|
566
|
+
<rpt-property-editor-validation
|
|
567
|
+
[comp]="comp"
|
|
568
|
+
(updateValidation)="updateValidation($event.key, $event.value)"
|
|
569
|
+
/>
|
|
570
|
+
</div>
|
|
571
|
+
}
|
|
572
|
+
</div>
|
|
573
|
+
</div>
|
|
574
|
+
</div>
|
|
575
|
+
} @else {
|
|
576
|
+
<div class="empty-selection">
|
|
577
|
+
<div class="empty-icon-wrap">
|
|
578
|
+
<rpt-icon name="cursor" [size]="24" color="#64748b" />
|
|
579
|
+
</div>
|
|
580
|
+
<p class="empty-text">Select a component on the canvas to configure its properties.</p>
|
|
581
|
+
</div>
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
<!-- 2. REPORT SETTINGS TAB -->
|
|
586
|
+
@if (activeTab() === 'report') {
|
|
587
|
+
<rpt-property-editor-report
|
|
588
|
+
[definition]="definition()"
|
|
589
|
+
(updateReport)="updateReport($event.field, $event.value)"
|
|
590
|
+
(updateLayout)="updateLayoutProp($event.field, $event.value)"
|
|
591
|
+
/>
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
<!-- 3. RESULT GRID SETTINGS TAB -->
|
|
595
|
+
@if (activeTab() === 'grid') {
|
|
596
|
+
<rpt-property-editor-grid
|
|
597
|
+
[grid]="definition().grid"
|
|
598
|
+
(addColumn)="addColumn()"
|
|
599
|
+
(removeColumn)="removeColumn($event)"
|
|
600
|
+
(updateColumn)="updateColumn($event.index, $event.field, $event.value)"
|
|
601
|
+
(updateOption)="updateGridOption($event.field, $event.value)"
|
|
602
|
+
/>
|
|
603
|
+
}
|
|
604
|
+
</div>
|
|
605
|
+
</div>
|
|
606
|
+
`, styles: [":host{display:block;height:100%;background:#fff;border-left:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;font-family:var(--rpt-font-family, inherit)}.editor-container{display:flex;flex-direction:column;height:100%}.editor-tabs{display:flex;flex-shrink:0;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);background:var(--rpt-color-surface, #f8fafc)}.tab-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:12px 8px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:transparent;border:none;border-bottom:2px solid transparent;cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease}.tab-btn:hover:not(:disabled){color:var(--rpt-color-text, #0f172a)}.tab-btn.active{color:var(--rpt-color-primary, #2563eb);border-bottom-color:var(--rpt-color-primary, #2563eb);background:#fff}.tab-btn:disabled{opacity:.4;cursor:not-allowed}.editor-body{flex:1;overflow-y:auto;padding:12px 14px}.component-sections-wrapper{display:flex;flex-direction:column;gap:12px}.comp-badge-header{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--rpt-color-surface, #f8fafc);border-radius:6px;border:1px solid var(--rpt-color-border, #e2e8f0)}.badge-title{display:flex;align-items:center}.badge-type{font-size:.75rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);text-transform:uppercase;margin-right:8px}.badge-id{font-size:.7rem;color:var(--rpt-color-text-muted, #94a3b8);font-family:monospace}.btn-deselect{background:none;border:none;display:flex;align-items:center;justify-content:center;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;padding:3px;border-radius:4px;transition:all .15s ease}.btn-deselect:hover{color:var(--rpt-color-danger, #ef4444);background:#fee2e2}.property-accordion{display:flex;flex-direction:column;gap:10px}.accordion-item{border:1px solid var(--rpt-color-border, #e2e8f0);border-radius:6px;background:#fff;overflow:hidden;transition:all .15s ease}.accordion-item.is-expanded{border-color:#cbd5e1;box-shadow:0 1px 3px #0000000a}.accordion-header{width:100%;display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:var(--rpt-color-surface, #f8fafc);border:none;cursor:pointer;text-align:left;-webkit-user-select:none;user-select:none;transition:background .15s ease}.accordion-header:hover{background:#f1f5f9}.accordion-item.is-expanded .accordion-header{background:#f8fafc;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.header-left{display:flex;align-items:center;gap:8px;min-width:0;flex:1}.header-title{font-size:.72rem;font-weight:700;color:var(--rpt-color-text, #0f172a);text-transform:uppercase;letter-spacing:.03em;white-space:nowrap}.header-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:120px}.header-right{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);margin-left:8px}.accordion-chevron{transition:transform .2s ease}.accordion-item.is-expanded .accordion-chevron{transform:rotate(180deg)}.accordion-content{padding:12px;display:flex;flex-direction:column;gap:12px}::ng-deep .accordion-content .group-title{display:none}::ng-deep .accordion-content .comp-badge-header{display:none}.empty-selection{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;box-sizing:border-box}.empty-icon-wrap{display:inline-flex;align-items:center;justify-content:center;width:52px;height:52px;border-radius:50%;background:#f1f5f9;margin-bottom:16px;box-shadow:0 1px 3px #0000000a}.empty-text{font-size:.8125rem;line-height:1.5;max-width:220px;margin:0;color:var(--rpt-color-text-muted, #64748b)}\n"] }]
|
|
607
|
+
}] });
|
|
608
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHktZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL2ZlYXR1cmVzL2Rlc2lnbmVyL2NvbXBvbmVudHMvcHJvcGVydHktZWRpdG9yL3Byb3BlcnR5LWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBcUIsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNoRyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUlqRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyREFBMkQsQ0FBQztBQUM3RixPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNyRixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUMzRixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMvRSxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQzs7QUFNM0Y7Ozs7O0dBS0c7QUFxYkgsTUFBTSxPQUFPLHVCQUF1QjtJQUNqQixhQUFhLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDN0MsUUFBUSxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBRTdDLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQztJQUMzQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUM7SUFDekMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQztJQUV6RCxVQUFVLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3BFLGFBQWEsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRTdELGNBQWMsR0FBRyxRQUFRLENBQXVCLEdBQUcsRUFBRTtRQUM1RCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QyxPQUFPLElBQUksRUFBRSxjQUFjLElBQUksRUFBRSxDQUFDO0lBQ3BDLENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxDQUFDLEdBQXNCO1FBQzNCLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxFQUFVLEVBQUUsVUFBeUM7UUFDeEUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxVQUFVLENBQUMsS0FBYSxFQUFFLEtBQWM7UUFDdEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDdEMsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDbEUsQ0FBQztJQUNILENBQUM7SUFFRCxVQUFVLENBQUMsRUFBVSxFQUFFLEdBQVcsRUFBRSxLQUFjO1FBQ2hELElBQUksQ0FBQyxhQUFhLENBQUMsdUJBQXVCLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQsWUFBWSxDQUFDLEdBQW9DLEVBQUUsS0FBYztRQUMvRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN0QyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7SUFDSCxDQUFDO0lBRUQscUJBQXFCLENBQUMsR0FBVztRQUMvQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUN0QyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU87UUFDbEIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxLQUFLLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDOUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFO1lBQ2hELE1BQU07WUFDTixTQUFTLEVBQUUsTUFBTTtTQUNsQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsd0JBQXdCLENBQUMsRUFBVSxFQUFFLElBQVk7UUFDL0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLEVBQUU7WUFDM0MsVUFBVSxFQUFFLFdBQVc7WUFDdkIsTUFBTSxFQUFFLFNBQVM7WUFDakIsU0FBUyxFQUFFLFNBQVM7WUFDcEIsS0FBSyxFQUFFLFNBQVM7U0FDakIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGdCQUFnQixDQUFDLEdBQVcsRUFBRSxLQUFjO1FBQzFDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3RDLElBQUksSUFBSSxFQUFFLENBQUM7WUFDVCxNQUFNLGNBQWMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDcEUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQzlFLENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBWSxDQUFDLEdBQVcsRUFBRSxLQUFjO1FBQ3RDLElBQUksQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELGdCQUFnQixDQUFDLEdBQVcsRUFBRSxLQUFjO1FBQzFDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQUM7UUFDL0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQztZQUN0QyxNQUFNLEVBQUUsRUFBRSxHQUFHLGFBQWEsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRTtTQUMzQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsU0FBUztRQUNQLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLElBQUk7WUFDeEMsWUFBWSxFQUFFLFNBQVM7WUFDdkIsT0FBTyxFQUFFLEVBQUU7U0FDWixDQUFDO1FBQ0YsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sTUFBTSxHQUF5QjtZQUNuQyxLQUFLLEVBQUUsU0FBUyxRQUFRLEVBQUU7WUFDMUIsS0FBSyxFQUFFLFVBQVUsUUFBUSxFQUFFO1lBQzNCLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLFFBQVEsRUFBRSxJQUFJO1lBQ2QsS0FBSyxFQUFFLE1BQU07U0FDZCxDQUFDO1FBQ0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQztZQUNwQyxHQUFHLE9BQU87WUFDVixPQUFPLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO1NBQ3RDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxZQUFZLENBQUMsS0FBYTtRQUN4QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUNyQixNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUM7WUFDcEMsR0FBRyxPQUFPO1lBQ1YsT0FBTyxFQUFFLFFBQVE7U0FDbEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFhLEVBQUUsS0FBYSxFQUFFLEtBQWM7UUFDdkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQztRQUN2QyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU87UUFDckIsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUU7WUFDOUMsSUFBSSxHQUFHLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQ2xCLE9BQU8sRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQ2xDLENBQUM7WUFDRCxPQUFPLENBQUMsQ0FBQztRQUNYLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQztZQUNwQyxHQUFHLE9BQU87WUFDVixPQUFPLEVBQUUsUUFBUTtTQUNsQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsS0FBYSxFQUFFLEtBQWM7UUFDNUMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLElBQUksSUFBSTtZQUN4QyxZQUFZLEVBQUUsU0FBUztZQUN2QixPQUFPLEVBQUUsRUFBRTtTQUNaLENBQUM7UUFDRixNQUFNLFdBQVcsR0FBRyxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDbkUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQztZQUNwQyxHQUFHLE9BQU87WUFDVixPQUFPLEVBQUUsV0FBVztTQUNyQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRVEsZ0JBQWdCLEdBQUcsTUFBTSxDQUEwQjtRQUMxRCxVQUFVLEVBQUUsSUFBSTtRQUNoQixPQUFPLEVBQUUsSUFBSTtRQUNiLE1BQU0sRUFBRSxLQUFLO1FBQ2IsVUFBVSxFQUFFLEtBQUs7S0FDbEIsQ0FBQyxDQUFDO0lBRUgsYUFBYSxDQUFDLE9BQWU7UUFDM0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0QyxHQUFHLElBQUk7WUFDUCxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztTQUMxQixDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxPQUFlO1FBQy9CLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxJQUErQjtRQUNoRCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQzNCLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLFVBQVUsS0FBSyxRQUFRO1lBQUUsT0FBTyxhQUFhLENBQUM7UUFDNUQsSUFBSSxFQUFFLENBQUMsVUFBVSxLQUFLLE9BQU8sSUFBSSxFQUFFLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDL0MsT0FBTyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDO1FBQ3BFLENBQUM7UUFDRCxJQUFJLEVBQUUsQ0FBQyxVQUFVLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsT0FBTyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDO1FBQ2hFLENBQUM7UUFDRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0lBRUQsY0FBYyxDQUFDLElBQStCO1FBQzVDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekUsT0FBTyxHQUFHLElBQUksSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQztJQUM3QyxDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBK0I7UUFDaEQsT0FBTyxJQUFJLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7SUFDN0QsQ0FBQzt3R0FyTFUsdUJBQXVCOzRGQUF2Qix1QkFBdUIsK0VBdGF4Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZNVCw4NEhBdk5DLFlBQVksK0JBQ1osZ0JBQWdCLHVHQUNoQiw4QkFBOEIsK0pBQzlCLDZCQUE2QixxS0FDN0IsaUNBQWlDLDRIQUNqQywyQkFBMkIsK0pBQzNCLDZCQUE2QiwwSUFDN0IsaUNBQWlDOzs0RkF5YXhCLHVCQUF1QjtrQkFwYm5DLFNBQVM7K0JBQ0UscUJBQXFCLGNBQ25CLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLGdCQUFnQjt3QkFDaEIsOEJBQThCO3dCQUM5Qiw2QkFBNkI7d0JBQzdCLGlDQUFpQzt3QkFDakMsMkJBQTJCO3dCQUMzQiw2QkFBNkI7d0JBQzdCLGlDQUFpQztxQkFDbEMsbUJBQ2dCLHVCQUF1QixDQUFDLE1BQU0sWUFDckM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2TVQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBjb21wdXRlZCxcbiAgaW5qZWN0LFxuICBzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IERlc2lnbmVyQWN0aXZlVGFiLCBEZXNpZ25lclN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2Rlc2lnbmVyLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVnaXN0cnkgfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3JlZ2lzdHJ5L2NvbXBvbmVudC1yZWdpc3RyeSc7XG5pbXBvcnQgeyBQcm9wZXJ0eURlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3JlZ2lzdHJ5L3Byb3BlcnR5LWRlZmluaXRpb24ubW9kZWwnO1xuaW1wb3J0IHsgQ29tcG9uZW50TGF5b3V0RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1sYXlvdXQubW9kZWwnO1xuaW1wb3J0IHsgR3JpZENvbHVtbkRlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtZ3JpZC5tb2RlbCc7XG5pbXBvcnQgeyBScHRJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vcHJpbWl0aXZlcy9jb21wb25lbnRzL2ljb24vcnB0LWljb24uY29tcG9uZW50JztcbmltcG9ydCB7IFByb3BlcnR5RWRpdG9yR2VuZXJhbENvbXBvbmVudCB9IGZyb20gJy4vcHJvcGVydHktZWRpdG9yLWdlbmVyYWwuY29tcG9uZW50JztcbmltcG9ydCB7IFByb3BlcnR5RWRpdG9yTGF5b3V0Q29tcG9uZW50IH0gZnJvbSAnLi9wcm9wZXJ0eS1lZGl0b3ItbGF5b3V0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQcm9wZXJ0eUVkaXRvclZhbGlkYXRpb25Db21wb25lbnQgfSBmcm9tICcuL3Byb3BlcnR5LWVkaXRvci12YWxpZGF0aW9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQcm9wZXJ0eUVkaXRvckdyaWRDb21wb25lbnQgfSBmcm9tICcuL3Byb3BlcnR5LWVkaXRvci1ncmlkLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQcm9wZXJ0eUVkaXRvclJlcG9ydENvbXBvbmVudCB9IGZyb20gJy4vcHJvcGVydHktZWRpdG9yLXJlcG9ydC5jb21wb25lbnQnO1xuaW1wb3J0IHsgUHJvcGVydHlFZGl0b3JEYXRhc291cmNlQ29tcG9uZW50IH0gZnJvbSAnLi9wcm9wZXJ0eS1lZGl0b3ItZGF0YXNvdXJjZS5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50RGF0YVNvdXJjZURlZmluaXRpb24sXG4gIFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sXG59IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1jb21wb25lbnQubW9kZWwnO1xuXG4vKipcbiAqIFByb3BlcnR5IEVkaXRvciBjb29yZGluYXRvciBjb21wb25lbnQuXG4gKlxuICogRGVjb21wb3NlZCBpbnRvIGZvY3VzZWQgY2hpbGQgcHJlc2VudGF0aW9uYWwgY29tcG9uZW50cyBwZXIgUnVsZSAxOCAmIDE5IChDb21wb3NpdGlvbiBPdmVyIEdpYW50IENvbXBvbmVudHMpXG4gKiBhbmQgUnVsZSAzMiAoQXZvaWQgR29kIENvbXBvbmVudHMpLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdycHQtcHJvcGVydHktZWRpdG9yJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBScHRJY29uQ29tcG9uZW50LFxuICAgIFByb3BlcnR5RWRpdG9yR2VuZXJhbENvbXBvbmVudCxcbiAgICBQcm9wZXJ0eUVkaXRvckxheW91dENvbXBvbmVudCxcbiAgICBQcm9wZXJ0eUVkaXRvclZhbGlkYXRpb25Db21wb25lbnQsXG4gICAgUHJvcGVydHlFZGl0b3JHcmlkQ29tcG9uZW50LFxuICAgIFByb3BlcnR5RWRpdG9yUmVwb3J0Q29tcG9uZW50LFxuICAgIFByb3BlcnR5RWRpdG9yRGF0YXNvdXJjZUNvbXBvbmVudCxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImVkaXRvci1jb250YWluZXJcIj5cbiAgICAgIDwhLS0gRWRpdG9yIEhlYWRlciAmIFRhYnMgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZWRpdG9yLXRhYnNcIj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwidGFiLWJ0blwiXG4gICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJhY3RpdmVUYWIoKSA9PT0gJ3Byb3BlcnRpZXMnXCJcbiAgICAgICAgICAoY2xpY2spPVwic2V0VGFiKCdwcm9wZXJ0aWVzJylcIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCIhc2VsZWN0ZWRDb21wb25lbnQoKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImVkaXRcIiBbc2l6ZV09XCIxM1wiIC8+XG4gICAgICAgICAgPHNwYW4+UHJvcGVydGllczwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cInRhYi1idG5cIlxuICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlVGFiKCkgPT09ICdyZXBvcnQnXCJcbiAgICAgICAgICAoY2xpY2spPVwic2V0VGFiKCdyZXBvcnQnKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImRlc2lnblwiIFtzaXplXT1cIjEzXCIgLz5cbiAgICAgICAgICA8c3Bhbj5MYXlvdXQ8L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJ0YWItYnRuXCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImFjdGl2ZVRhYigpID09PSAnZ3JpZCdcIlxuICAgICAgICAgIChjbGljayk9XCJzZXRUYWIoJ2dyaWQnKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTNcIiAvPlxuICAgICAgICAgIDxzcGFuPkdyaWQ8L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gRWRpdG9yIEJvZHkgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZWRpdG9yLWJvZHlcIj5cbiAgICAgICAgPCEtLSAxLiBDT01QT05FTlQgUFJPUEVSVElFUyBUQUIgLS0+XG4gICAgICAgIEBpZiAoYWN0aXZlVGFiKCkgPT09ICdwcm9wZXJ0aWVzJykge1xuICAgICAgICAgIEBpZiAoc2VsZWN0ZWRDb21wb25lbnQoKTsgYXMgY29tcCkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXBvbmVudC1zZWN0aW9ucy13cmFwcGVyXCI+XG4gICAgICAgICAgICAgIDwhLS0gQ29tcG9uZW50IElkZW50aWZpZXIgSGVhZGVyIChQaW5uZWQgYXQgVG9wKSAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbXAtYmFkZ2UtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJhZGdlLXRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlLXR5cGVcIj57eyBjb21wLnR5cGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlLWlkXCI+e3sgY29tcC5pZCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1kZXNlbGVjdFwiIChjbGljayk9XCJkZXNlbGVjdCgpXCIgdGl0bGU9XCJEZXNlbGVjdCBjb21wb25lbnRcIj5cbiAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2xvc2VcIiBbc2l6ZV09XCIxM1wiIC8+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIDwhLS0gQWNjb3JkaW9uIENvbnRhaW5lciAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInByb3BlcnR5LWFjY29yZGlvblwiPlxuICAgICAgICAgICAgICAgIDwhLS0gMS4gT1BUSU9OUyBEQVRBIFNPVVJDRSBBQ0NPUkRJT04gKEZJUlNUIGZvciBEcm9wZG93bikgLS0+XG4gICAgICAgICAgICAgICAgQGlmIChjb21wLnR5cGUgPT09ICdkcm9wZG93bicpIHtcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhY2NvcmRpb24taXRlbVwiIFtjbGFzcy5pcy1leHBhbmRlZF09XCJpc1NlY3Rpb25FeHBhbmRlZCgnZGF0YXNvdXJjZScpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFjY29yZGlvbi1oZWFkZXJcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCdkYXRhc291cmNlJylcIlxuICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiVG9nZ2xlIE9wdGlvbnMgRGF0YSBTb3VyY2Ugc2VjdGlvblwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLWxlZnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiZGF0YWJhc2VcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhlYWRlci10aXRsZVwiPk9wdGlvbnMgRGF0YSBTb3VyY2U8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhlYWRlci1iYWRnZVwiPnt7IGdldERhdGFzb3VyY2VCYWRnZShjb21wKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZXZyb24tZG93blwiIFtzaXplXT1cIjEzXCIgY2xhc3M9XCJhY2NvcmRpb24tY2hldnJvblwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKGlzU2VjdGlvbkV4cGFuZGVkKCdkYXRhc291cmNlJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWNjb3JkaW9uLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtcHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NvbXBdPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFthbGxDb21wb25lbnRzXT1cImFsbENvbXBvbmVudHMoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICh1cGRhdGVEYXRhU291cmNlKT1cInVwZGF0ZUNvbXBEYXRhU291cmNlKGNvbXAuaWQsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAodXBkYXRlUHJvcGVydHkpPVwidXBkYXRlUHJvcChjb21wLmlkLCAkZXZlbnQua2V5LCAkZXZlbnQudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIDwhLS0gMi4gR0VORVJBTCBQUk9QRVJUSUVTIEFDQ09SRElPTiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWNjb3JkaW9uLWl0ZW1cIiBbY2xhc3MuaXMtZXhwYW5kZWRdPVwiaXNTZWN0aW9uRXhwYW5kZWQoJ2dlbmVyYWwnKVwiPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJhY2NvcmRpb24taGVhZGVyXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVNlY3Rpb24oJ2dlbmVyYWwnKVwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiVG9nZ2xlIEdlbmVyYWwgUHJvcGVydGllcyBzZWN0aW9uXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci1sZWZ0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJlZGl0XCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaGVhZGVyLXRpdGxlXCI+R2VuZXJhbCBQcm9wZXJ0aWVzPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29tcC5sYWJlbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJoZWFkZXItYmFkZ2VcIj57eyBjb21wLmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZXZyb24tZG93blwiIFtzaXplXT1cIjEzXCIgY2xhc3M9XCJhY2NvcmRpb24tY2hldnJvblwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICBAaWYgKGlzU2VjdGlvbkV4cGFuZGVkKCdnZW5lcmFsJykpIHtcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjY29yZGlvbi1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHJwdC1wcm9wZXJ0eS1lZGl0b3ItZ2VuZXJhbFxuICAgICAgICAgICAgICAgICAgICAgICAgW2NvbXBdPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbcHJvcGVydHlTY2hlbWFdPVwicHJvcGVydHlTY2hlbWEoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAodXBkYXRlKT1cInVwZGF0ZUNvbXAoJGV2ZW50LmZpZWxkLCAkZXZlbnQudmFsdWUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICh1cGRhdGVQcm9wZXJ0eSk9XCJ1cGRhdGVQcm9wKGNvbXAuaWQsICRldmVudC5rZXksICRldmVudC52YWx1ZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGRlc2VsZWN0KT1cImRlc2VsZWN0KClcIlxuICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSAzLiBMQVlPVVQgJiBHUklEIEFDQ09SRElPTiAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWNjb3JkaW9uLWl0ZW1cIiBbY2xhc3MuaXMtZXhwYW5kZWRdPVwiaXNTZWN0aW9uRXhwYW5kZWQoJ2xheW91dCcpXCI+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFjY29yZGlvbi1oZWFkZXJcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwidG9nZ2xlU2VjdGlvbignbGF5b3V0JylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlRvZ2dsZSBMYXlvdXQgJiBEaW1lbnNpb25zIHNlY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLWxlZnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImRlc2lnblwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhlYWRlci10aXRsZVwiPkxheW91dCAmIEdyaWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJoZWFkZXItYmFkZ2VcIj57eyBnZXRMYXlvdXRCYWRnZShjb21wKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZXZyb24tZG93blwiIFtzaXplXT1cIjEzXCIgY2xhc3M9XCJhY2NvcmRpb24tY2hldnJvblwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICBAaWYgKGlzU2VjdGlvbkV4cGFuZGVkKCdsYXlvdXQnKSkge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWNjb3JkaW9uLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cnB0LXByb3BlcnR5LWVkaXRvci1sYXlvdXRcbiAgICAgICAgICAgICAgICAgICAgICAgIFtjb21wXT1cImNvbXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW21heENvbHVtbnNdPVwibWF4Q29sdW1ucygpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICh1cGRhdGVMYXlvdXQpPVwidXBkYXRlTGF5b3V0KCRldmVudC5rZXksICRldmVudC52YWx1ZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKHVwZGF0ZUhlaWdodCk9XCJ1cGRhdGVDb21wb25lbnRIZWlnaHQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAocmVzZXREaW1lbnNpb25zKT1cInJlc2V0Q29tcG9uZW50RGltZW5zaW9ucyhjb21wLmlkLCBjb21wLnR5cGUpXCJcbiAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gNC4gVkFMSURBVElPTiBBQ0NPUkRJT04gLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjY29yZGlvbi1pdGVtXCIgW2NsYXNzLmlzLWV4cGFuZGVkXT1cImlzU2VjdGlvbkV4cGFuZGVkKCd2YWxpZGF0aW9uJylcIj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYWNjb3JkaW9uLWhlYWRlclwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCd2YWxpZGF0aW9uJylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlRvZ2dsZSBWYWxpZGF0aW9uIFJ1bGVzIHNlY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLWxlZnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZWNrXCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaGVhZGVyLXRpdGxlXCI+VmFsaWRhdGlvbiBSdWxlczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhlYWRlci1iYWRnZVwiPnt7IGdldFZhbGlkYXRpb25CYWRnZShjb21wKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItcmlnaHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZXZyb24tZG93blwiIFtzaXplXT1cIjEzXCIgY2xhc3M9XCJhY2NvcmRpb24tY2hldnJvblwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICBAaWYgKGlzU2VjdGlvbkV4cGFuZGVkKCd2YWxpZGF0aW9uJykpIHtcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjY29yZGlvbi1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHJwdC1wcm9wZXJ0eS1lZGl0b3ItdmFsaWRhdGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgW2NvbXBdPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAodXBkYXRlVmFsaWRhdGlvbik9XCJ1cGRhdGVWYWxpZGF0aW9uKCRldmVudC5rZXksICRldmVudC52YWx1ZSlcIlxuICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXNlbGVjdGlvblwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktaWNvbi13cmFwXCI+XG4gICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjdXJzb3JcIiBbc2l6ZV09XCIyNFwiIGNvbG9yPVwiIzY0NzQ4YlwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8cCBjbGFzcz1cImVtcHR5LXRleHRcIj5TZWxlY3QgYSBjb21wb25lbnQgb24gdGhlIGNhbnZhcyB0byBjb25maWd1cmUgaXRzIHByb3BlcnRpZXMuPC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgPCEtLSAyLiBSRVBPUlQgU0VUVElOR1MgVEFCIC0tPlxuICAgICAgICBAaWYgKGFjdGl2ZVRhYigpID09PSAncmVwb3J0Jykge1xuICAgICAgICAgIDxycHQtcHJvcGVydHktZWRpdG9yLXJlcG9ydFxuICAgICAgICAgICAgW2RlZmluaXRpb25dPVwiZGVmaW5pdGlvbigpXCJcbiAgICAgICAgICAgICh1cGRhdGVSZXBvcnQpPVwidXBkYXRlUmVwb3J0KCRldmVudC5maWVsZCwgJGV2ZW50LnZhbHVlKVwiXG4gICAgICAgICAgICAodXBkYXRlTGF5b3V0KT1cInVwZGF0ZUxheW91dFByb3AoJGV2ZW50LmZpZWxkLCAkZXZlbnQudmFsdWUpXCJcbiAgICAgICAgICAvPlxuICAgICAgICB9XG5cbiAgICAgICAgPCEtLSAzLiBSRVNVTFQgR1JJRCBTRVRUSU5HUyBUQUIgLS0+XG4gICAgICAgIEBpZiAoYWN0aXZlVGFiKCkgPT09ICdncmlkJykge1xuICAgICAgICAgIDxycHQtcHJvcGVydHktZWRpdG9yLWdyaWRcbiAgICAgICAgICAgIFtncmlkXT1cImRlZmluaXRpb24oKS5ncmlkXCJcbiAgICAgICAgICAgIChhZGRDb2x1bW4pPVwiYWRkQ29sdW1uKClcIlxuICAgICAgICAgICAgKHJlbW92ZUNvbHVtbik9XCJyZW1vdmVDb2x1bW4oJGV2ZW50KVwiXG4gICAgICAgICAgICAodXBkYXRlQ29sdW1uKT1cInVwZGF0ZUNvbHVtbigkZXZlbnQuaW5kZXgsICRldmVudC5maWVsZCwgJGV2ZW50LnZhbHVlKVwiXG4gICAgICAgICAgICAodXBkYXRlT3B0aW9uKT1cInVwZGF0ZUdyaWRPcHRpb24oJGV2ZW50LmZpZWxkLCAkZXZlbnQudmFsdWUpXCJcbiAgICAgICAgICAvPlxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIDpob3N0IHtcbiAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgYmFja2dyb3VuZDogI2ZmZmZmZjtcbiAgICAgIGJvcmRlci1sZWZ0OiAxcHggc29saWQgdmFyKC0tcnB0LWNvbG9yLWJvcmRlciwgI2NiZDVlMSk7XG4gICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgZm9udC1mYW1pbHk6IHZhcigtLXJwdC1mb250LWZhbWlseSwgaW5oZXJpdCk7XG4gICAgfVxuICAgIC5lZGl0b3ItY29udGFpbmVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgIH1cbiAgICAuZWRpdG9yLXRhYnMge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtc2hyaW5rOiAwO1xuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLXJwdC1jb2xvci1ib3JkZXIsICNjYmQ1ZTEpO1xuICAgICAgYmFja2dyb3VuZDogdmFyKC0tcnB0LWNvbG9yLXN1cmZhY2UsICNmOGZhZmMpO1xuICAgIH1cbiAgICAudGFiLWJ0biB7XG4gICAgICBmbGV4OiAxO1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICBnYXA6IDZweDtcbiAgICAgIHBhZGRpbmc6IDEycHggOHB4O1xuICAgICAgZm9udC1zaXplOiB2YXIoLS1ycHQtZm9udC1zaXplLXNtLCAwLjc1cmVtKTtcbiAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLXRleHQtbXV0ZWQsICM2NDc0OGIpO1xuICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICBib3JkZXI6IG5vbmU7XG4gICAgICBib3JkZXItYm90dG9tOiAycHggc29saWQgdHJhbnNwYXJlbnQ7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB0cmFuc2l0aW9uOiBhbGwgdmFyKC0tcnB0LXRyYW5zaXRpb24tc3BlZWQsIDE1MG1zKSBlYXNlO1xuICAgIH1cbiAgICAudGFiLWJ0bjpob3Zlcjpub3QoOmRpc2FibGVkKSB7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLXRleHQsICMwZjE3MmEpO1xuICAgIH1cbiAgICAudGFiLWJ0bi5hY3RpdmUge1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci1wcmltYXJ5LCAjMjU2M2ViKTtcbiAgICAgIGJvcmRlci1ib3R0b20tY29sb3I6IHZhcigtLXJwdC1jb2xvci1wcmltYXJ5LCAjMjU2M2ViKTtcbiAgICAgIGJhY2tncm91bmQ6ICNmZmZmZmY7XG4gICAgfVxuICAgIC50YWItYnRuOmRpc2FibGVkIHtcbiAgICAgIG9wYWNpdHk6IDAuNDtcbiAgICAgIGN1cnNvcjogbm90LWFsbG93ZWQ7XG4gICAgfVxuICAgIC5lZGl0b3ItYm9keSB7XG4gICAgICBmbGV4OiAxO1xuICAgICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICAgIHBhZGRpbmc6IDEycHggMTRweDtcbiAgICB9XG4gICAgLmNvbXBvbmVudC1zZWN0aW9ucy13cmFwcGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgZ2FwOiAxMnB4O1xuICAgIH1cbiAgICAuY29tcC1iYWRnZS1oZWFkZXIge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgICBwYWRkaW5nOiA4cHggMTJweDtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLXJwdC1jb2xvci1zdXJmYWNlLCAjZjhmYWZjKTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHZhcigtLXJwdC1jb2xvci1ib3JkZXIsICNlMmU4ZjApO1xuICAgIH1cbiAgICAuYmFkZ2UtdGl0bGUge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgfVxuICAgIC5iYWRnZS10eXBlIHtcbiAgICAgIGZvbnQtc2l6ZTogMC43NXJlbTtcbiAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLXByaW1hcnksICMyNTYzZWIpO1xuICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICAgIG1hcmdpbi1yaWdodDogOHB4O1xuICAgIH1cbiAgICAuYmFkZ2UtaWQge1xuICAgICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLXRleHQtbXV0ZWQsICM5NGEzYjgpO1xuICAgICAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcbiAgICB9XG4gICAgLmJ0bi1kZXNlbGVjdCB7XG4gICAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItdGV4dC1tdXRlZCwgIzY0NzQ4Yik7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICBwYWRkaW5nOiAzcHg7XG4gICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICB0cmFuc2l0aW9uOiBhbGwgMTUwbXMgZWFzZTtcbiAgICB9XG4gICAgLmJ0bi1kZXNlbGVjdDpob3ZlciB7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLWRhbmdlciwgI2VmNDQ0NCk7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmVlMmUyO1xuICAgIH1cbiAgICAucHJvcGVydHktYWNjb3JkaW9uIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgZ2FwOiAxMHB4O1xuICAgIH1cbiAgICAuYWNjb3JkaW9uLWl0ZW0ge1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tcnB0LWNvbG9yLWJvcmRlciwgI2UyZThmMCk7XG4gICAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmZmZmZmO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIHRyYW5zaXRpb246IGFsbCAxNTBtcyBlYXNlO1xuICAgIH1cbiAgICAuYWNjb3JkaW9uLWl0ZW0uaXMtZXhwYW5kZWQge1xuICAgICAgYm9yZGVyLWNvbG9yOiAjY2JkNWUxO1xuICAgICAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC4wNCk7XG4gICAgfVxuICAgIC5hY2NvcmRpb24taGVhZGVyIHtcbiAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgICBwYWRkaW5nOiAxMHB4IDEycHg7XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1ycHQtY29sb3Itc3VyZmFjZSwgI2Y4ZmFmYyk7XG4gICAgICBib3JkZXI6IG5vbmU7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB0ZXh0LWFsaWduOiBsZWZ0O1xuICAgICAgdXNlci1zZWxlY3Q6IG5vbmU7XG4gICAgICB0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kIDE1MG1zIGVhc2U7XG4gICAgfVxuICAgIC5hY2NvcmRpb24taGVhZGVyOmhvdmVyIHtcbiAgICAgIGJhY2tncm91bmQ6ICNmMWY1Zjk7XG4gICAgfVxuICAgIC5hY2NvcmRpb24taXRlbS5pcy1leHBhbmRlZCAuYWNjb3JkaW9uLWhlYWRlciB7XG4gICAgICBiYWNrZ3JvdW5kOiAjZjhmYWZjO1xuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLXJwdC1jb2xvci1ib3JkZXIsICNlMmU4ZjApO1xuICAgIH1cbiAgICAuaGVhZGVyLWxlZnQge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBnYXA6IDhweDtcbiAgICAgIG1pbi13aWR0aDogMDtcbiAgICAgIGZsZXg6IDE7XG4gICAgfVxuICAgIC5oZWFkZXItdGl0bGUge1xuICAgICAgZm9udC1zaXplOiAwLjcycmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItdGV4dCwgIzBmMTcyYSk7XG4gICAgICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xuICAgICAgbGV0dGVyLXNwYWNpbmc6IDAuMDNlbTtcbiAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgfVxuICAgIC5oZWFkZXItYmFkZ2Uge1xuICAgICAgZm9udC1zaXplOiAwLjY1cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItcHJpbWFyeSwgIzI1NjNlYik7XG4gICAgICBiYWNrZ3JvdW5kOiAjZWZmNmZmO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgI2JmZGJmZTtcbiAgICAgIHBhZGRpbmc6IDFweCA2cHg7XG4gICAgICBib3JkZXItcmFkaXVzOiA5OTk5cHg7XG4gICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgICAgbWF4LXdpZHRoOiAxMjBweDtcbiAgICB9XG4gICAgLmhlYWRlci1yaWdodCB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItdGV4dC1tdXRlZCwgIzY0NzQ4Yik7XG4gICAgICBtYXJnaW4tbGVmdDogOHB4O1xuICAgIH1cbiAgICAuYWNjb3JkaW9uLWNoZXZyb24ge1xuICAgICAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIDIwMG1zIGVhc2U7XG4gICAgfVxuICAgIC5hY2NvcmRpb24taXRlbS5pcy1leHBhbmRlZCAuYWNjb3JkaW9uLWNoZXZyb24ge1xuICAgICAgdHJhbnNmb3JtOiByb3RhdGUoMTgwZGVnKTtcbiAgICB9XG4gICAgLmFjY29yZGlvbi1jb250ZW50IHtcbiAgICAgIHBhZGRpbmc6IDEycHg7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGdhcDogMTJweDtcbiAgICB9XG4gICAgOjpuZy1kZWVwIC5hY2NvcmRpb24tY29udGVudCAuZ3JvdXAtdGl0bGUge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gICAgOjpuZy1kZWVwIC5hY2NvcmRpb24tY29udGVudCAuY29tcC1iYWRnZS1oZWFkZXIge1xuICAgICAgZGlzcGxheTogbm9uZTtcbiAgICB9XG4gICAgLmVtcHR5LXNlbGVjdGlvbiB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIHBhZGRpbmc6IDYwcHggMjBweDtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgfVxuICAgIC5lbXB0eS1pY29uLXdyYXAge1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICB3aWR0aDogNTJweDtcbiAgICAgIGhlaWdodDogNTJweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgICAgIGJhY2tncm91bmQ6ICNmMWY1Zjk7XG4gICAgICBtYXJnaW4tYm90dG9tOiAxNnB4O1xuICAgICAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC4wNCk7XG4gICAgfVxuICAgIC5lbXB0eS10ZXh0IHtcbiAgICAgIGZvbnQtc2l6ZTogMC44MTI1cmVtO1xuICAgICAgbGluZS1oZWlnaHQ6IDEuNTtcbiAgICAgIG1heC13aWR0aDogMjIwcHg7XG4gICAgICBtYXJnaW46IDA7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLXRleHQtbXV0ZWQsICM2NDc0OGIpO1xuICAgIH1cbiAgYF0sXG59KVxuZXhwb3J0IGNsYXNzIFByb3BlcnR5RWRpdG9yQ29tcG9uZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXNpZ25lclN0YXRlID0gaW5qZWN0KERlc2lnbmVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSByZWFkb25seSByZWdpc3RyeSA9IGluamVjdChDb21wb25lbnRSZWdpc3RyeSk7XG5cbiAgcmVhZG9ubHkgZGVmaW5pdGlvbiA9IHRoaXMuZGVzaWduZXJTdGF0ZS5kZWZpbml0aW9uO1xuICByZWFkb25seSBhY3RpdmVUYWIgPSB0aGlzLmRlc2lnbmVyU3RhdGUuYWN0aXZlVGFiO1xuICByZWFkb25seSBzZWxlY3RlZENvbXBvbmVudCA9IHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RlZENvbXBvbmVudDtcblxuICByZWFkb25seSBtYXhDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kZWZpbml0aW9uKCkubGF5b3V0LmNvbHVtbnMgfHwgMTIpO1xuICByZWFkb25seSBhbGxDb21wb25lbnRzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5kZWZpbml0aW9uKCkuY29tcG9uZW50cyk7XG5cbiAgcmVhZG9ubHkgcHJvcGVydHlTY2hlbWEgPSBjb21wdXRlZDxQcm9wZXJ0eURlZmluaXRpb25bXT4oKCkgPT4ge1xuICAgIGNvbnN0IGNvbXAgPSB0aGlzLnNlbGVjdGVkQ29tcG9uZW50KCk7XG4gICAgaWYgKCFjb21wKSByZXR1cm4gW107XG4gICAgY29uc3QgbWV0YSA9IHRoaXMucmVnaXN0cnkucmVzb2x2ZShjb21wLnR5cGUpO1xuICAgIHJldHVybiBtZXRhPy5wcm9wZXJ0eVNjaGVtYSA/PyBbXTtcbiAgfSk7XG5cbiAgc2V0VGFiKHRhYjogRGVzaWduZXJBY3RpdmVUYWIpOiB2b2lkIHtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuc2V0QWN0aXZlVGFiKHRhYik7XG4gIH1cblxuICB1cGRhdGVDb21wRGF0YVNvdXJjZShpZDogc3RyaW5nLCBkYXRhU291cmNlOiBDb21wb25lbnREYXRhU291cmNlRGVmaW5pdGlvbik6IHZvaWQge1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnQoaWQsIHsgZGF0YVNvdXJjZSB9KTtcbiAgfVxuXG4gIGRlc2VsZWN0KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gIH1cblxuICB1cGRhdGVDb21wKGZpZWxkOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgY29uc3QgY29tcCA9IHRoaXMuc2VsZWN0ZWRDb21wb25lbnQoKTtcbiAgICBpZiAoY29tcCkge1xuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUNvbXBvbmVudChjb21wLmlkLCB7IFtmaWVsZF06IHZhbHVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZVByb3AoaWQ6IHN0cmluZywga2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUNvbXBvbmVudFByb3BlcnR5KGlkLCBrZXksIHZhbHVlKTtcbiAgfVxuXG4gIHVwZGF0ZUxheW91dChrZXk6IGtleW9mIENvbXBvbmVudExheW91dERlZmluaXRpb24sIHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgY29uc3QgY29tcCA9IHRoaXMuc2VsZWN0ZWRDb21wb25lbnQoKTtcbiAgICBpZiAoY29tcCkge1xuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUNvbXBvbmVudExheW91dChjb21wLmlkLCB7IFtrZXldOiB2YWx1ZSB9KTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVDb21wb25lbnRIZWlnaHQodmFsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjb21wID0gdGhpcy5zZWxlY3RlZENvbXBvbmVudCgpO1xuICAgIGlmICghY29tcCkgcmV0dXJuO1xuICAgIGNvbnN0IGhlaWdodCA9ICF2YWwgfHwgdmFsID09PSAnYXV0bycgfHwgIXZhbC50cmltKCkgPyB1bmRlZmluZWQgOiB2YWwudHJpbSgpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwge1xuICAgICAgaGVpZ2h0LFxuICAgICAgbWluSGVpZ2h0OiBoZWlnaHQsXG4gICAgfSk7XG4gIH1cblxuICByZXNldENvbXBvbmVudERpbWVuc2lvbnMoaWQ6IHN0cmluZywgdHlwZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZGVmYXVsdFNwYW4gPSB0eXBlID09PSAnYnV0dG9uJyA/IDIgOiA0O1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoaWQsIHtcbiAgICAgIGNvbHVtblNwYW46IGRlZmF1bHRTcGFuLFxuICAgICAgaGVpZ2h0OiB1bmRlZmluZWQsXG4gICAgICBtaW5IZWlnaHQ6IHVuZGVmaW5lZCxcbiAgICAgIHdpZHRoOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVWYWxpZGF0aW9uKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICAgIGNvbnN0IGNvbXAgPSB0aGlzLnNlbGVjdGVkQ29tcG9uZW50KCk7XG4gICAgaWYgKGNvbXApIHtcbiAgICAgIGNvbnN0IG5leHRWYWxpZGF0aW9uID0geyAuLi4oY29tcC52YWxpZGF0aW9uID8/IHt9KSwgW2tleV06IHZhbHVlIH07XG4gICAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlQ29tcG9uZW50KGNvbXAuaWQsIHsgdmFsaWRhdGlvbjogbmV4dFZhbGlkYXRpb24gfSk7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlUmVwb3J0KGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVSZXBvcnRTZXR0aW5ncyh7IFtrZXldOiB2YWx1ZSB9KTtcbiAgfVxuXG4gIHVwZGF0ZUxheW91dFByb3Aoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudExheW91dCA9IHRoaXMuZGVmaW5pdGlvbigpLmxheW91dDtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlUmVwb3J0U2V0dGluZ3Moe1xuICAgICAgbGF5b3V0OiB7IC4uLmN1cnJlbnRMYXlvdXQsIFtrZXldOiB2YWx1ZSB9LFxuICAgIH0pO1xuICB9XG5cbiAgYWRkQ29sdW1uKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmRlZmluaXRpb24oKS5ncmlkID8/IHtcbiAgICAgIGRhdGFTb3VyY2VJZDogJ2RlZmF1bHQnLFxuICAgICAgY29sdW1uczogW10sXG4gICAgfTtcbiAgICBjb25zdCBjb2xDb3VudCA9IGN1cnJlbnQuY29sdW1ucy5sZW5ndGggKyAxO1xuICAgIGNvbnN0IG5ld0NvbDogR3JpZENvbHVtbkRlZmluaXRpb24gPSB7XG4gICAgICBmaWVsZDogYGZpZWxkXyR7Y29sQ291bnR9YCxcbiAgICAgIGxhYmVsOiBgQ29sdW1uICR7Y29sQ291bnR9YCxcbiAgICAgIGRhdGFUeXBlOiAnc3RyaW5nJyxcbiAgICAgIHNvcnRhYmxlOiB0cnVlLFxuICAgICAgYWxpZ246ICdsZWZ0JyxcbiAgICB9O1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVHcmlkU2V0dGluZ3Moe1xuICAgICAgLi4uY3VycmVudCxcbiAgICAgIGNvbHVtbnM6IFsuLi5jdXJyZW50LmNvbHVtbnMsIG5ld0NvbF0sXG4gICAgfSk7XG4gIH1cblxuICByZW1vdmVDb2x1bW4oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmRlZmluaXRpb24oKS5ncmlkO1xuICAgIGlmICghY3VycmVudCkgcmV0dXJuO1xuICAgIGNvbnN0IG5leHRDb2xzID0gWy4uLmN1cnJlbnQuY29sdW1uc107XG4gICAgbmV4dENvbHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKHtcbiAgICAgIC4uLmN1cnJlbnQsXG4gICAgICBjb2x1bW5zOiBuZXh0Q29scyxcbiAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZUNvbHVtbihpbmRleDogbnVtYmVyLCBmaWVsZDogc3RyaW5nLCB2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmRlZmluaXRpb24oKS5ncmlkO1xuICAgIGlmICghY3VycmVudCkgcmV0dXJuO1xuICAgIGNvbnN0IG5leHRDb2xzID0gY3VycmVudC5jb2x1bW5zLm1hcCgoYywgaWR4KSA9PiB7XG4gICAgICBpZiAoaWR4ID09PSBpbmRleCkge1xuICAgICAgICByZXR1cm4geyAuLi5jLCBbZmllbGRdOiB2YWx1ZSB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGM7XG4gICAgfSk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUdyaWRTZXR0aW5ncyh7XG4gICAgICAuLi5jdXJyZW50LFxuICAgICAgY29sdW1uczogbmV4dENvbHMsXG4gICAgfSk7XG4gIH1cblxuICB1cGRhdGVHcmlkT3B0aW9uKGZpZWxkOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMuZGVmaW5pdGlvbigpLmdyaWQgPz8ge1xuICAgICAgZGF0YVNvdXJjZUlkOiAnZGVmYXVsdCcsXG4gICAgICBjb2x1bW5zOiBbXSxcbiAgICB9O1xuICAgIGNvbnN0IG5leHRPcHRpb25zID0geyAuLi4oY3VycmVudC5vcHRpb25zID8/IHt9KSwgW2ZpZWxkXTogdmFsdWUgfTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKHtcbiAgICAgIC4uLmN1cnJlbnQsXG4gICAgICBvcHRpb25zOiBuZXh0T3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIHJlYWRvbmx5IGV4cGFuZGVkU2VjdGlvbnMgPSBzaWduYWw8UmVjb3JkPHN0cmluZywgYm9vbGVhbj4+KHtcbiAgICBkYXRhc291cmNlOiB0cnVlLFxuICAgIGdlbmVyYWw6IHRydWUsXG4gICAgbGF5b3V0OiBmYWxzZSxcbiAgICB2YWxpZGF0aW9uOiBmYWxzZSxcbiAgfSk7XG5cbiAgdG9nZ2xlU2VjdGlvbihzZWN0aW9uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmV4cGFuZGVkU2VjdGlvbnMudXBkYXRlKChwcmV2KSA9PiAoe1xuICAgICAgLi4ucHJldixcbiAgICAgIFtzZWN0aW9uXTogIXByZXZbc2VjdGlvbl0sXG4gICAgfSkpO1xuICB9XG5cbiAgaXNTZWN0aW9uRXhwYW5kZWQoc2VjdGlvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhdGhpcy5leHBhbmRlZFNlY3Rpb25zKClbc2VjdGlvbl07XG4gIH1cblxuICBnZXREYXRhc291cmNlQmFkZ2UoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB7XG4gICAgY29uc3QgZHMgPSBjb21wLmRhdGFTb3VyY2U7XG4gICAgaWYgKCFkcyB8fCBkcy5zb3VyY2VUeXBlID09PSAnc3RhdGljJykgcmV0dXJuICdTdGF0aWMgTGlzdCc7XG4gICAgaWYgKGRzLnNvdXJjZVR5cGUgPT09ICd0YWJsZScgfHwgZHMuZW50aXR5TmFtZSkge1xuICAgICAgcmV0dXJuIGRzLmVudGl0eU5hbWUgPyBgVGFibGU6ICR7ZHMuZW50aXR5TmFtZX1gIDogJ1RhYmxlIC8gVmlldyc7XG4gICAgfVxuICAgIGlmIChkcy5zb3VyY2VUeXBlID09PSAncHJvY2VkdXJlJykge1xuICAgICAgcmV0dXJuIGRzLmVudGl0eU5hbWUgPyBgU1A6ICR7ZHMuZW50aXR5TmFtZX1gIDogJ1N0b3JlZCBQcm9jJztcbiAgICB9XG4gICAgcmV0dXJuICdTdGF0aWMgTGlzdCc7XG4gIH1cblxuICBnZXRMYXlvdXRCYWRnZShjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogc3RyaW5nIHtcbiAgICBjb25zdCBzcGFuID0gY29tcC5sYXlvdXQ/LmNvbHVtblNwYW4gfHwgKGNvbXAudHlwZSA9PT0gJ2J1dHRvbicgPyAyIDogNCk7XG4gICAgcmV0dXJuIGAke3NwYW59LyR7dGhpcy5tYXhDb2x1bW5zKCl9IGNvbHNgO1xuICB9XG5cbiAgZ2V0VmFsaWRhdGlvbkJhZGdlKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb21wLnZhbGlkYXRpb24/LnJlcXVpcmVkID8gJ1JlcXVpcmVkJyA6ICdPcHRpb25hbCc7XG4gIH1cbn1cbiJdfQ==
|