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.
Files changed (185) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +477 -0
  3. package/esm2022/bways-report.mjs +5 -0
  4. package/esm2022/lib/core/errors/index.mjs +2 -0
  5. package/esm2022/lib/core/errors/reporting-errors.mjs +65 -0
  6. package/esm2022/lib/core/index.mjs +8 -0
  7. package/esm2022/lib/core/models/component-event.model.mjs +8 -0
  8. package/esm2022/lib/core/models/index.mjs +5 -0
  9. package/esm2022/lib/core/models/report-component.model.mjs +10 -0
  10. package/esm2022/lib/core/models/report-datasource.model.mjs +9 -0
  11. package/esm2022/lib/core/models/report-definition.model.mjs +13 -0
  12. package/esm2022/lib/core/models/report-grid.model.mjs +10 -0
  13. package/esm2022/lib/core/models/report-layout.model.mjs +9 -0
  14. package/esm2022/lib/core/models/report-parameter.model.mjs +9 -0
  15. package/esm2022/lib/core/models/validation.model.mjs +8 -0
  16. package/esm2022/lib/core/registry/component-category.mjs +8 -0
  17. package/esm2022/lib/core/registry/component-registry.mjs +90 -0
  18. package/esm2022/lib/core/registry/index.mjs +2 -0
  19. package/esm2022/lib/core/registry/property-definition.model.mjs +10 -0
  20. package/esm2022/lib/core/services/dynamic-form-builder.service.mjs +55 -0
  21. package/esm2022/lib/core/services/index.mjs +3 -0
  22. package/esm2022/lib/core/services/report-session-context.service.mjs +314 -0
  23. package/esm2022/lib/core/tokens/index.mjs +3 -0
  24. package/esm2022/lib/core/tokens/reporting-config.token.mjs +26 -0
  25. package/esm2022/lib/core/tokens/session-context.token.mjs +18 -0
  26. package/esm2022/lib/core/utilities/id-generator.mjs +17 -0
  27. package/esm2022/lib/core/utilities/index.mjs +3 -0
  28. package/esm2022/lib/core/utilities/schema-migration.mjs +38 -0
  29. package/esm2022/lib/core/utils/identifier-humanizer.mjs +88 -0
  30. package/esm2022/lib/core/validation/index.mjs +2 -0
  31. package/esm2022/lib/core/validation/validation-factory.mjs +70 -0
  32. package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +107 -0
  33. package/esm2022/lib/data-access/adapters/http-schema-discovery.adapter.mjs +119 -0
  34. package/esm2022/lib/data-access/adapters/index.mjs +3 -0
  35. package/esm2022/lib/data-access/contracts/data-source.contract.mjs +28 -0
  36. package/esm2022/lib/data-access/contracts/index.mjs +7 -0
  37. package/esm2022/lib/data-access/contracts/lookup.contract.mjs +6 -0
  38. package/esm2022/lib/data-access/contracts/master-data.provider.mjs +24 -0
  39. package/esm2022/lib/data-access/contracts/report-persistence.contract.mjs +25 -0
  40. package/esm2022/lib/data-access/contracts/schema-discovery.contract.mjs +7 -0
  41. package/esm2022/lib/data-access/contracts/translation.contract.mjs +9 -0
  42. package/esm2022/lib/data-access/index.mjs +3 -0
  43. package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +542 -0
  44. package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +843 -0
  45. package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +556 -0
  46. package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +845 -0
  47. package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +185 -0
  48. package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +452 -0
  49. package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +350 -0
  50. package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +175 -0
  51. package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +137 -0
  52. package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +608 -0
  53. package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +225 -0
  54. package/esm2022/lib/features/designer/designer.component.mjs +285 -0
  55. package/esm2022/lib/features/designer/index.mjs +7 -0
  56. package/esm2022/lib/features/designer/services/designer-state.service.mjs +310 -0
  57. package/esm2022/lib/features/designer/services/index.mjs +2 -0
  58. package/esm2022/lib/features/designer/utilities/canvas-layout.util.mjs +124 -0
  59. package/esm2022/lib/features/export/index.mjs +2 -0
  60. package/esm2022/lib/features/export/models/export.models.mjs +2 -0
  61. package/esm2022/lib/features/export/services/report-export.service.mjs +107 -0
  62. package/esm2022/lib/features/index.mjs +6 -0
  63. package/esm2022/lib/features/persistence/index.mjs +2 -0
  64. package/esm2022/lib/features/persistence/services/index.mjs +4 -0
  65. package/esm2022/lib/features/persistence/services/report-store.service.mjs +183 -0
  66. package/esm2022/lib/features/persistence/services/report-versioning.service.mjs +81 -0
  67. package/esm2022/lib/features/persistence/services/schema-validator.service.mjs +102 -0
  68. package/esm2022/lib/features/routing/components/routed-report-designer.component.mjs +156 -0
  69. package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +163 -0
  70. package/esm2022/lib/features/routing/index.mjs +6 -0
  71. package/esm2022/lib/features/routing/models/report-route.models.mjs +2 -0
  72. package/esm2022/lib/features/routing/report-routes.mjs +49 -0
  73. package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +22 -0
  74. package/esm2022/lib/features/routing/services/report-menu.service.mjs +77 -0
  75. package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +222 -0
  76. package/esm2022/lib/features/runtime/index.mjs +4 -0
  77. package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +409 -0
  78. package/esm2022/lib/features/runtime/report-runtime.component.mjs +147 -0
  79. package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +88 -0
  80. package/esm2022/lib/primitives/components/chart-bridge/report-chart-bridge.component.mjs +361 -0
  81. package/esm2022/lib/primitives/components/checkbox/rpt-checkbox.component.mjs +86 -0
  82. package/esm2022/lib/primitives/components/date/rpt-date.component.mjs +91 -0
  83. package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +204 -0
  84. package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +476 -0
  85. package/esm2022/lib/primitives/components/index.mjs +10 -0
  86. package/esm2022/lib/primitives/components/input/rpt-input.component.mjs +88 -0
  87. package/esm2022/lib/primitives/components/kpi-card/rpt-kpi-card.component.mjs +197 -0
  88. package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +110 -0
  89. package/esm2022/lib/primitives/index.mjs +3 -0
  90. package/esm2022/lib/primitives/register-builtins.mjs +328 -0
  91. package/esm2022/lib/provide-reporting.mjs +92 -0
  92. package/esm2022/public-api.mjs +9 -0
  93. package/fesm2022/bways-report.mjs +10360 -0
  94. package/fesm2022/bways-report.mjs.map +1 -0
  95. package/index.d.ts +5 -0
  96. package/lib/core/errors/index.d.ts +1 -0
  97. package/lib/core/errors/reporting-errors.d.ts +42 -0
  98. package/lib/core/index.d.ts +7 -0
  99. package/lib/core/models/component-event.model.d.ts +37 -0
  100. package/lib/core/models/index.d.ts +11 -0
  101. package/lib/core/models/report-component.model.d.ts +95 -0
  102. package/lib/core/models/report-datasource.model.d.ts +39 -0
  103. package/lib/core/models/report-definition.model.d.ts +100 -0
  104. package/lib/core/models/report-grid.model.d.ts +73 -0
  105. package/lib/core/models/report-layout.model.d.ts +43 -0
  106. package/lib/core/models/report-parameter.model.d.ts +22 -0
  107. package/lib/core/models/validation.model.d.ts +30 -0
  108. package/lib/core/registry/component-category.d.ts +16 -0
  109. package/lib/core/registry/component-registry.d.ts +101 -0
  110. package/lib/core/registry/index.d.ts +4 -0
  111. package/lib/core/registry/property-definition.model.d.ts +38 -0
  112. package/lib/core/services/dynamic-form-builder.service.d.ts +30 -0
  113. package/lib/core/services/index.d.ts +3 -0
  114. package/lib/core/services/report-session-context.service.d.ts +87 -0
  115. package/lib/core/tokens/index.d.ts +4 -0
  116. package/lib/core/tokens/reporting-config.token.d.ts +42 -0
  117. package/lib/core/tokens/session-context.token.d.ts +36 -0
  118. package/lib/core/utilities/id-generator.d.ts +9 -0
  119. package/lib/core/utilities/index.d.ts +3 -0
  120. package/lib/core/utilities/schema-migration.d.ts +10 -0
  121. package/lib/core/utils/identifier-humanizer.d.ts +22 -0
  122. package/lib/core/validation/index.d.ts +1 -0
  123. package/lib/core/validation/validation-factory.d.ts +31 -0
  124. package/lib/data-access/adapters/http-lookup.adapter.d.ts +19 -0
  125. package/lib/data-access/adapters/http-schema-discovery.adapter.d.ts +20 -0
  126. package/lib/data-access/adapters/index.d.ts +2 -0
  127. package/lib/data-access/contracts/data-source.contract.d.ts +37 -0
  128. package/lib/data-access/contracts/index.d.ts +9 -0
  129. package/lib/data-access/contracts/lookup.contract.d.ts +32 -0
  130. package/lib/data-access/contracts/master-data.provider.d.ts +54 -0
  131. package/lib/data-access/contracts/report-persistence.contract.d.ts +36 -0
  132. package/lib/data-access/contracts/schema-discovery.contract.d.ts +52 -0
  133. package/lib/data-access/contracts/translation.contract.d.ts +16 -0
  134. package/lib/data-access/index.d.ts +2 -0
  135. package/lib/features/designer/components/component-palette/component-palette.component.d.ts +39 -0
  136. package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +42 -0
  137. package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +36 -0
  138. package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +68 -0
  139. package/lib/features/designer/components/property-editor/property-editor-general.component.d.ts +20 -0
  140. package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +20 -0
  141. package/lib/features/designer/components/property-editor/property-editor-layout.component.d.ts +18 -0
  142. package/lib/features/designer/components/property-editor/property-editor-report.component.d.ts +15 -0
  143. package/lib/features/designer/components/property-editor/property-editor-validation.component.d.ts +12 -0
  144. package/lib/features/designer/components/property-editor/property-editor.component.d.ts +44 -0
  145. package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +18 -0
  146. package/lib/features/designer/designer.component.d.ts +36 -0
  147. package/lib/features/designer/index.d.ts +7 -0
  148. package/lib/features/designer/services/designer-state.service.d.ts +103 -0
  149. package/lib/features/designer/services/index.d.ts +2 -0
  150. package/lib/features/designer/utilities/canvas-layout.util.d.ts +55 -0
  151. package/lib/features/export/index.d.ts +2 -0
  152. package/lib/features/export/models/export.models.d.ts +16 -0
  153. package/lib/features/export/services/report-export.service.d.ts +27 -0
  154. package/lib/features/index.d.ts +5 -0
  155. package/lib/features/persistence/index.d.ts +1 -0
  156. package/lib/features/persistence/services/index.d.ts +5 -0
  157. package/lib/features/persistence/services/report-store.service.d.ts +53 -0
  158. package/lib/features/persistence/services/report-versioning.service.d.ts +29 -0
  159. package/lib/features/persistence/services/schema-validator.service.d.ts +34 -0
  160. package/lib/features/routing/components/routed-report-designer.component.d.ts +18 -0
  161. package/lib/features/routing/components/routed-report-runtime.component.d.ts +18 -0
  162. package/lib/features/routing/index.d.ts +6 -0
  163. package/lib/features/routing/models/report-route.models.d.ts +41 -0
  164. package/lib/features/routing/report-routes.d.ts +16 -0
  165. package/lib/features/routing/resolvers/report.resolver.d.ts +7 -0
  166. package/lib/features/routing/services/report-menu.service.d.ts +30 -0
  167. package/lib/features/runtime/dynamic-renderer.component.d.ts +30 -0
  168. package/lib/features/runtime/index.d.ts +3 -0
  169. package/lib/features/runtime/report-grid-bridge.component.d.ts +94 -0
  170. package/lib/features/runtime/report-runtime.component.d.ts +26 -0
  171. package/lib/primitives/components/button/rpt-button.component.d.ts +19 -0
  172. package/lib/primitives/components/chart-bridge/report-chart-bridge.component.d.ts +45 -0
  173. package/lib/primitives/components/checkbox/rpt-checkbox.component.d.ts +14 -0
  174. package/lib/primitives/components/date/rpt-date.component.d.ts +17 -0
  175. package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +32 -0
  176. package/lib/primitives/components/icon/rpt-icon.component.d.ts +41 -0
  177. package/lib/primitives/components/index.d.ts +12 -0
  178. package/lib/primitives/components/input/rpt-input.component.d.ts +16 -0
  179. package/lib/primitives/components/kpi-card/rpt-kpi-card.component.d.ts +43 -0
  180. package/lib/primitives/components/number/rpt-number.component.d.ts +20 -0
  181. package/lib/primitives/index.d.ts +2 -0
  182. package/lib/primitives/register-builtins.d.ts +11 -0
  183. package/lib/provide-reporting.d.ts +75 -0
  184. package/package.json +55 -0
  185. package/public-api.d.ts +5 -0
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHktZWRpdG9yLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL2ZlYXR1cmVzL2Rlc2lnbmVyL2NvbXBvbmVudHMvcHJvcGVydHktZWRpdG9yL3Byb3BlcnR5LWVkaXRvci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBcUIsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNoRyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUlqRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyREFBMkQsQ0FBQztBQUM3RixPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNyRixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUMzRixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMvRSxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNuRixPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQzs7QUFNM0Y7Ozs7O0dBS0c7QUFxYkgsTUFBTSxPQUFPLHVCQUF1QjtJQUNqQixhQUFhLEdBQUcsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDN0MsUUFBUSxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBRTdDLFVBQVUs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Y2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBjb21wdXRlZCxcbiAgaW5qZWN0LFxuICBzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IERlc2lnbmVyQWN0aXZlVGFiLCBEZXNpZ25lclN0YXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2Rlc2lnbmVyLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVnaXN0cnkgfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3JlZ2lzdHJ5L2NvbXBvbmVudC1yZWdpc3RyeSc7XG5pbXBvcnQgeyBQcm9wZXJ0eURlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3JlZ2lzdHJ5L3Byb3BlcnR5LWRlZmluaXRpb24ubW9kZWwnO1xuaW1wb3J0IHsgQ29tcG9uZW50TGF5b3V0RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1sYXlvdXQubW9kZWwnO1xuaW1wb3J0IHsgR3JpZENvbHVtbkRlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtZ3JpZC5tb2RlbCc7XG5pbXBvcnQgeyBScHRJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vcHJpbWl0aXZlcy9jb21wb25lbnRzL2ljb24vcnB0LWljb24uY29tcG9uZW50JztcbmltcG9ydCB7IFByb3BlcnR5RWRpdG9yR2VuZXJhbENvbXBvbmVudCB9IGZyb20gJy4vcHJvcGVydHktZWRpdG9yLWdlbmVyYWwuY29tcG9uZW50JztcbmltcG9ydCB7IFByb3BlcnR5RWRpdG9yTGF5b3V0Q29tcG9uZW50IH0gZnJvbSAnLi9wcm9wZXJ0eS1lZGl0b3ItbGF5b3V0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQcm9wZXJ0eUVkaXRvclZhbGlkYXRpb25Db21wb25lbnQgfSBmcm9tICcuL3Byb3BlcnR5LWVkaXRvci12YWxpZGF0aW9uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQcm9wZXJ0eUVkaXRvckdyaWRDb21wb25lbnQgfSBmcm9tICcuL3Byb3BlcnR5LWVkaXRvci1ncmlkLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBQcm9wZXJ0eUVkaXRvclJlcG9ydENvbXBvbmVudCB9IGZyb20gJy4vcHJvcGVydHktZWRpdG9yLXJlcG9ydC5jb21wb25lbnQnO1xuaW1wb3J0IHsgUHJvcGVydHlFZGl0b3JEYXRhc291cmNlQ29tcG9uZW50IH0gZnJvbSAnLi9wcm9wZXJ0eS1lZGl0b3ItZGF0YXNvdXJjZS5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50RGF0YVNvdXJjZURlZmluaXRpb24sXG4gIFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sXG59IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1jb21wb25lbnQubW9kZWwnO1xuXG4vKipcbiAqIFByb3BlcnR5IEVkaXRvciBjb29yZGluYXRvciBjb21wb25lbnQuXG4gKlxuICogRGVjb21wb3NlZCBpbnRvIGZvY3VzZWQgY2hpbGQgcHJlc2VudGF0aW9uYWwgY29tcG9uZW50cyBwZXIgUnVsZSAxOCAmIDE5IChDb21wb3NpdGlvbiBPdmVyIEdpYW50IENvbXBvbmVudHMpXG4gKiBhbmQgUnVsZSAzMiAoQXZvaWQgR29kIENvbXBvbmVudHMpLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdycHQtcHJvcGVydHktZWRpdG9yJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBScHRJY29uQ29tcG9uZW50LFxuICAgIFByb3BlcnR5RWRpdG9yR2VuZXJhbENvbXBvbmVudCxcbiAgICBQcm9wZXJ0eUVkaXRvckxheW91dENvbXBvbmVudCxcbiAgICBQcm9wZXJ0eUVkaXRvclZhbGlkYXRpb25Db21wb25lbnQsXG4gICAgUHJvcGVydHlFZGl0b3JHcmlkQ29tcG9uZW50LFxuICAgIFByb3BlcnR5RWRpdG9yUmVwb3J0Q29tcG9uZW50LFxuICAgIFByb3BlcnR5RWRpdG9yRGF0YXNvdXJjZUNvbXBvbmVudCxcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImVkaXRvci1jb250YWluZXJcIj5cbiAgICAgIDwhLS0gRWRpdG9yIEhlYWRlciAmIFRhYnMgLS0+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==