@ogidor/dashboard 1.0.2 → 1.0.4

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.
@@ -1,56 +1,39 @@
1
- import { Component, Input } from '@angular/core';
1
+ import { Component, Input, Output, EventEmitter, ContentChild, TemplateRef } from '@angular/core';
2
2
  import { Subscription } from 'rxjs';
3
+ import { GridCellDirective } from './custom-grid.component';
3
4
  import * as i0 from "@angular/core";
4
5
  import * as i1 from "./dashboard-state.service";
5
6
  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";
7
+ import * as i3 from "./widget-renderer.component";
8
+ import * as i4 from "./custom-grid.component";
9
9
  const DEFAULT_THEME = {
10
10
  backgroundColor: '#000000',
11
11
  panelColor: '#1c1c1e',
12
12
  widgetCardColor: '#2c2c2e',
13
- chartForeColor: '#8e8e93',
13
+ foreColor: '#8e8e93',
14
14
  accentColor: '#0a84ff',
15
15
  dangerColor: '#ff453a',
16
- chartColors: ['#0a84ff', '#30d158', '#ff9f0a', '#bf5af2', '#ff453a'],
17
16
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
18
17
  };
19
18
  export class DashboardComponent {
20
19
  constructor(stateService) {
21
20
  this.stateService = stateService;
21
+ /**
22
+ * Emits when the user clicks "Add Widget".
23
+ * The consumer should open their own dialog and call `stateService.addWidget(...)`.
24
+ */
25
+ this.addWidgetRequested = new EventEmitter();
26
+ /**
27
+ * Emits the Widget when the user clicks the edit (pen) icon on a card.
28
+ * The consumer should open their own edit UI and call `stateService.updateWidget(...)`.
29
+ */
30
+ this.editWidgetRequested = new EventEmitter();
22
31
  this.resolvedTheme = { ...DEFAULT_THEME };
23
32
  this.wrapperStyles = {};
24
33
  this.pages = [];
25
34
  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
- ];
35
+ this.isPoppedOut = false;
42
36
  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
37
  }
55
38
  ngOnChanges(changes) {
56
39
  if (changes['theme'] || changes['initialLayout'])
@@ -66,21 +49,16 @@ export class DashboardComponent {
66
49
  console.error('[Dashboard] Failed to parse initialLayout', e);
67
50
  }
68
51
  }
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
- };
52
+ const hash = window.location.hash?.replace('#', '').trim();
53
+ if (hash)
54
+ this.isPoppedOut = true;
82
55
  this.subs.add(this.stateService.pages$.subscribe(pages => {
83
56
  this.pages = pages;
57
+ if (this.isPoppedOut && hash) {
58
+ const target = pages.find(p => p.id === hash);
59
+ if (target)
60
+ this.stateService.setActivePage(hash);
61
+ }
84
62
  this.updateActivePage();
85
63
  }));
86
64
  this.subs.add(this.stateService.activePageId$.subscribe(id => {
@@ -89,25 +67,13 @@ export class DashboardComponent {
89
67
  }));
90
68
  }
91
69
  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);
70
+ onItemChanged(widget) {
71
+ this.stateService.updateWidgetPosition(this.activePageId, widget.id, widget.x, widget.y, widget.cols, widget.rows);
106
72
  }
107
- // ── Page actions ──
73
+ onRemoveWidget(widgetId) { this.stateService.removeWidget(widgetId); }
108
74
  onSelectPage(id) { this.stateService.setActivePage(id); }
109
75
  onAddPage() {
110
- const name = prompt('Enter workspace name:', `Workspace ${this.pages.length + 1}`);
76
+ const name = prompt('Workspace name:', `Workspace ${this.pages.length + 1}`);
111
77
  if (name)
112
78
  this.stateService.addPage(name);
113
79
  }
@@ -116,588 +82,218 @@ export class DashboardComponent {
116
82
  if (confirm('Remove this workspace?'))
117
83
  this.stateService.removePage(id);
118
84
  }
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]);
85
+ onPopOut(event, pageId) {
86
+ event.stopPropagation();
87
+ this.stateService.popOutPage(pageId);
214
88
  }
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();
89
+ serializeLayout() { return this.stateService.serializeLayout(); }
90
+ applyTheme() {
91
+ this.resolvedTheme = { ...DEFAULT_THEME, ...(this.theme ?? {}) };
92
+ this.wrapperStyles = {
93
+ '--dash-bg': this.resolvedTheme.backgroundColor,
94
+ '--dash-panel-bg': this.resolvedTheme.panelColor,
95
+ '--dash-card-bg': this.resolvedTheme.widgetCardColor,
96
+ '--dash-fore-color': this.resolvedTheme.foreColor,
97
+ '--dash-accent-color': this.resolvedTheme.accentColor,
98
+ '--dash-danger-color': this.resolvedTheme.dangerColor,
99
+ '--dash-font-family': this.resolvedTheme.fontFamily,
100
+ };
245
101
  }
246
- // ── Widget actions ──
247
- onAddWidget(type) { this.stateService.addWidget(type); }
248
- updateWidgetData(widgetId, data) {
249
- this.stateService.updateWidgetData(widgetId, data);
102
+ updateActivePage() {
103
+ this.activePage = this.pages.find(p => p.id === this.activePageId);
250
104
  }
251
- serializeLayout() { return this.stateService.serializeLayout(); }
252
105
  }
253
106
  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>
107
+ DashboardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DashboardComponent, selector: "app-dashboard", inputs: { initialLayout: "initialLayout", theme: "theme" }, outputs: { addWidgetRequested: "addWidgetRequested", editWidgetRequested: "editWidgetRequested" }, queries: [{ propertyName: "cellTemplate", first: true, predicate: GridCellDirective, descendants: true, read: TemplateRef }], usesOnChanges: true, ngImport: i0, template: `
108
+ <!-- ══════════════════════════════════════════════════════════
109
+ POPPED-OUT MODE
110
+ ══════════════════════════════════════════════════════════ -->
111
+ <ng-container *ngIf="isPoppedOut; else normalMode">
112
+ <div class="popout-wrapper" [ngStyle]="wrapperStyles">
113
+ <header class="popout-header">
114
+ <span class="popout-title">{{ activePage?.name }}</span>
283
115
  </header>
284
-
285
- <!-- ── Grid ── -->
286
116
  <div class="grid-container">
287
- <gridster [options]="options">
288
- <gridster-item [item]="widget" *ngFor="let widget of activePage?.widgets">
117
+ <app-grid [widgets]="activePage?.widgets || []" (itemChanged)="onItemChanged($event)">
118
+ <ng-template gridCell let-widget="widget">
289
119
  <app-widget-renderer
290
120
  [widget]="widget"
291
- [onRemoveWidget]="removeWidgetHandler"
292
121
  [theme]="resolvedTheme"
293
- (editRequested)="openEditDialog($event)"
294
- ></app-widget-renderer>
295
- </gridster-item>
296
- </gridster>
122
+ (editRequested)="editWidgetRequested.emit($event)"
123
+ (removeRequested)="onRemoveWidget($event)"
124
+ >
125
+ <ng-container
126
+ *ngIf="cellTemplate"
127
+ [ngTemplateOutlet]="cellTemplate"
128
+ [ngTemplateOutletContext]="{ widget: widget }">
129
+ </ng-container>
130
+ </app-widget-renderer>
131
+ </ng-template>
132
+ </app-grid>
297
133
  </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
134
  </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>
135
+ </ng-container>
136
+
137
+ <!-- ══════════════════════════════════════════════════════════
138
+ NORMAL MODE
139
+ ══════════════════════════════════════════════════════════ -->
140
+ <ng-template #normalMode>
141
+ <div class="dashboard-wrapper" [ngStyle]="wrapperStyles">
142
+ <main class="main-content">
143
+
144
+ <header class="dashboard-header">
145
+ <div class="tabs-container">
146
+ <div
147
+ *ngFor="let page of pages"
148
+ class="tab"
149
+ [class.active]="page.id === activePageId"
150
+ (click)="onSelectPage(page.id)"
151
+ >
152
+ <span class="tab-name">{{ page.name }}</span>
153
+ <button class="tab-action tab-popout" (click)="onPopOut($event, page.id)" title="Open in new window">
154
+ <i class="la la-external-link-alt"></i>
371
155
  </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)">
156
+ <button class="tab-action tab-close" *ngIf="pages.length > 1" (click)="onRemovePage($event, page.id)" title="Close">
435
157
  <i class="la la-times"></i>
436
158
  </button>
437
159
  </div>
160
+ <button class="btn-add-page" (click)="onAddPage()" title="New workspace">
161
+ <i class="la la-plus"></i>
162
+ </button>
438
163
  </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
164
 
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>
165
+ <!-- Add Widget button — consumer decides what happens -->
166
+ <button class="btn-add-widget" (click)="addWidgetRequested.emit()" title="Add widget">
167
+ <i class="la la-plus"></i>
168
+ <span>Add Widget</span>
169
+ </button>
170
+ </header>
171
+
172
+ <div class="grid-container">
173
+ <app-grid [widgets]="activePage?.widgets || []" (itemChanged)="onItemChanged($event)">
174
+ <ng-template gridCell let-widget="widget">
175
+ <app-widget-renderer
176
+ [widget]="widget"
177
+ [theme]="resolvedTheme"
178
+ (editRequested)="editWidgetRequested.emit($event)"
179
+ (removeRequested)="onRemoveWidget($event)"
180
+ >
181
+ <!-- Stamp consumer's cell template (if provided) inside the card body -->
182
+ <ng-container
183
+ *ngIf="cellTemplate"
184
+ [ngTemplateOutlet]="cellTemplate"
185
+ [ngTemplateOutletContext]="{ widget: widget }">
186
+ </ng-container>
187
+ </app-widget-renderer>
188
+ </ng-template>
189
+ </app-grid>
462
190
  </div>
463
- </ng-container>
464
191
 
192
+ </main>
465
193
  </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"] }] });
194
+ </ng-template>
195
+ `, 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)}.popout-wrapper{display:flex;flex-direction:column;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)}.popout-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;padding:10px 18px;background:var(--dash-panel-bg);border-radius:20px;border:1px solid rgba(255,255,255,.06);flex-shrink:0}.popout-title{font-size:16px;font-weight:700;color:#fff}.popout-wrapper .grid-container{flex:1;overflow:auto;border-radius:24px;min-height:0;background:var(--dash-panel-bg);padding:16px;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;gap:4px;padding:8px 14px 8px 18px;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{flex:1;white-space:nowrap}.tab-action{background:transparent;border:none;color:var(--dash-fore-color);padding:2px;font-size:11px;cursor:pointer;opacity:0;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;transition:all .2s;flex-shrink:0}.tab:hover .tab-action{opacity:1}.tab-popout:hover{color:var(--dash-accent-color);background:rgba(10,132,255,.18)}.tab-close:hover{color:var(--dash-danger-color);background:rgba(255,69,58,.2)}.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)}.main-content .grid-container{flex:1;overflow:auto;border-radius:24px;min-height:0}app-grid{background:transparent;display:block;height:100%;width:100%}\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.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i3.WidgetRendererComponent, selector: "app-widget-renderer", inputs: ["widget", "theme"], outputs: ["editRequested", "removeRequested"] }, { kind: "component", type: i4.CustomGridComponent, selector: "app-grid", inputs: ["widgets", "columns", "gap", "rowHeight", "minItemCols", "minItemRows"], outputs: ["itemChanged", "layoutChanged"] }, { kind: "directive", type: i4.GridCellDirective, selector: "[gridCell]" }] });
475
196
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardComponent, decorators: [{
476
197
  type: Component,
477
198
  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>
199
+ <!-- ══════════════════════════════════════════════════════════
200
+ POPPED-OUT MODE
201
+ ══════════════════════════════════════════════════════════ -->
202
+ <ng-container *ngIf="isPoppedOut; else normalMode">
203
+ <div class="popout-wrapper" [ngStyle]="wrapperStyles">
204
+ <header class="popout-header">
205
+ <span class="popout-title">{{ activePage?.name }}</span>
506
206
  </header>
507
-
508
- <!-- ── Grid ── -->
509
207
  <div class="grid-container">
510
- <gridster [options]="options">
511
- <gridster-item [item]="widget" *ngFor="let widget of activePage?.widgets">
208
+ <app-grid [widgets]="activePage?.widgets || []" (itemChanged)="onItemChanged($event)">
209
+ <ng-template gridCell let-widget="widget">
512
210
  <app-widget-renderer
513
211
  [widget]="widget"
514
- [onRemoveWidget]="removeWidgetHandler"
515
212
  [theme]="resolvedTheme"
516
- (editRequested)="openEditDialog($event)"
517
- ></app-widget-renderer>
518
- </gridster-item>
519
- </gridster>
213
+ (editRequested)="editWidgetRequested.emit($event)"
214
+ (removeRequested)="onRemoveWidget($event)"
215
+ >
216
+ <ng-container
217
+ *ngIf="cellTemplate"
218
+ [ngTemplateOutlet]="cellTemplate"
219
+ [ngTemplateOutletContext]="{ widget: widget }">
220
+ </ng-container>
221
+ </app-widget-renderer>
222
+ </ng-template>
223
+ </app-grid>
520
224
  </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
225
  </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>
226
+ </ng-container>
227
+
228
+ <!-- ══════════════════════════════════════════════════════════
229
+ NORMAL MODE
230
+ ══════════════════════════════════════════════════════════ -->
231
+ <ng-template #normalMode>
232
+ <div class="dashboard-wrapper" [ngStyle]="wrapperStyles">
233
+ <main class="main-content">
234
+
235
+ <header class="dashboard-header">
236
+ <div class="tabs-container">
237
+ <div
238
+ *ngFor="let page of pages"
239
+ class="tab"
240
+ [class.active]="page.id === activePageId"
241
+ (click)="onSelectPage(page.id)"
242
+ >
243
+ <span class="tab-name">{{ page.name }}</span>
244
+ <button class="tab-action tab-popout" (click)="onPopOut($event, page.id)" title="Open in new window">
245
+ <i class="la la-external-link-alt"></i>
570
246
  </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)">
247
+ <button class="tab-action tab-close" *ngIf="pages.length > 1" (click)="onRemovePage($event, page.id)" title="Close">
658
248
  <i class="la la-times"></i>
659
249
  </button>
660
250
  </div>
251
+ <button class="btn-add-page" (click)="onAddPage()" title="New workspace">
252
+ <i class="la la-plus"></i>
253
+ </button>
661
254
  </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
255
 
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>
256
+ <!-- Add Widget button — consumer decides what happens -->
257
+ <button class="btn-add-widget" (click)="addWidgetRequested.emit()" title="Add widget">
258
+ <i class="la la-plus"></i>
259
+ <span>Add Widget</span>
260
+ </button>
261
+ </header>
262
+
263
+ <div class="grid-container">
264
+ <app-grid [widgets]="activePage?.widgets || []" (itemChanged)="onItemChanged($event)">
265
+ <ng-template gridCell let-widget="widget">
266
+ <app-widget-renderer
267
+ [widget]="widget"
268
+ [theme]="resolvedTheme"
269
+ (editRequested)="editWidgetRequested.emit($event)"
270
+ (removeRequested)="onRemoveWidget($event)"
271
+ >
272
+ <!-- Stamp consumer's cell template (if provided) inside the card body -->
273
+ <ng-container
274
+ *ngIf="cellTemplate"
275
+ [ngTemplateOutlet]="cellTemplate"
276
+ [ngTemplateOutletContext]="{ widget: widget }">
277
+ </ng-container>
278
+ </app-widget-renderer>
279
+ </ng-template>
280
+ </app-grid>
685
281
  </div>
686
- </ng-container>
687
-
688
- </div>
689
282
 
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>
283
+ </main>
695
284
  </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"] }]
285
+ </ng-template>
286
+ `, 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)}.popout-wrapper{display:flex;flex-direction:column;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)}.popout-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;padding:10px 18px;background:var(--dash-panel-bg);border-radius:20px;border:1px solid rgba(255,255,255,.06);flex-shrink:0}.popout-title{font-size:16px;font-weight:700;color:#fff}.popout-wrapper .grid-container{flex:1;overflow:auto;border-radius:24px;min-height:0;background:var(--dash-panel-bg);padding:16px;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;gap:4px;padding:8px 14px 8px 18px;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{flex:1;white-space:nowrap}.tab-action{background:transparent;border:none;color:var(--dash-fore-color);padding:2px;font-size:11px;cursor:pointer;opacity:0;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;transition:all .2s;flex-shrink:0}.tab:hover .tab-action{opacity:1}.tab-popout:hover{color:var(--dash-accent-color);background:rgba(10,132,255,.18)}.tab-close:hover{color:var(--dash-danger-color);background:rgba(255,69,58,.2)}.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)}.main-content .grid-container{flex:1;overflow:auto;border-radius:24px;min-height:0}app-grid{background:transparent;display:block;height:100%;width:100%}\n"] }]
698
287
  }], ctorParameters: function () { return [{ type: i1.DashboardStateService }]; }, propDecorators: { initialLayout: [{
699
288
  type: Input
700
289
  }], theme: [{
701
290
  type: Input
291
+ }], addWidgetRequested: [{
292
+ type: Output
293
+ }], editWidgetRequested: [{
294
+ type: Output
295
+ }], cellTemplate: [{
296
+ type: ContentChild,
297
+ args: [GridCellDirective, { read: TemplateRef }]
702
298
  }] } });
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=
299
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hcHAvZGFzaGJvYXJkLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUFxQixLQUFLLEVBQUUsTUFBTSxFQUM1QixZQUFZLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFDdkQsTUFBTSxlQUFlLENBQUM7QUFHdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7O0FBRTVELE1BQU0sYUFBYSxHQUE2QjtJQUM5QyxlQUFlLEVBQUUsU0FBUztJQUMxQixVQUFVLEVBQU8sU0FBUztJQUMxQixlQUFlLEVBQUUsU0FBUztJQUMxQixTQUFTLEVBQVEsU0FBUztJQUMxQixXQUFXLEVBQU0sU0FBUztJQUMxQixXQUFXLEVBQU0sU0FBUztJQUMxQixVQUFVLEVBQU8scUZBQXFGO0NBQ3ZHLENBQUM7QUErTEYsTUFBTSxPQUFPLGtCQUFrQjtJQWlDN0IsWUFBbUIsWUFBbUM7UUFBbkMsaUJBQVksR0FBWixZQUFZLENBQXVCO1FBN0J0RDs7O1dBR0c7UUFDTyx1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRXhEOzs7V0FHRztRQUNPLHdCQUFtQixHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFTM0Qsa0JBQWEsR0FBNkIsRUFBRSxHQUFHLGFBQWEsRUFBRSxDQUFDO1FBQy9ELGtCQUFhLEdBQTJCLEVBQUUsQ0FBQztRQUUzQyxVQUFLLEdBQVcsRUFBRSxDQUFDO1FBQ25CLGlCQUFZLEdBQUcsRUFBRSxDQUFDO1FBRWxCLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBRVosU0FBSSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7SUFFdUIsQ0FBQztJQUUxRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMs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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3RlQ7NEZBbUdVLGtCQUFrQjtrQkE3TDlCLFNBQVM7K0JBQ0UsZUFBZSxZQUNmOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0ZUOzRHQW9HUSxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFNSSxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBTUcsbUJBQW1CO3NCQUE1QixNQUFNO2dCQU9QLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxpQkFBaUIsRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsIE9uSW5pdCwgT25EZXN0cm95LCBJbnB1dCwgT3V0cHV0LCBPbkNoYW5nZXMsXG4gIFNpbXBsZUNoYW5nZXMsIEV2ZW50RW1pdHRlciwgQ29udGVudENoaWxkLCBUZW1wbGF0ZVJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERhc2hib2FyZFN0YXRlU2VydmljZSB9IGZyb20gJy4vZGFzaGJvYXJkLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUGFnZSwgV2lkZ2V0LCBEYXNoYm9hcmRUaGVtZSB9IGZyb20gJy4vbW9kZWxzJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgR3JpZENlbGxEaXJlY3RpdmUgfSBmcm9tICcuL2N1c3RvbS1ncmlkLmNvbXBvbmVudCc7XG5cbmNvbnN0IERFRkFVTFRfVEhFTUU6IFJlcXVpcmVkPERhc2hib2FyZFRoZW1lPiA9IHtcbiAgYmFja2dyb3VuZENvbG9yOiAnIzAwMDAwMCcsXG4gIHBhbmVsQ29sb3I6ICAgICAgJyMxYzFjMWUnLFxuICB3aWRnZXRDYXJkQ29sb3I6ICcjMmMyYzJlJyxcbiAgZm9yZUNvbG9yOiAgICAgICAnIzhlOGU5MycsXG4gIGFjY2VudENvbG9yOiAgICAgJyMwYTg0ZmYnLFxuICBkYW5nZXJDb2xvcjogICAgICcjZmY0NTNhJyxcbiAgZm9udEZhbWlseTogICAgICAnLWFwcGxlLXN5c3RlbSwgQmxpbmtNYWNTeXN0ZW1Gb250LCBcIlNlZ29lIFVJXCIsIFJvYm90bywgSGVsdmV0aWNhLCBBcmlhbCwgc2Fucy1zZXJpZicsXG59O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtZGFzaGJvYXJkJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8IS0tIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICAgICAgICAgUE9QUEVELU9VVCBNT0RFXG4gICAgICAgICDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzUG9wcGVkT3V0OyBlbHNlIG5vcm1hbE1vZGVcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJwb3BvdXQtd3JhcHBlclwiIFtuZ1N0eWxlXT1cIndyYXBwZXJTdHlsZXNcIj5cbiAgICAgICAgPGhlYWRlciBjbGFzcz1cInBvcG91dC1oZWFkZXJcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInBvcG91dC10aXRsZVwiPnt7IGFjdGl2ZVBhZ2U/Lm5hbWUgfX08L3NwYW4+XG4gICAgICAgIDwvaGVhZGVyPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZ3JpZC1jb250YWluZXJcIj5cbiAgICAgICAgICA8YXBwLWdyaWQgW3dpZGdldHNdPVwiYWN0aXZlUGFnZT8ud2lkZ2V0cyB8fCBbXVwiIChpdGVtQ2hhbmdlZCk9XCJvbkl0ZW1DaGFuZ2VkKCRldmVudClcIj5cbiAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBncmlkQ2VsbCBsZXQtd2lkZ2V0PVwid2lkZ2V0XCI+XG4gICAgICAgICAgICAgIDxhcHAtd2lkZ2V0LXJlbmRlcmVyXG4gICAgICAgICAgICAgICAgW3dpZGdldF09XCJ3aWRnZXRcIlxuICAgICAgICAgICAgICAgIFt0aGVtZV09XCJyZXNvbHZlZFRoZW1lXCJcbiAgICAgICAgICAgICAgICAoZWRpdFJlcXVlc3RlZCk9XCJlZGl0V2lkZ2V0UmVxdWVzdGVkLmVtaXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKHJlbW92ZVJlcXVlc3RlZCk9XCJvblJlbW92ZVdpZGdldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiY2VsbFRlbXBsYXRlXCJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImNlbGxUZW1wbGF0ZVwiXG4gICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyB3aWRnZXQ6IHdpZGdldCB9XCI+XG4gICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDwvYXBwLXdpZGdldC1yZW5kZXJlcj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9hcHAtZ3JpZD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDwhLS0g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gICAgICAgICBOT1JNQUwgTU9ERVxuICAgICAgICAg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIC0tPlxuICAgIDxuZy10ZW1wbGF0ZSAjbm9ybWFsTW9kZT5cbiAgICAgIDxkaXYgY2xhc3M9XCJkYXNoYm9hcmQtd3JhcHBlclwiIFtuZ1N0eWxlXT1cIndyYXBwZXJTdHlsZXNcIj5cbiAgICAgICAgPG1haW4gY2xhc3M9XCJtYWluLWNvbnRlbnRcIj5cblxuICAgICAgICAgIDxoZWFkZXIgY2xhc3M9XCJkYXNoYm9hcmQtaGVhZGVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFicy1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBwYWdlIG9mIHBhZ2VzXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRhYlwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJwYWdlLmlkID09PSBhY3RpdmVQYWdlSWRcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvblNlbGVjdFBhZ2UocGFnZS5pZClcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0YWItbmFtZVwiPnt7IHBhZ2UubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidGFiLWFjdGlvbiB0YWItcG9wb3V0XCIgKGNsaWNrKT1cIm9uUG9wT3V0KCRldmVudCwgcGFnZS5pZClcIiB0aXRsZT1cIk9wZW4gaW4gbmV3IHdpbmRvd1wiPlxuICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJsYSBsYS1leHRlcm5hbC1saW5rLWFsdFwiPjwvaT5cbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwidGFiLWFjdGlvbiB0YWItY2xvc2VcIiAqbmdJZj1cInBhZ2VzLmxlbmd0aCA+IDFcIiAoY2xpY2spPVwib25SZW1vdmVQYWdlKCRldmVudCwgcGFnZS5pZClcIiB0aXRsZT1cIkNsb3NlXCI+XG4gICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImxhIGxhLXRpbWVzXCI+PC9pPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0bi1hZGQtcGFnZVwiIChjbGljayk9XCJvbkFkZFBhZ2UoKVwiIHRpdGxlPVwiTmV3IHdvcmtzcGFjZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwibGEgbGEtcGx1c1wiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBBZGQgV2lkZ2V0IGJ1dHRvbiDigJQgY29uc3VtZXIgZGVjaWRlcyB3aGF0IGhhcHBlbnMgLS0+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuLWFkZC13aWRnZXRcIiAoY2xpY2spPVwiYWRkV2lkZ2V0UmVxdWVzdGVkLmVtaXQoKVwiIHRpdGxlPVwiQWRkIHdpZGdldFwiPlxuICAgICAgICAgICAgICA8aSBjbGFzcz1cImxhIGxhLXBsdXNcIj48L2k+XG4gICAgICAgICAgICAgIDxzcGFuPkFkZCBXaWRnZXQ8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2hlYWRlcj5cblxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgPGFwcC1ncmlkIFt3aWRnZXRzXT1cImFjdGl2ZVBhZ2U/LndpZGdldHMgfHwgW11cIiAoaXRlbUNoYW5nZWQpPVwib25JdGVtQ2hhbmdlZCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBncmlkQ2VsbCBsZXQtd2lkZ2V0PVwid2lkZ2V0XCI+XG4gICAgICAgICAgICAgICAgPGFwcC13aWRnZXQtcmVuZGVyZXJcbiAgICAgICAgICAgICAgICAgIFt3aWRnZXRdPVwid2lkZ2V0XCJcbiAgICAgICAgICAgICAgICAgIFt0aGVtZV09XCJyZXNvbHZlZFRoZW1lXCJcbiAgICAgICAgICAgICAgICAgIChlZGl0UmVxdWVzdGVkKT1cImVkaXRXaWRnZXRSZXF1ZXN0ZWQuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChyZW1vdmVSZXF1ZXN0ZWQpPVwib25SZW1vdmVXaWRnZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgPCEtLSBTdGFtcCBjb25zdW1lcidzIGNlbGwgdGVtcGxhdGUgKGlmIHByb3ZpZGVkKSBpbnNpZGUgdGhlIGNhcmQgYm9keSAtLT5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJjZWxsVGVtcGxhdGVcIlxuICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJjZWxsVGVtcGxhdGVcIlxuICAgICAgICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyB3aWRnZXQ6IHdpZGdldCB9XCI+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8L2FwcC13aWRnZXQtcmVuZGVyZXI+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICA8L2FwcC1ncmlkPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwvbWFpbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIGAsXG4gIHN0eWxlczogW2BcbiAgICA6aG9zdCB7XG4gICAgICAtLWRhc2gtYmc6ICAgICAgICAjMDAwMDAwO1xuICAgICAgLS1kYXNoLXBhbmVsLWJnOiAgIzFjMWMxZTtcbiAgICAgIC0tZGFzaC1jYXJkLWJnOiAgICMyYzJjMmU7XG4gICAgICAtLWRhc2gtZm9yZS1jb2xvcjojOGU4ZTkzO1xuICAgICAgLS1kYXNoLWFjY2VudC1jb2xvcjogIzBhODRmZjtcbiAgICAgIC0tZGFzaC1kYW5nZXItY29sb3I6ICNmZjQ1M2E7XG4gICAgICAtLWRhc2gtZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgXCJTZWdvZSBVSVwiLCBSb2JvdG8sIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWY7XG4gICAgfVxuXG4gICAgLyog4pSA4pSAIE5vcm1hbCBsYXlvdXQg4pSA4pSAICovXG4gICAgLmRhc2hib2FyZC13cmFwcGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7IGhlaWdodDogMTAwdmg7IHdpZHRoOiAxMDB2dzsgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIHBhZGRpbmc6IDE2cHg7IGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1kYXNoLWJnKTtcbiAgICAgIGNvbG9yOiB2YXIoLS1kYXNoLWZvcmUtY29sb3IpO1xuICAgICAgZm9udC1mYW1pbHk6IHZhcigtLWRhc2gtZm9udC1mYW1pbHkpO1xuICAgIH1cbiAgICAubWFpbi1jb250ZW50IHtcbiAgICAgIGZsZXg6IDE7IGRpc3BsYXk6IGZsZXg7IGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47IG92ZXJmbG93OiBoaWRkZW47XG4gICAgICBib3JkZXItcmFkaXVzOiA0MHB4OyBwYWRkaW5nOiAyMHB4O1xuICAgICAgYmFja2dyb3VuZDogdmFyKC0tZGFzaC1wYW5lbC1iZyk7XG4gICAgICBib3gtc2hhZG93OiAwIDEwcHggMzBweCByZ2JhKDAsMCwwLDAuNSk7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDAuMDUpO1xuICAgIH1cblxuICAgIC8qIOKUgOKUgCBQb3Atb3V0IGxheW91dCDilIDilIAgKi9cbiAgICAucG9wb3V0LXdyYXBwZXIge1xuICAgICAgZGlzcGxheTogZmxleDsgZmxleC1kaXJlY3Rpb246IGNvbHVtbjsgaGVpZ2h0OiAxMDB2aDsgd2lkdGg6IDEwMHZ3O1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjsgcGFkZGluZzogMTZweDsgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWRhc2gtYmcpO1xuICAgICAgY29sb3I6IHZhcigtLWRhc2gtZm9yZS1jb2xvcik7XG4gICAgICBmb250LWZhbWlseTogdmFyKC0tZGFzaC1mb250LWZhbWlseSk7XG4gICAgfVxuICAgIC5wb3BvdXQtaGVhZGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgIG1hcmdpbi1ib3R0b206IDE2cHg7IHBhZGRpbmc6IDEwcHggMThweDtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWRhc2gtcGFuZWwtYmcpOyBib3JkZXItcmFkaXVzOiAyMHB4O1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjA2KTsgZmxleC1zaHJpbms6IDA7XG4gICAgfVxuICAgIC5wb3BvdXQtdGl0bGUgeyBmb250LXNpemU6IDE2cHg7IGZvbnQtd2VpZ2h0OiA3MDA7IGNvbG9yOiAjZmZmOyB9XG4gICAgLnBvcG91dC13cmFwcGVyIC5ncmlkLWNvbnRhaW5lciB7XG4gICAgICBmbGV4OiAxOyBvdmVyZmxvdzogYXV0bzsgYm9yZGVyLXJhZGl1czogMjRweDsgbWluLWhlaWdodDogMDtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWRhc2gtcGFuZWwtYmcpOyBwYWRkaW5nOiAxNnB4O1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjA1KTtcbiAgICB9XG5cbiAgICAvKiDilIDilIAgSGVhZGVyIOKUgOKUgCAqL1xuICAgIC5kYXNoYm9hcmQtaGVhZGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgIG1hcmdpbi1ib3R0b206IDIwcHg7IGdhcDogMTJweDtcbiAgICB9XG4gICAgLnRhYnMtY29udGFpbmVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4O1xuICAgICAgYmFja2dyb3VuZDogcmdiYSg0NCw0NCw0NiwwLjYpOyBiYWNrZHJvcC1maWx0ZXI6IGJsdXIoMTBweCk7XG4gICAgICBib3JkZXItcmFkaXVzOiAyNXB4OyBwYWRkaW5nOiA2cHg7XG4gICAgfVxuICAgIC50YWIge1xuICAgICAgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA0cHg7XG4gICAgICBwYWRkaW5nOiA4cHggMTRweCA4cHggMThweDsgYm9yZGVyLXJhZGl1czogMjBweDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjsgZm9udC1zaXplOiAxNHB4OyBmb250LXdlaWdodDogNTAwO1xuICAgICAgY29sb3I6IHZhcigtLWRhc2gtZm9yZS1jb2xvcik7XG4gICAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBjdWJpYy1iZXppZXIoMC4yNSwwLjgsMC4yNSwxKTtcbiAgICB9XG4gICAgLnRhYi5hY3RpdmUgeyBiYWNrZ3JvdW5kOiAjM2EzYTNjOyBjb2xvcjogI2ZmZjsgYm94LXNoYWRvdzogMCAycHggMTBweCByZ2JhKDAsMCwwLDAuMik7IH1cbiAgICAudGFiOmhvdmVyOm5vdCguYWN0aXZlKSB7IGNvbG9yOiAjZTVlNWVhOyBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwyNTUsMjU1LDAuMDUpOyB9XG4gICAgLnRhYi1uYW1lIHsgZmxleDogMTsgd2hpdGUtc3BhY2U6IG5vd3JhcDsgfVxuICAgIC50YWItYWN0aW9uIHtcbiAgICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyBib3JkZXI6IG5vbmU7IGNvbG9yOiB2YXIoLS1kYXNoLWZvcmUtY29sb3IpO1xuICAgICAgcGFkZGluZzogMnB4OyBmb250LXNpemU6IDExcHg7IGN1cnNvcjogcG9pbnRlcjsgb3BhY2l0eTogMDsgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgICAgd2lkdGg6IDIwcHg7IGhlaWdodDogMjBweDsgZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICB0cmFuc2l0aW9uOiBhbGwgMC4yczsgZmxleC1zaHJpbms6IDA7XG4gICAgfVxuICAgIC50YWI6aG92ZXIgLnRhYi1hY3Rpb24geyBvcGFjaXR5OiAxOyB9XG4gICAgLnRhYi1wb3BvdXQ6aG92ZXIgeyBjb2xvcjogdmFyKC0tZGFzaC1hY2NlbnQtY29sb3IpOyBiYWNrZ3JvdW5kOiByZ2JhKDEwLDEzMiwyNTUsMC4xOCk7IH1cbiAgICAudGFiLWNsb3NlOmhvdmVyICB7IGNvbG9yOiB2YXIoLS1kYXNoLWRhbmdlci1jb2xvcik7IGJhY2tncm91bmQ6IHJnYmEoMjU1LDY5LDU4LDAuMik7IH1cbiAgICAuYnRuLWFkZC1wYWdlIHtcbiAgICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50OyBib3JkZXI6IG5vbmU7IGNvbG9yOiB2YXIoLS1kYXNoLWZvcmUtY29sb3IpO1xuICAgICAgcGFkZGluZzogOHB4IDE2cHg7IGN1cnNvcjogcG9pbnRlcjsgYm9yZGVyLXJhZGl1czogMjBweDsgdHJhbnNpdGlvbjogYWxsIDAuMnM7XG4gICAgfVxuICAgIC5idG4tYWRkLXBhZ2U6aG92ZXIgeyBjb2xvcjogdmFyKC0tZGFzaC1hY2NlbnQtY29sb3IpOyBiYWNrZ3JvdW5kOiByZ2JhKDEwLDEzMiwyNTUsMC4xKTsgfVxuICAgIC5idG4tYWRkLXdpZGdldCB7XG4gICAgICBkaXNwbGF5OiBmbGV4OyBhbGlnbi1pdGVtczogY2VudGVyOyBnYXA6IDZweDtcbiAgICAgIGJhY2tncm91bmQ6IHZhcigtLWRhc2gtYWNjZW50LWNvbG9yKTsgYm9yZGVyOiBub25lOyBjb2xvcjogI2ZmZjtcbiAgICAgIGZvbnQtc2l6ZTogMTRweDsgZm9udC13ZWlnaHQ6IDYwMDsgcGFkZGluZzogMTBweCAyMHB4OyBib3JkZXItcmFkaXVzOiAyMnB4O1xuICAgICAgY3Vyc29yOiBwb2ludGVyOyB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjJzLCB0cmFuc2Zvcm0gMC4xNXM7XG4gICAgICBib3gtc2hhZG93OiAwIDRweCAxNHB4IHJnYmEoMTAsMTMyLDI1NSwwLjQpO1xuICAgIH1cbiAgICAuYnRuLWFkZC13aWRnZXQ6aG92ZXIgIHsgb3BhY2l0eTogMC45OyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoLTFweCk7IH1cbiAgICAuYnRuLWFkZC13aWRnZXQ6YWN0aXZlIHsgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKDApOyB9XG5cbiAgICAvKiDilIDilIAgR3JpZCDilIDilIAgKi9cbiAgICAubWFpbi1jb250ZW50IC5ncmlkLWNvbnRhaW5lciB7IGZsZXg6IDE7IG92ZXJmbG93OiBhdXRvOyBib3JkZXItcmFkaXVzOiAyNHB4OyBtaW4taGVpZ2h0OiAwOyB9XG4gICAgYXBwLWdyaWQgeyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgZGlzcGxheTogYmxvY2s7IGhlaWdodDogMTAwJTsgd2lkdGg6IDEwMCU7IH1cbiAgYF1cbn0pXG5leHBvcnQgY2xhc3MgRGFzaGJvYXJkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIGluaXRpYWxMYXlvdXQ/OiBzdHJpbmc7XG4gIEBJbnB1dCgpIHRoZW1lPzogRGFzaGJvYXJkVGhlbWU7XG5cbiAgLyoqXG4gICAqIEVtaXRzIHdoZW4gdGhlIHVzZXIgY2xpY2tzIFwiQWRkIFdpZGdldFwiLlxuICAgKiBUaGUgY29uc3VtZXIgc2hvdWxkIG9wZW4gdGhlaXIgb3duIGRpYWxvZyBhbmQgY2FsbCBgc3RhdGVTZXJ2aWNlLmFkZFdpZGdldCguLi4pYC5cbiAgICovXG4gIEBPdXRwdXQoKSBhZGRXaWRnZXRSZXF1ZXN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBXaWRnZXQgd2hlbiB0aGUgdXNlciBjbGlja3MgdGhlIGVkaXQgKHBlbikgaWNvbiBvbiBhIGNhcmQuXG4gICAqIFRoZSBjb25zdW1lciBzaG91bGQgb3BlbiB0aGVpciBvd24gZWRpdCBVSSBhbmQgY2FsbCBgc3RhdGVTZXJ2aWNlLnVwZGF0ZVdpZGdldCguLi4pYC5cbiAgICovXG4gIEBPdXRwdXQoKSBlZGl0V2lkZ2V0UmVxdWVzdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxXaWRnZXQ+KCk7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsOiBjb25zdW1lciBjYW4gcHJvdmlkZSBhbiBgPG5nLXRlbXBsYXRlIHdpZGdldENlbGwgbGV0LXdpZGdldD1cIndpZGdldFwiPmAgY2hpbGRcbiAgICogdG8gcmVuZGVyIGN1c3RvbSBjb250ZW50IGluc2lkZSBldmVyeSBjYXJkIGJvZHkuXG4gICAqL1xuICBAQ29udGVudENoaWxkKEdyaWRDZWxsRGlyZWN0aXZlLCB7IHJlYWQ6IFRlbXBsYXRlUmVmIH0pXG4gIGNlbGxUZW1wbGF0ZT86IFRlbXBsYXRlUmVmPHsgd2lkZ2V0OiBXaWRnZXQgfT47XG5cbiAgcmVzb2x2ZWRUaGVtZTogUmVxdWlyZWQ8RGFzaGJvYXJkVGhlbWU+ID0geyAuLi5ERUZBVUxUX1RIRU1FIH07XG4gIHdyYXBwZXJTdHlsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICBwYWdlczogUGFnZVtdID0gW107XG4gIGFjdGl2ZVBhZ2VJZCA9ICcnO1xuICBhY3RpdmVQYWdlPzogUGFnZTtcbiAgaXNQb3BwZWRPdXQgPSBmYWxzZTtcblxuICBwcml2YXRlIHN1YnMgPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgY29uc3RydWN0b3IocHVibGljIHN0YXRlU2VydmljZTogRGFzaGJvYXJkU3RhdGVTZXJ2aWNlKSB7fVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlc1sndGhlbWUnXSB8fCBjaGFuZ2VzWydpbml0aWFsTGF5b3V0J10pIHRoaXMuYXBwbHlUaGVtZSgpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5hcHBseVRoZW1lKCk7XG5cbiAgICBpZiAodGhpcy5pbml0aWFsTGF5b3V0KSB7XG4gICAgICB0cnkgeyB0aGlzLnN0YXRlU2VydmljZS5sb2FkTGF5b3V0KEpTT04ucGFyc2UodGhpcy5pbml0aWFsTGF5b3V0KSk7IH1cbiAgICAgIGNhdGNoIChlKSB7IGNvbnNvbGUuZXJyb3IoJ1tEYXNoYm9hcmRdIEZhaWxlZCB0byBwYXJzZSBpbml0aWFsTGF5b3V0JywgZSk7IH1cbiAgICB9XG5cbiAgICBjb25zdCBoYXNoID0gd2luZG93LmxvY2F0aW9uLmhhc2g/LnJlcGxhY2UoJyMnLCAnJykudHJpbSgpO1xuICAgIGlmIChoYXNoKSB0aGlzLmlzUG9wcGVkT3V0ID0gdHJ1ZTtcblxuICAgIHRoaXMuc3Vicy5hZGQodGhpcy5zdGF0ZVNlcnZpY2UucGFnZXMkLnN1YnNjcmliZShwYWdlcyA9PiB7XG4gICAgICB0aGlzLnBhZ2VzID0gcGFnZXM7XG4gICAgICBpZiAodGhpcy5pc1BvcHBlZE91dCAmJiBoYXNoKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHBhZ2VzLmZpbmQocCA9PiBwLmlkID09PSBoYXNoKTtcbiAgICAgICAgaWYgKHRhcmdldCkgdGhpcy5zdGF0ZVNlcnZpY2Uuc2V0QWN0aXZlUGFnZShoYXNoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudXBkYXRlQWN0aXZlUGFnZSgpO1xuICAgIH0pKTtcbiAgICB0aGlzLnN1YnMuYWRkKHRoaXMuc3RhdGVTZXJ2aWNlLmFjdGl2ZVBhZ2VJZCQuc3Vic2NyaWJlKGlkID0+IHtcbiAgICAgIHRoaXMuYWN0aXZlUGFnZUlkID0gaWQ7XG4gICAgICB0aGlzLnVwZGF0ZUFjdGl2ZVBhZ2UoKTtcbiAgICB9KSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHsgdGhpcy5zdWJzLnVuc3Vic2NyaWJlKCk7IH1cblxuICBvbkl0ZW1DaGFuZ2VkKHdpZGdldDogV2lkZ2V0KSB7XG4gICAgdGhpcy5zdGF0ZVNlcnZpY2UudXBkYXRlV2lkZ2V0UG9zaXRpb24oXG4gICAgICB0aGlzLmFjdGl2ZVBhZ2VJZCwgd2lkZ2V0LmlkLCB3aWRnZXQueCwgd2lkZ2V0LnksIHdpZGdldC5jb2xzLCB3aWRnZXQucm93c1xuICAgICk7XG4gIH1cblxuICBvblJlbW92ZVdpZGdldCh3aWRnZXRJZDogc3RyaW5nKSB7IHRoaXMuc3RhdGVTZXJ2aWNlLnJlbW92ZVdpZGdldCh3aWRnZXRJZCk7IH1cblxuICBvblNlbGVjdFBhZ2UoaWQ6IHN0cmluZykgeyB0aGlzLnN0YXRlU2VydmljZS5zZXRBY3RpdmVQYWdlKGlkKTsgfVxuXG4gIG9uQWRkUGFnZSgpIHtcbiAgICBjb25zdCBuYW1lID0gcHJvbXB0KCdXb3Jrc3BhY2UgbmFtZTonLCBgV29ya3NwYWNlICR7dGhpcy5wYWdlcy5sZW5ndGggKyAxfWApO1xuICAgIGlmIChuYW1lKSB0aGlzLnN0YXRlU2VydmljZS5hZGRQYWdlKG5hbWUpO1xuICB9XG5cbiAgb25SZW1vdmVQYWdlKGV2ZW50OiBFdmVudCwgaWQ6IHN0cmluZykge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmIChjb25maXJtKCdSZW1vdmUgdGhpcyB3b3Jrc3BhY2U/JykpIHRoaXMuc3RhdGVTZXJ2aWNlLnJlbW92ZVBhZ2UoaWQpO1xuICB9XG5cbiAgb25Qb3BPdXQoZXZlbnQ6IEV2ZW50LCBwYWdlSWQ6IHN0cmluZykge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuc3RhdGVTZXJ2aWNlLnBvcE91dFBhZ2UocGFnZUlkKTtcbiAgfVxuXG4gIHNlcmlhbGl6ZUxheW91dCgpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5zdGF0ZVNlcnZpY2Uuc2VyaWFsaXplTGF5b3V0KCk7IH1cblxuICBwcml2YXRlIGFwcGx5VGhlbWUoKSB7XG4gICAgdGhpcy5yZXNvbHZlZFRoZW1lID0geyAuLi5ERUZBVUxUX1RIRU1FLCAuLi4odGhpcy50aGVtZSA/PyB7fSkgfTtcbiAgICB0aGlzLndyYXBwZXJTdHlsZXMgPSB7XG4gICAgICAnLS1kYXNoLWJnJzogICAgICAgICAgIHRoaXMucmVzb2x2ZWRUaGVtZS5iYWNrZ3JvdW5kQ29sb3IsXG4gICAgICAnLS1kYXNoLXBhbmVsLWJnJzogICAgIHRoaXMucmVzb2x2ZWRUaGVtZS5wYW5lbENvbG9yLFxuICAgICAgJy0tZGFzaC1jYXJkLWJnJzogICAgICB0aGlzLnJlc29sdmVkVGhlbWUud2lkZ2V0Q2FyZENvbG9yLFxuICAgICAgJy0tZGFzaC1mb3JlLWNvbG9yJzogICB0aGlzLnJlc29sdmVkVGhlbWUuZm9yZUNvbG9yLFxuICAgICAgJy0tZGFzaC1hY2NlbnQtY29sb3InOiB0aGlzLnJlc29sdmVkVGhlbWUuYWNjZW50Q29sb3IsXG4gICAgICAnLS1kYXNoLWRhbmdlci1jb2xvcic6IHRoaXMucmVzb2x2ZWRUaGVtZS5kYW5nZXJDb2xvcixcbiAgICAgICctLWRhc2gtZm9udC1mYW1pbHknOiAgdGhpcy5yZXNvbHZlZFRoZW1lLmZvbnRGYW1pbHksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlQWN0aXZlUGFnZSgpIHtcbiAgICB0aGlzLmFjdGl2ZVBhZ2UgPSB0aGlzLnBhZ2VzLmZpbmQocCA9PiBwLmlkID09PSB0aGlzLmFjdGl2ZVBhZ2VJZCk7XG4gIH1cbn1cbiJdfQ==