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,409 @@
1
+ import { ChangeDetectionStrategy, Component, computed, inject, input, signal, } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { GRID_COMPONENT } from '../../core/tokens/reporting-config.token';
4
+ import { RptIconComponent } from '../../primitives/components/icon/rpt-icon.component';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "@angular/common";
7
+ export class ReportGridBridgeComponent {
8
+ injectedGrid = inject(GRID_COMPONENT, { optional: true });
9
+ gridDefinition = input.required();
10
+ data = input([]);
11
+ customGridComponent = computed(() => this.injectedGrid ?? null);
12
+ sortColumn = signal(null);
13
+ sortDirection = signal('asc');
14
+ currentPage = signal(1);
15
+ bridgedColumns = computed(() => {
16
+ return this.gridDefinition().columns.map((col) => {
17
+ let widthNum;
18
+ if (typeof col.width === 'string' && col.width.endsWith('px')) {
19
+ widthNum = parseInt(col.width, 10);
20
+ }
21
+ else if (typeof col.width === 'number') {
22
+ widthNum = col.width;
23
+ }
24
+ return {
25
+ ...col,
26
+ headerName: col.label, // BWays-grid / AG Grid standard
27
+ header: col.label,
28
+ title: col.label,
29
+ hide: col.visible === false,
30
+ width: widthNum,
31
+ aggFunc: col.aggregate && col.aggregate !== 'none' ? col.aggregate : undefined,
32
+ };
33
+ });
34
+ });
35
+ gridInputs = computed(() => ({
36
+ columns: this.bridgedColumns(),
37
+ columnDefs: this.bridgedColumns(),
38
+ data: this.data(),
39
+ rowData: this.data(),
40
+ options: this.gridDefinition().options,
41
+ config: this.gridDefinition().options,
42
+ pagination: this.gridDefinition().options?.pagination !== false,
43
+ pageSize: this.gridDefinition().options?.pageSize ?? 10,
44
+ }));
45
+ visibleColumns = computed(() => {
46
+ return this.gridDefinition().columns.filter((c) => c.visible !== false);
47
+ });
48
+ showRowNumbers = computed(() => {
49
+ return !!this.gridDefinition().options?.showRowNumbers;
50
+ });
51
+ isPaginationEnabled = computed(() => {
52
+ return this.gridDefinition().options?.pagination !== false;
53
+ });
54
+ pageSize = computed(() => {
55
+ return this.gridDefinition().options?.pageSize ?? 10;
56
+ });
57
+ colSpan = computed(() => {
58
+ return this.visibleColumns().length + (this.showRowNumbers() ? 1 : 0);
59
+ });
60
+ hasAggregates = computed(() => {
61
+ return (this.gridDefinition().options?.showFooter &&
62
+ this.visibleColumns().some((c) => c.aggregate && c.aggregate !== 'none'));
63
+ });
64
+ sortedData = computed(() => {
65
+ const raw = this.data() || [];
66
+ const col = this.sortColumn();
67
+ const dir = this.sortDirection();
68
+ if (!col)
69
+ return raw;
70
+ return [...raw].sort((a, b) => {
71
+ const valA = a[col];
72
+ const valB = b[col];
73
+ if (valA == null && valB == null)
74
+ return 0;
75
+ if (valA == null)
76
+ return 1;
77
+ if (valB == null)
78
+ return -1;
79
+ if (valA < valB)
80
+ return dir === 'asc' ? -1 : 1;
81
+ if (valA > valB)
82
+ return dir === 'asc' ? 1 : -1;
83
+ return 0;
84
+ });
85
+ });
86
+ totalPages = computed(() => {
87
+ if (!this.isPaginationEnabled())
88
+ return 1;
89
+ const len = this.sortedData().length;
90
+ return Math.max(1, Math.ceil(len / this.pageSize()));
91
+ });
92
+ paginatedData = computed(() => {
93
+ const sorted = this.sortedData();
94
+ if (!this.isPaginationEnabled()) {
95
+ return sorted;
96
+ }
97
+ const start = (this.currentPage() - 1) * this.pageSize();
98
+ return sorted.slice(start, start + this.pageSize());
99
+ });
100
+ getJustifyContent(align) {
101
+ if (align === 'right')
102
+ return 'flex-end';
103
+ if (align === 'center')
104
+ return 'center';
105
+ return 'flex-start';
106
+ }
107
+ toggleSort(col) {
108
+ if (col.sortable === false)
109
+ return;
110
+ if (this.sortColumn() === col.field) {
111
+ this.sortDirection.set(this.sortDirection() === 'asc' ? 'desc' : 'asc');
112
+ }
113
+ else {
114
+ this.sortColumn.set(col.field);
115
+ this.sortDirection.set('asc');
116
+ }
117
+ this.currentPage.set(1);
118
+ }
119
+ prevPage() {
120
+ if (this.currentPage() > 1) {
121
+ this.currentPage.update((p) => p - 1);
122
+ }
123
+ }
124
+ nextPage() {
125
+ if (this.currentPage() < this.totalPages()) {
126
+ this.currentPage.update((p) => p + 1);
127
+ }
128
+ }
129
+ formatValue(value, col) {
130
+ if (value == null)
131
+ return '';
132
+ if (col.dataType === 'currency') {
133
+ const num = Number(value);
134
+ return isNaN(num) ? String(value) : `$${num.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
135
+ }
136
+ if (col.dataType === 'number') {
137
+ const num = Number(value);
138
+ return isNaN(num) ? String(value) : num.toLocaleString();
139
+ }
140
+ if (col.dataType === 'date' && typeof value === 'string') {
141
+ const d = new Date(value);
142
+ return isNaN(d.getTime()) ? String(value) : d.toLocaleDateString();
143
+ }
144
+ return String(value);
145
+ }
146
+ computeAggregate(col) {
147
+ const data = this.sortedData();
148
+ if (data.length === 0)
149
+ return '0';
150
+ if (col.aggregate === 'count') {
151
+ return String(data.length);
152
+ }
153
+ const numbers = data
154
+ .map((row) => Number(row[col.field]))
155
+ .filter((n) => !isNaN(n));
156
+ if (numbers.length === 0)
157
+ return '0';
158
+ if (col.aggregate === 'sum') {
159
+ const sum = numbers.reduce((acc, n) => acc + n, 0);
160
+ return col.dataType === 'currency' ? `$${sum.toFixed(2)}` : sum.toLocaleString();
161
+ }
162
+ if (col.aggregate === 'avg') {
163
+ const avg = numbers.reduce((acc, n) => acc + n, 0) / numbers.length;
164
+ return col.dataType === 'currency' ? `$${avg.toFixed(2)}` : avg.toFixed(2);
165
+ }
166
+ if (col.aggregate === 'min') {
167
+ const min = Math.min(...numbers);
168
+ return col.dataType === 'currency' ? `$${min.toFixed(2)}` : String(min);
169
+ }
170
+ if (col.aggregate === 'max') {
171
+ const max = Math.max(...numbers);
172
+ return col.dataType === 'currency' ? `$${max.toFixed(2)}` : String(max);
173
+ }
174
+ return '';
175
+ }
176
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportGridBridgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
177
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportGridBridgeComponent, isStandalone: true, selector: "rpt-grid-bridge", inputs: { gridDefinition: { classPropertyName: "gridDefinition", publicName: "gridDefinition", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
178
+ <div class="rpt-grid-container">
179
+ @if (customGridComponent()) {
180
+ <!-- Host-provided grid component (e.g. BWays-grid or custom AG Grid wrapper) -->
181
+ <ng-container
182
+ [ngComponentOutlet]="customGridComponent()!"
183
+ [ngComponentOutletInputs]="gridInputs()"
184
+ />
185
+ } @else {
186
+ <!-- Built-in fallback table when no external grid is provided -->
187
+ <div class="rpt-table-card">
188
+ <div class="rpt-table-toolbar">
189
+ <span class="rpt-table-title">Results ({{ data().length }} rows)</span>
190
+ </div>
191
+
192
+ <div class="rpt-table-responsive">
193
+ <table class="rpt-table">
194
+ <thead>
195
+ <tr>
196
+ @if (showRowNumbers()) {
197
+ <th class="rpt-th rpt-th-num">#</th>
198
+ }
199
+ @for (col of visibleColumns(); track col.field) {
200
+ <th
201
+ class="rpt-th"
202
+ [style.width]="col.width || 'auto'"
203
+ [style.text-align]="col.align || 'left'"
204
+ [class.sortable]="col.sortable !== false"
205
+ (click)="toggleSort(col)"
206
+ >
207
+ <div class="rpt-th-content" [style.justify-content]="getJustifyContent(col.align)">
208
+ <span>{{ col.label }}</span>
209
+ @if (col.sortable !== false && sortColumn() === col.field) {
210
+ <span class="rpt-sort-indicator">
211
+ <rpt-icon [name]="sortDirection() === 'asc' ? 'chevron-up' : 'chevron-down'" [size]="12" />
212
+ </span>
213
+ }
214
+ </div>
215
+ </th>
216
+ }
217
+ </tr>
218
+ </thead>
219
+ <tbody>
220
+ @if (paginatedData().length === 0) {
221
+ <tr>
222
+ <td [attr.colspan]="colSpan()" class="rpt-empty-message">
223
+ No data found matching criteria
224
+ </td>
225
+ </tr>
226
+ } @else {
227
+ @for (row of paginatedData(); track $index) {
228
+ <tr class="rpt-tr">
229
+ @if (showRowNumbers()) {
230
+ <td class="rpt-td rpt-td-num">{{ (currentPage() - 1) * pageSize() + $index + 1 }}</td>
231
+ }
232
+ @for (col of visibleColumns(); track col.field) {
233
+ <td class="rpt-td" [style.text-align]="col.align || 'left'">
234
+ {{ formatValue(row[col.field], col) }}
235
+ </td>
236
+ }
237
+ </tr>
238
+ }
239
+ }
240
+ </tbody>
241
+ @if (hasAggregates()) {
242
+ <tfoot>
243
+ <tr class="rpt-tfoot-row">
244
+ @if (showRowNumbers()) {
245
+ <td class="rpt-td-num"></td>
246
+ }
247
+ @for (col of visibleColumns(); track col.field) {
248
+ <td class="rpt-td-aggregate" [style.text-align]="col.align || 'left'">
249
+ @if (col.aggregate && col.aggregate !== 'none') {
250
+ <strong>{{ col.aggregate | uppercase }}: {{ computeAggregate(col) }}</strong>
251
+ }
252
+ </td>
253
+ }
254
+ </tr>
255
+ </tfoot>
256
+ }
257
+ </table>
258
+ </div>
259
+
260
+ @if (isPaginationEnabled() && totalPages() > 1) {
261
+ <div class="rpt-pagination-bar">
262
+ <span class="rpt-page-info">
263
+ Page {{ currentPage() }} of {{ totalPages() }}
264
+ </span>
265
+ <div class="rpt-page-buttons">
266
+ <button
267
+ type="button"
268
+ class="rpt-page-btn"
269
+ [disabled]="currentPage() === 1"
270
+ (click)="prevPage()"
271
+ >
272
+ <rpt-icon name="arrow-left" [size]="12" />
273
+ <span>Previous</span>
274
+ </button>
275
+ <button
276
+ type="button"
277
+ class="rpt-page-btn"
278
+ [disabled]="currentPage() === totalPages()"
279
+ (click)="nextPage()"
280
+ >
281
+ <span>Next</span>
282
+ <rpt-icon name="arrow-right" [size]="12" />
283
+ </button>
284
+ </div>
285
+ </div>
286
+ }
287
+ </div>
288
+ }
289
+ </div>
290
+ `, isInline: true, styles: [":host{display:block;width:100%;margin-top:16px;font-family:var(--rpt-font-family, inherit)}.rpt-grid-container{width:100%}.rpt-table-card{background:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:var(--rpt-box-shadow, 0 1px 3px rgba(0, 0, 0, .05));overflow:hidden}.rpt-table-toolbar{padding:12px 16px;background-color:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);display:flex;align-items:center;justify-content:space-between}.rpt-table-title{font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;color:var(--rpt-color-text-muted, #64748b);text-transform:uppercase;letter-spacing:.05em}.rpt-table-responsive{width:100%;overflow-x:auto}.rpt-table{width:100%;border-collapse:collapse;font-size:var(--rpt-font-size-base, .875rem);text-align:left}.rpt-th{background-color:var(--rpt-color-surface, #f8fafc);padding:10px 14px;font-weight:600;font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #475569);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);white-space:nowrap;-webkit-user-select:none;user-select:none}.rpt-th.sortable{cursor:pointer}.rpt-th.sortable:hover{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.rpt-th-content{display:flex;align-items:center;gap:4px}.rpt-sort-indicator{display:inline-flex;align-items:center;color:var(--rpt-color-primary, #2563eb)}.rpt-th-num,.rpt-td-num{width:48px;text-align:center;color:var(--rpt-color-text-muted, #94a3b8);font-size:var(--rpt-font-size-sm, .75rem)}.rpt-td{padding:10px 14px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);color:var(--rpt-color-text, #1e293b)}.rpt-tr:hover{background-color:var(--rpt-color-surface-hover, #f8fafc)}.rpt-empty-message{text-align:center;padding:40px 20px;color:var(--rpt-color-text-muted, #94a3b8);font-style:italic}.rpt-tfoot-row{background-color:var(--rpt-color-surface, #f8fafc);border-top:2px solid var(--rpt-color-border, #cbd5e1)}.rpt-td-aggregate{padding:10px 14px;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.rpt-pagination-bar{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-top:1px solid var(--rpt-color-border, #e2e8f0);background-color:var(--rpt-color-surface, #f8fafc)}.rpt-page-info{font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b)}.rpt-page-buttons{display:flex;gap:8px}.rpt-page-btn{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:var(--rpt-font-size-sm, .75rem);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-sm, 4px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease}.rpt-page-btn:hover:not(:disabled){background-color:var(--rpt-color-surface-hover, #f1f5f9);border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-page-btn:disabled{opacity:.5;cursor:not-allowed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "pipe", type: i1.UpperCasePipe, name: "uppercase" }, { kind: "component", type: RptIconComponent, selector: "rpt-icon", inputs: ["name", "size", "color", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
291
+ }
292
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportGridBridgeComponent, decorators: [{
293
+ type: Component,
294
+ args: [{ selector: 'rpt-grid-bridge', standalone: true, imports: [CommonModule, RptIconComponent], template: `
295
+ <div class="rpt-grid-container">
296
+ @if (customGridComponent()) {
297
+ <!-- Host-provided grid component (e.g. BWays-grid or custom AG Grid wrapper) -->
298
+ <ng-container
299
+ [ngComponentOutlet]="customGridComponent()!"
300
+ [ngComponentOutletInputs]="gridInputs()"
301
+ />
302
+ } @else {
303
+ <!-- Built-in fallback table when no external grid is provided -->
304
+ <div class="rpt-table-card">
305
+ <div class="rpt-table-toolbar">
306
+ <span class="rpt-table-title">Results ({{ data().length }} rows)</span>
307
+ </div>
308
+
309
+ <div class="rpt-table-responsive">
310
+ <table class="rpt-table">
311
+ <thead>
312
+ <tr>
313
+ @if (showRowNumbers()) {
314
+ <th class="rpt-th rpt-th-num">#</th>
315
+ }
316
+ @for (col of visibleColumns(); track col.field) {
317
+ <th
318
+ class="rpt-th"
319
+ [style.width]="col.width || 'auto'"
320
+ [style.text-align]="col.align || 'left'"
321
+ [class.sortable]="col.sortable !== false"
322
+ (click)="toggleSort(col)"
323
+ >
324
+ <div class="rpt-th-content" [style.justify-content]="getJustifyContent(col.align)">
325
+ <span>{{ col.label }}</span>
326
+ @if (col.sortable !== false && sortColumn() === col.field) {
327
+ <span class="rpt-sort-indicator">
328
+ <rpt-icon [name]="sortDirection() === 'asc' ? 'chevron-up' : 'chevron-down'" [size]="12" />
329
+ </span>
330
+ }
331
+ </div>
332
+ </th>
333
+ }
334
+ </tr>
335
+ </thead>
336
+ <tbody>
337
+ @if (paginatedData().length === 0) {
338
+ <tr>
339
+ <td [attr.colspan]="colSpan()" class="rpt-empty-message">
340
+ No data found matching criteria
341
+ </td>
342
+ </tr>
343
+ } @else {
344
+ @for (row of paginatedData(); track $index) {
345
+ <tr class="rpt-tr">
346
+ @if (showRowNumbers()) {
347
+ <td class="rpt-td rpt-td-num">{{ (currentPage() - 1) * pageSize() + $index + 1 }}</td>
348
+ }
349
+ @for (col of visibleColumns(); track col.field) {
350
+ <td class="rpt-td" [style.text-align]="col.align || 'left'">
351
+ {{ formatValue(row[col.field], col) }}
352
+ </td>
353
+ }
354
+ </tr>
355
+ }
356
+ }
357
+ </tbody>
358
+ @if (hasAggregates()) {
359
+ <tfoot>
360
+ <tr class="rpt-tfoot-row">
361
+ @if (showRowNumbers()) {
362
+ <td class="rpt-td-num"></td>
363
+ }
364
+ @for (col of visibleColumns(); track col.field) {
365
+ <td class="rpt-td-aggregate" [style.text-align]="col.align || 'left'">
366
+ @if (col.aggregate && col.aggregate !== 'none') {
367
+ <strong>{{ col.aggregate | uppercase }}: {{ computeAggregate(col) }}</strong>
368
+ }
369
+ </td>
370
+ }
371
+ </tr>
372
+ </tfoot>
373
+ }
374
+ </table>
375
+ </div>
376
+
377
+ @if (isPaginationEnabled() && totalPages() > 1) {
378
+ <div class="rpt-pagination-bar">
379
+ <span class="rpt-page-info">
380
+ Page {{ currentPage() }} of {{ totalPages() }}
381
+ </span>
382
+ <div class="rpt-page-buttons">
383
+ <button
384
+ type="button"
385
+ class="rpt-page-btn"
386
+ [disabled]="currentPage() === 1"
387
+ (click)="prevPage()"
388
+ >
389
+ <rpt-icon name="arrow-left" [size]="12" />
390
+ <span>Previous</span>
391
+ </button>
392
+ <button
393
+ type="button"
394
+ class="rpt-page-btn"
395
+ [disabled]="currentPage() === totalPages()"
396
+ (click)="nextPage()"
397
+ >
398
+ <span>Next</span>
399
+ <rpt-icon name="arrow-right" [size]="12" />
400
+ </button>
401
+ </div>
402
+ </div>
403
+ }
404
+ </div>
405
+ }
406
+ </div>
407
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;width:100%;margin-top:16px;font-family:var(--rpt-font-family, inherit)}.rpt-grid-container{width:100%}.rpt-table-card{background:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:var(--rpt-box-shadow, 0 1px 3px rgba(0, 0, 0, .05));overflow:hidden}.rpt-table-toolbar{padding:12px 16px;background-color:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);display:flex;align-items:center;justify-content:space-between}.rpt-table-title{font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;color:var(--rpt-color-text-muted, #64748b);text-transform:uppercase;letter-spacing:.05em}.rpt-table-responsive{width:100%;overflow-x:auto}.rpt-table{width:100%;border-collapse:collapse;font-size:var(--rpt-font-size-base, .875rem);text-align:left}.rpt-th{background-color:var(--rpt-color-surface, #f8fafc);padding:10px 14px;font-weight:600;font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #475569);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);white-space:nowrap;-webkit-user-select:none;user-select:none}.rpt-th.sortable{cursor:pointer}.rpt-th.sortable:hover{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.rpt-th-content{display:flex;align-items:center;gap:4px}.rpt-sort-indicator{display:inline-flex;align-items:center;color:var(--rpt-color-primary, #2563eb)}.rpt-th-num,.rpt-td-num{width:48px;text-align:center;color:var(--rpt-color-text-muted, #94a3b8);font-size:var(--rpt-font-size-sm, .75rem)}.rpt-td{padding:10px 14px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);color:var(--rpt-color-text, #1e293b)}.rpt-tr:hover{background-color:var(--rpt-color-surface-hover, #f8fafc)}.rpt-empty-message{text-align:center;padding:40px 20px;color:var(--rpt-color-text-muted, #94a3b8);font-style:italic}.rpt-tfoot-row{background-color:var(--rpt-color-surface, #f8fafc);border-top:2px solid var(--rpt-color-border, #cbd5e1)}.rpt-td-aggregate{padding:10px 14px;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.rpt-pagination-bar{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-top:1px solid var(--rpt-color-border, #e2e8f0);background-color:var(--rpt-color-surface, #f8fafc)}.rpt-page-info{font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b)}.rpt-page-buttons{display:flex;gap:8px}.rpt-page-btn{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:var(--rpt-font-size-sm, .75rem);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-sm, 4px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease}.rpt-page-btn:hover:not(:disabled){background-color:var(--rpt-color-surface-hover, #f1f5f9);border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-page-btn:disabled{opacity:.5;cursor:not-allowed}\n"] }]
408
+ }] });
409
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWdyaWQtYnJpZGdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL2ZlYXR1cmVzL3J1bnRpbWUvcmVwb3J0LWdyaWQtYnJpZGdlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLEtBQUssRUFDTCxNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUsxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQzs7O0FBZ1F2RixNQUFNLE9BQU8seUJBQXlCO0lBQ25CLFlBQVksR0FBRyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFbEUsY0FBYyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQXdCLENBQUM7SUFDeEQsSUFBSSxHQUFHLEtBQUssQ0FBWSxFQUFFLENBQUMsQ0FBQztJQUU1QixtQkFBbUIsR0FBRyxRQUFRLENBQXVCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLENBQUM7SUFFdEYsVUFBVSxHQUFHLE1BQU0sQ0FBZ0IsSUFBSSxDQUFDLENBQUM7SUFDekMsYUFBYSxHQUFHLE1BQU0sQ0FBaUIsS0FBSyxDQUFDLENBQUM7SUFDOUMsV0FBVyxHQUFHLE1BQU0sQ0FBUyxDQUFDLENBQUMsQ0FBQztJQUNoQyxjQUFjLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtRQUN0QyxPQUFPLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxD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QUFDLFlBQVksRUFBRSxnQkFBZ0IsQ0FBQyxZQUMvQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpSFQsbUJBdUlnQix1QkFBdUIsQ0FBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIGluamVjdCxcbiAgaW5wdXQsXG4gIHNpZ25hbCxcbiAgVHlwZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgR1JJRF9DT01QT05FTlQgfSBmcm9tICcuLi8uLi9jb3JlL3Rva2Vucy9yZXBvcnRpbmctY29uZmlnLnRva2VuJztcbmltcG9ydCB7XG4gIEdyaWRDb2x1bW5EZWZpbml0aW9uLFxuICBSZXBvcnRHcmlkRGVmaW5pdGlvbixcbn0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWdyaWQubW9kZWwnO1xuaW1wb3J0IHsgUnB0SWNvbkNvbXBvbmVudCB9IGZyb20gJy4uLy4uL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9pY29uL3JwdC1pY29uLmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3JwdC1ncmlkLWJyaWRnZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIFJwdEljb25Db21wb25lbnRdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJycHQtZ3JpZC1jb250YWluZXJcIj5cbiAgICAgIEBpZiAoY3VzdG9tR3JpZENvbXBvbmVudCgpKSB7XG4gICAgICAgIDwhLS0gSG9zdC1wcm92aWRlZCBncmlkIGNvbXBvbmVudCAoZS5nLiBCV2F5cy1ncmlkIG9yIGN1c3RvbSBBRyBHcmlkIHdyYXBwZXIpIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgW25nQ29tcG9uZW50T3V0bGV0XT1cImN1c3RvbUdyaWRDb21wb25lbnQoKSFcIlxuICAgICAgICAgIFtuZ0NvbXBvbmVudE91dGxldElucHV0c109XCJncmlkSW5wdXRzKClcIlxuICAgICAgICAvPlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDwhLS0gQnVpbHQtaW4gZmFsbGJhY2sgdGFibGUgd2hlbiBubyBleHRlcm5hbCBncmlkIGlzIHByb3ZpZGVkIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXRhYmxlLWNhcmRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXRhYmxlLXRvb2xiYXJcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicnB0LXRhYmxlLXRpdGxlXCI+UmVzdWx0cyAoe3sgZGF0YSgpLmxlbmd0aCB9fSByb3dzKTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJycHQtdGFibGUtcmVzcG9uc2l2ZVwiPlxuICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwicnB0LXRhYmxlXCI+XG4gICAgICAgICAgICAgIDx0aGVhZD5cbiAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICBAaWYgKHNob3dSb3dOdW1iZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwicnB0LXRoIHJwdC10aC1udW1cIj4jPC90aD5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIEBmb3IgKGNvbCBvZiB2aXNpYmxlQ29sdW1ucygpOyB0cmFjayBjb2wuZmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJycHQtdGhcIlxuICAgICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2wud2lkdGggfHwgJ2F1dG8nXCJcbiAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUudGV4dC1hbGlnbl09XCJjb2wuYWxpZ24gfHwgJ2xlZnQnXCJcbiAgICAgICAgICAgICAgICAgICAgICBbY2xhc3Muc29ydGFibGVdPVwiY29sLnNvcnRhYmxlICE9PSBmYWxzZVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZVNvcnQoY29sKVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXRoLWNvbnRlbnRcIiBbc3R5bGUuanVzdGlmeS1jb250ZW50XT1cImdldEp1c3RpZnlDb250ZW50KGNvbC5hbGlnbilcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7IGNvbC5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29sLnNvcnRhYmxlICE9PSBmYWxzZSAmJiBzb3J0Q29sdW1uKCkgPT09IGNvbC5maWVsZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInJwdC1zb3J0LWluZGljYXRvclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBbbmFtZV09XCJzb3J0RGlyZWN0aW9uKCkgPT09ICdhc2MnID8gJ2NoZXZyb24tdXAnIDogJ2NoZXZyb24tZG93bidcIiBbc2l6ZV09XCIxMlwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICAgICAgQGlmIChwYWdpbmF0ZWREYXRhKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbFNwYW4oKVwiIGNsYXNzPVwicnB0LWVtcHR5LW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICBObyBkYXRhIGZvdW5kIG1hdGNoaW5nIGNyaXRlcmlhXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgQGZvciAocm93IG9mIHBhZ2luYXRlZERhdGEoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cInJwdC10clwiPlxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAoc2hvd1Jvd051bWJlcnMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicnB0LXRkIHJwdC10ZC1udW1cIj57eyAoY3VycmVudFBhZ2UoKSAtIDEpICogcGFnZVNpemUoKSArICRpbmRleCArIDEgfX08L3RkPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgdmlzaWJsZUNvbHVtbnMoKTsgdHJhY2sgY29sLmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJycHQtdGRcIiBbc3R5bGUudGV4dC1hbGlnbl09XCJjb2wuYWxpZ24gfHwgJ2xlZnQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGZvcm1hdFZhbHVlKHJvd1tjb2wuZmllbGRdLCBjb2wpIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgIEBpZiAoaGFzQWdncmVnYXRlcygpKSB7XG4gICAgICAgICAgICAgICAgPHRmb290PlxuICAgICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwicnB0LXRmb290LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKHNob3dSb3dOdW1iZXJzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJycHQtdGQtbnVtXCI+PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgdmlzaWJsZUNvbHVtbnMoKTsgdHJhY2sgY29sLmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicnB0LXRkLWFnZ3JlZ2F0ZVwiIFtzdHlsZS50ZXh0LWFsaWduXT1cImNvbC5hbGlnbiB8fCAnbGVmdCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoY29sLmFnZ3JlZ2F0ZSAmJiBjb2wuYWdncmVnYXRlICE9PSAnbm9uZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHN0cm9uZz57eyBjb2wuYWdncmVnYXRlIHwgdXBwZXJjYXNlIH19OiB7eyBjb21wdXRlQWdncmVnYXRlKGNvbCkgfX08L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgIDwvdGZvb3Q+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICBAaWYgKGlzUGFnaW5hdGlvbkVuYWJsZWQoKSAmJiB0b3RhbFBhZ2VzKCkgPiAxKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXBhZ2luYXRpb24tYmFyXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicnB0LXBhZ2UtaW5mb1wiPlxuICAgICAgICAgICAgICAgIFBhZ2Uge3sgY3VycmVudFBhZ2UoKSB9fSBvZiB7eyB0b3RhbFBhZ2VzKCkgfX1cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXBhZ2UtYnV0dG9uc1wiPlxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJycHQtcGFnZS1idG5cIlxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImN1cnJlbnRQYWdlKCkgPT09IDFcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInByZXZQYWdlKClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiYXJyb3ctbGVmdFwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPlByZXZpb3VzPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJycHQtcGFnZS1idG5cIlxuICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImN1cnJlbnRQYWdlKCkgPT09IHRvdGFsUGFnZXMoKVwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwibmV4dFBhZ2UoKVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+TmV4dDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiYXJyb3ctcmlnaHRcIiBbc2l6ZV09XCIxMlwiIC8+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIDpob3N0IHtcbiAgICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBtYXJnaW4tdG9wOiAxNnB4O1xuICAgICAgZm9udC1mYW1pbHk6IHZhcigtLXJwdC1mb250LWZhbWlseSwgaW5oZXJpdCk7XG4gICAgfVxuICAgIC5ycHQtZ3JpZC1jb250YWluZXIge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgfVxuICAgIC5ycHQtdGFibGUtY2FyZCB7XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1ycHQtY29sb3ItYmcsICNmZmZmZmYpO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tcnB0LWNvbG9yLWJvcmRlciwgI2NiZDVlMSk7XG4gICAgICBib3JkZXItcmFkaXVzOiB2YXIoLS1ycHQtYm9yZGVyLXJhZGl1cy1sZywgOHB4KTtcbiAgICAgIGJveC1zaGFkb3c6IHZhcigtLXJwdC1ib3gtc2hhZG93LCAwIDFweCAzcHggcmdiYSgwLCAwLCAwLCAwLjA1KSk7XG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIH1cbiAgICAucnB0LXRhYmxlLXRvb2xiYXIge1xuICAgICAgcGFkZGluZzogMTJweCAxNnB4O1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tcnB0LWNvbG9yLXN1cmZhY2UsICNmOGZhZmMpO1xuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLXJwdC1jb2xvci1ib3JkZXIsICNjYmQ1ZTEpO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgfVxuICAgIC5ycHQtdGFibGUtdGl0bGUge1xuICAgICAgZm9udC1zaXplOiB2YXIoLS1ycHQtZm9udC1zaXplLXNtLCAwLjc1cmVtKTtcbiAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLXRleHQtbXV0ZWQsICM2NDc0OGIpO1xuICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICAgIGxldHRlci1zcGFjaW5nOiAwLjA1ZW07XG4gICAgfVxuICAgIC5ycHQtdGFibGUtcmVzcG9uc2l2ZSB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIG92ZXJmbG93LXg6IGF1dG87XG4gICAgfVxuICAgIC5ycHQtdGFibGUge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBib3JkZXItY29sbGFwc2U6IGNvbGxhcHNlO1xuICAgICAgZm9udC1zaXplOiB2YXIoLS1ycHQtZm9udC1zaXplLWJhc2UsIDAuODc1cmVtKTtcbiAgICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgfVxuICAgIC5ycHQtdGgge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tcnB0LWNvbG9yLXN1cmZhY2UsICNmOGZhZmMpO1xuICAgICAgcGFkZGluZzogMTBweCAxNHB4O1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIGZvbnQtc2l6ZTogdmFyKC0tcnB0LWZvbnQtc2l6ZS1zbSwgMC43NXJlbSk7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLXRleHQtbXV0ZWQsICM0NzU1NjkpO1xuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHZhcigtLXJwdC1jb2xvci1ib3JkZXIsICNjYmQ1ZTEpO1xuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgIHVzZXItc2VsZWN0OiBub25lO1xuICAgIH1cbiAgICAucnB0LXRoLnNvcnRhYmxlIHtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICB9XG4gICAgLnJwdC10aC5zb3J0YWJsZTpob3ZlciB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1ycHQtY29sb3Itc3VyZmFjZS1ob3ZlciwgI2YxZjVmOSk7XG4gICAgfVxuICAgIC5ycHQtdGgtY29udGVudCB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGdhcDogNHB4O1xuICAgIH1cbiAgICAucnB0LXNvcnQtaW5kaWNhdG9yIHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItcHJpbWFyeSwgIzI1NjNlYik7XG4gICAgfVxuICAgIC5ycHQtdGgtbnVtLCAucnB0LXRkLW51bSB7XG4gICAgICB3aWR0aDogNDhweDtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItdGV4dC1tdXRlZCwgIzk0YTNiOCk7XG4gICAgICBmb250LXNpemU6IHZhcigtLXJwdC1mb250LXNpemUtc20sIDAuNzVyZW0pO1xuICAgIH1cbiAgICAucnB0LXRkIHtcbiAgICAgIHBhZGRpbmc6IDEwcHggMTRweDtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS1ycHQtY29sb3ItYm9yZGVyLCAjZTJlOGYwKTtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItdGV4dCwgIzFlMjkzYik7XG4gICAgfVxuICAgIC5ycHQtdHI6aG92ZXIge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tcnB0LWNvbG9yLXN1cmZhY2UtaG92ZXIsICNmOGZhZmMpO1xuICAgIH1cbiAgICAucnB0LWVtcHR5LW1lc3NhZ2Uge1xuICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgcGFkZGluZzogNDBweCAyMHB4O1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci10ZXh0LW11dGVkLCAjOTRhM2I4KTtcbiAgICAgIGZvbnQtc3R5bGU6IGl0YWxpYztcbiAgICB9XG4gICAgLnJwdC10Zm9vdC1yb3cge1xuICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0tcnB0LWNvbG9yLXN1cmZhY2UsICNmOGZhZmMpO1xuICAgICAgYm9yZGVyLXRvcDogMnB4IHNvbGlkIHZhcigtLXJwdC1jb2xvci1ib3JkZXIsICNjYmQ1ZTEpO1xuICAgIH1cbiAgICAucnB0LXRkLWFnZ3JlZ2F0ZSB7XG4gICAgICBwYWRkaW5nOiAxMHB4IDE0cHg7XG4gICAgICBjb2xvcjogdmFyKC0tcnB0LWNvbG9yLXRleHQsICMwZjE3MmEpO1xuICAgICAgZm9udC1zaXplOiB2YXIoLS1ycHQtZm9udC1zaXplLXNtLCAwLjc1cmVtKTtcbiAgICB9XG4gICAgLnJwdC1wYWdpbmF0aW9uLWJhciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIHBhZGRpbmc6IDEycHggMTZweDtcbiAgICAgIGJvcmRlci10b3A6IDFweCBzb2xpZCB2YXIoLS1ycHQtY29sb3ItYm9yZGVyLCAjZTJlOGYwKTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXJwdC1jb2xvci1zdXJmYWNlLCAjZjhmYWZjKTtcbiAgICB9XG4gICAgLnJwdC1wYWdlLWluZm8ge1xuICAgICAgZm9udC1zaXplOiB2YXIoLS1ycHQtZm9udC1zaXplLXNtLCAwLjc1cmVtKTtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItdGV4dC1tdXRlZCwgIzY0NzQ4Yik7XG4gICAgfVxuICAgIC5ycHQtcGFnZS1idXR0b25zIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBnYXA6IDhweDtcbiAgICB9XG4gICAgLnJwdC1wYWdlLWJ0biB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBnYXA6IDVweDtcbiAgICAgIHBhZGRpbmc6IDRweCAxMHB4O1xuICAgICAgZm9udC1zaXplOiB2YXIoLS1ycHQtZm9udC1zaXplLXNtLCAwLjc1cmVtKTtcbiAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLXJwdC1jb2xvci1iZywgI2ZmZmZmZik7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ycHQtY29sb3ItYm9yZGVyLCAjY2JkNWUxKTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IHZhcigtLXJwdC1ib3JkZXItcmFkaXVzLXNtLCA0cHgpO1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgdHJhbnNpdGlvbjogYWxsIHZhcigtLXJwdC10cmFuc2l0aW9uLXNwZWVkLCAxNTBtcykgZWFzZTtcbiAgICB9XG4gICAgLnJwdC1wYWdlLWJ0bjpob3Zlcjpub3QoOmRpc2FibGVkKSB7XG4gICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1ycHQtY29sb3Itc3VyZmFjZS1ob3ZlciwgI2YxZjVmOSk7XG4gICAgICBib3JkZXItY29sb3I6IHZhcigtLXJwdC1jb2xvci1ib3JkZXItaG92ZXIsICM5NGEzYjgpO1xuICAgIH1cbiAgICAucnB0LXBhZ2UtYnRuOmRpc2FibGVkIHtcbiAgICAgIG9wYWNpdHk6IDAuNTtcbiAgICAgIGN1cnNvcjogbm90LWFsbG93ZWQ7XG4gICAgfVxuICBgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFJlcG9ydEdyaWRCcmlkZ2VDb21wb25lbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IGluamVjdGVkR3JpZCA9IGluamVjdChHUklEX0NPTVBPTkVOVCwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblxuICByZWFkb25seSBncmlkRGVmaW5pdGlvbiA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydEdyaWREZWZpbml0aW9uPigpO1xuICByZWFkb25seSBkYXRhID0gaW5wdXQ8dW5rbm93bltdPihbXSk7XG5cbiAgcmVhZG9ubHkgY3VzdG9tR3JpZENvbXBvbmVudCA9IGNvbXB1dGVkPFR5cGU8dW5rbm93bj4gfCBudWxsPigoKSA9PiB0aGlzLmluamVjdGVkR3JpZCA/PyBudWxsKTtcblxuICByZWFkb25seSBzb3J0Q29sdW1uID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSBzb3J0RGlyZWN0aW9uID0gc2lnbmFsPCdhc2MnIHwgJ2Rlc2MnPignYXNjJyk7XG4gIHJlYWRvbmx5IGN1cnJlbnRQYWdlID0gc2lnbmFsPG51bWJlcj4oMSk7XG4gIHJlYWRvbmx5IGJyaWRnZWRDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiB0aGlzLmdyaWREZWZpbml0aW9uKCkuY29sdW1ucy5tYXAoKGNvbCkgPT4ge1xuICAgICAgbGV0IHdpZHRoTnVtOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgICBpZiAodHlwZW9mIGNvbC53aWR0aCA9PT0gJ3N0cmluZycgJiYgY29sLndpZHRoLmVuZHNXaXRoKCdweCcpKSB7XG4gICAgICAgIHdpZHRoTnVtID0gcGFyc2VJbnQoY29sLndpZHRoLCAxMCk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiAoY29sLndpZHRoIGFzIHVua25vd24pID09PSAnbnVtYmVyJykge1xuICAgICAgICB3aWR0aE51bSA9IGNvbC53aWR0aCBhcyB1bmtub3duIGFzIG51bWJlcjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uY29sLFxuICAgICAgICBoZWFkZXJOYW1lOiBjb2wubGFiZWwsIC8vIEJXYXlzLWdyaWQgLyBBRyBHcmlkIHN0YW5kYXJkXG4gICAgICAgIGhlYWRlcjogY29sLmxhYmVsLFxuICAgICAgICB0aXRsZTogY29sLmxhYmVsLFxuICAgICAgICBoaWRlOiBjb2wudmlzaWJsZSA9PT0gZmFsc2UsXG4gICAgICAgIHdpZHRoOiB3aWR0aE51bSxcbiAgICAgICAgYWdnRnVuYzogY29sLmFnZ3JlZ2F0ZSAmJiBjb2wuYWdncmVnYXRlICE9PSAnbm9uZScgPyBjb2wuYWdncmVnYXRlIDogdW5kZWZpbmVkLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgZ3JpZElucHV0cyA9IGNvbXB1dGVkKCgpID0+ICh7XG4gICAgY29sdW1uczogdGhpcy5icmlkZ2VkQ29sdW1ucygpLFxuICAgIGNvbHVtbkRlZnM6IHRoaXMuYnJpZGdlZENvbHVtbnMoKSxcbiAgICBkYXRhOiB0aGlzLmRhdGEoKSxcbiAgICByb3dEYXRhOiB0aGlzLmRhdGEoKSxcbiAgICBvcHRpb25zOiB0aGlzLmdyaWREZWZpbml0aW9uKCkub3B0aW9ucyxcbiAgICBjb25maWc6IHRoaXMuZ3JpZERlZmluaXRpb24oKS5vcHRpb25zLFxuICAgIHBhZ2luYXRpb246IHRoaXMuZ3JpZERlZmluaXRpb24oKS5vcHRpb25zPy5wYWdpbmF0aW9uICE9PSBmYWxzZSxcbiAgICBwYWdlU2l6ZTogdGhpcy5ncmlkRGVmaW5pdGlvbigpLm9wdGlvbnM/LnBhZ2VTaXplID8/IDEwLFxuICB9KSk7XG5cbiAgcmVhZG9ubHkgdmlzaWJsZUNvbHVtbnMgPSBjb21wdXRlZDxHcmlkQ29sdW1uRGVmaW5pdGlvbltdPigoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuZ3JpZERlZmluaXRpb24oKS5jb2x1bW5zLmZpbHRlcigoYykgPT4gYy52aXNpYmxlICE9PSBmYWxzZSk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNob3dSb3dOdW1iZXJzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiAhIXRoaXMuZ3JpZERlZmluaXRpb24oKS5vcHRpb25zPy5zaG93Um93TnVtYmVycztcbiAgfSk7XG5cbiAgcmVhZG9ubHkgaXNQYWdpbmF0aW9uRW5hYmxlZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5ncmlkRGVmaW5pdGlvbigpLm9wdGlvbnM/LnBhZ2luYXRpb24gIT09IGZhbHNlO1xuICB9KTtcblxuICByZWFkb25seSBwYWdlU2l6ZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5ncmlkRGVmaW5pdGlvbigpLm9wdGlvbnM/LnBhZ2VTaXplID8/IDEwO1xuICB9KTtcblxuICByZWFkb25seSBjb2xTcGFuID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiB0aGlzLnZpc2libGVDb2x1bW5zKCkubGVuZ3RoICsgKHRoaXMuc2hvd1Jvd051bWJlcnMoKSA/IDEgOiAwKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgaGFzQWdncmVnYXRlcyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5ncmlkRGVmaW5pdGlvbigpLm9wdGlvbnM/LnNob3dGb290ZXIgJiZcbiAgICAgIHRoaXMudmlzaWJsZUNvbHVtbnMoKS5zb21lKChjKSA9PiBjLmFnZ3JlZ2F0ZSAmJiBjLmFnZ3JlZ2F0ZSAhPT0gJ25vbmUnKVxuICAgICk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNvcnRlZERhdGEgPSBjb21wdXRlZDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPigoKSA9PiB7XG4gICAgY29uc3QgcmF3ID0gKHRoaXMuZGF0YSgpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10pIHx8IFtdO1xuICAgIGNvbnN0IGNvbCA9IHRoaXMuc29ydENvbHVtbigpO1xuICAgIGNvbnN0IGRpciA9IHRoaXMuc29ydERpcmVjdGlvbigpO1xuXG4gICAgaWYgKCFjb2wpIHJldHVybiByYXc7XG5cbiAgICByZXR1cm4gWy4uLnJhd10uc29ydCgoYSwgYikgPT4ge1xuICAgICAgY29uc3QgdmFsQSA9IGFbY29sXTtcbiAgICAgIGNvbnN0IHZhbEIgPSBiW2NvbF07XG4gICAgICBpZiAodmFsQSA9PSBudWxsICYmIHZhbEIgPT0gbnVsbCkgcmV0dXJuIDA7XG4gICAgICBpZiAodmFsQSA9PSBudWxsKSByZXR1cm4gMTtcbiAgICAgIGlmICh2YWxCID09IG51bGwpIHJldHVybiAtMTtcbiAgICAgIGlmICh2YWxBIDwgdmFsQikgcmV0dXJuIGRpciA9PT0gJ2FzYycgPyAtMSA6IDE7XG4gICAgICBpZiAodmFsQSA+IHZhbEIpIHJldHVybiBkaXIgPT09ICdhc2MnID8gMSA6IC0xO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHRvdGFsUGFnZXMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgaWYgKCF0aGlzLmlzUGFnaW5hdGlvbkVuYWJsZWQoKSkgcmV0dXJuIDE7XG4gICAgY29uc3QgbGVuID0gdGhpcy5zb3J0ZWREYXRhKCkubGVuZ3RoO1xuICAgIHJldHVybiBNYXRoLm1heCgxLCBNYXRoLmNlaWwobGVuIC8gdGhpcy5wYWdlU2l6ZSgpKSk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHBhZ2luYXRlZERhdGEgPSBjb21wdXRlZDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPigoKSA9PiB7XG4gICAgY29uc3Qgc29ydGVkID0gdGhpcy5zb3J0ZWREYXRhKCk7XG4gICAgaWYgKCF0aGlzLmlzUGFnaW5hdGlvbkVuYWJsZWQoKSkge1xuICAgICAgcmV0dXJuIHNvcnRlZDtcbiAgICB9XG4gICAgY29uc3Qgc3RhcnQgPSAodGhpcy5jdXJyZW50UGFnZSgpIC0gMSkgKiB0aGlzLnBhZ2VTaXplKCk7XG4gICAgcmV0dXJuIHNvcnRlZC5zbGljZShzdGFydCwgc3RhcnQgKyB0aGlzLnBhZ2VTaXplKCkpO1xuICB9KTtcblxuICBnZXRKdXN0aWZ5Q29udGVudChhbGlnbj86ICdsZWZ0JyB8ICdjZW50ZXInIHwgJ3JpZ2h0Jyk6IHN0cmluZyB7XG4gICAgaWYgKGFsaWduID09PSAncmlnaHQnKSByZXR1cm4gJ2ZsZXgtZW5kJztcbiAgICBpZiAoYWxpZ24gPT09ICdjZW50ZXInKSByZXR1cm4gJ2NlbnRlcic7XG4gICAgcmV0dXJuICdmbGV4LXN0YXJ0JztcbiAgfVxuXG4gIHRvZ2dsZVNvcnQoY29sOiBHcmlkQ29sdW1uRGVmaW5pdGlvbik6IHZvaWQge1xuICAgIGlmIChjb2wuc29ydGFibGUgPT09IGZhbHNlKSByZXR1cm47XG4gICAgaWYgKHRoaXMuc29ydENvbHVtbigpID09PSBjb2wuZmllbGQpIHtcbiAgICAgIHRoaXMuc29ydERpcmVjdGlvbi5zZXQodGhpcy5zb3J0RGlyZWN0aW9uKCkgPT09ICdhc2MnID8gJ2Rlc2MnIDogJ2FzYycpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNvcnRDb2x1bW4uc2V0KGNvbC5maWVsZCk7XG4gICAgICB0aGlzLnNvcnREaXJlY3Rpb24uc2V0KCdhc2MnKTtcbiAgICB9XG4gICAgdGhpcy5jdXJyZW50UGFnZS5zZXQoMSk7XG4gIH1cblxuICBwcmV2UGFnZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jdXJyZW50UGFnZSgpID4gMSkge1xuICAgICAgdGhpcy5jdXJyZW50UGFnZS51cGRhdGUoKHApID0+IHAgLSAxKTtcbiAgICB9XG4gIH1cblxuICBuZXh0UGFnZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jdXJyZW50UGFnZSgpIDwgdGhpcy50b3RhbFBhZ2VzKCkpIHtcbiAgICAgIHRoaXMuY3VycmVudFBhZ2UudXBkYXRlKChwKSA9PiBwICsgMSk7XG4gICAgfVxuICB9XG5cbiAgZm9ybWF0VmFsdWUodmFsdWU6IHVua25vd24sIGNvbDogR3JpZENvbHVtbkRlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gJyc7XG4gICAgaWYgKGNvbC5kYXRhVHlwZSA9PT0gJ2N1cnJlbmN5Jykge1xuICAgICAgY29uc3QgbnVtID0gTnVtYmVyKHZhbHVlKTtcbiAgICAgIHJldHVybiBpc05hTihudW0pID8gU3RyaW5nKHZhbHVlKSA6IGAkJHtudW0udG9Mb2NhbGVTdHJpbmcodW5kZWZpbmVkLCB7IG1pbmltdW1GcmFjdGlvbkRpZ2l0czogMiwgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiAyIH0pfWA7XG4gICAgfVxuICAgIGlmIChjb2wuZGF0YVR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25zdCBudW0gPSBOdW1iZXIodmFsdWUpO1xuICAgICAgcmV0dXJuIGlzTmFOKG51bSkgPyBTdHJpbmcodmFsdWUpIDogbnVtLnRvTG9jYWxlU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmIChjb2wuZGF0YVR5cGUgPT09ICdkYXRlJyAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBkID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgcmV0dXJuIGlzTmFOKGQuZ2V0VGltZSgpKSA/IFN0cmluZyh2YWx1ZSkgOiBkLnRvTG9jYWxlRGF0ZVN0cmluZygpO1xuICAgIH1cbiAgICByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgfVxuXG4gIGNvbXB1dGVBZ2dyZWdhdGUoY29sOiBHcmlkQ29sdW1uRGVmaW5pdGlvbik6IHN0cmluZyB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuc29ydGVkRGF0YSgpO1xuICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcwJztcblxuICAgIGlmIChjb2wuYWdncmVnYXRlID09PSAnY291bnQnKSB7XG4gICAgICByZXR1cm4gU3RyaW5nKGRhdGEubGVuZ3RoKTtcbiAgICB9XG5cbiAgICBjb25zdCBudW1iZXJzID0gZGF0YVxuICAgICAgLm1hcCgocm93KSA9PiBOdW1iZXIocm93W2NvbC5maWVsZF0pKVxuICAgICAgLmZpbHRlcigobikgPT4gIWlzTmFOKG4pKTtcblxuICAgIGlmIChudW1iZXJzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICcwJztcblxuICAgIGlmIChjb2wuYWdncmVnYXRlID09PSAnc3VtJykge1xuICAgICAgY29uc3Qgc3VtID0gbnVtYmVycy5yZWR1Y2UoKGFjYywgbikgPT4gYWNjICsgbiwgMCk7XG4gICAgICByZXR1cm4gY29sLmRhdGFUeXBlID09PSAnY3VycmVuY3knID8gYCQke3N1bS50b0ZpeGVkKDIpfWAgOiBzdW0udG9Mb2NhbGVTdHJpbmcoKTtcbiAgICB9XG5cbiAgICBpZiAoY29sLmFnZ3JlZ2F0ZSA9PT0gJ2F2ZycpIHtcbiAgICAgIGNvbnN0IGF2ZyA9IG51bWJlcnMucmVkdWNlKChhY2MsIG4pID0+IGFjYyArIG4sIDApIC8gbnVtYmVycy5sZW5ndGg7XG4gICAgICByZXR1cm4gY29sLmRhdGFUeXBlID09PSAnY3VycmVuY3knID8gYCQke2F2Zy50b0ZpeGVkKDIpfWAgOiBhdmcudG9GaXhlZCgyKTtcbiAgICB9XG5cbiAgICBpZiAoY29sLmFnZ3JlZ2F0ZSA9PT0gJ21pbicpIHtcbiAgICAgIGNvbnN0IG1pbiA9IE1hdGgubWluKC4uLm51bWJlcnMpO1xuICAgICAgcmV0dXJuIGNvbC5kYXRhVHlwZSA9PT0gJ2N1cnJlbmN5JyA/IGAkJHttaW4udG9GaXhlZCgyKX1gIDogU3RyaW5nKG1pbik7XG4gICAgfVxuXG4gICAgaWYgKGNvbC5hZ2dyZWdhdGUgPT09ICdtYXgnKSB7XG4gICAgICBjb25zdCBtYXggPSBNYXRoLm1heCguLi5udW1iZXJzKTtcbiAgICAgIHJldHVybiBjb2wuZGF0YVR5cGUgPT09ICdjdXJyZW5jeScgPyBgJCR7bWF4LnRvRml4ZWQoMil9YCA6IFN0cmluZyhtYXgpO1xuICAgIH1cblxuICAgIHJldHVybiAnJztcbiAgfVxufVxuIl19