@ogidor/dashboard 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -0
- package/app/app.module.d.ts +22 -0
- package/app/dashboard-state.service.d.ts +49 -0
- package/app/dashboard.component.d.ts +80 -0
- package/app/models.d.ts +73 -0
- package/app/widget-renderer.component.d.ts +40 -0
- package/esm2020/app/app.module.mjs +64 -0
- package/esm2020/app/dashboard-state.service.mjs +218 -0
- package/esm2020/app/dashboard.component.mjs +703 -0
- package/esm2020/app/models.mjs +2 -0
- package/esm2020/app/widget-renderer.component.mjs +163 -0
- package/esm2020/ogidor-dashboard.mjs +5 -0
- package/esm2020/public-api.mjs +9 -0
- package/fesm2015/ogidor-dashboard.mjs +1153 -0
- package/fesm2015/ogidor-dashboard.mjs.map +1 -0
- package/fesm2020/ogidor-dashboard.mjs +1144 -0
- package/fesm2020/ogidor-dashboard.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/package.json +70 -0
- package/public-api.d.ts +5 -0
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
import { Component, Input } from '@angular/core';
|
|
2
|
+
import { Subscription } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "./dashboard-state.service";
|
|
5
|
+
import * as i2 from "@angular/common";
|
|
6
|
+
import * as i3 from "@angular/forms";
|
|
7
|
+
import * as i4 from "angular-gridster2";
|
|
8
|
+
import * as i5 from "./widget-renderer.component";
|
|
9
|
+
const DEFAULT_THEME = {
|
|
10
|
+
backgroundColor: '#000000',
|
|
11
|
+
panelColor: '#1c1c1e',
|
|
12
|
+
widgetCardColor: '#2c2c2e',
|
|
13
|
+
chartForeColor: '#8e8e93',
|
|
14
|
+
accentColor: '#0a84ff',
|
|
15
|
+
dangerColor: '#ff453a',
|
|
16
|
+
chartColors: ['#0a84ff', '#30d158', '#ff9f0a', '#bf5af2', '#ff453a'],
|
|
17
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
|
|
18
|
+
};
|
|
19
|
+
export class DashboardComponent {
|
|
20
|
+
constructor(stateService) {
|
|
21
|
+
this.stateService = stateService;
|
|
22
|
+
this.resolvedTheme = { ...DEFAULT_THEME };
|
|
23
|
+
this.wrapperStyles = {};
|
|
24
|
+
this.pages = [];
|
|
25
|
+
this.activePageId = '';
|
|
26
|
+
// ── Dialog state ──
|
|
27
|
+
this.dialogOpen = false;
|
|
28
|
+
this.dialogType = 'LINE';
|
|
29
|
+
this.dialogTitle = '';
|
|
30
|
+
this.dialogCategories = '';
|
|
31
|
+
this.dialogSeries = [{ name: 'Series 1', dataRaw: '' }];
|
|
32
|
+
this.dialogSlices = [
|
|
33
|
+
{ label: 'Slice A', value: null },
|
|
34
|
+
{ label: 'Slice B', value: null },
|
|
35
|
+
{ label: 'Slice C', value: null },
|
|
36
|
+
];
|
|
37
|
+
this.widgetTypes = [
|
|
38
|
+
{ value: 'LINE', label: 'Line', icon: 'la-chart-area' },
|
|
39
|
+
{ value: 'BAR', label: 'Bar', icon: 'la-chart-bar' },
|
|
40
|
+
{ value: 'DONUT', label: 'Donut', icon: 'la-chart-pie' },
|
|
41
|
+
];
|
|
42
|
+
this.subs = new Subscription();
|
|
43
|
+
// ── Edit dialog state ──
|
|
44
|
+
this.editDialogOpen = false;
|
|
45
|
+
this.editWidgetType = 'LINE';
|
|
46
|
+
this.editTitle = '';
|
|
47
|
+
this.editCardColor = '';
|
|
48
|
+
this.editColors = [];
|
|
49
|
+
this.editSeries = [];
|
|
50
|
+
this.editCategories = '';
|
|
51
|
+
this.editSlices = [];
|
|
52
|
+
this.DEFAULT_COLORS = ['#0a84ff', '#30d158', '#ff9f0a', '#bf5af2', '#ff453a'];
|
|
53
|
+
this.removeWidgetHandler = (id) => { this.stateService.removeWidget(id); };
|
|
54
|
+
}
|
|
55
|
+
ngOnChanges(changes) {
|
|
56
|
+
if (changes['theme'] || changes['initialLayout'])
|
|
57
|
+
this.applyTheme();
|
|
58
|
+
}
|
|
59
|
+
ngOnInit() {
|
|
60
|
+
this.applyTheme();
|
|
61
|
+
if (this.initialLayout) {
|
|
62
|
+
try {
|
|
63
|
+
this.stateService.loadLayout(JSON.parse(this.initialLayout));
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
console.error('[Dashboard] Failed to parse initialLayout', e);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
this.options = {
|
|
70
|
+
gridType: 'fit',
|
|
71
|
+
displayGrid: 'none',
|
|
72
|
+
pushItems: true,
|
|
73
|
+
draggable: { enabled: true },
|
|
74
|
+
resizable: { enabled: true },
|
|
75
|
+
minCols: 12, maxCols: 12,
|
|
76
|
+
minRows: 12, maxRows: 50,
|
|
77
|
+
margin: 20, outerMargin: true,
|
|
78
|
+
itemChangeCallback: (item) => {
|
|
79
|
+
this.stateService.updateWidgetPosition(this.activePageId, item.id, item.x, item.y, item.cols, item.rows);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
this.subs.add(this.stateService.pages$.subscribe(pages => {
|
|
83
|
+
this.pages = pages;
|
|
84
|
+
this.updateActivePage();
|
|
85
|
+
}));
|
|
86
|
+
this.subs.add(this.stateService.activePageId$.subscribe(id => {
|
|
87
|
+
this.activePageId = id;
|
|
88
|
+
this.updateActivePage();
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
ngOnDestroy() { this.subs.unsubscribe(); }
|
|
92
|
+
applyTheme() {
|
|
93
|
+
this.resolvedTheme = { ...DEFAULT_THEME, ...(this.theme ?? {}) };
|
|
94
|
+
this.wrapperStyles = {
|
|
95
|
+
'--dash-bg': this.resolvedTheme.backgroundColor,
|
|
96
|
+
'--dash-panel-bg': this.resolvedTheme.panelColor,
|
|
97
|
+
'--dash-card-bg': this.resolvedTheme.widgetCardColor,
|
|
98
|
+
'--dash-fore-color': this.resolvedTheme.chartForeColor,
|
|
99
|
+
'--dash-accent-color': this.resolvedTheme.accentColor,
|
|
100
|
+
'--dash-danger-color': this.resolvedTheme.dangerColor,
|
|
101
|
+
'--dash-font-family': this.resolvedTheme.fontFamily,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
updateActivePage() {
|
|
105
|
+
this.activePage = this.pages.find(p => p.id === this.activePageId);
|
|
106
|
+
}
|
|
107
|
+
// ── Page actions ──
|
|
108
|
+
onSelectPage(id) { this.stateService.setActivePage(id); }
|
|
109
|
+
onAddPage() {
|
|
110
|
+
const name = prompt('Enter workspace name:', `Workspace ${this.pages.length + 1}`);
|
|
111
|
+
if (name)
|
|
112
|
+
this.stateService.addPage(name);
|
|
113
|
+
}
|
|
114
|
+
onRemovePage(event, id) {
|
|
115
|
+
event.stopPropagation();
|
|
116
|
+
if (confirm('Remove this workspace?'))
|
|
117
|
+
this.stateService.removePage(id);
|
|
118
|
+
}
|
|
119
|
+
// ── Dialog ──
|
|
120
|
+
openDialog() {
|
|
121
|
+
this.dialogType = 'LINE';
|
|
122
|
+
this.dialogTitle = '';
|
|
123
|
+
this.dialogCategories = '';
|
|
124
|
+
this.dialogSeries = [{ name: 'Series 1', dataRaw: '' }];
|
|
125
|
+
this.dialogSlices = [
|
|
126
|
+
{ label: 'Slice A', value: null },
|
|
127
|
+
{ label: 'Slice B', value: null },
|
|
128
|
+
{ label: 'Slice C', value: null },
|
|
129
|
+
];
|
|
130
|
+
this.dialogOpen = true;
|
|
131
|
+
}
|
|
132
|
+
closeDialog() { this.dialogOpen = false; }
|
|
133
|
+
addSeries() { this.dialogSeries.push({ name: `Series ${this.dialogSeries.length + 1}`, dataRaw: '' }); }
|
|
134
|
+
removeSeries(i) { this.dialogSeries.splice(i, 1); }
|
|
135
|
+
addSlice() { this.dialogSlices.push({ label: `Slice ${this.dialogSlices.length + 1}`, value: null }); }
|
|
136
|
+
removeSlice(i) { this.dialogSlices.splice(i, 1); }
|
|
137
|
+
confirmAddWidget() {
|
|
138
|
+
const title = this.dialogTitle.trim();
|
|
139
|
+
if (!title)
|
|
140
|
+
return;
|
|
141
|
+
let data;
|
|
142
|
+
if (this.dialogType === 'DONUT') {
|
|
143
|
+
const validSlices = this.dialogSlices.filter(s => s.value !== null && s.label.trim());
|
|
144
|
+
data = {
|
|
145
|
+
series: validSlices.length
|
|
146
|
+
? validSlices.map(s => Number(s.value))
|
|
147
|
+
: [30, 20, 50],
|
|
148
|
+
labels: validSlices.length
|
|
149
|
+
? validSlices.map(s => s.label)
|
|
150
|
+
: ['A', 'B', 'C'],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
const parseNums = (raw) => raw.split(',').map(v => parseFloat(v.trim())).filter(n => !isNaN(n));
|
|
155
|
+
data = {
|
|
156
|
+
series: this.dialogSeries.map(s => ({
|
|
157
|
+
name: s.name || 'Series',
|
|
158
|
+
data: s.dataRaw.trim()
|
|
159
|
+
? parseNums(s.dataRaw)
|
|
160
|
+
: Array.from({ length: 8 }, () => Math.floor(Math.random() * 100)),
|
|
161
|
+
})),
|
|
162
|
+
categories: this.dialogCategories.trim()
|
|
163
|
+
? this.dialogCategories.split(',').map(c => c.trim())
|
|
164
|
+
: undefined,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
this.stateService.addWidgetWithData(this.dialogType, title, data);
|
|
168
|
+
this.closeDialog();
|
|
169
|
+
}
|
|
170
|
+
openEditDialog(widget) {
|
|
171
|
+
this.editingWidget = widget;
|
|
172
|
+
this.editWidgetType = widget.type;
|
|
173
|
+
this.editTitle = widget.title;
|
|
174
|
+
this.editCardColor = widget.cardColor ?? this.resolvedTheme.widgetCardColor;
|
|
175
|
+
this.editColors = widget.colors?.length
|
|
176
|
+
? [...widget.colors]
|
|
177
|
+
: [...this.resolvedTheme.chartColors];
|
|
178
|
+
if (widget.type === 'DONUT') {
|
|
179
|
+
const d = widget.data;
|
|
180
|
+
this.editSlices = d.series.map((v, i) => ({
|
|
181
|
+
label: d.labels?.[i] ?? `Slice ${i + 1}`,
|
|
182
|
+
value: v,
|
|
183
|
+
}));
|
|
184
|
+
this.editColors = this.editColors.slice(0, this.editSlices.length);
|
|
185
|
+
while (this.editColors.length < this.editSlices.length) {
|
|
186
|
+
this.editColors.push(this.DEFAULT_COLORS[this.editColors.length % this.DEFAULT_COLORS.length]);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
const d = widget.data;
|
|
191
|
+
this.editSeries = d.series.map((s) => ({ name: s.name, dataRaw: s.data.join(',') }));
|
|
192
|
+
this.editCategories = d.categories?.join(',') ?? '';
|
|
193
|
+
this.editColors = this.editColors.slice(0, this.editSeries.length);
|
|
194
|
+
while (this.editColors.length < this.editSeries.length) {
|
|
195
|
+
this.editColors.push(this.DEFAULT_COLORS[this.editColors.length % this.DEFAULT_COLORS.length]);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
this.editDialogOpen = true;
|
|
199
|
+
}
|
|
200
|
+
closeEditDialog() { this.editDialogOpen = false; this.editingWidget = undefined; }
|
|
201
|
+
getEditSeriesLabel(i) {
|
|
202
|
+
if (this.editWidgetType === 'DONUT')
|
|
203
|
+
return this.editSlices[i]?.label || `Slice ${i + 1}`;
|
|
204
|
+
return this.editSeries[i]?.name || `Series ${i + 1}`;
|
|
205
|
+
}
|
|
206
|
+
addEditSeries() {
|
|
207
|
+
this.editSeries.push({ name: `Series ${this.editSeries.length + 1}`, dataRaw: '' });
|
|
208
|
+
this.editColors.push(this.DEFAULT_COLORS[this.editColors.length % this.DEFAULT_COLORS.length]);
|
|
209
|
+
}
|
|
210
|
+
removeEditSeries(i) { this.editSeries.splice(i, 1); this.editColors.splice(i, 1); }
|
|
211
|
+
addEditSlice() {
|
|
212
|
+
this.editSlices.push({ label: `Slice ${this.editSlices.length + 1}`, value: null });
|
|
213
|
+
this.editColors.push(this.DEFAULT_COLORS[this.editColors.length % this.DEFAULT_COLORS.length]);
|
|
214
|
+
}
|
|
215
|
+
removeEditSlice(i) { this.editSlices.splice(i, 1); this.editColors.splice(i, 1); }
|
|
216
|
+
confirmEditWidget() {
|
|
217
|
+
if (!this.editingWidget)
|
|
218
|
+
return;
|
|
219
|
+
const parseNums = (raw) => raw.split(',').map(v => parseFloat(v.trim())).filter(n => !isNaN(n));
|
|
220
|
+
let data;
|
|
221
|
+
if (this.editWidgetType === 'DONUT') {
|
|
222
|
+
data = {
|
|
223
|
+
series: this.editSlices.map(s => Number(s.value) || 0),
|
|
224
|
+
labels: this.editSlices.map(s => s.label),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
data = {
|
|
229
|
+
series: this.editSeries.map(s => ({
|
|
230
|
+
name: s.name || 'Series',
|
|
231
|
+
data: s.dataRaw.trim() ? parseNums(s.dataRaw) : [],
|
|
232
|
+
})),
|
|
233
|
+
categories: this.editCategories.trim()
|
|
234
|
+
? this.editCategories.split(',').map(c => c.trim())
|
|
235
|
+
: undefined,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
this.stateService.updateWidgetMeta(this.editingWidget.id, {
|
|
239
|
+
title: this.editTitle.trim() || this.editingWidget.title,
|
|
240
|
+
colors: [...this.editColors],
|
|
241
|
+
cardColor: this.editCardColor,
|
|
242
|
+
data,
|
|
243
|
+
});
|
|
244
|
+
this.closeEditDialog();
|
|
245
|
+
}
|
|
246
|
+
// ── Widget actions ──
|
|
247
|
+
onAddWidget(type) { this.stateService.addWidget(type); }
|
|
248
|
+
updateWidgetData(widgetId, data) {
|
|
249
|
+
this.stateService.updateWidgetData(widgetId, data);
|
|
250
|
+
}
|
|
251
|
+
serializeLayout() { return this.stateService.serializeLayout(); }
|
|
252
|
+
}
|
|
253
|
+
DashboardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardComponent, deps: [{ token: i1.DashboardStateService }], target: i0.ɵɵFactoryTarget.Component });
|
|
254
|
+
DashboardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DashboardComponent, selector: "app-dashboard", inputs: { initialLayout: "initialLayout", theme: "theme" }, usesOnChanges: true, ngImport: i0, template: `
|
|
255
|
+
<div class="dashboard-wrapper" [ngStyle]="wrapperStyles">
|
|
256
|
+
<main class="main-content">
|
|
257
|
+
|
|
258
|
+
<!-- ── Header ── -->
|
|
259
|
+
<header class="dashboard-header">
|
|
260
|
+
<!-- Tabs -->
|
|
261
|
+
<div class="tabs-container">
|
|
262
|
+
<div
|
|
263
|
+
*ngFor="let page of pages"
|
|
264
|
+
class="tab"
|
|
265
|
+
[class.active]="page.id === activePageId"
|
|
266
|
+
(click)="onSelectPage(page.id)"
|
|
267
|
+
>
|
|
268
|
+
<span class="tab-name">{{ page.name }}</span>
|
|
269
|
+
<button class="tab-close" *ngIf="pages.length > 1" (click)="onRemovePage($event, page.id)">
|
|
270
|
+
<i class="la la-times"></i>
|
|
271
|
+
</button>
|
|
272
|
+
</div>
|
|
273
|
+
<button class="btn-add-page" (click)="onAddPage()" title="New workspace">
|
|
274
|
+
<i class="la la-plus"></i>
|
|
275
|
+
</button>
|
|
276
|
+
</div>
|
|
277
|
+
|
|
278
|
+
<!-- Add Widget button -->
|
|
279
|
+
<button class="btn-add-widget" (click)="openDialog()" title="Add widget">
|
|
280
|
+
<i class="la la-plus"></i>
|
|
281
|
+
<span>Add Widget</span>
|
|
282
|
+
</button>
|
|
283
|
+
</header>
|
|
284
|
+
|
|
285
|
+
<!-- ── Grid ── -->
|
|
286
|
+
<div class="grid-container">
|
|
287
|
+
<gridster [options]="options">
|
|
288
|
+
<gridster-item [item]="widget" *ngFor="let widget of activePage?.widgets">
|
|
289
|
+
<app-widget-renderer
|
|
290
|
+
[widget]="widget"
|
|
291
|
+
[onRemoveWidget]="removeWidgetHandler"
|
|
292
|
+
[theme]="resolvedTheme"
|
|
293
|
+
(editRequested)="openEditDialog($event)"
|
|
294
|
+
></app-widget-renderer>
|
|
295
|
+
</gridster-item>
|
|
296
|
+
</gridster>
|
|
297
|
+
</div>
|
|
298
|
+
</main>
|
|
299
|
+
</div>
|
|
300
|
+
|
|
301
|
+
<!-- ── Add Widget Dialog ── -->
|
|
302
|
+
<div class="dialog-backdrop" *ngIf="dialogOpen" (click)="closeDialog()"></div>
|
|
303
|
+
<div class="dialog" *ngIf="dialogOpen">
|
|
304
|
+
<div class="dialog-header">
|
|
305
|
+
<span class="dialog-title">Add Widget</span>
|
|
306
|
+
<button class="dialog-close" (click)="closeDialog()"><i class="la la-times"></i></button>
|
|
307
|
+
</div>
|
|
308
|
+
|
|
309
|
+
<div class="dialog-body">
|
|
310
|
+
|
|
311
|
+
<!-- Chart type picker -->
|
|
312
|
+
<div class="field-group">
|
|
313
|
+
<label class="field-label">Chart type</label>
|
|
314
|
+
<div class="type-picker">
|
|
315
|
+
<button
|
|
316
|
+
*ngFor="let t of widgetTypes"
|
|
317
|
+
class="type-btn"
|
|
318
|
+
[class.selected]="dialogType === t.value"
|
|
319
|
+
(click)="dialogType = t.value"
|
|
320
|
+
>
|
|
321
|
+
<i [class]="'la ' + t.icon"></i>
|
|
322
|
+
<span>{{ t.label }}</span>
|
|
323
|
+
</button>
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
326
|
+
|
|
327
|
+
<!-- Title -->
|
|
328
|
+
<div class="field-group">
|
|
329
|
+
<label class="field-label">Title</label>
|
|
330
|
+
<input class="field-input" [(ngModel)]="dialogTitle" placeholder="My Chart" />
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
<!-- Series (LINE / BAR) -->
|
|
334
|
+
<ng-container *ngIf="dialogType !== 'DONUT'">
|
|
335
|
+
<div class="field-group">
|
|
336
|
+
<div class="field-row-header">
|
|
337
|
+
<label class="field-label">Series</label>
|
|
338
|
+
<button class="btn-link" (click)="addSeries()"><i class="la la-plus"></i> Add series</button>
|
|
339
|
+
</div>
|
|
340
|
+
<div class="series-list">
|
|
341
|
+
<div class="series-row" *ngFor="let s of dialogSeries; let i = index">
|
|
342
|
+
<input class="field-input series-name" [(ngModel)]="s.name" placeholder="Series name" />
|
|
343
|
+
<input class="field-input series-data" [(ngModel)]="s.dataRaw"
|
|
344
|
+
placeholder="Comma-separated values, e.g. 10,25,40" />
|
|
345
|
+
<button class="btn-remove-series" *ngIf="dialogSeries.length > 1" (click)="removeSeries(i)">
|
|
346
|
+
<i class="la la-times"></i>
|
|
347
|
+
</button>
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
<div class="field-group">
|
|
353
|
+
<label class="field-label">X-axis labels <span class="field-hint">(optional, comma-separated)</span></label>
|
|
354
|
+
<input class="field-input" [(ngModel)]="dialogCategories" placeholder="Jan,Feb,Mar,Apr" />
|
|
355
|
+
</div>
|
|
356
|
+
</ng-container>
|
|
357
|
+
|
|
358
|
+
<!-- Slices (DONUT) -->
|
|
359
|
+
<ng-container *ngIf="dialogType === 'DONUT'">
|
|
360
|
+
<div class="field-group">
|
|
361
|
+
<div class="field-row-header">
|
|
362
|
+
<label class="field-label">Slices</label>
|
|
363
|
+
<button class="btn-link" (click)="addSlice()"><i class="la la-plus"></i> Add slice</button>
|
|
364
|
+
</div>
|
|
365
|
+
<div class="series-list">
|
|
366
|
+
<div class="series-row" *ngFor="let sl of dialogSlices; let i = index">
|
|
367
|
+
<input class="field-input series-name" [(ngModel)]="sl.label" placeholder="Label" />
|
|
368
|
+
<input class="field-input series-data" [(ngModel)]="sl.value" type="number" placeholder="Value" />
|
|
369
|
+
<button class="btn-remove-series" *ngIf="dialogSlices.length > 1" (click)="removeSlice(i)">
|
|
370
|
+
<i class="la la-times"></i>
|
|
371
|
+
</button>
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
</ng-container>
|
|
376
|
+
|
|
377
|
+
</div>
|
|
378
|
+
|
|
379
|
+
<div class="dialog-footer">
|
|
380
|
+
<button class="btn-cancel" (click)="closeDialog()">Cancel</button>
|
|
381
|
+
<button class="btn-confirm" (click)="confirmAddWidget()" [disabled]="!dialogTitle.trim()">
|
|
382
|
+
<i class="la la-check"></i> Add Widget
|
|
383
|
+
</button>
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
<!-- ── Edit Widget Dialog ── -->
|
|
387
|
+
<div class="dialog-backdrop" *ngIf="editDialogOpen" (click)="closeEditDialog()"></div>
|
|
388
|
+
<div class="dialog" *ngIf="editDialogOpen">
|
|
389
|
+
<div class="dialog-header">
|
|
390
|
+
<span class="dialog-title">Edit Widget</span>
|
|
391
|
+
<button class="dialog-close" (click)="closeEditDialog()"><i class="la la-times"></i></button>
|
|
392
|
+
</div>
|
|
393
|
+
|
|
394
|
+
<div class="dialog-body">
|
|
395
|
+
|
|
396
|
+
<!-- Title -->
|
|
397
|
+
<div class="field-group">
|
|
398
|
+
<label class="field-label">Title</label>
|
|
399
|
+
<input class="field-input" [(ngModel)]="editTitle" placeholder="Chart title" />
|
|
400
|
+
</div>
|
|
401
|
+
|
|
402
|
+
<!-- Card background -->
|
|
403
|
+
<div class="field-group">
|
|
404
|
+
<label class="field-label">Card color</label>
|
|
405
|
+
<div class="color-row">
|
|
406
|
+
<input type="color" class="color-swatch" [(ngModel)]="editCardColor" />
|
|
407
|
+
<input class="field-input" [(ngModel)]="editCardColor" placeholder="#2c2c2e" />
|
|
408
|
+
</div>
|
|
409
|
+
</div>
|
|
410
|
+
|
|
411
|
+
<!-- Series colors -->
|
|
412
|
+
<div class="field-group">
|
|
413
|
+
<label class="field-label">Series colors</label>
|
|
414
|
+
<div class="color-list">
|
|
415
|
+
<div class="color-item" *ngFor="let c of editColors; let i = index">
|
|
416
|
+
<input type="color" class="color-swatch" [(ngModel)]="editColors[i]" />
|
|
417
|
+
<input class="field-input color-hex" [(ngModel)]="editColors[i]" placeholder="#0a84ff" />
|
|
418
|
+
<span class="color-label">{{ getEditSeriesLabel(i) }}</span>
|
|
419
|
+
</div>
|
|
420
|
+
</div>
|
|
421
|
+
</div>
|
|
422
|
+
|
|
423
|
+
<!-- Data: LINE / BAR -->
|
|
424
|
+
<ng-container *ngIf="editWidgetType !== 'DONUT'">
|
|
425
|
+
<div class="field-group">
|
|
426
|
+
<div class="field-row-header">
|
|
427
|
+
<label class="field-label">Series data</label>
|
|
428
|
+
<button class="btn-link" (click)="addEditSeries()"><i class="la la-plus"></i> Add</button>
|
|
429
|
+
</div>
|
|
430
|
+
<div class="series-list">
|
|
431
|
+
<div class="series-row" *ngFor="let s of editSeries; let i = index">
|
|
432
|
+
<input class="field-input series-name" [(ngModel)]="s.name" placeholder="Name" />
|
|
433
|
+
<input class="field-input series-data" [(ngModel)]="s.dataRaw" placeholder="10,20,30" />
|
|
434
|
+
<button class="btn-remove-series" *ngIf="editSeries.length > 1" (click)="removeEditSeries(i)">
|
|
435
|
+
<i class="la la-times"></i>
|
|
436
|
+
</button>
|
|
437
|
+
</div>
|
|
438
|
+
</div>
|
|
439
|
+
</div>
|
|
440
|
+
<div class="field-group">
|
|
441
|
+
<label class="field-label">X-axis labels <span class="field-hint">(optional, comma-separated)</span></label>
|
|
442
|
+
<input class="field-input" [(ngModel)]="editCategories" placeholder="Jan,Feb,Mar" />
|
|
443
|
+
</div>
|
|
444
|
+
</ng-container>
|
|
445
|
+
|
|
446
|
+
<!-- Data: DONUT -->
|
|
447
|
+
<ng-container *ngIf="editWidgetType === 'DONUT'">
|
|
448
|
+
<div class="field-group">
|
|
449
|
+
<div class="field-row-header">
|
|
450
|
+
<label class="field-label">Slices</label>
|
|
451
|
+
<button class="btn-link" (click)="addEditSlice()"><i class="la la-plus"></i> Add</button>
|
|
452
|
+
</div>
|
|
453
|
+
<div class="series-list">
|
|
454
|
+
<div class="series-row" *ngFor="let sl of editSlices; let i = index">
|
|
455
|
+
<input class="field-input series-name" [(ngModel)]="sl.label" placeholder="Label" />
|
|
456
|
+
<input class="field-input series-data" [(ngModel)]="sl.value" type="number" placeholder="Value" />
|
|
457
|
+
<button class="btn-remove-series" *ngIf="editSlices.length > 1" (click)="removeEditSlice(i)">
|
|
458
|
+
<i class="la la-times"></i>
|
|
459
|
+
</button>
|
|
460
|
+
</div>
|
|
461
|
+
</div>
|
|
462
|
+
</div>
|
|
463
|
+
</ng-container>
|
|
464
|
+
|
|
465
|
+
</div>
|
|
466
|
+
|
|
467
|
+
<div class="dialog-footer">
|
|
468
|
+
<button class="btn-cancel" (click)="closeEditDialog()">Cancel</button>
|
|
469
|
+
<button class="btn-confirm" (click)="confirmEditWidget()">
|
|
470
|
+
<i class="la la-check"></i> Save
|
|
471
|
+
</button>
|
|
472
|
+
</div>
|
|
473
|
+
</div>
|
|
474
|
+
`, isInline: true, styles: [":host{--dash-bg: #000000;--dash-panel-bg: #1c1c1e;--dash-card-bg: #2c2c2e;--dash-fore-color: #8e8e93;--dash-accent-color: #0a84ff;--dash-danger-color: #ff453a;--dash-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif}.dashboard-wrapper{display:flex;height:100vh;width:100vw;overflow:hidden;padding:16px;box-sizing:border-box;background:var(--dash-bg);color:var(--dash-fore-color);font-family:var(--dash-font-family)}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden;border-radius:40px;padding:20px;background:var(--dash-panel-bg);box-shadow:0 10px 30px #00000080;border:1px solid rgba(255,255,255,.05)}.dashboard-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;gap:12px}.tabs-container{display:flex;align-items:center;gap:8px;background:rgba(44,44,46,.6);backdrop-filter:blur(10px);border-radius:25px;padding:6px}.tab{display:flex;align-items:center;padding:8px 20px;border-radius:20px;cursor:pointer;font-size:14px;font-weight:500;color:var(--dash-fore-color);transition:all .3s cubic-bezier(.25,.8,.25,1)}.tab.active{background:#3a3a3c;color:#fff;box-shadow:0 2px 10px #0003}.tab:hover:not(.active){color:#e5e5ea;background:rgba(255,255,255,.05)}.tab-name{margin-right:8px}.tab-close{background:transparent;border:none;color:var(--dash-fore-color);padding:2px;font-size:12px;cursor:pointer;opacity:0;border-radius:50%;display:flex;align-items:center;justify-content:center;transition:all .2s}.tab-close:hover{color:var(--dash-danger-color);background:rgba(255,69,58,.2)}.tab:hover .tab-close{opacity:1}.btn-add-page{background:transparent;border:none;color:var(--dash-fore-color);padding:8px 16px;cursor:pointer;border-radius:20px;transition:all .2s}.btn-add-page:hover{color:var(--dash-accent-color);background:rgba(10,132,255,.1)}.btn-add-widget{display:flex;align-items:center;gap:6px;background:var(--dash-accent-color);border:none;color:#fff;font-size:14px;font-weight:600;padding:10px 20px;border-radius:22px;cursor:pointer;white-space:nowrap;transition:opacity .2s,transform .15s;box-shadow:0 4px 14px #0a84ff66}.btn-add-widget:hover{opacity:.9;transform:translateY(-1px)}.btn-add-widget:active{transform:translateY(0)}.grid-container{flex:1;overflow:auto;border-radius:24px;min-height:0}gridster{background:transparent;height:100%!important}.dialog-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.6);backdrop-filter:blur(6px);z-index:900}.dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:901;width:min(520px,calc(100vw - 32px));max-height:calc(100vh - 64px);display:flex;flex-direction:column;background:var(--dash-panel-bg);border-radius:28px;border:1px solid rgba(255,255,255,.1);box-shadow:0 24px 60px #000000b3;overflow:hidden}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:22px 24px 16px;border-bottom:1px solid rgba(255,255,255,.07)}.dialog-title{font-size:17px;font-weight:700;color:#fff}.dialog-close{background:rgba(255,255,255,.08);border:none;color:var(--dash-fore-color);width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;transition:all .2s}.dialog-close:hover{background:rgba(255,69,58,.25);color:var(--dash-danger-color)}.dialog-body{flex:1;overflow-y:auto;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.field-group{display:flex;flex-direction:column;gap:8px}.field-label{font-size:13px;font-weight:600;color:var(--dash-fore-color);text-transform:uppercase;letter-spacing:.5px}.field-input{background:var(--dash-card-bg);border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:10px 14px;color:#fff;font-size:14px;outline:none;width:100%;box-sizing:border-box}.field-input:focus{border-color:var(--dash-accent-color)}.type-picker{display:flex;gap:10px}.type-btn{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;padding:14px 10px;background:var(--dash-card-bg);border:2px solid transparent;border-radius:16px;color:var(--dash-fore-color);font-size:12px;font-weight:600;cursor:pointer;transition:all .2s}.type-btn.selected{border-color:var(--dash-accent-color);color:var(--dash-accent-color);background:rgba(10,132,255,.12)}.btn-link{background:transparent;border:none;color:var(--dash-accent-color);font-size:13px;font-weight:600;cursor:pointer}.dialog-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px;padding:16px 24px 22px;border-top:1px solid rgba(255,255,255,.07)}.btn-cancel{background:transparent;border:1px solid rgba(255,255,255,.12);color:var(--dash-fore-color);padding:10px 20px;border-radius:20px;cursor:pointer}.btn-confirm{background:var(--dash-accent-color);border:none;color:#fff;padding:10px 22px;border-radius:20px;font-weight:600;cursor:pointer}.btn-confirm:disabled{opacity:.4;cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.GridsterComponent, selector: "gridster", inputs: ["options"] }, { kind: "component", type: i4.GridsterItemComponent, selector: "gridster-item", inputs: ["item"], outputs: ["itemInit", "itemChange", "itemResize"] }, { kind: "component", type: i5.WidgetRendererComponent, selector: "app-widget-renderer", inputs: ["widget", "onRemoveWidget", "theme"], outputs: ["editRequested"] }] });
|
|
475
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardComponent, decorators: [{
|
|
476
|
+
type: Component,
|
|
477
|
+
args: [{ selector: 'app-dashboard', template: `
|
|
478
|
+
<div class="dashboard-wrapper" [ngStyle]="wrapperStyles">
|
|
479
|
+
<main class="main-content">
|
|
480
|
+
|
|
481
|
+
<!-- ── Header ── -->
|
|
482
|
+
<header class="dashboard-header">
|
|
483
|
+
<!-- Tabs -->
|
|
484
|
+
<div class="tabs-container">
|
|
485
|
+
<div
|
|
486
|
+
*ngFor="let page of pages"
|
|
487
|
+
class="tab"
|
|
488
|
+
[class.active]="page.id === activePageId"
|
|
489
|
+
(click)="onSelectPage(page.id)"
|
|
490
|
+
>
|
|
491
|
+
<span class="tab-name">{{ page.name }}</span>
|
|
492
|
+
<button class="tab-close" *ngIf="pages.length > 1" (click)="onRemovePage($event, page.id)">
|
|
493
|
+
<i class="la la-times"></i>
|
|
494
|
+
</button>
|
|
495
|
+
</div>
|
|
496
|
+
<button class="btn-add-page" (click)="onAddPage()" title="New workspace">
|
|
497
|
+
<i class="la la-plus"></i>
|
|
498
|
+
</button>
|
|
499
|
+
</div>
|
|
500
|
+
|
|
501
|
+
<!-- Add Widget button -->
|
|
502
|
+
<button class="btn-add-widget" (click)="openDialog()" title="Add widget">
|
|
503
|
+
<i class="la la-plus"></i>
|
|
504
|
+
<span>Add Widget</span>
|
|
505
|
+
</button>
|
|
506
|
+
</header>
|
|
507
|
+
|
|
508
|
+
<!-- ── Grid ── -->
|
|
509
|
+
<div class="grid-container">
|
|
510
|
+
<gridster [options]="options">
|
|
511
|
+
<gridster-item [item]="widget" *ngFor="let widget of activePage?.widgets">
|
|
512
|
+
<app-widget-renderer
|
|
513
|
+
[widget]="widget"
|
|
514
|
+
[onRemoveWidget]="removeWidgetHandler"
|
|
515
|
+
[theme]="resolvedTheme"
|
|
516
|
+
(editRequested)="openEditDialog($event)"
|
|
517
|
+
></app-widget-renderer>
|
|
518
|
+
</gridster-item>
|
|
519
|
+
</gridster>
|
|
520
|
+
</div>
|
|
521
|
+
</main>
|
|
522
|
+
</div>
|
|
523
|
+
|
|
524
|
+
<!-- ── Add Widget Dialog ── -->
|
|
525
|
+
<div class="dialog-backdrop" *ngIf="dialogOpen" (click)="closeDialog()"></div>
|
|
526
|
+
<div class="dialog" *ngIf="dialogOpen">
|
|
527
|
+
<div class="dialog-header">
|
|
528
|
+
<span class="dialog-title">Add Widget</span>
|
|
529
|
+
<button class="dialog-close" (click)="closeDialog()"><i class="la la-times"></i></button>
|
|
530
|
+
</div>
|
|
531
|
+
|
|
532
|
+
<div class="dialog-body">
|
|
533
|
+
|
|
534
|
+
<!-- Chart type picker -->
|
|
535
|
+
<div class="field-group">
|
|
536
|
+
<label class="field-label">Chart type</label>
|
|
537
|
+
<div class="type-picker">
|
|
538
|
+
<button
|
|
539
|
+
*ngFor="let t of widgetTypes"
|
|
540
|
+
class="type-btn"
|
|
541
|
+
[class.selected]="dialogType === t.value"
|
|
542
|
+
(click)="dialogType = t.value"
|
|
543
|
+
>
|
|
544
|
+
<i [class]="'la ' + t.icon"></i>
|
|
545
|
+
<span>{{ t.label }}</span>
|
|
546
|
+
</button>
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
|
|
550
|
+
<!-- Title -->
|
|
551
|
+
<div class="field-group">
|
|
552
|
+
<label class="field-label">Title</label>
|
|
553
|
+
<input class="field-input" [(ngModel)]="dialogTitle" placeholder="My Chart" />
|
|
554
|
+
</div>
|
|
555
|
+
|
|
556
|
+
<!-- Series (LINE / BAR) -->
|
|
557
|
+
<ng-container *ngIf="dialogType !== 'DONUT'">
|
|
558
|
+
<div class="field-group">
|
|
559
|
+
<div class="field-row-header">
|
|
560
|
+
<label class="field-label">Series</label>
|
|
561
|
+
<button class="btn-link" (click)="addSeries()"><i class="la la-plus"></i> Add series</button>
|
|
562
|
+
</div>
|
|
563
|
+
<div class="series-list">
|
|
564
|
+
<div class="series-row" *ngFor="let s of dialogSeries; let i = index">
|
|
565
|
+
<input class="field-input series-name" [(ngModel)]="s.name" placeholder="Series name" />
|
|
566
|
+
<input class="field-input series-data" [(ngModel)]="s.dataRaw"
|
|
567
|
+
placeholder="Comma-separated values, e.g. 10,25,40" />
|
|
568
|
+
<button class="btn-remove-series" *ngIf="dialogSeries.length > 1" (click)="removeSeries(i)">
|
|
569
|
+
<i class="la la-times"></i>
|
|
570
|
+
</button>
|
|
571
|
+
</div>
|
|
572
|
+
</div>
|
|
573
|
+
</div>
|
|
574
|
+
|
|
575
|
+
<div class="field-group">
|
|
576
|
+
<label class="field-label">X-axis labels <span class="field-hint">(optional, comma-separated)</span></label>
|
|
577
|
+
<input class="field-input" [(ngModel)]="dialogCategories" placeholder="Jan,Feb,Mar,Apr" />
|
|
578
|
+
</div>
|
|
579
|
+
</ng-container>
|
|
580
|
+
|
|
581
|
+
<!-- Slices (DONUT) -->
|
|
582
|
+
<ng-container *ngIf="dialogType === 'DONUT'">
|
|
583
|
+
<div class="field-group">
|
|
584
|
+
<div class="field-row-header">
|
|
585
|
+
<label class="field-label">Slices</label>
|
|
586
|
+
<button class="btn-link" (click)="addSlice()"><i class="la la-plus"></i> Add slice</button>
|
|
587
|
+
</div>
|
|
588
|
+
<div class="series-list">
|
|
589
|
+
<div class="series-row" *ngFor="let sl of dialogSlices; let i = index">
|
|
590
|
+
<input class="field-input series-name" [(ngModel)]="sl.label" placeholder="Label" />
|
|
591
|
+
<input class="field-input series-data" [(ngModel)]="sl.value" type="number" placeholder="Value" />
|
|
592
|
+
<button class="btn-remove-series" *ngIf="dialogSlices.length > 1" (click)="removeSlice(i)">
|
|
593
|
+
<i class="la la-times"></i>
|
|
594
|
+
</button>
|
|
595
|
+
</div>
|
|
596
|
+
</div>
|
|
597
|
+
</div>
|
|
598
|
+
</ng-container>
|
|
599
|
+
|
|
600
|
+
</div>
|
|
601
|
+
|
|
602
|
+
<div class="dialog-footer">
|
|
603
|
+
<button class="btn-cancel" (click)="closeDialog()">Cancel</button>
|
|
604
|
+
<button class="btn-confirm" (click)="confirmAddWidget()" [disabled]="!dialogTitle.trim()">
|
|
605
|
+
<i class="la la-check"></i> Add Widget
|
|
606
|
+
</button>
|
|
607
|
+
</div>
|
|
608
|
+
</div>
|
|
609
|
+
<!-- ── Edit Widget Dialog ── -->
|
|
610
|
+
<div class="dialog-backdrop" *ngIf="editDialogOpen" (click)="closeEditDialog()"></div>
|
|
611
|
+
<div class="dialog" *ngIf="editDialogOpen">
|
|
612
|
+
<div class="dialog-header">
|
|
613
|
+
<span class="dialog-title">Edit Widget</span>
|
|
614
|
+
<button class="dialog-close" (click)="closeEditDialog()"><i class="la la-times"></i></button>
|
|
615
|
+
</div>
|
|
616
|
+
|
|
617
|
+
<div class="dialog-body">
|
|
618
|
+
|
|
619
|
+
<!-- Title -->
|
|
620
|
+
<div class="field-group">
|
|
621
|
+
<label class="field-label">Title</label>
|
|
622
|
+
<input class="field-input" [(ngModel)]="editTitle" placeholder="Chart title" />
|
|
623
|
+
</div>
|
|
624
|
+
|
|
625
|
+
<!-- Card background -->
|
|
626
|
+
<div class="field-group">
|
|
627
|
+
<label class="field-label">Card color</label>
|
|
628
|
+
<div class="color-row">
|
|
629
|
+
<input type="color" class="color-swatch" [(ngModel)]="editCardColor" />
|
|
630
|
+
<input class="field-input" [(ngModel)]="editCardColor" placeholder="#2c2c2e" />
|
|
631
|
+
</div>
|
|
632
|
+
</div>
|
|
633
|
+
|
|
634
|
+
<!-- Series colors -->
|
|
635
|
+
<div class="field-group">
|
|
636
|
+
<label class="field-label">Series colors</label>
|
|
637
|
+
<div class="color-list">
|
|
638
|
+
<div class="color-item" *ngFor="let c of editColors; let i = index">
|
|
639
|
+
<input type="color" class="color-swatch" [(ngModel)]="editColors[i]" />
|
|
640
|
+
<input class="field-input color-hex" [(ngModel)]="editColors[i]" placeholder="#0a84ff" />
|
|
641
|
+
<span class="color-label">{{ getEditSeriesLabel(i) }}</span>
|
|
642
|
+
</div>
|
|
643
|
+
</div>
|
|
644
|
+
</div>
|
|
645
|
+
|
|
646
|
+
<!-- Data: LINE / BAR -->
|
|
647
|
+
<ng-container *ngIf="editWidgetType !== 'DONUT'">
|
|
648
|
+
<div class="field-group">
|
|
649
|
+
<div class="field-row-header">
|
|
650
|
+
<label class="field-label">Series data</label>
|
|
651
|
+
<button class="btn-link" (click)="addEditSeries()"><i class="la la-plus"></i> Add</button>
|
|
652
|
+
</div>
|
|
653
|
+
<div class="series-list">
|
|
654
|
+
<div class="series-row" *ngFor="let s of editSeries; let i = index">
|
|
655
|
+
<input class="field-input series-name" [(ngModel)]="s.name" placeholder="Name" />
|
|
656
|
+
<input class="field-input series-data" [(ngModel)]="s.dataRaw" placeholder="10,20,30" />
|
|
657
|
+
<button class="btn-remove-series" *ngIf="editSeries.length > 1" (click)="removeEditSeries(i)">
|
|
658
|
+
<i class="la la-times"></i>
|
|
659
|
+
</button>
|
|
660
|
+
</div>
|
|
661
|
+
</div>
|
|
662
|
+
</div>
|
|
663
|
+
<div class="field-group">
|
|
664
|
+
<label class="field-label">X-axis labels <span class="field-hint">(optional, comma-separated)</span></label>
|
|
665
|
+
<input class="field-input" [(ngModel)]="editCategories" placeholder="Jan,Feb,Mar" />
|
|
666
|
+
</div>
|
|
667
|
+
</ng-container>
|
|
668
|
+
|
|
669
|
+
<!-- Data: DONUT -->
|
|
670
|
+
<ng-container *ngIf="editWidgetType === 'DONUT'">
|
|
671
|
+
<div class="field-group">
|
|
672
|
+
<div class="field-row-header">
|
|
673
|
+
<label class="field-label">Slices</label>
|
|
674
|
+
<button class="btn-link" (click)="addEditSlice()"><i class="la la-plus"></i> Add</button>
|
|
675
|
+
</div>
|
|
676
|
+
<div class="series-list">
|
|
677
|
+
<div class="series-row" *ngFor="let sl of editSlices; let i = index">
|
|
678
|
+
<input class="field-input series-name" [(ngModel)]="sl.label" placeholder="Label" />
|
|
679
|
+
<input class="field-input series-data" [(ngModel)]="sl.value" type="number" placeholder="Value" />
|
|
680
|
+
<button class="btn-remove-series" *ngIf="editSlices.length > 1" (click)="removeEditSlice(i)">
|
|
681
|
+
<i class="la la-times"></i>
|
|
682
|
+
</button>
|
|
683
|
+
</div>
|
|
684
|
+
</div>
|
|
685
|
+
</div>
|
|
686
|
+
</ng-container>
|
|
687
|
+
|
|
688
|
+
</div>
|
|
689
|
+
|
|
690
|
+
<div class="dialog-footer">
|
|
691
|
+
<button class="btn-cancel" (click)="closeEditDialog()">Cancel</button>
|
|
692
|
+
<button class="btn-confirm" (click)="confirmEditWidget()">
|
|
693
|
+
<i class="la la-check"></i> Save
|
|
694
|
+
</button>
|
|
695
|
+
</div>
|
|
696
|
+
</div>
|
|
697
|
+
`, styles: [":host{--dash-bg: #000000;--dash-panel-bg: #1c1c1e;--dash-card-bg: #2c2c2e;--dash-fore-color: #8e8e93;--dash-accent-color: #0a84ff;--dash-danger-color: #ff453a;--dash-font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif}.dashboard-wrapper{display:flex;height:100vh;width:100vw;overflow:hidden;padding:16px;box-sizing:border-box;background:var(--dash-bg);color:var(--dash-fore-color);font-family:var(--dash-font-family)}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden;border-radius:40px;padding:20px;background:var(--dash-panel-bg);box-shadow:0 10px 30px #00000080;border:1px solid rgba(255,255,255,.05)}.dashboard-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;gap:12px}.tabs-container{display:flex;align-items:center;gap:8px;background:rgba(44,44,46,.6);backdrop-filter:blur(10px);border-radius:25px;padding:6px}.tab{display:flex;align-items:center;padding:8px 20px;border-radius:20px;cursor:pointer;font-size:14px;font-weight:500;color:var(--dash-fore-color);transition:all .3s cubic-bezier(.25,.8,.25,1)}.tab.active{background:#3a3a3c;color:#fff;box-shadow:0 2px 10px #0003}.tab:hover:not(.active){color:#e5e5ea;background:rgba(255,255,255,.05)}.tab-name{margin-right:8px}.tab-close{background:transparent;border:none;color:var(--dash-fore-color);padding:2px;font-size:12px;cursor:pointer;opacity:0;border-radius:50%;display:flex;align-items:center;justify-content:center;transition:all .2s}.tab-close:hover{color:var(--dash-danger-color);background:rgba(255,69,58,.2)}.tab:hover .tab-close{opacity:1}.btn-add-page{background:transparent;border:none;color:var(--dash-fore-color);padding:8px 16px;cursor:pointer;border-radius:20px;transition:all .2s}.btn-add-page:hover{color:var(--dash-accent-color);background:rgba(10,132,255,.1)}.btn-add-widget{display:flex;align-items:center;gap:6px;background:var(--dash-accent-color);border:none;color:#fff;font-size:14px;font-weight:600;padding:10px 20px;border-radius:22px;cursor:pointer;white-space:nowrap;transition:opacity .2s,transform .15s;box-shadow:0 4px 14px #0a84ff66}.btn-add-widget:hover{opacity:.9;transform:translateY(-1px)}.btn-add-widget:active{transform:translateY(0)}.grid-container{flex:1;overflow:auto;border-radius:24px;min-height:0}gridster{background:transparent;height:100%!important}.dialog-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.6);backdrop-filter:blur(6px);z-index:900}.dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:901;width:min(520px,calc(100vw - 32px));max-height:calc(100vh - 64px);display:flex;flex-direction:column;background:var(--dash-panel-bg);border-radius:28px;border:1px solid rgba(255,255,255,.1);box-shadow:0 24px 60px #000000b3;overflow:hidden}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:22px 24px 16px;border-bottom:1px solid rgba(255,255,255,.07)}.dialog-title{font-size:17px;font-weight:700;color:#fff}.dialog-close{background:rgba(255,255,255,.08);border:none;color:var(--dash-fore-color);width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:14px;transition:all .2s}.dialog-close:hover{background:rgba(255,69,58,.25);color:var(--dash-danger-color)}.dialog-body{flex:1;overflow-y:auto;padding:20px 24px;display:flex;flex-direction:column;gap:20px}.field-group{display:flex;flex-direction:column;gap:8px}.field-label{font-size:13px;font-weight:600;color:var(--dash-fore-color);text-transform:uppercase;letter-spacing:.5px}.field-input{background:var(--dash-card-bg);border:1px solid rgba(255,255,255,.08);border-radius:12px;padding:10px 14px;color:#fff;font-size:14px;outline:none;width:100%;box-sizing:border-box}.field-input:focus{border-color:var(--dash-accent-color)}.type-picker{display:flex;gap:10px}.type-btn{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;padding:14px 10px;background:var(--dash-card-bg);border:2px solid transparent;border-radius:16px;color:var(--dash-fore-color);font-size:12px;font-weight:600;cursor:pointer;transition:all .2s}.type-btn.selected{border-color:var(--dash-accent-color);color:var(--dash-accent-color);background:rgba(10,132,255,.12)}.btn-link{background:transparent;border:none;color:var(--dash-accent-color);font-size:13px;font-weight:600;cursor:pointer}.dialog-footer{display:flex;align-items:center;justify-content:flex-end;gap:10px;padding:16px 24px 22px;border-top:1px solid rgba(255,255,255,.07)}.btn-cancel{background:transparent;border:1px solid rgba(255,255,255,.12);color:var(--dash-fore-color);padding:10px 20px;border-radius:20px;cursor:pointer}.btn-confirm{background:var(--dash-accent-color);border:none;color:#fff;padding:10px 22px;border-radius:20px;font-weight:600;cursor:pointer}.btn-confirm:disabled{opacity:.4;cursor:not-allowed}\n"] }]
|
|
698
|
+
}], ctorParameters: function () { return [{ type: i1.DashboardStateService }]; }, propDecorators: { initialLayout: [{
|
|
699
|
+
type: Input
|
|
700
|
+
}], theme: [{
|
|
701
|
+
type: Input
|
|
702
|
+
}] } });
|
|
703
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcHAvZGFzaGJvYXJkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFxQixLQUFLLEVBQTRCLE1BQU0sZUFBZSxDQUFDO0FBSTlGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7QUFFcEMsTUFBTSxhQUFhLEdBQTZCO0lBQzlDLGVBQWUsRUFBRSxTQUFTO0lBQzFCLFVBQVUsRUFBRSxTQUFTO0lBQ3JCLGVBQWUsRUFBRSxTQUFTO0lBQzFCLGNBQWMsRUFBRSxTQUFTO0lBQ3pCLFdBQVcsRUFBRSxTQUFTO0lBQ3RCLFdBQVcsRUFBRSxTQUFTO0lBQ3RCLFdBQVcsRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUM7SUFDcEUsVUFBVSxFQUFFLHFGQUFxRjtDQUNsRyxDQUFDO0FBbVpGLE1BQU0sT0FBTyxrQkFBa0I7SUFnQzdCLFlBQW9CLFlBQW1DO1FBQW5DLGlCQUFZLEdBQVosWUFBWSxDQUF1QjtRQTVCdkQsa0JBQWEsR0FBNkIsRUFBRSxHQUFHLGFBQWEsRUFBRSxDQUFDO1FBQy9ELGtCQUFhLEdBQTJCLEVBQUUsQ0FBQztRQUczQyxVQUFLLEdBQVcsRUFBRSxDQUFDO1FBQ25CLGlCQUFZLEdBQVcsRUFBRSxDQUFDO1FBRzFCLHFCQUFxQjtRQUNyQixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ25CLGVBQVUsR0FBZSxNQUFNLENBQUM7UUFDaEMsZ0JBQVcsR0FBRyxFQUFFLENBQUM7UUFDakIscUJBQWdCLEdBQUcsRUFBRSxDQUFDO1FBQ3RCLGlCQUFZLEdBQXdDLENBQUMsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3hGLGlCQUFZLEdBQThD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LGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIE9uRGVzdHJveSwgSW5wdXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3JpZHN0ZXJDb25maWcgfSBmcm9tICdhbmd1bGFyLWdyaWRzdGVyMic7XG5pbXBvcnQgeyBEYXNoYm9hcmRTdGF0ZVNlcnZpY2UgfSBmcm9tICcuL2Rhc2hib2FyZC1zdGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFBhZ2UsIFdpZGdldCwgV2lkZ2V0VHlwZSwgRGFzaGJvYXJkVGhlbWUsIExpbmVCYXJEYXRhLCBEb251dERhdGEgfSBmcm9tICcuL21vZGVscyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuY29uc3QgREVGQVVMVF9USEVNRTogUmVxdWlyZWQ8RGFzaGJvYXJkVGhlbWU+ID0ge1xuICBiYWNrZ3JvdW5kQ29sb3I6ICcjMDAwMDAwJyxcbiAgcGFuZWxDb2xvcjogJyMxYzFjMWUnLFxuICB3aWRnZXRDYXJkQ29sb3I6ICcjMmMyYzJlJyxcbiAgY2hhcnRGb3JlQ29sb3I6ICcjOGU4ZTkzJyxcbiAgYWNjZW50Q29sb3I6ICcjMGE4NGZmJyxcbiAgZGFuZ2VyQ29sb3I6ICcjZmY0NTNhJyxcbiAgY2hhcnRDb2xvcnM6IFsnIzBhODRmZicsICcjMzBkMTU4JywgJyNmZjlmMGEnLCAnI2JmNWFmMicsICcjZmY0NTNhJ10sXG4gIGZvbnRGYW1pbHk6ICctYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIFwiU2Vnb2UgVUlcIiwgUm9ib3RvLCBIZWx2ZXRpY2EsIEFyaWFsLCBzYW5zLXNlcmlmJyxcbn07XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1kYXNoYm9hcmQnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJkYXNoYm9hcmQtd3JhcHBlclwiIFtuZ1N0eWxlXT1cIndyYXBwZXJTdHlsZXNcIj5cbiAgICAgIDxtYWluIGNsYXNzPVwibWFpbi1jb250ZW50XCI+XG5cbiAgICAgICAgPCEtLSDilIDilIAgSGVhZGVyIOKUgOKUgCAtLT5cbiAgICAgICAgPGhlYWRlciBjbGFzcz1cImRhc2hib2FyZC1oZWFkZXJcIj5cbiAgICAgICAgICA8IS0tIFRhYnMgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRhYnMtY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBwYWdlIG9mIHBhZ2VzXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJ0YWJcIlxuICAgICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cInBhZ2UuaWQgPT09IGFjdGl2ZVBhZ2VJZFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJvblNlbGVjdFBhZ2UocGFnZS5pZClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRhYi1uYW1lXCI+e3sgcGFnZS5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidGFiLWNsb3NlXCIgKm5nSWY9XCJwYWdlcy5sZW5ndGggPiAxXCIgKGNsaWNrKT1cIm9uUmVtb3ZlUGFnZSgkZXZlbnQsIHBhZ2UuaWQpXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYSBsYS10aW1lc1wiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tYWRkLXBhZ2VcIiAoY2xpY2spPVwib25BZGRQYWdlKClcIiB0aXRsZT1cIk5ldyB3b3Jrc3BhY2VcIj5cbiAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYSBsYS1wbHVzXCI+PC9pPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIEFkZCBXaWRnZXQgYnV0dG9uIC0tPlxuICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tYWRkLXdpZGdldFwiIChjbGljayk9XCJvcGVuRGlhbG9nKClcIiB0aXRsZT1cIkFkZCB3aWRnZXRcIj5cbiAgICAgICAgICAgIDxpIGNsYXNzPVwibGEgbGEtcGx1c1wiPjwvaT5cbiAgICAgICAgICAgIDxzcGFuPkFkZCBXaWRnZXQ8L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvaGVhZGVyPlxuXG4gICAgICAgIDwhLS0g4pSA4pSAIEdyaWQg4pSA4pSAIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZC1jb250YWluZXJcIj5cbiAgICAgICAgICA8Z3JpZHN0ZXIgW29wdGlvbnNdPVwib3B0aW9uc1wiPlxuICAgICAgICAgICAgPGdyaWRzdGVyLWl0ZW0gW2l0ZW1dPVwid2lkZ2V0XCIgKm5nRm9yPVwibGV0IHdpZGdldCBvZiBhY3RpdmVQYWdlPy53aWRnZXRzXCI+XG4gICAgICAgICAgICAgIDxhcHAtd2lkZ2V0LXJlbmRlcmVyXG4gICAgICAgICAgICAgICAgW3dpZGdldF09XCJ3aWRnZXRcIlxuICAgICAgICAgICAgICAgIFtvblJlbW92ZVdpZGdldF09XCJyZW1vdmVXaWRnZXRIYW5kbGVyXCJcbiAgICAgICAgICAgICAgICBbdGhlbWVdPVwicmVzb2x2ZWRUaGVtZVwiXG4gICAgICAgICAgICAgICAgKGVkaXRSZXF1ZXN0ZWQpPVwib3BlbkVkaXREaWFsb2coJGV2ZW50KVwiXG4gICAgICAgICAgICAgID48L2FwcC13aWRnZXQtcmVuZGVyZXI+XG4gICAgICAgICAgICA8L2dyaWRzdGVyLWl0ZW0+XG4gICAgICAgICAgPC9ncmlkc3Rlcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L21haW4+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIOKUgOKUgCBBZGQgV2lkZ2V0IERpYWxvZyDilIDilIAgLS0+XG4gICAgPGRpdiBjbGFzcz1cImRpYWxvZy1iYWNrZHJvcFwiICpuZ0lmPVwiZGlhbG9nT3BlblwiIChjbGljayk9XCJjbG9zZURpYWxvZygpXCI+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRpYWxvZ1wiICpuZ0lmPVwiZGlhbG9nT3BlblwiPlxuICAgICAgPGRpdiBjbGFzcz1cImRpYWxvZy1oZWFkZXJcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJkaWFsb2ctdGl0bGVcIj5BZGQgV2lkZ2V0PC9zcGFuPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiZGlhbG9nLWNsb3NlXCIgKGNsaWNrKT1cImNsb3NlRGlhbG9nKClcIj48aSBjbGFzcz1cImxhIGxhLXRpbWVzXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctYm9keVwiPlxuXG4gICAgICAgIDwhLS0gQ2hhcnQgdHlwZSBwaWNrZXIgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1ncm91cFwiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+Q2hhcnQgdHlwZTwvbGFiZWw+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInR5cGUtcGlja2VyXCI+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCB0IG9mIHdpZGdldFR5cGVzXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJ0eXBlLWJ0blwiXG4gICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJkaWFsb2dUeXBlID09PSB0LnZhbHVlXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImRpYWxvZ1R5cGUgPSB0LnZhbHVlXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGkgW2NsYXNzXT1cIidsYSAnICsgdC5pY29uXCI+PC9pPlxuICAgICAgICAgICAgICA8c3Bhbj57eyB0LmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gVGl0bGUgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1ncm91cFwiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+VGl0bGU8L2xhYmVsPlxuICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZpZWxkLWlucHV0XCIgWyhuZ01vZGVsKV09XCJkaWFsb2dUaXRsZVwiIHBsYWNlaG9sZGVyPVwiTXkgQ2hhcnRcIiAvPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFNlcmllcyAoTElORSAvIEJBUikgLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJkaWFsb2dUeXBlICE9PSAnRE9OVVQnXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWdyb3VwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93LWhlYWRlclwiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlNlcmllczwvbGFiZWw+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tbGlua1wiIChjbGljayk9XCJhZGRTZXJpZXMoKVwiPjxpIGNsYXNzPVwibGEgbGEtcGx1c1wiPjwvaT4gQWRkIHNlcmllczwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VyaWVzLWxpc3RcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcmllcy1yb3dcIiAqbmdGb3I9XCJsZXQgcyBvZiBkaWFsb2dTZXJpZXM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmaWVsZC1pbnB1dCBzZXJpZXMtbmFtZVwiIFsobmdNb2RlbCldPVwicy5uYW1lXCIgcGxhY2Vob2xkZXI9XCJTZXJpZXMgbmFtZVwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmllbGQtaW5wdXQgc2VyaWVzLWRhdGFcIiBbKG5nTW9kZWwpXT1cInMuZGF0YVJhd1wiXG4gICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiQ29tbWEtc2VwYXJhdGVkIHZhbHVlcywgZS5nLiAxMCwyNSw0MFwiIC8+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0bi1yZW1vdmUtc2VyaWVzXCIgKm5nSWY9XCJkaWFsb2dTZXJpZXMubGVuZ3RoID4gMVwiIChjbGljayk9XCJyZW1vdmVTZXJpZXMoaSlcIj5cbiAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGEgbGEtdGltZXNcIj48L2k+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtZ3JvdXBcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+WC1heGlzIGxhYmVscyA8c3BhbiBjbGFzcz1cImZpZWxkLWhpbnRcIj4ob3B0aW9uYWwsIGNvbW1hLXNlcGFyYXRlZCk8L3NwYW4+PC9sYWJlbD5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZpZWxkLWlucHV0XCIgWyhuZ01vZGVsKV09XCJkaWFsb2dDYXRlZ29yaWVzXCIgcGxhY2Vob2xkZXI9XCJKYW4sRmViLE1hcixBcHJcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIFNsaWNlcyAoRE9OVVQpIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGlhbG9nVHlwZSA9PT0gJ0RPTlVUJ1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1ncm91cFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXJvdy1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5TbGljZXM8L2xhYmVsPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuLWxpbmtcIiAoY2xpY2spPVwiYWRkU2xpY2UoKVwiPjxpIGNsYXNzPVwibGEgbGEtcGx1c1wiPjwvaT4gQWRkIHNsaWNlPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJpZXMtbGlzdFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VyaWVzLXJvd1wiICpuZ0Zvcj1cImxldCBzbCBvZiBkaWFsb2dTbGljZXM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmaWVsZC1pbnB1dCBzZXJpZXMtbmFtZVwiIFsobmdNb2RlbCldPVwic2wubGFiZWxcIiBwbGFjZWhvbGRlcj1cIkxhYmVsXCIgLz5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmaWVsZC1pbnB1dCBzZXJpZXMtZGF0YVwiIFsobmdNb2RlbCldPVwic2wudmFsdWVcIiB0eXBlPVwibnVtYmVyXCIgcGxhY2Vob2xkZXI9XCJWYWx1ZVwiIC8+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0bi1yZW1vdmUtc2VyaWVzXCIgKm5nSWY9XCJkaWFsb2dTbGljZXMubGVuZ3RoID4gMVwiIChjbGljayk9XCJyZW1vdmVTbGljZShpKVwiPlxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYSBsYS10aW1lc1wiPjwvaT5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWZvb3RlclwiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuLWNhbmNlbFwiIChjbGljayk9XCJjbG9zZURpYWxvZygpXCI+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tY29uZmlybVwiIChjbGljayk9XCJjb25maXJtQWRkV2lkZ2V0KClcIiBbZGlzYWJsZWRdPVwiIWRpYWxvZ1RpdGxlLnRyaW0oKVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwibGEgbGEtY2hlY2tcIj48L2k+IEFkZCBXaWRnZXRcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8IS0tIOKUgOKUgCBFZGl0IFdpZGdldCBEaWFsb2cg4pSA4pSAIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctYmFja2Ryb3BcIiAqbmdJZj1cImVkaXREaWFsb2dPcGVuXCIgKGNsaWNrKT1cImNsb3NlRWRpdERpYWxvZygpXCI+PC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRpYWxvZ1wiICpuZ0lmPVwiZWRpdERpYWxvZ09wZW5cIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctaGVhZGVyXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiZGlhbG9nLXRpdGxlXCI+RWRpdCBXaWRnZXQ8L3NwYW4+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJkaWFsb2ctY2xvc2VcIiAoY2xpY2spPVwiY2xvc2VFZGl0RGlhbG9nKClcIj48aSBjbGFzcz1cImxhIGxhLXRpbWVzXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJkaWFsb2ctYm9keVwiPlxuXG4gICAgICAgIDwhLS0gVGl0bGUgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1ncm91cFwiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+VGl0bGU8L2xhYmVsPlxuICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZpZWxkLWlucHV0XCIgWyhuZ01vZGVsKV09XCJlZGl0VGl0bGVcIiBwbGFjZWhvbGRlcj1cIkNoYXJ0IHRpdGxlXCIgLz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBDYXJkIGJhY2tncm91bmQgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1ncm91cFwiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+Q2FyZCBjb2xvcjwvbGFiZWw+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNvbG9yLXJvd1wiPlxuICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIGNsYXNzPVwiY29sb3Itc3dhdGNoXCIgWyhuZ01vZGVsKV09XCJlZGl0Q2FyZENvbG9yXCIgLz5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZpZWxkLWlucHV0XCIgWyhuZ01vZGVsKV09XCJlZGl0Q2FyZENvbG9yXCIgcGxhY2Vob2xkZXI9XCIjMmMyYzJlXCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBTZXJpZXMgY29sb3JzIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtZ3JvdXBcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlNlcmllcyBjb2xvcnM8L2xhYmVsPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2xvci1saXN0XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sb3ItaXRlbVwiICpuZ0Zvcj1cImxldCBjIG9mIGVkaXRDb2xvcnM7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjb2xvclwiIGNsYXNzPVwiY29sb3Itc3dhdGNoXCIgWyhuZ01vZGVsKV09XCJlZGl0Q29sb3JzW2ldXCIgLz5cbiAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmllbGQtaW5wdXQgY29sb3ItaGV4XCIgWyhuZ01vZGVsKV09XCJlZGl0Q29sb3JzW2ldXCIgcGxhY2Vob2xkZXI9XCIjMGE4NGZmXCIgLz5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb2xvci1sYWJlbFwiPnt7IGdldEVkaXRTZXJpZXNMYWJlbChpKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIERhdGE6IExJTkUgLyBCQVIgLS0+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJlZGl0V2lkZ2V0VHlwZSAhPT0gJ0RPTlVUJ1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1ncm91cFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXJvdy1oZWFkZXJcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5TZXJpZXMgZGF0YTwvbGFiZWw+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tbGlua1wiIChjbGljayk9XCJhZGRFZGl0U2VyaWVzKClcIj48aSBjbGFzcz1cImxhIGxhLXBsdXNcIj48L2k+IEFkZDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VyaWVzLWxpc3RcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNlcmllcy1yb3dcIiAqbmdGb3I9XCJsZXQgcyBvZiBlZGl0U2VyaWVzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmllbGQtaW5wdXQgc2VyaWVzLW5hbWVcIiBbKG5nTW9kZWwpXT1cInMubmFtZVwiIHBsYWNlaG9sZGVyPVwiTmFtZVwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmllbGQtaW5wdXQgc2VyaWVzLWRhdGFcIiBbKG5nTW9kZWwpXT1cInMuZGF0YVJhd1wiIHBsYWNlaG9sZGVyPVwiMTAsMjAsMzBcIiAvPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tcmVtb3ZlLXNlcmllc1wiICpuZ0lmPVwiZWRpdFNlcmllcy5sZW5ndGggPiAxXCIgKGNsaWNrKT1cInJlbW92ZUVkaXRTZXJpZXMoaSlcIj5cbiAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGEgbGEtdGltZXNcIj48L2k+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWdyb3VwXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlgtYXhpcyBsYWJlbHMgPHNwYW4gY2xhc3M9XCJmaWVsZC1oaW50XCI+KG9wdGlvbmFsLCBjb21tYS1zZXBhcmF0ZWQpPC9zcGFuPjwvbGFiZWw+XG4gICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmaWVsZC1pbnB1dFwiIFsobmdNb2RlbCldPVwiZWRpdENhdGVnb3JpZXNcIiBwbGFjZWhvbGRlcj1cIkphbixGZWIsTWFyXCIgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgPCEtLSBEYXRhOiBET05VVCAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImVkaXRXaWRnZXRUeXBlID09PSAnRE9OVVQnXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWdyb3VwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93LWhlYWRlclwiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlNsaWNlczwvbGFiZWw+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tbGlua1wiIChjbGljayk9XCJhZGRFZGl0U2xpY2UoKVwiPjxpIGNsYXNzPVwibGEgbGEtcGx1c1wiPjwvaT4gQWRkPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXJpZXMtbGlzdFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2VyaWVzLXJvd1wiICpuZ0Zvcj1cImxldCBzbCBvZiBlZGl0U2xpY2VzOyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmllbGQtaW5wdXQgc2VyaWVzLW5hbWVcIiBbKG5nTW9kZWwpXT1cInNsLmxhYmVsXCIgcGxhY2Vob2xkZXI9XCJMYWJlbFwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZmllbGQtaW5wdXQgc2VyaWVzLWRhdGFcIiBbKG5nTW9kZWwpXT1cInNsLnZhbHVlXCIgdHlwZT1cIm51bWJlclwiIHBsYWNlaG9sZGVyPVwiVmFsdWVcIiAvPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4tcmVtb3ZlLXNlcmllc1wiICpuZ0lmPVwiZWRpdFNsaWNlcy5sZW5ndGggPiAxXCIgKGNsaWNrKT1cInJlbW92ZUVkaXRTbGljZShpKVwiPlxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYSBsYS10aW1lc1wiPjwvaT5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwiZGlhbG9nLWZvb3RlclwiPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuLWNhbmNlbFwiIChjbGljayk9XCJjbG9zZUVkaXREaWFsb2coKVwiPkNhbmNlbDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuLWNvbmZpcm1cIiAoY2xpY2spPVwiY29uZmlybUVkaXRXaWRnZXQoKVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwibGEgbGEtY2hlY2tcIj48L2k+IFNhdmVcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIDpob3N0IHtcbiAgICAgIC0tZGFzaC1iZzogIzAwMDAwMDtcbiAgICAgIC0tZGFzaC1wYW5lbC1iZzogIzFjMWMxZTtcbiAgICAgIC0tZGFzaC1jYXJkLWJnOiAjMmMyYzJlO1xuICAgICAgLS1kYXNoLWZvcmUtY29sb3I6ICM4ZThlOTM7XG4gICAgICAtLWRhc2gtYWNjZW50LWNvbG9yOiAjMGE4NGZmO1xuICAgICAgLS1kYXNoLWRhbmdlci1jb2xvcjogI2ZmNDUzYTtcbiAgICAgIC0tZGFzaC1mb250LWZhbWlseTogLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCBcIlNlZ29lIFVJXCIsIFJvYm90bywgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZjtcbiAgICB9XG5cbiAgICAvKiDilIDilIAgTGF5b3V0IOKUgOKUgCAqL1xuICAgIC5kYXNoYm9hcmQtd3JhcHBlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgaGVpZ2h0OiAxMDB2aDtcbiAgICAgIHdpZHRoOiAxMDB2dztcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICBwYWRkaW5nOiAxNnB4O1xuICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWRhc2gtYmcpO1xuICAgICAgY29sb3I6IHZhcigtLWRhc2gtZm9yZS1jb2xvcik7XG4gICAgICBmb250LWZhbWlseTogdmFyKC0tZGFzaC1mb250LWZhbWlseSk7XG4gICAgfVxuICAgIC5tYWluLWNvbnRlbnQge1xuICAgICAgZmxleDogMTtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDQwcHg7XG4gICAgICBwYWRkaW5nOiAyMHB4O1xuICAgICAgYmFja2dyb3VuZDogdmFyKC0tZGFzaC1wYW5lbC1iZyk7XG4gICAgICBib3gtc2hhZG93OiAwIDEwcHggMzBweCByZ2JhKDAsMCwwLDAuNSk7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuMDUpO1xuICAgIH1cblxuICAgIC8qIOKUgOKUgCBIZWFkZXIg4pSA4pSAICovXG4gICAgLmRhc2hib2FyZC1oZWFkZXIge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgICBtYXJnaW4tYm90dG9tOiAyMHB4O1xuICAgICAgZ2FwOiAxMnB4O1xuICAgIH1cbiAgICAudGFicy1jb250YWluZXIge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBnYXA6IDhweDtcbiAgICAgIGJhY2tncm91bmQ6IHJnYmEoNDQsNDQsNDYsMC42KTtcbiAgICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cigxMHB4KTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDI1cHg7XG4gICAgICBwYWRkaW5nOiA2cHg7XG4gICAgfVxuICAgIC50YWIge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBwYWRkaW5nOiA4cHggMjBweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDIwcHg7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICBmb250LXdlaWdodDogNTAwO1xuICAgICAgY29sb3I6IHZhcigtLWRhc2gtZm9yZS1jb2xvcik7XG4gICAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwwLjgsMC4yNSwxKTtcbiAgICB9XG4gICAgLnRhYi5hY3RpdmUge1xuICAgICAgYmFja2dyb3VuZDogIzNhM2EzYztcbiAgICAgIGNvbG9yOiAjZmZmZmZmO1xuICAgICAgYm94LXNoYWRvdzogMCAycHggMTBweCByZ2JhKDAsMCwwLDAuMik7XG4gICAgfVxuICAgIC50YWI6aG92ZXI6bm90KC5hY3RpdmUpIHtcbiAgICAgIGNvbG9yOiAjZTVlNWVhO1xuICAgICAgYmFja2dyb3VuZDogcmdiYSgyNTUsMjU1LDI1NSwwLjA1KTtcbiAgICB9XG4gICAgLnRhYi1uYW1lIHsgbWFyZ2luLXJpZ2h0OiA4cHg7IH1cbiAgICAudGFiLWNsb3NlIHtcbiAgICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyBib3JkZXI6IG5vbmU7IGNvbG9yOiB2YXIoLS1kYXNoLWZvcmUtY29sb3IpOyBwYWRkaW5nOiAycHg7XG4gICAgICBmb250LXNpemU6IDEycHg7IGN1cnNvcjogcG9pbnRlcjsgb3BhY2l0eTogMDsgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgICAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7IHRyYW5zaXRpb246IGFsbCAwLjJzO1xuICAgIH1cbiAgICAudGFiLWNsb3NlOmhvdmVyIHsgY29sb3I6IHZhcigtLWRhc2gtZGFuZ2VyLWNvbG9yKTsgYmFja2dyb3VuZDogcmdiYSgyNTUsIDY5LCA1OCwgMC4yKTsgfVxuICAgIC50YWI6aG92ZXIgLnRhYi1jbG9zZSB7IG9wYWNpdHk6IDE7IH1cbiAgICAuYnRuLWFkZC1wYWdlIHtcbiAgICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyBib3JkZXI6IG5vbmU7IGNvbG9yOiB2YXIoLS1kYXNoLWZvcmUtY29sb3IpO1xuICAgICAgcGFkZGluZzogOHB4IDE2cHg7IGN1cnNvcjogcG9pbnRlcjsgYm9yZGVyLXJhZGl1czogMjBweDsgdHJhbnNpdGlvbjogYWxsIDAuMnM7XG4gICAgfVxuICAgIC5idG4tYWRkLXBhZ2U6aG92ZXIgeyBjb2xvcjogdmFyKC0tZGFzaC1hY2NlbnQtY29sb3IpOyBiYWNrZ3JvdW5kOiByZ2JhKDEwLCAxMzIsIDI1NSwgMC4xKTsgfVxuXG4gICAgLyogQWRkIFdpZGdldCBidXR0b24gKi9cbiAgICAuYnRuLWFkZC13aWRnZXQge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBnYXA6IDZweDtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWRhc2gtYWNjZW50LWNvbG9yKTtcbiAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgIGNvbG9yOiAjZmZmZmZmO1xuICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIHBhZGRpbmc6IDEwcHggMjBweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDIycHg7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjJzLCB0cmFuc2Zvcm0gMC4xNXM7XG4gICAgICBib3gtc2hhZG93OiAwIDRweCAxNHB4IHJnYmEoMTAsMTMyLDI1NSwwLjQpO1xuICAgIH1cbiAgICAuYnRuLWFkZC13aWRnZXQ6aG92ZXIgeyBvcGFjaXR5OiAwLjk7IHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMXB4KTsgfVxuICAgIC5idG4tYWRkLXdpZGdldDphY3RpdmUgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMCk7IH1cblxuICAgIC8qIOKUgOKUgCBHcmlkIOKUgOKUgCAqL1xuICAgIC5ncmlkLWNvbnRhaW5lciB7IGZsZXg6IDE7IG92ZXJmbG93OiBhdXRvOyBib3JkZXItcmFkaXVzOiAyNHB4OyBtaW4taGVpZ2h0OiAwOyB9XG4gICAgZ3JpZHN0ZXIgeyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgaGVpZ2h0OiAxMDAlICFpbXBvcnRhbnQ7IH1cblxuICAgIC8qIOKUgOKUgCBEaWFsb2cg4pSA4pSAICovXG4gICAgLmRpYWxvZy1iYWNrZHJvcCB7XG4gICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgICBpbnNldDogMDtcbiAgICAgIGJhY2tncm91bmQ6IHJnYmEoMCwwLDAsMC42KTtcbiAgICAgIGJhY2tkcm9wLWZpbHRlcjogYmx1cig2cHgpO1xuICAgICAgei1pbmRleDogOTAwO1xuICAgIH1cbiAgICAuZGlhbG9nIHtcbiAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgIHRvcDogNTAlO1xuICAgICAgbGVmdDogNTAlO1xuICAgICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gICAgICB6LWluZGV4OiA5MDE7XG4gICAgICB3aWR0aDogbWluKDUyMHB4LCBjYWxjKDEwMHZ3IC0gMzJweCkpO1xuICAgICAgbWF4LWhlaWdodDogY2FsYygxMDB2aCAtIDY0cHgpO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1kYXNoLXBhbmVsLWJnKTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDI4cHg7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuMSk7XG4gICAgICBib3gtc2hhZG93OiAwIDI0cHggNjBweCByZ2JhKDAsMCwwLDAuNyk7XG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIH1cbiAgICAuZGlhbG9nLWhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgIHBhZGRpbmc6IDIycHggMjRweCAxNnB4O1xuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkIHJnYmEoMjU1LDI1NSwyNTUsMC4wNyk7XG4gICAgfVxuICAgIC5kaWFsb2ctdGl0bGUgeyBmb250LXNpemU6IDE3cHg7IGZvbnQtd2VpZ2h0OiA3MDA7IGNvbG9yOiAjZmZmZmZmOyB9XG4gICAgLmRpYWxvZy1jbG9zZSB7XG4gICAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwyNTUsMjU1LDAuMDgpOyBib3JkZXI6IG5vbmU7IGNvbG9yOiB2YXIoLS1kYXNoLWZvcmUtY29sb3IpO1xuICAgICAgd2lkdGg6IDMwcHg7IGhlaWdodDogMzBweDsgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgICAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7IGZvbnQtc2l6ZTogMTRweDsgdHJhbnNpdGlvbjogYWxsIDAuMnM7XG4gICAgfVxuICAgIC5kaWFsb2ctY2xvc2U6aG92ZXIgeyBiYWNrZ3JvdW5kOiByZ2JhKDI1NSw2OSw1OCwwLjI1KTsgY29sb3I6IHZhcigtLWRhc2gtZGFuZ2VyLWNvbG9yKTsgfVxuICAgIC5kaWFsb2ctYm9keSB7IGZsZXg6IDE7IG92ZXJmbG93LXk6IGF1dG87IHBhZGRpbmc6IDIwcHggMjRweDsgZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiAyMHB4OyB9XG4gICAgLmZpZWxkLWdyb3VwIHsgZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgZ2FwOiA4cHg7IH1cbiAgICAuZmllbGQtbGFiZWwgeyBmb250LXNpemU6IDEzcHg7IGZvbnQtd2VpZ2h0OiA2MDA7IGNvbG9yOiB2YXIoLS1kYXNoLWZvcmUtY29sb3IpOyB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOyBsZXR0ZXItc3BhY2luZzogMC41cHg7IH1cbiAgICAuZmllbGQtaW5wdXQge1xuICAgICAgYmFja2dyb3VuZDogdmFyKC0tZGFzaC1jYXJkLWJnKTtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjU1LDI1NSwyNTUsMC4wOCk7XG4gICAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgICAgcGFkZGluZzogMTBweCAxNHB4O1xuICAgICAgY29sb3I6ICNmZmZmZmY7XG4gICAgICBmb250LXNpemU6IDE0cHg7XG4gICAgICBvdXRsaW5lOiBub25lO1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIH1cbiAgICAuZmllbGQtaW5wdXQ6Zm9jdXMgeyBib3JkZXItY29sb3I6IHZhcigtLWRhc2gtYWNjZW50LWNvbG9yKTsgfVxuICAgIC50eXBlLXBpY2tlciB7IGRpc3BsYXk6IGZsZXg7IGdhcDogMTBweDsgfVxuICAgIC50eXBlLWJ0biB7XG4gICAgICBmbGV4OiAxOyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDZweDsgcGFkZGluZzogMTRweCAxMHB4O1xuICAgICAgYmFja2dyb3VuZDogdmFyKC0tZGFzaC1jYXJkLWJnKTsgYm9yZGVyOiAycHggc29saWQgdHJhbnNwYXJlbnQ7IGJvcmRlci1yYWRpdXM6IDE2cHg7XG4gICAgICBjb2xvcjogdmFyKC0tZGFzaC1mb3JlLWNvbG9yKTsgZm9udC1zaXplOiAxMnB4OyBmb250LXdlaWdodDogNjAwOyBjdXJzb3I6IHBvaW50ZXI7IHRyYW5zaXRpb246IGFsbCAwLjJzO1xuICAgIH1cbiAgICAudHlwZS1idG4uc2VsZWN0ZWQgeyBib3JkZXItY29sb3I6IHZhcigtLWRhc2gtYWNjZW50LWNvbG9yKTsgY29sb3I6IHZhcigtLWRhc2gtYWNjZW50LWNvbG9yKTsgYmFja2dyb3VuZDogcmdiYSgxMCwxMzIsMjU1LDAuMTIpOyB9XG4gICAgLmJ0bi1saW5rIHsgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7IGJvcmRlcjogbm9uZTsgY29sb3I6IHZhcigtLWRhc2gtYWNjZW50LWNvbG9yKTsgZm9udC1zaXplOiAxM3B4OyBmb250LXdlaWdodDogNjAwOyBjdXJzb3I6IHBvaW50ZXI7IH1cbiAgICAuZGlhbG9nLWZvb3RlciB7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogZmxleC1lbmQ7IGdhcDogMTBweDsgcGFkZGluZzogMTZweCAyNHB4IDIycHg7IGJvcmRlci10b3A6IDFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuMDcpOyB9XG4gICAgLmJ0bi1jYW5jZWwgeyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjEyKTsgY29sb3I6IHZhcigtLWRhc2gtZm9yZS1jb2xvcik7IHBhZGRpbmc6IDEwcHggMjBweDsgYm9yZGVyLXJhZGl1czogMjBweDsgY3Vyc29yOiBwb2ludGVyOyB9XG4gICAgLmJ0bi1jb25maXJtIHsgYmFja2dyb3VuZDogdmFyKC0tZGFzaC1hY2NlbnQtY29sb3IpOyBib3JkZXI6IG5vbmU7IGNvbG9yOiAjZmZmZmZmOyBwYWRkaW5nOiAxMHB4IDIycHg7IGJvcmRlci1yYWRpdXM6IDIwcHg7IGZvbnQtd2VpZ2h0OiA2MDA7IGN1cnNvcjogcG9pbnRlcjsgfVxuICAgIC5idG4tY29uZmlybTpkaXNhYmxlZCB7IG9wYWNpdHk6IDAuNDsgY3Vyc29yOiBub3QtYWxsb3dlZDsgfVxuICBgXVxufSlcbmV4cG9ydCBjbGFzcyBEYXNoYm9hcmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcbiAgQElucHV0KCkgaW5pdGlhbExheW91dD86IHN0cmluZztcbiAgQElucHV0KCkgdGhlbWU/OiBEYXNoYm9hcmRUaGVtZTtcblxuICByZXNvbHZlZFRoZW1lOiBSZXF1aXJlZDxEYXNoYm9hcmRUaGVtZT4gPSB7IC4uLkRFRkFVTFRfVEhFTUUgfTtcbiAgd3JhcHBlclN0eWxlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gIG9wdGlvbnMhOiBHcmlkc3RlckNvbmZpZztcbiAgcGFnZXM6IFBhZ2VbXSA9IFtdO1xuICBhY3RpdmVQYWdlSWQ6IHN0cmluZyA9ICcnO1xuICBhY3RpdmVQYWdlPzogUGFnZTtcblxuICAvLyDilIDilIAgRGlhbG9nIHN0YXRlIOKUgOKUgFxuICBkaWFsb2dPcGVuID0gZmFsc2U7XG4gIGRpYWxvZ1R5cGU6IFdpZGdldFR5cGUgPSAnTElORSc7XG4gIGRpYWxvZ1RpdGxlID0gJyc7XG4gIGRpYWxvZ0NhdGVnb3JpZXMgPSAnJztcbiAgZGlhbG9nU2VyaWVzOiB7IG5hbWU6IHN0cmluZzsgZGF0YVJhdzogc3RyaW5nIH1bXSA9IFt7IG5hbWU6ICdTZXJpZXMgMScsIGRhdGFSYXc6ICcnIH1dO1xuICBkaWFsb2dTbGljZXM6IHsgbGFiZWw6IHN0cmluZzsgdmFsdWU6IG51bWJlciB8IG51bGwgfVtdID0gW1xuICAgIHsgbGFiZWw6ICdTbGljZSBBJywgdmFsdWU6IG51bGwgfSxcbiAgICB7IGxhYmVsOiAnU2xpY2UgQicsIHZhbHVlOiBudWxsIH0sXG4gICAgeyBsYWJlbDogJ1NsaWNlIEMnLCB2YWx1ZTogbnVsbCB9LFxuICBdO1xuXG4gIHJlYWRvbmx5IHdpZGdldFR5cGVzOiB7IHZhbHVlOiBXaWRnZXRUeXBlOyBsYWJlbDogc3RyaW5nOyBpY29uOiBzdHJpbmcgfVtdID0gW1xuICAgIHsgdmFsdWU6ICdMSU5FJywgbGFiZWw6ICdMaW5lJywgIGljb246ICdsYS1jaGFydC1hcmVhJyB9LFxuICAgIHsgdmFsdWU6ICdCQVInLCAgbGFiZWw6ICdCYXInLCAgIGljb246ICdsYS1jaGFydC1iYXInICB9LFxuICAgIHsgdmFsdWU6ICdET05VVCcsbGFiZWw6ICdEb251dCcsIGljb246ICdsYS1jaGFydC1waWUnICB9LFxuICBdO1xuXG4gIHByaXZhdGUgc3VicyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHN0YXRlU2VydmljZTogRGFzaGJvYXJkU3RhdGVTZXJ2aWNlKSB7fVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlc1sndGhlbWUnXSB8fCBjaGFuZ2VzWydpbml0aWFsTGF5b3V0J10pIHRoaXMuYXBwbHlUaGVtZSgpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5hcHBseVRoZW1lKCk7XG5cbiAgICBpZiAodGhpcy5pbml0aWFsTGF5b3V0KSB7XG4gICAgICB0cnkgeyB0aGlzLnN0YXRlU2VydmljZS5sb2FkTGF5b3V0KEpTT04ucGFyc2UodGhpcy5pbml0aWFsTGF5b3V0KSk7IH1cbiAgICAgIGNhdGNoIChlKSB7IGNvbnNvbGUuZXJyb3IoJ1tEYXNoYm9hcmRdIEZhaWxlZCB0byBwYXJzZSBpbml0aWFsTGF5b3V0JywgZSk7IH1cbiAgICB9XG5cbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBncmlkVHlwZTogJ2ZpdCcsXG4gICAgICBkaXNwbGF5R3JpZDogJ25vbmUnLFxuICAgICAgcHVzaEl0ZW1zOiB0cnVlLFxuICAgICAgZHJhZ2dhYmxlOiB7IGVuYWJsZWQ6IHRydWUgfSxcbiAgICAgIHJlc2l6YWJsZTogeyBlbmFibGVkOiB0cnVlIH0sXG4gICAgICBtaW5Db2xzOiAxMiwgbWF4Q29sczogMTIsXG4gICAgICBtaW5Sb3dzOiAxMiwgbWF4Um93czogNTAsXG4gICAgICBtYXJnaW46IDIwLCBvdXRlck1hcmdpbjogdHJ1ZSxcbiAgICAgIGl0ZW1DaGFuZ2VDYWxsYmFjazogKGl0ZW06IGFueSkgPT4ge1xuICAgICAgICB0aGlzLnN0YXRlU2VydmljZS51cGRhdGVXaWRnZXRQb3NpdGlvbihcbiAgICAgICAgICB0aGlzLmFjdGl2ZVBhZ2VJZCwgaXRlbS5pZCwgaXRlbS54LCBpdGVtLnksIGl0ZW0uY29scywgaXRlbS5yb3dzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMuc3Vicy5hZGQodGhpcy5zdGF0ZVNlcnZpY2UucGFnZXMkLnN1YnNjcmliZShwYWdlcyA9PiB7XG4gICAgICB0aGlzLnBhZ2VzID0gcGFnZXM7XG4gICAgICB0aGlzLnVwZGF0ZUFjdGl2ZVBhZ2UoKTtcbiAgICB9KSk7XG4gICAgdGhpcy5zdWJzLmFkZCh0aGlzLnN0YXRlU2VydmljZS5hY3RpdmVQYWdlSWQkLnN1YnNjcmliZShpZCA9PiB7XG4gICAgICB0aGlzLmFjdGl2ZVBhZ2VJZCA9IGlkO1xuICAgICAgdGhpcy51cGRhdGVBY3RpdmVQYWdlKCk7XG4gICAgfSkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7IHRoaXMuc3Vicy51bnN1YnNjcmliZSgpOyB9XG5cbiAgcHJpdmF0ZSBhcHBseVRoZW1lKCkge1xuICAgIHRoaXMucmVzb2x2ZWRUaGVtZSA9IHsgLi4uREVGQVVMVF9USEVNRSwgLi4uKHRoaXMudGhlbWUgPz8ge30pIH07XG4gICAgdGhpcy53cmFwcGVyU3R5bGVzID0ge1xuICAgICAgJy0tZGFzaC1iZyc6IHRoaXMucmVzb2x2ZWRUaGVtZS5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAnLS1kYXNoLXBhbmVsLWJnJzogdGhpcy5yZXNvbHZlZFRoZW1lLnBhbmVsQ29sb3IsXG4gICAgICAnLS1kYXNoLWNhcmQtYmcnOiB0aGlzLnJlc29sdmVkVGhlbWUud2lkZ2V0Q2FyZENvbG9yLFxuICAgICAgJy0tZGFzaC1mb3JlLWNvbG9yJzogdGhpcy5yZXNvbHZlZFRoZW1lLmNoYXJ0Rm9yZUNvbG9yLFxuICAgICAgJy0tZGFzaC1hY2NlbnQtY29sb3InOiB0aGlzLnJlc29sdmVkVGhlbWUuYWNjZW50Q29sb3IsXG4gICAgICAnLS1kYXNoLWRhbmdlci1jb2xvcic6IHRoaXMucmVzb2x2ZWRUaGVtZS5kYW5nZXJDb2xvcixcbiAgICAgICctLWRhc2gtZm9udC1mYW1pbHknOiB0aGlzLnJlc29sdmVkVGhlbWUuZm9udEZhbWlseSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVBY3RpdmVQYWdlKCkge1xuICAgIHRoaXMuYWN0aXZlUGFnZSA9IHRoaXMucGFnZXMuZmluZChwID0+IHAuaWQgPT09IHRoaXMuYWN0aXZlUGFnZUlkKTtcbiAgfVxuXG5cbiAgLy8g4pSA4pSAIFBhZ2UgYWN0aW9ucyDilIDilIBcbiAgb25TZWxlY3RQYWdlKGlkOiBzdHJpbmcpIHsgdGhpcy5zdGF0ZVNlcnZpY2Uuc2V0QWN0aXZlUGFnZShpZCk7IH1cblxuICBvbkFkZFBhZ2UoKSB7XG4gICAgY29uc3QgbmFtZSA9IHByb21wdCgnRW50ZXIgd29ya3NwYWNlIG5hbWU6JywgYFdvcmtzcGFjZSAke3RoaXMucGFnZXMubGVuZ3RoICsgMX1gKTtcbiAgICBpZiAobmFtZSkgdGhpcy5zdGF0ZVNlcnZpY2UuYWRkUGFnZShuYW1lKTtcbiAgfVxuXG4gIG9uUmVtb3ZlUGFnZShldmVudDogRXZlbnQsIGlkOiBzdHJpbmcpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBpZiAoY29uZmlybSgnUmVtb3ZlIHRoaXMgd29ya3NwYWNlPycpKSB0aGlzLnN0YXRlU2VydmljZS5yZW1vdmVQYWdlKGlkKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBEaWFsb2cg4pSA4pSAXG4gIG9wZW5EaWFsb2coKSB7XG4gICAgdGhpcy5kaWFsb2dUeXBlID0gJ0xJTkUnO1xuICAgIHRoaXMuZGlhbG9nVGl0bGUgPSAnJztcbiAgICB0aGlzLmRpYWxvZ0NhdGVnb3JpZXMgPSAnJztcbiAgICB0aGlzLmRpYWxvZ1NlcmllcyA9IFt7IG5hbWU6ICdTZXJpZXMgMScsIGRhdGFSYXc6ICcnIH1dO1xuICAgIHRoaXMuZGlhbG9nU2xpY2VzID0gW1xuICAgICAgeyBsYWJlbDogJ1NsaWNlIEEnLCB2YWx1ZTogbnVsbCB9LFxuICAgICAgeyBsYWJlbDogJ1NsaWNlIEInLCB2YWx1ZTogbnVsbCB9LFxuICAgICAgeyBsYWJlbDogJ1NsaWNlIEMnLCB2YWx1ZTogbnVsbCB9LFxuICAgIF07XG4gICAgdGhpcy5kaWFsb2dPcGVuID0gdHJ1ZTtcbiAgfVxuXG4gIGNsb3NlRGlhbG9nKCkgeyB0aGlzLmRpYWxvZ09wZW4gPSBmYWxzZTsgfVxuXG4gIGFkZFNlcmllcygpIHsgdGhpcy5kaWFsb2dTZXJpZXMucHVzaCh7IG5hbWU6IGBTZXJpZXMgJHt0aGlzLmRpYWxvZ1Nlcmllcy5sZW5ndGggKyAxfWAsIGRhdGFSYXc6ICcnIH0pOyB9XG4gIHJlbW92ZVNlcmllcyhpOiBudW1iZXIpIHsgdGhpcy5kaWFsb2dTZXJpZXMuc3BsaWNlKGksIDEpOyB9XG5cbiAgYWRkU2xpY2UoKSB7IHRoaXMuZGlhbG9nU2xpY2VzLnB1c2goeyBsYWJlbDogYFNsaWNlICR7dGhpcy5kaWFsb2dTbGljZXMubGVuZ3RoICsgMX1gLCB2YWx1ZTogbnVsbCB9KTsgfVxuICByZW1vdmVTbGljZShpOiBudW1iZXIpIHsgdGhpcy5kaWFsb2dTbGljZXMuc3BsaWNlKGksIDEpOyB9XG5cbiAgY29uZmlybUFkZFdpZGdldCgpIHtcbiAgICBjb25zdCB0aXRsZSA9IHRoaXMuZGlhbG9nVGl0bGUudHJpbSgpO1xuICAgIGlmICghdGl0bGUpIHJldHVybjtcblxuICAgIGxldCBkYXRhOiBMaW5lQmFyRGF0YSB8IERvbnV0RGF0YTtcblxuICAgIGlmICh0aGlzLmRpYWxvZ1R5cGUgPT09ICdET05VVCcpIHtcbiAgICAgIGNvbnN0IHZhbGlkU2xpY2VzID0gdGhpcy5kaWFsb2dTbGljZXMuZmlsdGVyKHMgPT4gcy52YWx1ZSAhPT0gbnVsbCAmJiBzLmxhYmVsLnRyaW0oKSk7XG4gICAgICBkYXRhID0ge1xuICAgICAgICBzZXJpZXM6IHZhbGlkU2xpY2VzLmxlbmd0aFxuICAgICAgICAgID8gdmFsaWRTbGljZXMubWFwKHMgPT4gTnVtYmVyKHMudmFsdWUpKVxuICAgICAgICAgIDogWzMwLCAyMCwgNTBdLFxuICAgICAgICBsYWJlbHM6IHZhbGlkU2xpY2VzLmxlbmd0aFxuICAgICAgICAgID8gdmFsaWRTbGljZXMubWFwKHMgPT4gcy5sYWJlbClcbiAgICAgICAgICA6IFsnQScsICdCJywgJ0MnXSxcbiAgICAgIH0gYXMgRG9udXREYXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBwYXJzZU51bXMgPSAocmF3OiBzdHJpbmcpID0+XG4gICAgICAgIHJhdy5zcGxpdCgnLCcpLm1hcCh2ID0+IHBhcnNlRmxvYXQodi50cmltKCkpKS5maWx0ZXIobiA9PiAhaXNOYU4obikpO1xuXG4gICAgICBkYXRhID0ge1xuICAgICAgICBzZXJpZXM6IHRoaXMuZGlhbG9nU2VyaWVzLm1hcChzID0+ICh7XG4gICAgICAgICAgbmFtZTogcy5uYW1lIHx8ICdTZXJpZXMnLFxuICAgICAgICAgIGRhdGE6IHMuZGF0YVJhdy50cmltKClcbiAgICAgICAgICAgID8gcGFyc2VOdW1zKHMuZGF0YVJhdylcbiAgICAgICAgICAgIDogQXJyYXkuZnJvbSh7IGxlbmd0aDogOCB9LCAoKSA9PiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDApKSxcbiAgICAgICAgfSkpLFxuICAgICAgICBjYXRlZ29yaWVzOiB0aGlzLmRpYWxvZ0NhdGVnb3JpZXMudHJpbSgpXG4gICAgICAgICAgPyB0aGlzLmRpYWxvZ0NhdGVnb3JpZXMuc3BsaXQoJywnKS5tYXAoYyA9PiBjLnRyaW0oKSlcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIH0gYXMgTGluZUJhckRhdGE7XG4gICAgfVxuXG4gICAgdGhpcy5zdGF0ZVNlcnZpY2UuYWRkV2lkZ2V0V2l0aERhdGEodGhpcy5kaWFsb2dUeXBlLCB0aXRsZSwgZGF0YSk7XG4gICAgdGhpcy5jbG9zZURpYWxvZygpO1xuICB9XG5cbiAgLy8g4pSA4pSAIEVkaXQgZGlhbG9nIHN0YXRlIOKUgOKUgFxuICBlZGl0RGlhbG9nT3BlbiA9IGZhbHNlO1xuICBlZGl0aW5nV2lkZ2V0PzogV2lkZ2V0O1xuICBlZGl0V2lkZ2V0VHlwZTogV2lkZ2V0VHlwZSA9ICdMSU5FJztcbiAgZWRpdFRpdGxlID0gJyc7XG4gIGVkaXRDYXJkQ29sb3IgPSAnJztcbiAgZWRpdENvbG9yczogc3RyaW5nW10gPSBbXTtcbiAgZWRpdFNlcmllczogeyBuYW1lOiBzdHJpbmc7IGRhdGFSYXc6IHN0cmluZyB9W10gPSBbXTtcbiAgZWRpdENhdGVnb3JpZXMgPSAnJztcbiAgZWRpdFNsaWNlczogeyBsYWJlbDogc3RyaW5nOyB2YWx1ZTogbnVtYmVyIHwgbnVsbCB9W10gPSBbXTtcblxuICBwcml2YXRlIHJlYWRvbmx5IERFRkFVTFRfQ09MT1JTID0gWycjMGE4NGZmJywgJyMzMGQxNTgnLCAnI2ZmOWYwYScsICcjYmY1YWYyJywgJyNmZjQ1M2EnXTtcblxuICBvcGVuRWRpdERpYWxvZyh3aWRnZXQ6IFdpZGdldCkge1xuICAgIHRoaXMuZWRpdGluZ1dpZGdldCAgPSB3aWRnZXQ7XG4gICAgdGhpcy5lZGl0V2lkZ2V0VHlwZSA9IHdpZGdldC50eXBlO1xuICAgIHRoaXMuZWRpdFRpdGxlICAgICAgPSB3aWRnZXQudGl0bGU7XG4gICAgdGhpcy5lZGl0Q2FyZENvbG9yICA9IHdpZGdldC5jYXJkQ29sb3IgPz8gdGhpcy5yZXNvbHZlZFRoZW1lLndpZGdldENhcmRDb2xvcjtcbiAgICB0aGlzLmVkaXRDb2xvcnMgICAgID0gd2lkZ2V0LmNvbG9ycz8ubGVuZ3RoXG4gICAgICA/IFsuLi53aWRnZXQuY29sb3JzXVxuICAgICAgOiBbLi4udGhpcy5yZXNvbHZlZFRoZW1lLmNoYXJ0Q29sb3JzXTtcblxuICAgIGlmICh3aWRnZXQudHlwZSA9PT0gJ0RPTlVUJykge1xuICAgICAgY29uc3QgZCA9IHdpZGdldC5kYXRhIGFzIGFueTtcbiAgICAgIHRoaXMuZWRpdFNsaWNlcyA9IChkLnNlcmllcyBhcyBudW1iZXJbXSkubWFwKCh2OiBudW1iZXIsIGk6IG51bWJlcikgPT4gKHtcbiAgICAgICAgbGFiZWw6IGQubGFiZWxzPy5baV0gPz8gYFNsaWNlICR7aSArIDF9YCxcbiAgICAgICAgdmFsdWU6IHYsXG4gICAgICB9KSk7XG4gICAgICB0aGlzLmVkaXRDb2xvcnMgPSB0aGlzLmVkaXRDb2xvcnMuc2xpY2UoMCwgdGhpcy5lZGl0U2xpY2VzLmxlbmd0aCk7XG4gICAgICB3aGlsZSAodGhpcy5lZGl0Q29sb3JzLmxlbmd0aCA8IHRoaXMuZWRpdFNsaWNlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5lZGl0Q29sb3JzLnB1c2godGhpcy5ERUZBVUxUX0NPTE9SU1t0aGlzLmVkaXRDb2xvcnMubGVuZ3RoICUgdGhpcy5ERUZBVUxUX0NPTE9SUy5sZW5ndGhdKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZCA9IHdpZGdldC5kYXRhIGFzIGFueTtcbiAgICAgIHRoaXMuZWRpdFNlcmllcyAgICAgPSAoZC5zZXJpZXMgYXMgYW55W10pLm1hcCgoczogYW55KSA9PiAoeyBuYW1lOiBzLm5hbWUsIGRhdGFSYXc6IHMuZGF0YS5qb2luKCcsJykgfSkpO1xuICAgICAgdGhpcy5lZGl0Q2F0ZWdvcmllcyA9IGQuY2F0ZWdvcmllcz8uam9pbignLCcpID8/ICcnO1xuICAgICAgdGhpcy5lZGl0Q29sb3JzICAgICA9IHRoaXMuZWRpdENvbG9ycy5zbGljZSgwLCB0aGlzLmVkaXRTZXJpZXMubGVuZ3RoKTtcbiAgICAgIHdoaWxlICh0aGlzLmVkaXRDb2xvcnMubGVuZ3RoIDwgdGhpcy5lZGl0U2VyaWVzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmVkaXRDb2xvcnMucHVzaCh0aGlzLkRFRkFVTFRfQ09MT1JTW3RoaXMuZWRpdENvbG9ycy5sZW5ndGggJSB0aGlzLkRFRkFVTFRfQ09MT1JTLmxlbmd0aF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZWRpdERpYWxvZ09wZW4gPSB0cnVlO1xuICB9XG5cbiAgY2xvc2VFZGl0RGlhbG9nKCkgeyB0aGlzLmVkaXREaWFsb2dPcGVuID0gZmFsc2U7IHRoaXMuZWRpdGluZ1dpZGdldCA9IHVuZGVmaW5lZDsgfVxuXG4gIGdldEVkaXRTZXJpZXNMYWJlbChpOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmVkaXRXaWRnZXRUeXBlID09PSAnRE9OVVQnKSByZXR1cm4gdGhpcy5lZGl0U2xpY2VzW2ldPy5sYWJlbCB8fCBgU2xpY2UgJHtpICsgMX1gO1xuICAgIHJldHVybiB0aGlzLmVkaXRTZXJpZXNbaV0/Lm5hbWUgfHwgYFNlcmllcyAke2kgKyAxfWA7XG4gIH1cblxuICBhZGRFZGl0U2VyaWVzKCkge1xuICAgIHRoaXMuZWRpdFNlcmllcy5wdXNoKHsgbmFtZTogYFNlcmllcyAke3RoaXMuZWRpdFNlcmllcy5sZW5ndGggKyAxfWAsIGRhdGFSYXc6ICcnIH0pO1xuICAgIHRoaXMuZWRpdENvbG9ycy5wdXNoKHRoaXMuREVGQVVMVF9DT0xPUlNbdGhpcy5lZGl0Q29sb3JzLmxlbmd0aCAlIHRoaXMuREVGQVVMVF9DT0xPUlMubGVuZ3RoXSk7XG4gIH1cbiAgcmVtb3ZlRWRpdFNlcmllcyhpOiBudW1iZXIpIHsgdGhpcy5lZGl0U2VyaWVzLnNwbGljZShpLCAxKTsgdGhpcy5lZGl0Q29sb3JzLnNwbGljZShpLCAxKTsgfVxuXG4gIGFkZEVkaXRTbGljZSgpIHtcbiAgICB0aGlzLmVkaXRTbGljZXMucHVzaCh7IGxhYmVsOiBgU2xpY2UgJHt0aGlzLmVkaXRTbGljZXMubGVuZ3RoICsgMX1gLCB2YWx1ZTogbnVsbCB9KTtcbiAgICB0aGlzLmVkaXRDb2xvcnMucHVzaCh0aGlzLkRFRkFVTFRfQ09MT1JTW3RoaXMuZWRpdENvbG9ycy5sZW5ndGggJSB0aGlzLkRFRkFVTFRfQ09MT1JTLmxlbmd0aF0pO1xuICB9XG4gIHJlbW92ZUVkaXRTbGljZShpOiBudW1iZXIpIHsgdGhpcy5lZGl0U2xpY2VzLnNwbGljZShpLCAxKTsgdGhpcy5lZGl0Q29sb3JzLnNwbGljZShpLCAxKTsgfVxuXG4gIGNvbmZpcm1FZGl0V2lkZ2V0KCkge1xuICAgIGlmICghdGhpcy5lZGl0aW5nV2lkZ2V0KSByZXR1cm47XG4gICAgY29uc3QgcGFyc2VOdW1zID0gKHJhdzogc3RyaW5nKSA9PlxuICAgICAgcmF3LnNwbGl0KCcsJykubWFwKHYgPT4gcGFyc2VGbG9hdCh2LnRyaW0oKSkpLmZpbHRlcihuID0+ICFpc05hTihuKSk7XG5cbiAgICBsZXQgZGF0YTogTGluZUJhckRhdGEgfCBEb251dERhdGE7XG4gICAgaWYgKHRoaXMuZWRpdFdpZGdldFR5cGUgPT09ICdET05VVCcpIHtcbiAgICAgIGRhdGEgPSB7XG4gICAgICAgIHNlcmllczogdGhpcy5lZGl0U2xpY2VzLm1hcChzID0+IE51bWJlcihzLnZhbHVlKSB8fCAwKSxcbiAgICAgICAgbGFiZWxzOiB0aGlzLmVkaXRTbGljZXMubWFwKHMgPT4gcy5sYWJlbCksXG4gICAgICB9IGFzIERvbnV0RGF0YTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IHtcbiAgICAgICAgc2VyaWVzOiB0aGlzLmVkaXRTZXJpZXMubWFwKHMgPT4gKHtcbiAgICAgICAgICBuYW1lOiBzLm5hbWUgfHwgJ1NlcmllcycsXG4gICAgICAgICAgZGF0YTogcy5kYXRhUmF3LnRyaW0oKSA/IHBhcnNlTnVtcyhzLmRhdGFSYXcpIDogW10sXG4gICAgICAgIH0pKSxcbiAgICAgICAgY2F0ZWdvcmllczogdGhpcy5lZGl0Q2F0ZWdvcmllcy50cmltKClcbiAgICAgICAgICA/IHRoaXMuZWRpdENhdGVnb3JpZXMuc3BsaXQoJywnKS5tYXAoYyA9PiBjLnRyaW0oKSlcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIH0gYXMgTGluZUJhckRhdGE7XG4gICAgfVxuXG4gICAgdGhpcy5zdGF0ZVNlcnZpY2UudXBkYXRlV2lkZ2V0TWV0YSh0aGlzLmVkaXRpbmdXaWRnZXQuaWQsIHtcbiAgICAgIHRpdGxlOiAgICAgdGhpcy5lZGl0VGl0bGUudHJpbSgpIHx8IHRoaXMuZWRpdGluZ1dpZGdldC50aXRsZSxcbiAgICAgIGNvbG9yczogICAgWy4uLnRoaXMuZWRpdENvbG9yc10sXG4gICAgICBjYXJkQ29sb3I6IHRoaXMuZWRpdENhcmRDb2xvcixcbiAgICAgIGRhdGEsXG4gICAgfSk7XG4gICAgdGhpcy5jbG9zZUVkaXREaWFsb2coKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBXaWRnZXQgYWN0aW9ucyDilIDilIBcbiAgb25BZGRXaWRnZXQodHlwZTogV2lkZ2V0VHlwZSkgeyB0aGlzLnN0YXRlU2VydmljZS5hZGRXaWRnZXQodHlwZSk7IH1cblxuICB1cGRhdGVXaWRnZXREYXRhKHdpZGdldElkOiBzdHJpbmcsIGRhdGE6IExpbmVCYXJEYXRhIHwgRG9udXREYXRhKSB7XG4gICAgdGhpcy5zdGF0ZVNlcnZpY2UudXBkYXRlV2lkZ2V0RGF0YSh3aWRnZXRJZCwgZGF0YSk7XG4gIH1cblxuICByZW1vdmVXaWRnZXRIYW5kbGVyID0gKGlkOiBzdHJpbmcpID0+IHsgdGhpcy5zdGF0ZVNlcnZpY2UucmVtb3ZlV2lkZ2V0KGlkKTsgfTtcblxuICBzZXJpYWxpemVMYXlvdXQoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuc3RhdGVTZXJ2aWNlLnNlcmlhbGl6ZUxheW91dCgpOyB9XG59XG4iXX0=
|