angular-debug-recorder 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/esm2022/angular-debug-recorder.mjs +5 -0
- package/esm2022/lib/action-list/action-list.component.mjs +220 -0
- package/esm2022/lib/debug-panel/debug-panel.component.mjs +516 -0
- package/esm2022/lib/models/recorded-action.model.mjs +2 -0
- package/esm2022/lib/services/ai-generator.service.mjs +61 -0
- package/esm2022/lib/services/recorder.service.mjs +354 -0
- package/esm2022/lib/services/rrweb-recorder.service.mjs +108 -0
- package/esm2022/lib/session-replay/session-replay.component.mjs +166 -0
- package/esm2022/lib/settings-dialog/settings-dialog.component.mjs +105 -0
- package/esm2022/lib/test-preview/test-preview.component.mjs +120 -0
- package/esm2022/public-api.mjs +17 -0
- package/fesm2022/angular-debug-recorder.mjs +1631 -0
- package/fesm2022/angular-debug-recorder.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/action-list/action-list.component.d.ts +21 -0
- package/lib/debug-panel/debug-panel.component.d.ts +38 -0
- package/lib/models/recorded-action.model.d.ts +45 -0
- package/lib/services/ai-generator.service.d.ts +20 -0
- package/lib/services/recorder.service.d.ts +46 -0
- package/lib/services/rrweb-recorder.service.d.ts +27 -0
- package/lib/session-replay/session-replay.component.d.ts +19 -0
- package/lib/settings-dialog/settings-dialog.component.d.ts +11 -0
- package/lib/test-preview/test-preview.component.d.ts +13 -0
- package/package.json +37 -0
- package/public-api.d.ts +9 -0
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
import { Component, signal, computed, inject, } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { RecorderService } from '../services/recorder.service';
|
|
5
|
+
import { AiGeneratorService } from '../services/ai-generator.service';
|
|
6
|
+
import { RrwebRecorderService } from '../services/rrweb-recorder.service';
|
|
7
|
+
import { ActionListComponent } from '../action-list/action-list.component';
|
|
8
|
+
import { TestPreviewComponent } from '../test-preview/test-preview.component';
|
|
9
|
+
import { SettingsDialogComponent } from '../settings-dialog/settings-dialog.component';
|
|
10
|
+
import { SessionReplayComponent } from '../session-replay/session-replay.component';
|
|
11
|
+
import * as i0 from "@angular/core";
|
|
12
|
+
import * as i1 from "@angular/forms";
|
|
13
|
+
export class DebugPanelComponent {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.recorder = inject(RecorderService);
|
|
16
|
+
this.aiService = inject(AiGeneratorService);
|
|
17
|
+
this.rrweb = inject(RrwebRecorderService);
|
|
18
|
+
this.panelOpen = signal(false);
|
|
19
|
+
this.activeTab = signal('actions');
|
|
20
|
+
this.position = signal('bottom-right');
|
|
21
|
+
this.panelWidth = signal(420);
|
|
22
|
+
this.showSettings = signal(false);
|
|
23
|
+
this.sessionName = '';
|
|
24
|
+
this.sessionDesc = '';
|
|
25
|
+
this.hasActions = computed(() => (this.recorder.currentSession()?.actions.length ?? 0) > 0 ||
|
|
26
|
+
(this.recorder.sessions().length > 0));
|
|
27
|
+
this.resizing = false;
|
|
28
|
+
this.resizeStartY = 0;
|
|
29
|
+
this.resizeStartH = 0;
|
|
30
|
+
this.handleHotkey = (e) => {
|
|
31
|
+
if (e.ctrlKey && e.shiftKey && e.key === 'D') {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
this.togglePanel();
|
|
34
|
+
}
|
|
35
|
+
if (e.ctrlKey && e.shiftKey && e.key === 'R') {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
if (this.recorder.isRecording()) {
|
|
38
|
+
this.stopRecording();
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.startRecording();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
ngOnInit() {
|
|
47
|
+
// Keyboard shortcut: Ctrl+Shift+D
|
|
48
|
+
document.addEventListener('keydown', this.handleHotkey);
|
|
49
|
+
}
|
|
50
|
+
ngOnDestroy() {
|
|
51
|
+
document.removeEventListener('keydown', this.handleHotkey);
|
|
52
|
+
}
|
|
53
|
+
togglePanel() {
|
|
54
|
+
this.panelOpen.update(v => !v);
|
|
55
|
+
if (this.panelOpen() && !this.recorder.currentSession()) {
|
|
56
|
+
this.activeTab.set('actions');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
cyclePosition() {
|
|
60
|
+
const positions = ['bottom-right', 'bottom-left', 'top-right', 'top-left'];
|
|
61
|
+
const idx = positions.indexOf(this.position());
|
|
62
|
+
this.position.set(positions[(idx + 1) % positions.length]);
|
|
63
|
+
}
|
|
64
|
+
startRecording() {
|
|
65
|
+
this.recorder.startRecording(this.sessionName || undefined, this.sessionDesc || undefined);
|
|
66
|
+
// Start rrweb in parallel for visual replay
|
|
67
|
+
this.rrweb.startRecording();
|
|
68
|
+
this.activeTab.set('actions');
|
|
69
|
+
}
|
|
70
|
+
stopRecording() {
|
|
71
|
+
const session = this.recorder.stopRecording();
|
|
72
|
+
this.rrweb.stopRecording();
|
|
73
|
+
if (session) {
|
|
74
|
+
this.activeTab.set('actions');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async generateTest() {
|
|
78
|
+
const session = this.recorder.currentSession() ?? this.recorder.sessions().at(-1);
|
|
79
|
+
if (!session)
|
|
80
|
+
return;
|
|
81
|
+
await this.aiService.generateCypressTest(session);
|
|
82
|
+
this.activeTab.set('test');
|
|
83
|
+
}
|
|
84
|
+
async loadAndGenerate(session) {
|
|
85
|
+
await this.aiService.generateCypressTest(session);
|
|
86
|
+
this.activeTab.set('test');
|
|
87
|
+
}
|
|
88
|
+
// Drag to reposition
|
|
89
|
+
startDrag(e) {
|
|
90
|
+
if (e.target.closest('button'))
|
|
91
|
+
return;
|
|
92
|
+
const panel = e.currentTarget.parentElement;
|
|
93
|
+
const startX = e.clientX - panel.getBoundingClientRect().left;
|
|
94
|
+
const startY = e.clientY - panel.getBoundingClientRect().top;
|
|
95
|
+
const onMove = (ev) => {
|
|
96
|
+
panel.style.left = `${ev.clientX - startX}px`;
|
|
97
|
+
panel.style.top = `${ev.clientY - startY}px`;
|
|
98
|
+
panel.style.right = 'auto';
|
|
99
|
+
panel.style.bottom = 'auto';
|
|
100
|
+
};
|
|
101
|
+
const onUp = () => {
|
|
102
|
+
document.removeEventListener('mousemove', onMove);
|
|
103
|
+
document.removeEventListener('mouseup', onUp);
|
|
104
|
+
};
|
|
105
|
+
document.addEventListener('mousemove', onMove);
|
|
106
|
+
document.addEventListener('mouseup', onUp);
|
|
107
|
+
}
|
|
108
|
+
// Resize height
|
|
109
|
+
startResize(e) {
|
|
110
|
+
const panel = e.currentTarget.parentElement;
|
|
111
|
+
this.resizeStartY = e.clientY;
|
|
112
|
+
this.resizeStartH = panel.getBoundingClientRect().height;
|
|
113
|
+
const onMove = (ev) => {
|
|
114
|
+
const newH = Math.max(250, this.resizeStartH + (ev.clientY - this.resizeStartY));
|
|
115
|
+
panel.style.maxHeight = `${newH}px`;
|
|
116
|
+
};
|
|
117
|
+
const onUp = () => {
|
|
118
|
+
document.removeEventListener('mousemove', onMove);
|
|
119
|
+
document.removeEventListener('mouseup', onUp);
|
|
120
|
+
};
|
|
121
|
+
document.addEventListener('mousemove', onMove);
|
|
122
|
+
document.addEventListener('mouseup', onUp);
|
|
123
|
+
e.preventDefault();
|
|
124
|
+
}
|
|
125
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DebugPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
126
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: DebugPanelComponent, isStandalone: true, selector: "app-debug-panel", ngImport: i0, template: `
|
|
127
|
+
<!-- Toggle FAB -->
|
|
128
|
+
<button
|
|
129
|
+
data-debug-panel
|
|
130
|
+
class="debug-fab"
|
|
131
|
+
[class.recording]="recorder.isRecording()"
|
|
132
|
+
[class.pulse]="recorder.isRecording() && !recorder.isPaused()"
|
|
133
|
+
(click)="togglePanel()"
|
|
134
|
+
[title]="panelOpen() ? 'Debug Panel schließen' : 'Debug Panel öffnen'"
|
|
135
|
+
>
|
|
136
|
+
<span class="fab-icon">{{ recorder.isRecording() ? '⏺' : '🐛' }}</span>
|
|
137
|
+
@if (recorder.isRecording() && recorder.actionCount() > 0) {
|
|
138
|
+
<span class="fab-badge">{{ recorder.actionCount() }}</span>
|
|
139
|
+
}
|
|
140
|
+
</button>
|
|
141
|
+
|
|
142
|
+
<!-- Main Panel -->
|
|
143
|
+
@if (panelOpen()) {
|
|
144
|
+
<div
|
|
145
|
+
data-debug-panel
|
|
146
|
+
class="debug-panel"
|
|
147
|
+
[class]="'pos-' + position()"
|
|
148
|
+
[style.width.px]="panelWidth()"
|
|
149
|
+
>
|
|
150
|
+
<!-- Header -->
|
|
151
|
+
<div class="panel-header" (mousedown)="startDrag($event)">
|
|
152
|
+
<div class="header-left">
|
|
153
|
+
<span class="panel-icon">🐛</span>
|
|
154
|
+
<span class="panel-title">Debug Recorder</span>
|
|
155
|
+
@if (recorder.isRecording()) {
|
|
156
|
+
<span class="rec-indicator" [class.paused]="recorder.isPaused()">
|
|
157
|
+
{{ recorder.isPaused() ? '⏸ PAUSED' : '⏺ REC' }}
|
|
158
|
+
</span>
|
|
159
|
+
}
|
|
160
|
+
</div>
|
|
161
|
+
<div class="header-actions">
|
|
162
|
+
<button class="icon-btn" title="Einstellungen" (click)="showSettings.set(true)">⚙️</button>
|
|
163
|
+
<button class="icon-btn" title="Position wechseln" (click)="cyclePosition()">📌</button>
|
|
164
|
+
<button class="icon-btn" title="Schließen" (click)="togglePanel()">✕</button>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<!-- Session Name Input (only when not recording) -->
|
|
169
|
+
@if (!recorder.isRecording()) {
|
|
170
|
+
<div class="session-setup">
|
|
171
|
+
<input
|
|
172
|
+
data-debug-panel
|
|
173
|
+
class="session-input"
|
|
174
|
+
type="text"
|
|
175
|
+
[(ngModel)]="sessionName"
|
|
176
|
+
placeholder="Session-Name (optional)"
|
|
177
|
+
/>
|
|
178
|
+
<textarea
|
|
179
|
+
data-debug-panel
|
|
180
|
+
class="session-desc"
|
|
181
|
+
[(ngModel)]="sessionDesc"
|
|
182
|
+
placeholder="Fehlerbeschreibung..."
|
|
183
|
+
rows="2"
|
|
184
|
+
></textarea>
|
|
185
|
+
</div>
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
<!-- Recording Controls -->
|
|
189
|
+
<div class="recording-controls" data-debug-panel>
|
|
190
|
+
@if (!recorder.isRecording()) {
|
|
191
|
+
<button class="ctrl-btn start" (click)="startRecording()">
|
|
192
|
+
▶ Aufnahme starten
|
|
193
|
+
</button>
|
|
194
|
+
} @else {
|
|
195
|
+
<button class="ctrl-btn pause" (click)="recorder.pauseRecording()">
|
|
196
|
+
{{ recorder.isPaused() ? '▶ Fortsetzen' : '⏸ Pause' }}
|
|
197
|
+
</button>
|
|
198
|
+
<button class="ctrl-btn stop" (click)="stopRecording()">
|
|
199
|
+
⏹ Stoppen
|
|
200
|
+
</button>
|
|
201
|
+
<button class="ctrl-btn clear" title="Aktionen löschen" (click)="recorder.clearCurrentSession()">
|
|
202
|
+
🗑
|
|
203
|
+
</button>
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@if (hasActions()) {
|
|
207
|
+
<button
|
|
208
|
+
class="ctrl-btn generate"
|
|
209
|
+
[disabled]="aiService.isGenerating() || !aiService.webhookUrl()"
|
|
210
|
+
[title]="!aiService.webhookUrl() ? 'Webhook-URL in Einstellungen eintragen' : 'Cypress Test generieren'"
|
|
211
|
+
(click)="generateTest()"
|
|
212
|
+
>
|
|
213
|
+
@if (aiService.isGenerating()) {
|
|
214
|
+
<span class="spinner">⟳</span> Generiere...
|
|
215
|
+
} @else {
|
|
216
|
+
🤖 → Cypress Test
|
|
217
|
+
}
|
|
218
|
+
</button>
|
|
219
|
+
}
|
|
220
|
+
</div>
|
|
221
|
+
|
|
222
|
+
<!-- Error Banner -->
|
|
223
|
+
@if (aiService.error()) {
|
|
224
|
+
<div class="error-banner" data-debug-panel>
|
|
225
|
+
⚠️ {{ aiService.error() }}
|
|
226
|
+
</div>
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
<!-- Tabs -->
|
|
230
|
+
<div class="tab-bar" data-debug-panel>
|
|
231
|
+
<button
|
|
232
|
+
class="tab-btn"
|
|
233
|
+
[class.active]="activeTab() === 'actions'"
|
|
234
|
+
(click)="activeTab.set('actions')"
|
|
235
|
+
>
|
|
236
|
+
Aktionen
|
|
237
|
+
@if (recorder.actionCount() > 0) {
|
|
238
|
+
<span class="tab-badge">{{ recorder.actionCount() }}</span>
|
|
239
|
+
}
|
|
240
|
+
</button>
|
|
241
|
+
<button
|
|
242
|
+
class="tab-btn"
|
|
243
|
+
[class.active]="activeTab() === 'replay'"
|
|
244
|
+
(click)="activeTab.set('replay')"
|
|
245
|
+
title="rrweb Session Replay"
|
|
246
|
+
>
|
|
247
|
+
📽️ Replay
|
|
248
|
+
@if (rrweb.events().length > 0) {
|
|
249
|
+
<span class="tab-badge">{{ rrweb.events().length }}</span>
|
|
250
|
+
}
|
|
251
|
+
</button>
|
|
252
|
+
<button
|
|
253
|
+
class="tab-btn"
|
|
254
|
+
[class.active]="activeTab() === 'test'"
|
|
255
|
+
[disabled]="!aiService.lastTest()"
|
|
256
|
+
(click)="activeTab.set('test')"
|
|
257
|
+
>
|
|
258
|
+
🤖 Test
|
|
259
|
+
@if (aiService.lastTest()) {
|
|
260
|
+
<span class="tab-badge new">NEU</span>
|
|
261
|
+
}
|
|
262
|
+
</button>
|
|
263
|
+
<button
|
|
264
|
+
class="tab-btn"
|
|
265
|
+
[class.active]="activeTab() === 'sessions'"
|
|
266
|
+
[disabled]="recorder.sessions().length === 0"
|
|
267
|
+
(click)="activeTab.set('sessions')"
|
|
268
|
+
>
|
|
269
|
+
Sessions ({{ recorder.sessions().length }})
|
|
270
|
+
</button>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<!-- Tab Content -->
|
|
274
|
+
<div class="tab-content">
|
|
275
|
+
@if (activeTab() === 'actions') {
|
|
276
|
+
<app-action-list
|
|
277
|
+
[session]="recorder.currentSession()"
|
|
278
|
+
(removeAction)="recorder.removeAction($event)"
|
|
279
|
+
(addNote)="recorder.addNote($event.id, $event.note)"
|
|
280
|
+
/>
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
@if (activeTab() === 'replay') {
|
|
284
|
+
<app-session-replay />
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
@if (activeTab() === 'test') {
|
|
288
|
+
<app-test-preview [test]="aiService.lastTest()" />
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
@if (activeTab() === 'sessions') {
|
|
292
|
+
<div class="sessions-list">
|
|
293
|
+
@for (session of recorder.sessions(); track session.id) {
|
|
294
|
+
<div class="session-card">
|
|
295
|
+
<div class="session-card-header">
|
|
296
|
+
<span class="session-name">{{ session.name }}</span>
|
|
297
|
+
<span class="session-meta">{{ session.actions.length }} Aktionen</span>
|
|
298
|
+
</div>
|
|
299
|
+
<div class="session-card-actions">
|
|
300
|
+
<button class="sm-btn" (click)="loadAndGenerate(session)">🤖 Neu generieren</button>
|
|
301
|
+
<button class="sm-btn danger" (click)="recorder.deleteSession(session.id)">🗑</button>
|
|
302
|
+
</div>
|
|
303
|
+
</div>
|
|
304
|
+
}
|
|
305
|
+
</div>
|
|
306
|
+
}
|
|
307
|
+
</div>
|
|
308
|
+
|
|
309
|
+
<!-- Resize Handle -->
|
|
310
|
+
<div class="resize-handle" (mousedown)="startResize($event)">⠿</div>
|
|
311
|
+
</div>
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
<!-- Settings Dialog -->
|
|
315
|
+
@if (showSettings()) {
|
|
316
|
+
<app-settings-dialog (close)="showSettings.set(false)" />
|
|
317
|
+
}
|
|
318
|
+
`, isInline: true, styles: [".debug-fab{bottom:24px;right:24px;z-index:99999;width:52px;height:52px;border-radius:50%;border:none;background:#1e293b;color:#fff;font-size:22px;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 20px #0006;transition:transform .2s,background .2s;position:fixed}.debug-fab:hover{transform:scale(1.1);background:#334155}.debug-fab.recording{background:#dc2626}.debug-fab.pulse{animation:fabPulse 1.5s ease-in-out infinite}@keyframes fabPulse{0%,to{box-shadow:0 4px 20px #dc262666}50%{box-shadow:0 4px 30px #dc2626e6,0 0 0 8px #dc262626}}.fab-badge{position:absolute;top:-4px;right:-4px;background:#f59e0b;color:#000;font-size:10px;font-weight:700;min-width:18px;height:18px;border-radius:9px;display:flex;align-items:center;justify-content:center;padding:0 4px}.debug-panel{position:fixed;z-index:99998;width:420px;max-height:80vh;background:#0f172a;color:#e2e8f0;border-radius:12px;border:1px solid #1e3a5f;box-shadow:0 25px 60px #0009;display:flex;flex-direction:column;font-family:Segoe UI,system-ui,sans-serif;font-size:13px;overflow:hidden}.pos-bottom-right{bottom:88px;right:24px}.pos-bottom-left{bottom:88px;left:24px}.pos-top-right{top:24px;right:24px}.pos-top-left{top:24px;left:24px}.panel-header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:#1e293b;border-bottom:1px solid #334155;cursor:move;-webkit-user-select:none;user-select:none;flex-shrink:0}.header-left{display:flex;align-items:center;gap:8px}.panel-icon{font-size:16px}.panel-title{font-weight:600;font-size:14px;color:#f1f5f9}.rec-indicator{font-size:10px;font-weight:700;color:#ef4444;background:#ef444426;padding:2px 7px;border-radius:4px;animation:blink 1s step-end infinite}.rec-indicator.paused{color:#f59e0b;background:#f59e0b26;animation:none}@keyframes blink{50%{opacity:.4}}.header-actions{display:flex;gap:4px}.icon-btn{background:none;border:none;color:#94a3b8;cursor:pointer;padding:4px;border-radius:4px;font-size:14px;line-height:1;transition:color .15s,background .15s}.icon-btn:hover{color:#f1f5f9;background:#334155}.session-setup{padding:10px 14px;border-bottom:1px solid #1e293b;display:flex;flex-direction:column;gap:6px;flex-shrink:0}.session-input,.session-desc{background:#1e293b;border:1px solid #334155;color:#e2e8f0;border-radius:6px;padding:6px 10px;font-size:12px;width:100%;box-sizing:border-box;resize:vertical}.session-input:focus,.session-desc:focus{outline:none;border-color:#3b82f6}.recording-controls{display:flex;gap:6px;padding:10px 14px;border-bottom:1px solid #1e293b;flex-wrap:wrap;flex-shrink:0}.ctrl-btn{border:none;border-radius:6px;padding:6px 14px;font-size:12px;font-weight:600;cursor:pointer;transition:filter .15s,transform .1s;display:flex;align-items:center;gap:5px}.ctrl-btn:hover:not(:disabled){filter:brightness(1.15);transform:translateY(-1px)}.ctrl-btn:active:not(:disabled){transform:translateY(0)}.ctrl-btn:disabled{opacity:.5;cursor:not-allowed}.ctrl-btn.start{background:#16a34a;color:#fff}.ctrl-btn.stop{background:#dc2626;color:#fff}.ctrl-btn.pause{background:#d97706;color:#fff}.ctrl-btn.generate{background:#7c3aed;color:#fff;flex:1;justify-content:center}.ctrl-btn.clear{background:#374151;color:#9ca3af;padding:6px 10px}.spinner{display:inline-block;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.error-banner{background:#dc262626;border-left:3px solid #dc2626;color:#fca5a5;padding:8px 14px;font-size:12px;flex-shrink:0}.tab-bar{display:flex;border-bottom:1px solid #1e293b;flex-shrink:0}.tab-btn{flex:1;background:none;border:none;color:#64748b;padding:8px 4px;font-size:12px;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:5px;border-bottom:2px solid transparent;transition:color .15s}.tab-btn:hover:not(:disabled){color:#cbd5e1}.tab-btn.active{color:#60a5fa;border-bottom-color:#3b82f6}.tab-btn:disabled{opacity:.4;cursor:not-allowed}.tab-badge{background:#334155;color:#94a3b8;font-size:10px;padding:1px 5px;border-radius:3px}.tab-badge.new{background:#7c3aed;color:#e9d5ff}.tab-content{overflow-y:auto;flex:1;min-height:0}.tab-content::-webkit-scrollbar{width:5px}.tab-content::-webkit-scrollbar-track{background:transparent}.tab-content::-webkit-scrollbar-thumb{background:#334155;border-radius:3px}.sessions-list{padding:10px 14px;display:flex;flex-direction:column;gap:8px}.session-card{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:10px}.session-card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.session-name{font-weight:600;color:#f1f5f9;font-size:13px}.session-meta{font-size:11px;color:#64748b}.session-card-actions{display:flex;gap:6px}.sm-btn{background:#334155;border:none;color:#cbd5e1;padding:4px 10px;border-radius:5px;font-size:11px;cursor:pointer;transition:background .15s}.sm-btn:hover{background:#475569}.sm-btn.danger{color:#fca5a5}.sm-btn.danger:hover{background:#dc262633}.resize-handle{text-align:center;color:#334155;cursor:ns-resize;font-size:16px;padding:2px;flex-shrink:0;background:#0f172a;-webkit-user-select:none;user-select:none}.resize-handle:hover{color:#64748b}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ActionListComponent, selector: "app-action-list", inputs: ["session"], outputs: ["removeAction", "addNote"] }, { kind: "component", type: TestPreviewComponent, selector: "app-test-preview", inputs: ["test"] }, { kind: "component", type: SettingsDialogComponent, selector: "app-settings-dialog", outputs: ["close"] }, { kind: "component", type: SessionReplayComponent, selector: "app-session-replay" }] }); }
|
|
319
|
+
}
|
|
320
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DebugPanelComponent, decorators: [{
|
|
321
|
+
type: Component,
|
|
322
|
+
args: [{ selector: 'app-debug-panel', standalone: true, imports: [CommonModule, FormsModule, ActionListComponent, TestPreviewComponent, SettingsDialogComponent, SessionReplayComponent], template: `
|
|
323
|
+
<!-- Toggle FAB -->
|
|
324
|
+
<button
|
|
325
|
+
data-debug-panel
|
|
326
|
+
class="debug-fab"
|
|
327
|
+
[class.recording]="recorder.isRecording()"
|
|
328
|
+
[class.pulse]="recorder.isRecording() && !recorder.isPaused()"
|
|
329
|
+
(click)="togglePanel()"
|
|
330
|
+
[title]="panelOpen() ? 'Debug Panel schließen' : 'Debug Panel öffnen'"
|
|
331
|
+
>
|
|
332
|
+
<span class="fab-icon">{{ recorder.isRecording() ? '⏺' : '🐛' }}</span>
|
|
333
|
+
@if (recorder.isRecording() && recorder.actionCount() > 0) {
|
|
334
|
+
<span class="fab-badge">{{ recorder.actionCount() }}</span>
|
|
335
|
+
}
|
|
336
|
+
</button>
|
|
337
|
+
|
|
338
|
+
<!-- Main Panel -->
|
|
339
|
+
@if (panelOpen()) {
|
|
340
|
+
<div
|
|
341
|
+
data-debug-panel
|
|
342
|
+
class="debug-panel"
|
|
343
|
+
[class]="'pos-' + position()"
|
|
344
|
+
[style.width.px]="panelWidth()"
|
|
345
|
+
>
|
|
346
|
+
<!-- Header -->
|
|
347
|
+
<div class="panel-header" (mousedown)="startDrag($event)">
|
|
348
|
+
<div class="header-left">
|
|
349
|
+
<span class="panel-icon">🐛</span>
|
|
350
|
+
<span class="panel-title">Debug Recorder</span>
|
|
351
|
+
@if (recorder.isRecording()) {
|
|
352
|
+
<span class="rec-indicator" [class.paused]="recorder.isPaused()">
|
|
353
|
+
{{ recorder.isPaused() ? '⏸ PAUSED' : '⏺ REC' }}
|
|
354
|
+
</span>
|
|
355
|
+
}
|
|
356
|
+
</div>
|
|
357
|
+
<div class="header-actions">
|
|
358
|
+
<button class="icon-btn" title="Einstellungen" (click)="showSettings.set(true)">⚙️</button>
|
|
359
|
+
<button class="icon-btn" title="Position wechseln" (click)="cyclePosition()">📌</button>
|
|
360
|
+
<button class="icon-btn" title="Schließen" (click)="togglePanel()">✕</button>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
|
|
364
|
+
<!-- Session Name Input (only when not recording) -->
|
|
365
|
+
@if (!recorder.isRecording()) {
|
|
366
|
+
<div class="session-setup">
|
|
367
|
+
<input
|
|
368
|
+
data-debug-panel
|
|
369
|
+
class="session-input"
|
|
370
|
+
type="text"
|
|
371
|
+
[(ngModel)]="sessionName"
|
|
372
|
+
placeholder="Session-Name (optional)"
|
|
373
|
+
/>
|
|
374
|
+
<textarea
|
|
375
|
+
data-debug-panel
|
|
376
|
+
class="session-desc"
|
|
377
|
+
[(ngModel)]="sessionDesc"
|
|
378
|
+
placeholder="Fehlerbeschreibung..."
|
|
379
|
+
rows="2"
|
|
380
|
+
></textarea>
|
|
381
|
+
</div>
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
<!-- Recording Controls -->
|
|
385
|
+
<div class="recording-controls" data-debug-panel>
|
|
386
|
+
@if (!recorder.isRecording()) {
|
|
387
|
+
<button class="ctrl-btn start" (click)="startRecording()">
|
|
388
|
+
▶ Aufnahme starten
|
|
389
|
+
</button>
|
|
390
|
+
} @else {
|
|
391
|
+
<button class="ctrl-btn pause" (click)="recorder.pauseRecording()">
|
|
392
|
+
{{ recorder.isPaused() ? '▶ Fortsetzen' : '⏸ Pause' }}
|
|
393
|
+
</button>
|
|
394
|
+
<button class="ctrl-btn stop" (click)="stopRecording()">
|
|
395
|
+
⏹ Stoppen
|
|
396
|
+
</button>
|
|
397
|
+
<button class="ctrl-btn clear" title="Aktionen löschen" (click)="recorder.clearCurrentSession()">
|
|
398
|
+
🗑
|
|
399
|
+
</button>
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
@if (hasActions()) {
|
|
403
|
+
<button
|
|
404
|
+
class="ctrl-btn generate"
|
|
405
|
+
[disabled]="aiService.isGenerating() || !aiService.webhookUrl()"
|
|
406
|
+
[title]="!aiService.webhookUrl() ? 'Webhook-URL in Einstellungen eintragen' : 'Cypress Test generieren'"
|
|
407
|
+
(click)="generateTest()"
|
|
408
|
+
>
|
|
409
|
+
@if (aiService.isGenerating()) {
|
|
410
|
+
<span class="spinner">⟳</span> Generiere...
|
|
411
|
+
} @else {
|
|
412
|
+
🤖 → Cypress Test
|
|
413
|
+
}
|
|
414
|
+
</button>
|
|
415
|
+
}
|
|
416
|
+
</div>
|
|
417
|
+
|
|
418
|
+
<!-- Error Banner -->
|
|
419
|
+
@if (aiService.error()) {
|
|
420
|
+
<div class="error-banner" data-debug-panel>
|
|
421
|
+
⚠️ {{ aiService.error() }}
|
|
422
|
+
</div>
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
<!-- Tabs -->
|
|
426
|
+
<div class="tab-bar" data-debug-panel>
|
|
427
|
+
<button
|
|
428
|
+
class="tab-btn"
|
|
429
|
+
[class.active]="activeTab() === 'actions'"
|
|
430
|
+
(click)="activeTab.set('actions')"
|
|
431
|
+
>
|
|
432
|
+
Aktionen
|
|
433
|
+
@if (recorder.actionCount() > 0) {
|
|
434
|
+
<span class="tab-badge">{{ recorder.actionCount() }}</span>
|
|
435
|
+
}
|
|
436
|
+
</button>
|
|
437
|
+
<button
|
|
438
|
+
class="tab-btn"
|
|
439
|
+
[class.active]="activeTab() === 'replay'"
|
|
440
|
+
(click)="activeTab.set('replay')"
|
|
441
|
+
title="rrweb Session Replay"
|
|
442
|
+
>
|
|
443
|
+
📽️ Replay
|
|
444
|
+
@if (rrweb.events().length > 0) {
|
|
445
|
+
<span class="tab-badge">{{ rrweb.events().length }}</span>
|
|
446
|
+
}
|
|
447
|
+
</button>
|
|
448
|
+
<button
|
|
449
|
+
class="tab-btn"
|
|
450
|
+
[class.active]="activeTab() === 'test'"
|
|
451
|
+
[disabled]="!aiService.lastTest()"
|
|
452
|
+
(click)="activeTab.set('test')"
|
|
453
|
+
>
|
|
454
|
+
🤖 Test
|
|
455
|
+
@if (aiService.lastTest()) {
|
|
456
|
+
<span class="tab-badge new">NEU</span>
|
|
457
|
+
}
|
|
458
|
+
</button>
|
|
459
|
+
<button
|
|
460
|
+
class="tab-btn"
|
|
461
|
+
[class.active]="activeTab() === 'sessions'"
|
|
462
|
+
[disabled]="recorder.sessions().length === 0"
|
|
463
|
+
(click)="activeTab.set('sessions')"
|
|
464
|
+
>
|
|
465
|
+
Sessions ({{ recorder.sessions().length }})
|
|
466
|
+
</button>
|
|
467
|
+
</div>
|
|
468
|
+
|
|
469
|
+
<!-- Tab Content -->
|
|
470
|
+
<div class="tab-content">
|
|
471
|
+
@if (activeTab() === 'actions') {
|
|
472
|
+
<app-action-list
|
|
473
|
+
[session]="recorder.currentSession()"
|
|
474
|
+
(removeAction)="recorder.removeAction($event)"
|
|
475
|
+
(addNote)="recorder.addNote($event.id, $event.note)"
|
|
476
|
+
/>
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
@if (activeTab() === 'replay') {
|
|
480
|
+
<app-session-replay />
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
@if (activeTab() === 'test') {
|
|
484
|
+
<app-test-preview [test]="aiService.lastTest()" />
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
@if (activeTab() === 'sessions') {
|
|
488
|
+
<div class="sessions-list">
|
|
489
|
+
@for (session of recorder.sessions(); track session.id) {
|
|
490
|
+
<div class="session-card">
|
|
491
|
+
<div class="session-card-header">
|
|
492
|
+
<span class="session-name">{{ session.name }}</span>
|
|
493
|
+
<span class="session-meta">{{ session.actions.length }} Aktionen</span>
|
|
494
|
+
</div>
|
|
495
|
+
<div class="session-card-actions">
|
|
496
|
+
<button class="sm-btn" (click)="loadAndGenerate(session)">🤖 Neu generieren</button>
|
|
497
|
+
<button class="sm-btn danger" (click)="recorder.deleteSession(session.id)">🗑</button>
|
|
498
|
+
</div>
|
|
499
|
+
</div>
|
|
500
|
+
}
|
|
501
|
+
</div>
|
|
502
|
+
}
|
|
503
|
+
</div>
|
|
504
|
+
|
|
505
|
+
<!-- Resize Handle -->
|
|
506
|
+
<div class="resize-handle" (mousedown)="startResize($event)">⠿</div>
|
|
507
|
+
</div>
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
<!-- Settings Dialog -->
|
|
511
|
+
@if (showSettings()) {
|
|
512
|
+
<app-settings-dialog (close)="showSettings.set(false)" />
|
|
513
|
+
}
|
|
514
|
+
`, styles: [".debug-fab{bottom:24px;right:24px;z-index:99999;width:52px;height:52px;border-radius:50%;border:none;background:#1e293b;color:#fff;font-size:22px;cursor:pointer;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 20px #0006;transition:transform .2s,background .2s;position:fixed}.debug-fab:hover{transform:scale(1.1);background:#334155}.debug-fab.recording{background:#dc2626}.debug-fab.pulse{animation:fabPulse 1.5s ease-in-out infinite}@keyframes fabPulse{0%,to{box-shadow:0 4px 20px #dc262666}50%{box-shadow:0 4px 30px #dc2626e6,0 0 0 8px #dc262626}}.fab-badge{position:absolute;top:-4px;right:-4px;background:#f59e0b;color:#000;font-size:10px;font-weight:700;min-width:18px;height:18px;border-radius:9px;display:flex;align-items:center;justify-content:center;padding:0 4px}.debug-panel{position:fixed;z-index:99998;width:420px;max-height:80vh;background:#0f172a;color:#e2e8f0;border-radius:12px;border:1px solid #1e3a5f;box-shadow:0 25px 60px #0009;display:flex;flex-direction:column;font-family:Segoe UI,system-ui,sans-serif;font-size:13px;overflow:hidden}.pos-bottom-right{bottom:88px;right:24px}.pos-bottom-left{bottom:88px;left:24px}.pos-top-right{top:24px;right:24px}.pos-top-left{top:24px;left:24px}.panel-header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;background:#1e293b;border-bottom:1px solid #334155;cursor:move;-webkit-user-select:none;user-select:none;flex-shrink:0}.header-left{display:flex;align-items:center;gap:8px}.panel-icon{font-size:16px}.panel-title{font-weight:600;font-size:14px;color:#f1f5f9}.rec-indicator{font-size:10px;font-weight:700;color:#ef4444;background:#ef444426;padding:2px 7px;border-radius:4px;animation:blink 1s step-end infinite}.rec-indicator.paused{color:#f59e0b;background:#f59e0b26;animation:none}@keyframes blink{50%{opacity:.4}}.header-actions{display:flex;gap:4px}.icon-btn{background:none;border:none;color:#94a3b8;cursor:pointer;padding:4px;border-radius:4px;font-size:14px;line-height:1;transition:color .15s,background .15s}.icon-btn:hover{color:#f1f5f9;background:#334155}.session-setup{padding:10px 14px;border-bottom:1px solid #1e293b;display:flex;flex-direction:column;gap:6px;flex-shrink:0}.session-input,.session-desc{background:#1e293b;border:1px solid #334155;color:#e2e8f0;border-radius:6px;padding:6px 10px;font-size:12px;width:100%;box-sizing:border-box;resize:vertical}.session-input:focus,.session-desc:focus{outline:none;border-color:#3b82f6}.recording-controls{display:flex;gap:6px;padding:10px 14px;border-bottom:1px solid #1e293b;flex-wrap:wrap;flex-shrink:0}.ctrl-btn{border:none;border-radius:6px;padding:6px 14px;font-size:12px;font-weight:600;cursor:pointer;transition:filter .15s,transform .1s;display:flex;align-items:center;gap:5px}.ctrl-btn:hover:not(:disabled){filter:brightness(1.15);transform:translateY(-1px)}.ctrl-btn:active:not(:disabled){transform:translateY(0)}.ctrl-btn:disabled{opacity:.5;cursor:not-allowed}.ctrl-btn.start{background:#16a34a;color:#fff}.ctrl-btn.stop{background:#dc2626;color:#fff}.ctrl-btn.pause{background:#d97706;color:#fff}.ctrl-btn.generate{background:#7c3aed;color:#fff;flex:1;justify-content:center}.ctrl-btn.clear{background:#374151;color:#9ca3af;padding:6px 10px}.spinner{display:inline-block;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.error-banner{background:#dc262626;border-left:3px solid #dc2626;color:#fca5a5;padding:8px 14px;font-size:12px;flex-shrink:0}.tab-bar{display:flex;border-bottom:1px solid #1e293b;flex-shrink:0}.tab-btn{flex:1;background:none;border:none;color:#64748b;padding:8px 4px;font-size:12px;cursor:pointer;display:flex;align-items:center;justify-content:center;gap:5px;border-bottom:2px solid transparent;transition:color .15s}.tab-btn:hover:not(:disabled){color:#cbd5e1}.tab-btn.active{color:#60a5fa;border-bottom-color:#3b82f6}.tab-btn:disabled{opacity:.4;cursor:not-allowed}.tab-badge{background:#334155;color:#94a3b8;font-size:10px;padding:1px 5px;border-radius:3px}.tab-badge.new{background:#7c3aed;color:#e9d5ff}.tab-content{overflow-y:auto;flex:1;min-height:0}.tab-content::-webkit-scrollbar{width:5px}.tab-content::-webkit-scrollbar-track{background:transparent}.tab-content::-webkit-scrollbar-thumb{background:#334155;border-radius:3px}.sessions-list{padding:10px 14px;display:flex;flex-direction:column;gap:8px}.session-card{background:#1e293b;border:1px solid #334155;border-radius:8px;padding:10px}.session-card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.session-name{font-weight:600;color:#f1f5f9;font-size:13px}.session-meta{font-size:11px;color:#64748b}.session-card-actions{display:flex;gap:6px}.sm-btn{background:#334155;border:none;color:#cbd5e1;padding:4px 10px;border-radius:5px;font-size:11px;cursor:pointer;transition:background .15s}.sm-btn:hover{background:#475569}.sm-btn.danger{color:#fca5a5}.sm-btn.danger:hover{background:#dc262633}.resize-handle{text-align:center;color:#334155;cursor:ns-resize;font-size:16px;padding:2px;flex-shrink:0;background:#0f172a;-webkit-user-select:none;user-select:none}.resize-handle:hover{color:#64748b}\n"] }]
|
|
515
|
+
}] });
|
|
516
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVidWctcGFuZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVidWctcmVjb3JkZXIvc3JjL2xpYi9kZWJ1Zy1wYW5lbC9kZWJ1Zy1wYW5lbC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sR0FDcEMsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDL0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFMUUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDM0UsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFDOUUsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDdkYsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNENBQTRDLENBQUM7OztBQXVjcEYsTUFBTSxPQUFPLG1CQUFtQjtJQWxjaEM7UUFtY0UsYUFBUSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNuQyxjQUFTLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDdkMsVUFBSyxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO1FBRXJDLGNBQVMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDMUIsY0FBUyxHQUFHLE1BQU0sQ0FBVyxTQUFTLENBQUMsQ0FBQztRQUN4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QVcsRUFBRSxtQkFBbUIsRUFBRSxvQkFBb0IsRUFBRSx1QkFBdUIsRUFBRSxzQkFBc0IsQ0FBQyxZQUN0SDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ01UIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LCBzaWduYWwsIGNvbXB1dGVkLCBpbmplY3QsIE9uSW5pdCwgT25EZXN0cm95LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFJlY29yZGVyU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL3JlY29yZGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgQWlHZW5lcmF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvYWktZ2VuZXJhdG9yLnNlcnZpY2UnO1xuaW1wb3J0IHsgUnJ3ZWJSZWNvcmRlclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9ycndlYi1yZWNvcmRlci5zZXJ2aWNlJztcbmltcG9ydCB7IFJlY29yZGluZ1Nlc3Npb24gfSBmcm9tICcuLi9tb2RlbHMvcmVjb3JkZWQtYWN0aW9uLm1vZGVsJztcbmltcG9ydCB7IEFjdGlvbkxpc3RDb21wb25lbnQgfSBmcm9tICcuLi9hY3Rpb24tbGlzdC9hY3Rpb24tbGlzdC5jb21wb25lbnQnO1xuaW1wb3J0IHsgVGVzdFByZXZpZXdDb21wb25lbnQgfSBmcm9tICcuLi90ZXN0LXByZXZpZXcvdGVzdC1wcmV2aWV3LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTZXR0aW5nc0RpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4uL3NldHRpbmdzLWRpYWxvZy9zZXR0aW5ncy1kaWFsb2cuY29tcG9uZW50JztcbmltcG9ydCB7IFNlc3Npb25SZXBsYXlDb21wb25lbnQgfSBmcm9tICcuLi9zZXNzaW9uLXJlcGxheS9zZXNzaW9uLXJlcGxheS5jb21wb25lbnQnO1xuXG50eXBlIFBhbmVsVGFiID0gJ2FjdGlvbnMnIHwgJ3Rlc3QnIHwgJ3Nlc3Npb25zJyB8ICdyZXBsYXknO1xudHlwZSBQYW5lbFBvc2l0aW9uID0gJ2JvdHRvbS1yaWdodCcgfCAnYm90dG9tLWxlZnQnIHwgJ3RvcC1yaWdodCcgfCAndG9wLWxlZnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdhcHAtZGVidWctcGFuZWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgQWN0aW9uTGlzdENvbXBvbmVudCwgVGVzdFByZXZpZXdDb21wb25lbnQsIFNldHRpbmdzRGlhbG9nQ29tcG9uZW50LCBTZXNzaW9uUmVwbGF5Q29tcG9uZW50XSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8IS0tIFRvZ2dsZSBGQUIgLS0+XG4gICAgPGJ1dHRvblxuICAgICAgZGF0YS1kZWJ1Zy1wYW5lbFxuICAgICAgY2xhc3M9XCJkZWJ1Zy1mYWJcIlxuICAgICAgW2NsYXNzLnJlY29yZGluZ109XCJyZWNvcmRlci5pc1JlY29yZGluZygpXCJcbiAgICAgIFtjbGFzcy5wdWxzZV09XCJyZWNvcmRlci5pc1JlY29yZGluZygpICYmICFyZWNvcmRlci5pc1BhdXNlZCgpXCJcbiAgICAgIChjbGljayk9XCJ0b2dnbGVQYW5lbCgpXCJcbiAgICAgIFt0aXRsZV09XCJwYW5lbE9wZW4oKSA/ICdEZWJ1ZyBQYW5lbCBzY2hsaWXDn2VuJyA6ICdEZWJ1ZyBQYW5lbCDDtmZmbmVuJ1wiXG4gICAgPlxuICAgICAgPHNwYW4gY2xhc3M9XCJmYWItaWNvblwiPnt7IHJlY29yZGVyLmlzUmVjb3JkaW5nKCkgPyAn4o+6JyA6ICfwn5CbJyB9fTwvc3Bhbj5cbiAgICAgIEBpZiAocmVjb3JkZXIuaXNSZWNvcmRpbmcoKSAmJiByZWNvcmRlci5hY3Rpb25Db3VudCgpID4gMCkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cImZhYi1iYWRnZVwiPnt7IHJlY29yZGVyLmFjdGlvbkNvdW50KCkgfX08L3NwYW4+XG4gICAgICB9XG4gICAgPC9idXR0b24+XG5cbiAgICA8IS0tIE1haW4gUGFuZWwgLS0+XG4gICAgQGlmIChwYW5lbE9wZW4oKSkge1xuICAgICAgPGRpdlxuICAgICAgICBkYXRhLWRlYnVnLXBhbmVsXG4gICAgICAgIGNsYXNzPVwiZGVidWctcGFuZWxcIlxuICAgICAgICBbY2xhc3NdPVwiJ3Bvcy0nICsgcG9zaXRpb24oKVwiXG4gICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJwYW5lbFdpZHRoKClcIlxuICAgICAgPlxuICAgICAgICA8IS0tIEhlYWRlciAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBhbmVsLWhlYWRlclwiIChtb3VzZWRvd24pPVwic3RhcnREcmFnKCRldmVudClcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyLWxlZnRcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGFuZWwtaWNvblwiPvCfkJs8L3NwYW4+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBhbmVsLXRpdGxlXCI+RGVidWcgUmVjb3JkZXI8L3NwYW4+XG4gICAgICAgICAgICBAaWYgKHJlY29yZGVyLmlzUmVjb3JkaW5nKCkpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJyZWMtaW5kaWNhdG9yXCIgW2NsYXNzLnBhdXNlZF09XCJyZWNvcmRlci5pc1BhdXNlZCgpXCI+XG4gICAgICAgICAgICAgICAge3sgcmVjb3JkZXIuaXNQYXVzZWQoKSA/ICfij7ggUEFVU0VEJyA6ICfij7ogUkVDJyB9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImhlYWRlci1hY3Rpb25zXCI+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiaWNvbi1idG5cIiB0aXRsZT1cIkVpbnN0ZWxsdW5nZW5cIiAoY2xpY2spPVwic2hvd1NldHRpbmdzLnNldCh0cnVlKVwiPuKame+4jzwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImljb24tYnRuXCIgdGl0bGU9XCJQb3NpdGlvbiB3ZWNoc2VsblwiIChjbGljayk9XCJjeWNsZVBvc2l0aW9uKClcIj7wn5OMPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiaWNvbi1idG5cIiB0aXRsZT1cIlNjaGxpZcOfZW5cIiAoY2xpY2spPVwidG9nZ2xlUGFuZWwoKVwiPuKclTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFNlc3Npb24gTmFtZSBJbnB1dCAob25seSB3aGVuIG5vdCByZWNvcmRpbmcpIC0tPlxuICAgICAgICBAaWYgKCFyZWNvcmRlci5pc1JlY29yZGluZygpKSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNlc3Npb24tc2V0dXBcIj5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICBkYXRhLWRlYnVnLXBhbmVsXG4gICAgICAgICAgICAgIGNsYXNzPVwic2Vzc2lvbi1pbnB1dFwiXG4gICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJzZXNzaW9uTmFtZVwiXG4gICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2Vzc2lvbi1OYW1lIChvcHRpb25hbClcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDx0ZXh0YXJlYVxuICAgICAgICAgICAgICBkYXRhLWRlYnVnLXBhbmVsXG4gICAgICAgICAgICAgIGNsYXNzPVwic2Vzc2lvbi1kZXNjXCJcbiAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJzZXNzaW9uRGVzY1wiXG4gICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiRmVobGVyYmVzY2hyZWlidW5nLi4uXCJcbiAgICAgICAgICAgICAgcm93cz1cIjJcIlxuICAgICAgICAgICAgPjwvdGV4dGFyZWE+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cblxuICAgICAgICA8IS0tIFJlY29yZGluZyBDb250cm9scyAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJlY29yZGluZy1jb250cm9sc1wiIGRhdGEtZGVidWctcGFuZWw+XG4gICAgICAgICAgQGlmICghcmVjb3JkZXIuaXNSZWNvcmRpbmcoKSkge1xuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImN0cmwtYnRuIHN0YXJ0XCIgKGNsaWNrKT1cInN0YXJ0UmVjb3JkaW5nKClcIj5cbiAgICAgICAgICAgICAg4pa2IEF1Zm5haG1lIHN0YXJ0ZW5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImN0cmwtYnRuIHBhdXNlXCIgKGNsaWNrKT1cInJlY29yZGVyLnBhdXNlUmVjb3JkaW5nKClcIj5cbiAgICAgICAgICAgICAge3sgcmVjb3JkZXIuaXNQYXVzZWQoKSA/ICfilrYgRm9ydHNldHplbicgOiAn4o+4IFBhdXNlJyB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY3RybC1idG4gc3RvcFwiIChjbGljayk9XCJzdG9wUmVjb3JkaW5nKClcIj5cbiAgICAgICAgICAgICAg4o+5IFN0b3BwZW5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImN0cmwtYnRuIGNsZWFyXCIgdGl0bGU9XCJBa3Rpb25lbiBsw7ZzY2hlblwiIChjbGljayk9XCJyZWNvcmRlci5jbGVhckN1cnJlbnRTZXNzaW9uKClcIj5cbiAgICAgICAgICAgICAg8J+XkVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQGlmIChoYXNBY3Rpb25zKCkpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgY2xhc3M9XCJjdHJsLWJ0biBnZW5lcmF0ZVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJhaVNlcnZpY2UuaXNHZW5lcmF0aW5nKCkgfHwgIWFpU2VydmljZS53ZWJob29rVXJsKClcIlxuICAgICAgICAgICAgICBbdGl0bGVdPVwiIWFpU2VydmljZS53ZWJob29rVXJsKCkgPyAnV2ViaG9vay1VUkwgaW4gRWluc3RlbGx1bmdlbiBlaW50cmFnZW4nIDogJ0N5cHJlc3MgVGVzdCBnZW5lcmllcmVuJ1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJnZW5lcmF0ZVRlc3QoKVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIEBpZiAoYWlTZXJ2aWNlLmlzR2VuZXJhdGluZygpKSB7XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcGlubmVyXCI+4p+zPC9zcGFuPiBHZW5lcmllcmUuLi5cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAg8J+kliDihpIgQ3lwcmVzcyBUZXN0XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBFcnJvciBCYW5uZXIgLS0+XG4gICAgICAgIEBpZiAoYWlTZXJ2aWNlLmVycm9yKCkpIHtcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXJyb3ItYmFubmVyXCIgZGF0YS1kZWJ1Zy1wYW5lbD5cbiAgICAgICAgICAgIOKaoO+4jyB7eyBhaVNlcnZpY2UuZXJyb3IoKSB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgPCEtLSBUYWJzIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJhclwiIGRhdGEtZGVidWctcGFuZWw+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJ0YWItYnRuXCJcbiAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlVGFiKCkgPT09ICdhY3Rpb25zJ1wiXG4gICAgICAgICAgICAoY2xpY2spPVwiYWN0aXZlVGFiLnNldCgnYWN0aW9ucycpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBBa3Rpb25lblxuICAgICAgICAgICAgQGlmIChyZWNvcmRlci5hY3Rpb25Db3VudCgpID4gMCkge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRhYi1iYWRnZVwiPnt7IHJlY29yZGVyLmFjdGlvbkNvdW50KCkgfX08L3NwYW4+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJ0YWItYnRuXCJcbiAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiYWN0aXZlVGFiKCkgPT09ICdyZXBsYXknXCJcbiAgICAgICAgICAgIChjbGljayk9XCJhY3RpdmVUYWIuc2V0KCdyZXBsYXknKVwiXG4gICAgICAgICAgICB0aXRsZT1cInJyd2ViIFNlc3Npb24gUmVwbGF5XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICDwn5O977iPIFJlcGxheVxuICAgICAgICAgICAgQGlmIChycndlYi5ldmVudHMoKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGFiLWJhZGdlXCI+e3sgcnJ3ZWIuZXZlbnRzKCkubGVuZ3RoIH19PC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGNsYXNzPVwidGFiLWJ0blwiXG4gICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImFjdGl2ZVRhYigpID09PSAndGVzdCdcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cIiFhaVNlcnZpY2UubGFzdFRlc3QoKVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiYWN0aXZlVGFiLnNldCgndGVzdCcpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICDwn6SWIFRlc3RcbiAgICAgICAgICAgIEBpZiAoYWlTZXJ2aWNlLmxhc3RUZXN0KCkpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0YWItYmFkZ2UgbmV3XCI+TkVVPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIGNsYXNzPVwidGFiLWJ0blwiXG4gICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImFjdGl2ZVRhYigpID09PSAnc2Vzc2lvbnMnXCJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJyZWNvcmRlci5zZXNzaW9ucygpLmxlbmd0aCA9PT0gMFwiXG4gICAgICAgICAgICAoY2xpY2spPVwiYWN0aXZlVGFiLnNldCgnc2Vzc2lvbnMnKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgU2Vzc2lvbnMgKHt7IHJlY29yZGVyLnNlc3Npb25zKCkubGVuZ3RoIH19KVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFRhYiBDb250ZW50IC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWNvbnRlbnRcIj5cbiAgICAgICAgICBAaWYgKGFjdGl2ZVRhYigpID09PSAnYWN0aW9ucycpIHtcbiAgICAgICAgICAgIDxhcHAtYWN0aW9uLWxpc3RcbiAgICAgICAgICAgICAgW3Nlc3Npb25dPVwicmVjb3JkZXIuY3VycmVudFNlc3Npb24oKVwiXG4gICAgICAgICAgICAgIChyZW1vdmVBY3Rpb24pPVwicmVjb3JkZXIucmVtb3ZlQWN0aW9uKCRldmVudClcIlxuICAgICAgICAgICAgICAoYWRkTm90ZSk9XCJyZWNvcmRlci5hZGROb3RlKCRldmVudC5pZCwgJGV2ZW50Lm5vdGUpXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgQGlmIChhY3RpdmVUYWIoKSA9PT0gJ3JlcGxheScpIHtcbiAgICAgICAgICAgIDxhcHAtc2Vzc2lvbi1yZXBsYXkgLz5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBAaWYgKGFjdGl2ZVRhYigpID09PSAndGVzdCcpIHtcbiAgICAgICAgICAgIDxhcHAtdGVzdC1wcmV2aWV3IFt0ZXN0XT1cImFpU2VydmljZS5sYXN0VGVzdCgpXCIgLz5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBAaWYgKGFjdGl2ZVRhYigpID09PSAnc2Vzc2lvbnMnKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2Vzc2lvbnMtbGlzdFwiPlxuICAgICAgICAgICAgICBAZm9yIChzZXNzaW9uIG9mIHJlY29yZGVyLnNlc3Npb25zKCk7IHRyYWNrIHNlc3Npb24uaWQpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2Vzc2lvbi1jYXJkXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2Vzc2lvbi1jYXJkLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNlc3Npb24tbmFtZVwiPnt7IHNlc3Npb24ubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzZXNzaW9uLW1ldGFcIj57eyBzZXNzaW9uLmFjdGlvbnMubGVuZ3RoIH19IEFrdGlvbmVuPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2Vzc2lvbi1jYXJkLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInNtLWJ0blwiIChjbGljayk9XCJsb2FkQW5kR2VuZXJhdGUoc2Vzc2lvbilcIj7wn6SWIE5ldSBnZW5lcmllcmVuPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJzbS1idG4gZGFuZ2VyXCIgKGNsaWNrKT1cInJlY29yZGVyLmRlbGV0ZVNlc3Npb24oc2Vzc2lvbi5pZClcIj7wn5eRPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIFJlc2l6ZSBIYW5kbGUgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpemUtaGFuZGxlXCIgKG1vdXNlZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQpXCI+4qC/PC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICB9XG5cbiAgICA8IS0tIFNldHRpbmdzIERpYWxvZyAtLT5cbiAgICBAaWYgKHNob3dTZXR0aW5ncygpKSB7XG4gICAgICA8YXBwLXNldHRpbmdzLWRpYWxvZyAoY2xvc2UpPVwic2hvd1NldHRpbmdzLnNldChmYWxzZSlcIiAvPlxuICAgIH1cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIC5kZWJ1Zy1mYWIge1xuICAgICAgcG9zaXRpb246IGZpeGVkO1xuICAgICAgYm90dG9tOiAyNHB4O1xuICAgICAgcmlnaHQ6IDI0cHg7XG4gICAgICB6LWluZGV4OiA5OTk5OTtcbiAgICAgIHdpZHRoOiA1MnB4O1xuICAgICAgaGVpZ2h0OiA1MnB4O1xuICAgICAgYm9yZGVyLXJhZGl1czogNTAlO1xuICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgYmFja2dyb3VuZDogIzFlMjkzYjtcbiAgICAgIGNvbG9yOiB3aGl0ZTtcbiAgICAgIGZvbnQtc2l6ZTogMjJweDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICBib3gtc2hhZG93OiAwIDRweCAyMHB4IHJnYmEoMCwwLDAsMC40KTtcbiAgICAgIHRyYW5zaXRpb246IHRyYW5zZm9ybSAwLjJzLCBiYWNrZ3JvdW5kIDAuMnM7XG4gICAgICBwb3NpdGlvbjogZml4ZWQ7XG4gICAgfVxuICAgIC5kZWJ1Zy1mYWI6aG92ZXIgeyB0cmFuc2Zvcm06IHNjYWxlKDEuMSk7IGJhY2tncm91bmQ6ICMzMzQxNTU7IH1cbiAgICAuZGVidWctZmFiLnJlY29yZGluZyB7IGJhY2tncm91bmQ6ICNkYzI2MjY7IH1cbiAgICAuZGVidWctZmFiLnB1bHNlIHsgYW5pbWF0aW9uOiBmYWJQdWxzZSAxLjVzIGVhc2UtaW4tb3V0IGluZmluaXRlOyB9XG4gICAgQGtleWZyYW1lcyBmYWJQdWxzZSB7XG4gICAgICAwJSwgMTAwJSB7IGJveC1zaGFkb3c6IDAgNHB4IDIwcHggcmdiYSgyMjAsMzgsMzgsMC40KTsgfVxuICAgICAgNTAlIHsgYm94LXNoYWRvdzogMCA0cHggMzBweCByZ2JhKDIyMCwzOCwzOCwwLjkpLCAwIDAgMCA4cHggcmdiYSgyMjAsMzgsMzgsMC4xNSk7IH1cbiAgICB9XG4gICAgLmZhYi1iYWRnZSB7XG4gICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICB0b3A6IC00cHg7XG4gICAgICByaWdodDogLTRweDtcbiAgICAgIGJhY2tncm91bmQ6ICNmNTllMGI7XG4gICAgICBjb2xvcjogIzAwMDtcbiAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgICBtaW4td2lkdGg6IDE4cHg7XG4gICAgICBoZWlnaHQ6IDE4cHg7XG4gICAgICBib3JkZXItcmFkaXVzOiA5cHg7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgcGFkZGluZzogMCA0cHg7XG4gICAgfVxuXG4gICAgLmRlYnVnLXBhbmVsIHtcbiAgICAgIHBvc2l0aW9uOiBmaXhlZDtcbiAgICAgIHotaW5kZXg6IDk5OTk4O1xuICAgICAgd2lkdGg6IDQyMHB4O1xuICAgICAgbWF4LWhlaWdodDogODB2aDtcbiAgICAgIGJhY2tncm91bmQ6ICMwZjE3MmE7XG4gICAgICBjb2xvcjogI2UyZThmMDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjMWUzYTVmO1xuICAgICAgYm94LXNoYWRvdzogMCAyNXB4IDYwcHggcmdiYSgwLDAsMCwwLjYpO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBmb250LWZhbWlseTogJ1NlZ29lIFVJJywgc3lzdGVtLXVpLCBzYW5zLXNlcmlmO1xuICAgICAgZm9udC1zaXplOiAxM3B4O1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICB9XG4gICAgLnBvcy1ib3R0b20tcmlnaHQgeyBib3R0b206IDg4cHg7IHJpZ2h0OiAyNHB4OyB9XG4gICAgLnBvcy1ib3R0b20tbGVmdCAgeyBib3R0b206IDg4cHg7IGxlZnQ6IDI0cHg7IH1cbiAgICAucG9zLXRvcC1yaWdodCAgICB7IHRvcDogMjRweDsgcmlnaHQ6IDI0cHg7IH1cbiAgICAucG9zLXRvcC1sZWZ0ICAgICB7IHRvcDogMjRweDsgbGVmdDogMjRweDsgfVxuXG4gICAgLnBhbmVsLWhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgIHBhZGRpbmc6IDEwcHggMTRweDtcbiAgICAgIGJhY2tncm91bmQ6ICMxZTI5M2I7XG4gICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgIzMzNDE1NTtcbiAgICAgIGN1cnNvcjogbW92ZTtcbiAgICAgIHVzZXItc2VsZWN0OiBub25lO1xuICAgICAgZmxleC1zaHJpbms6IDA7XG4gICAgfVxuICAgIC5oZWFkZXItbGVmdCB7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4OyB9XG4gICAgLnBhbmVsLWljb24geyBmb250LXNpemU6IDE2cHg7IH1cbiAgICAucGFuZWwtdGl0bGUgeyBmb250LXdlaWdodDogNjAwOyBmb250LXNpemU6IDE0cHg7IGNvbG9yOiAjZjFmNWY5OyB9XG4gICAgLnJlYy1pbmRpY2F0b3Ige1xuICAgICAgZm9udC1zaXplOiAxMHB4O1xuICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICAgIGNvbG9yOiAjZWY0NDQ0O1xuICAgICAgYmFja2dyb3VuZDogcmdiYSgyMzksNjgsNjgsMC4xNSk7XG4gICAgICBwYWRkaW5nOiAycHggN3B4O1xuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgYW5pbWF0aW9uOiBibGluayAxcyBzdGVwLWVuZCBpbmZpbml0ZTtcbiAgICB9XG4gICAgLnJlYy1pbmRpY2F0b3IucGF1c2VkIHsgY29sb3I6ICNmNTllMGI7IGJhY2tncm91bmQ6IHJnYmEoMjQ1LDE1OCwxMSwwLjE1KTsgYW5pbWF0aW9uOiBub25lOyB9XG4gICAgQGtleWZyYW1lcyBibGluayB7IDUwJSB7IG9wYWNpdHk6IDAuNDsgfSB9XG4gICAgLmhlYWRlci1hY3Rpb25zIHsgZGlzcGxheTogZmxleDsgZ2FwOiA0cHg7IH1cbiAgICAuaWNvbi1idG4ge1xuICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgIGNvbG9yOiAjOTRhM2I4O1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgcGFkZGluZzogNHB4O1xuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgZm9udC1zaXplOiAxNHB4O1xuICAgICAgbGluZS1oZWlnaHQ6IDE7XG4gICAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjE1cywgYmFja2dyb3VuZCAwLjE1cztcbiAgICB9XG4gICAgLmljb24tYnRuOmhvdmVyIHsgY29sb3I6ICNmMWY1Zjk7IGJhY2tncm91bmQ6ICMzMzQxNTU7IH1cblxuICAgIC5zZXNzaW9uLXNldHVwIHtcbiAgICAgIHBhZGRpbmc6IDEwcHggMTRweDtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjMWUyOTNiO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBnYXA6IDZweDtcbiAgICAgIGZsZXgtc2hyaW5rOiAwO1xuICAgIH1cbiAgICAuc2Vzc2lvbi1pbnB1dCwgLnNlc3Npb24tZGVzYyB7XG4gICAgICBiYWNrZ3JvdW5kOiAjMWUyOTNiO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgIzMzNDE1NTtcbiAgICAgIGNvbG9yOiAjZTJlOGYwO1xuICAgICAgYm9yZGVyLXJhZGl1czogNnB4O1xuICAgICAgcGFkZGluZzogNnB4IDEwcHg7XG4gICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gICAgICByZXNpemU6IHZlcnRpY2FsO1xuICAgIH1cbiAgICAuc2Vzc2lvbi1pbnB1dDpmb2N1cywgLnNlc3Npb24tZGVzYzpmb2N1cyB7XG4gICAgICBvdXRsaW5lOiBub25lO1xuICAgICAgYm9yZGVyLWNvbG9yOiAjM2I4MmY2O1xuICAgIH1cblxuICAgIC5yZWNvcmRpbmctY29udHJvbHMge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGdhcDogNnB4O1xuICAgICAgcGFkZGluZzogMTBweCAxNHB4O1xuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICMxZTI5M2I7XG4gICAgICBmbGV4LXdyYXA6IHdyYXA7XG4gICAgICBmbGV4LXNocmluazogMDtcbiAgICB9XG4gICAgLmN0cmwtYnRuIHtcbiAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgICAgIHBhZGRpbmc6IDZweCAxNHB4O1xuICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIHRyYW5zaXRpb246IGZpbHRlciAwLjE1cywgdHJhbnNmb3JtIDAuMXM7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGdhcDogNXB4O1xuICAgIH1cbiAgICAuY3RybC1idG46aG92ZXI6bm90KDpkaXNhYmxlZCkgeyBmaWx0ZXI6IGJyaWdodG5lc3MoMS4xNSk7IHRyYW5zZm9ybTogdHJhbnNsYXRlWSgtMXB4KTsgfVxuICAgIC5jdHJsLWJ0bjphY3RpdmU6bm90KDpkaXNhYmxlZCkgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVkoMCk7IH1cbiAgICAuY3RybC1idG46ZGlzYWJsZWQgeyBvcGFjaXR5OiAwLjU7IGN1cnNvcjogbm90LWFsbG93ZWQ7IH1cbiAgICAuY3RybC1idG4uc3RhcnQgICAgeyBiYWNrZ3JvdW5kOiAjMTZhMzRhOyBjb2xvcjogI2ZmZjsgfVxuICAgIC5jdHJsLWJ0bi5zdG9wICAgICB7IGJhY2tncm91bmQ6ICNkYzI2MjY7IGNvbG9yOiAjZmZmOyB9XG4gICAgLmN0cmwtYnRuLnBhdXNlICAgIHsgYmFja2dyb3VuZDogI2Q5NzcwNjsgY29sb3I6ICNmZmY7IH1cbiAgICAuY3RybC1idG4uZ2VuZXJhdGUgeyBiYWNrZ3JvdW5kOiAjN2MzYWVkOyBjb2xvcjogI2ZmZjsgZmxleDogMTsganVzdGlmeS1jb250ZW50OiBjZW50ZXI7IH1cbiAgICAuY3RybC1idG4uY2xlYXIgICAgeyBiYWNrZ3JvdW5kOiAjMzc0MTUxOyBjb2xvcjogIzljYTNhZjsgcGFkZGluZzogNnB4IDEwcHg7IH1cbiAgICAuc3Bpbm5lciB7IGRpc3BsYXk6IGlubGluZS1ibG9jazsgYW5pbWF0aW9uOiBzcGluIDAuOHMgbGluZWFyIGluZmluaXRlOyB9XG4gICAgQGtleWZyYW1lcyBzcGluIHsgdG8geyB0cmFuc2Zvcm06IHJvdGF0ZSgzNjBkZWcpOyB9IH1cblxuICAgIC5lcnJvci1iYW5uZXIge1xuICAgICAgYmFja2dyb3VuZDogcmdiYSgyMjAsMzgsMzgsMC4xNSk7XG4gICAgICBib3JkZXItbGVmdDogM3B4IHNvbGlkICNkYzI2MjY7XG4gICAgICBjb2xvcjogI2ZjYTVhNTtcbiAgICAgIHBhZGRpbmc6IDhweCAxNHB4O1xuICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgZmxleC1zaHJpbms6IDA7XG4gICAgfVxuXG4gICAgLnRhYi1iYXIge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjMWUyOTNiO1xuICAgICAgZmxleC1zaHJpbms6IDA7XG4gICAgfVxuICAgIC50YWItYnRuIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBiYWNrZ3JvdW5kOiBub25lO1xuICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgY29sb3I6ICM2NDc0OGI7XG4gICAgICBwYWRkaW5nOiA4cHggNHB4O1xuICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGdhcDogNXB4O1xuICAgICAgYm9yZGVyLWJvdHRvbTogMnB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgICAgdHJhbnNpdGlvbjogY29sb3IgMC4xNXM7XG4gICAgfVxuICAgIC50YWItYnRuOmhvdmVyOm5vdCg6ZGlzYWJsZWQpIHsgY29sb3I6ICNjYmQ1ZTE7IH1cbiAgICAudGFiLWJ0bi5hY3RpdmUgeyBjb2xvcjogIzYwYTVmYTsgYm9yZGVyLWJvdHRvbS1jb2xvcjogIzNiODJmNjsgfVxuICAgIC50YWItYnRuOmRpc2FibGVkIHsgb3BhY2l0eTogMC40OyBjdXJzb3I6IG5vdC1hbGxvd2VkOyB9XG4gICAgLnRhYi1iYWRnZSB7XG4gICAgICBiYWNrZ3JvdW5kOiAjMzM0MTU1O1xuICAgICAgY29sb3I6ICM5NGEzYjg7XG4gICAgICBmb250LXNpemU6IDEwcHg7XG4gICAgICBwYWRkaW5nOiAxcHggNXB4O1xuICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xuICAgIH1cbiAgICAudGFiLWJhZGdlLm5ldyB7IGJhY2tncm91bmQ6ICM3YzNhZWQ7IGNvbG9yOiAjZTlkNWZmOyB9XG5cbiAgICAudGFiLWNvbnRlbnQge1xuICAgICAgb3ZlcmZsb3cteTogYXV0bztcbiAgICAgIGZsZXg6IDE7XG4gICAgICBtaW4taGVpZ2h0OiAwO1xuICAgIH1cbiAgICAudGFiLWNvbnRlbnQ6Oi13ZWJraXQtc2Nyb2xsYmFyIHsgd2lkdGg6IDVweDsgfVxuICAgIC50YWItY29udGVudDo6LXdlYmtpdC1zY3JvbGxiYXItdHJhY2sgeyBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDsgfVxuICAgIC50YWItY29udGVudDo6LXdlYmtpdC1zY3JvbGxiYXItdGh1bWIgeyBiYWNrZ3JvdW5kOiAjMzM0MTU1OyBib3JkZXItcmFkaXVzOiAzcHg7IH1cblxuICAgIC5zZXNzaW9ucy1saXN0IHsgcGFkZGluZzogMTBweCAxNHB4OyBkaXNwbGF5OiBmbGV4OyBmbGV4LWRpcmVjdGlvbjogY29sdW1uOyBnYXA6IDhweDsgfVxuICAgIC5zZXNzaW9uLWNhcmQge1xuICAgICAgYmFja2dyb3VuZDogIzFlMjkzYjtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICMzMzQxNTU7XG4gICAgICBib3JkZXItcmFkaXVzOiA4cHg7XG4gICAgICBwYWRkaW5nOiAxMHB4O1xuICAgIH1cbiAgICAuc2Vzc2lvbi1jYXJkLWhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIG1hcmdpbi1ib3R0b206IDhweDtcbiAgICB9XG4gICAgLnNlc3Npb24tbmFtZSB7IGZvbnQtd2VpZ2h0OiA2MDA7IGNvbG9yOiAjZjFmNWY5OyBmb250LXNpemU6IDEzcHg7IH1cbiAgICAuc2Vzc2lvbi1tZXRhIHsgZm9udC1zaXplOiAxMXB4OyBjb2xvcjogIzY0NzQ4YjsgfVxuICAgIC5zZXNzaW9uLWNhcmQtYWN0aW9ucyB7IGRpc3BsYXk6IGZsZXg7IGdhcDogNnB4OyB9XG4gICAgLnNtLWJ0biB7XG4gICAgICBiYWNrZ3JvdW5kOiAjMzM0MTU1O1xuICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgY29sb3I6ICNjYmQ1ZTE7XG4gICAgICBwYWRkaW5nOiA0cHggMTBweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgICAgIGZvbnQtc2l6ZTogMTFweDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIHRyYW5zaXRpb246IGJhY2tncm91bmQgMC4xNXM7XG4gICAgfVxuICAgIC5zbS1idG46aG92ZXIgeyBiYWNrZ3JvdW5kOiAjNDc1NTY5OyB9XG4gICAgLnNtLWJ0bi5kYW5nZXIgeyBjb2xvcjogI2ZjYTVhNTsgfVxuICAgIC5zbS1idG4uZGFuZ2VyOmhvdmVyIHsgYmFja2dyb3VuZDogcmdiYSgyMjAsMzgsMzgsMC4yKTsgfVxuXG4gICAgLnJlc2l6ZS1oYW5kbGUge1xuICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xuICAgICAgY29sb3I6ICMzMzQxNTU7XG4gICAgICBjdXJzb3I6IG5zLXJlc2l6ZTtcbiAgICAgIGZvbnQtc2l6ZTogMTZweDtcbiAgICAgIHBhZGRpbmc6IDJweDtcbiAgICAgIGZsZXgtc2hyaW5rOiAwO1xuICAgICAgYmFja2dyb3VuZDogIzBmMTcyYTtcbiAgICAgIHVzZXItc2VsZWN0OiBub25lO1xuICAgIH1cbiAgICAucmVzaXplLWhhbmRsZTpob3ZlciB7IGNvbG9yOiAjNjQ3NDhiOyB9XG4gIGBdLFxufSlcbmV4cG9ydCBjbGFzcyBEZWJ1Z1BhbmVsQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICByZWNvcmRlciA9IGluamVjdChSZWNvcmRlclNlcnZpY2UpO1xuICBhaVNlcnZpY2UgPSBpbmplY3QoQWlHZW5lcmF0b3JTZXJ2aWNlKTtcbiAgcnJ3ZWIgPSBpbmplY3QoUnJ3ZWJSZWNvcmRlclNlcnZpY2UpO1xuXG4gIHBhbmVsT3BlbiA9IHNpZ25hbChmYWxzZSk7XG4gIGFjdGl2ZVRhYiA9IHNpZ25hbDxQYW5lbFRhYj4oJ2FjdGlvbnMnKTtcbiAgcG9zaXRpb24gPSBzaWduYWw8UGFuZWxQb3NpdGlvbj4oJ2JvdHRvbS1yaWdodCcpO1xuICBwYW5lbFdpZHRoID0gc2lnbmFsKDQyMCk7XG4gIHNob3dTZXR0aW5ncyA9IHNpZ25hbChmYWxzZSk7XG4gIHNlc3Npb25OYW1lID0gJyc7XG4gIHNlc3Npb25EZXNjID0gJyc7XG5cbiAgaGFzQWN0aW9ucyA9IGNvbXB1dGVkKFxuICAgICgpID0+ICh0aGlzLnJlY29yZGVyLmN1cnJlbnRTZXNzaW9uKCk/LmFjdGlvbnMubGVuZ3RoID8/IDApID4gMCB8fFxuICAgICAgICAgICh0aGlzLnJlY29yZGVyLnNlc3Npb25zKCkubGVuZ3RoID4gMClcbiAgKTtcblxuICBwcml2YXRlIHJlc2l6aW5nID0gZmFsc2U7XG4gIHByaXZhdGUgcmVzaXplU3RhcnRZID0gMDtcbiAgcHJpdmF0ZSByZXNpemVTdGFydEggPSAwO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIEtleWJvYXJkIHNob3J0Y3V0OiBDdHJsK1NoaWZ0K0RcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5oYW5kbGVIb3RrZXkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuaGFuZGxlSG90a2V5KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlSG90a2V5ID0gKGU6IEtleWJvYXJkRXZlbnQpID0+IHtcbiAgICBpZiAoZS5jdHJsS2V5ICYmIGUuc2hpZnRLZXkgJiYgZS5rZXkgPT09ICdEJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy50b2dnbGVQYW5lbCgpO1xuICAgIH1cbiAgICBpZiAoZS5jdHJsS2V5ICYmIGUuc2hpZnRLZXkgJiYgZS5rZXkgPT09ICdSJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgaWYgKHRoaXMucmVjb3JkZXIuaXNSZWNvcmRpbmcoKSkge1xuICAgICAgICB0aGlzLnN0b3BSZWNvcmRpbmcoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc3RhcnRSZWNvcmRpbmcoKTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdG9nZ2xlUGFuZWwoKTogdm9pZCB7XG4gICAgdGhpcy5wYW5lbE9wZW4udXBkYXRlKHYgPT4gIXYpO1xuICAgIGlmICh0aGlzLnBhbmVsT3BlbigpICYmICF0aGlzLnJlY29yZGVyLmN1cnJlbnRTZXNzaW9uKCkpIHtcbiAgICAgIHRoaXMuYWN0aXZlVGFiLnNldCgnYWN0aW9ucycpO1xuICAgIH1cbiAgfVxuXG4gIGN5Y2xlUG9zaXRpb24oKTogdm9pZCB7XG4gICAgY29uc3QgcG9zaXRpb25zOiBQYW5lbFBvc2l0aW9uW10gPSBbJ2JvdHRvbS1yaWdodCcsICdib3R0b20tbGVmdCcsICd0b3AtcmlnaHQnLCAndG9wLWxlZnQnXTtcbiAgICBjb25zdCBpZHggPSBwb3NpdGlvbnMuaW5kZXhPZih0aGlzLnBvc2l0aW9uKCkpO1xuICAgIHRoaXMucG9zaXRpb24uc2V0KHBvc2l0aW9uc1soaWR4ICsgMSkgJSBwb3NpdGlvbnMubGVuZ3RoXSk7XG4gIH1cblxuICBzdGFydFJlY29yZGluZygpOiB2b2lkIHtcbiAgICB0aGlzLnJlY29yZGVyLnN0YXJ0UmVjb3JkaW5nKFxuICAgICAgdGhpcy5zZXNzaW9uTmFtZSB8fCB1bmRlZmluZWQsXG4gICAgICB0aGlzLnNlc3Npb25EZXNjIHx8IHVuZGVmaW5lZFxuICAgICk7XG4gICAgLy8gU3RhcnQgcnJ3ZWIgaW4gcGFyYWxsZWwgZm9yIHZpc3VhbCByZXBsYXlcbiAgICB0aGlzLnJyd2ViLnN0YXJ0UmVjb3JkaW5nKCk7XG4gICAgdGhpcy5hY3RpdmVUYWIuc2V0KCdhY3Rpb25zJyk7XG4gIH1cblxuICBzdG9wUmVjb3JkaW5nKCk6IHZvaWQge1xuICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnJlY29yZGVyLnN0b3BSZWNvcmRpbmcoKTtcbiAgICB0aGlzLnJyd2ViLnN0b3BSZWNvcmRpbmcoKTtcbiAgICBpZiAoc2Vzc2lvbikge1xuICAgICAgdGhpcy5hY3RpdmVUYWIuc2V0KCdhY3Rpb25zJyk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGVUZXN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnJlY29yZGVyLmN1cnJlbnRTZXNzaW9uKCkgPz8gdGhpcy5yZWNvcmRlci5zZXNzaW9ucygpLmF0KC0xKTtcbiAgICBpZiAoIXNlc3Npb24pIHJldHVybjtcbiAgICBhd2FpdCB0aGlzLmFpU2VydmljZS5nZW5lcmF0ZUN5cHJlc3NUZXN0KHNlc3Npb24pO1xuICAgIHRoaXMuYWN0aXZlVGFiLnNldCgndGVzdCcpO1xuICB9XG5cbiAgYXN5bmMgbG9hZEFuZEdlbmVyYXRlKHNlc3Npb246IFJlY29yZGluZ1Nlc3Npb24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmFpU2VydmljZS5nZW5lcmF0ZUN5cHJlc3NUZXN0KHNlc3Npb24pO1xuICAgIHRoaXMuYWN0aXZlVGFiLnNldCgndGVzdCcpO1xuICB9XG5cbiAgLy8gRHJhZyB0byByZXBvc2l0aW9uXG4gIHN0YXJ0RHJhZyhlOiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKChlLnRhcmdldCBhcyBIVE1MRWxlbWVudCkuY2xvc2VzdCgnYnV0dG9uJykpIHJldHVybjtcbiAgICBjb25zdCBwYW5lbCA9IChlLmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQpLnBhcmVudEVsZW1lbnQhO1xuICAgIGNvbnN0IHN0YXJ0WCA9IGUuY2xpZW50WCAtIHBhbmVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XG4gICAgY29uc3Qgc3RhcnRZID0gZS5jbGllbnRZIC0gcGFuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wO1xuXG4gICAgY29uc3Qgb25Nb3ZlID0gKGV2OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBwYW5lbC5zdHlsZS5sZWZ0ID0gYCR7ZXYuY2xpZW50WCAtIHN0YXJ0WH1weGA7XG4gICAgICBwYW5lbC5zdHlsZS50b3AgID0gYCR7ZXYuY2xpZW50WSAtIHN0YXJ0WX1weGA7XG4gICAgICBwYW5lbC5zdHlsZS5yaWdodCA9ICdhdXRvJztcbiAgICAgIHBhbmVsLnN0eWxlLmJvdHRvbSA9ICdhdXRvJztcbiAgICB9O1xuICAgIGNvbnN0IG9uVXAgPSAoKSA9PiB7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvbk1vdmUpO1xuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIG9uVXApO1xuICAgIH07XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgb25Nb3ZlKTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgb25VcCk7XG4gIH1cblxuICAvLyBSZXNpemUgaGVpZ2h0XG4gIHN0YXJ0UmVzaXplKGU6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBwYW5lbCA9IChlLmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQpLnBhcmVudEVsZW1lbnQhO1xuICAgIHRoaXMucmVzaXplU3RhcnRZID0gZS5jbGllbnRZO1xuICAgIHRoaXMucmVzaXplU3RhcnRIID0gcGFuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xuXG4gICAgY29uc3Qgb25Nb3ZlID0gKGV2OiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBuZXdIID0gTWF0aC5tYXgoMjUwLCB0aGlzLnJlc2l6ZVN0YXJ0SCArIChldi5jbGllbnRZIC0gdGhpcy5yZXNpemVTdGFydFkpKTtcbiAgICAgIHBhbmVsLnN0eWxlLm1heEhlaWdodCA9IGAke25ld0h9cHhgO1xuICAgIH07XG4gICAgY29uc3Qgb25VcCA9ICgpID0+IHtcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG9uTW92ZSk7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgb25VcCk7XG4gICAgfTtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvbk1vdmUpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBvblVwKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkZWQtYWN0aW9uLm1vZGVsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVidWctcmVjb3JkZXIvc3JjL2xpYi9tb2RlbHMvcmVjb3JkZWQtYWN0aW9uLm1vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdHlwZSBBY3Rpb25UeXBlID1cclxuICB8ICdjbGljaydcclxuICB8ICdkYmxjbGljaydcclxuICB8ICdpbnB1dCdcclxuICB8ICdzZWxlY3QnXHJcbiAgfCAnc3VibWl0J1xyXG4gIHwgJ25hdmlnYXRpb24nXHJcbiAgfCAna2V5cHJlc3MnXHJcbiAgfCAnc2Nyb2xsJ1xyXG4gIHwgJ2hvdmVyJ1xyXG4gIHwgJ2Fzc2VydGlvbidcclxuICB8ICdzY3JlZW5zaG90JztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRWxlbWVudEluZm8ge1xyXG4gIHRhZ05hbWU6IHN0cmluZztcclxuICBpZD86IHN0cmluZztcclxuICBjbGFzc2VzOiBzdHJpbmdbXTtcclxuICBkYXRhVGVzdElkPzogc3RyaW5nO1xyXG4gIGRhdGFDeT86IHN0cmluZztcclxuICBuYW1lPzogc3RyaW5nO1xyXG4gIHR5cGU/OiBzdHJpbmc7XHJcbiAgcGxhY2Vob2xkZXI/OiBzdHJpbmc7XHJcbiAgdGV4dD86IHN0cmluZztcclxuICBocmVmPzogc3RyaW5nO1xyXG4gIGFyaWFMYWJlbD86IHN0cmluZztcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBSZWNvcmRlZEFjdGlvbiB7XHJcbiAgaWQ6IHN0cmluZztcclxuICB0eXBlOiBBY3Rpb25UeXBlO1xyXG4gIHRpbWVzdGFtcDogbnVtYmVyO1xyXG4gIHNlbGVjdG9yOiBzdHJpbmc7XHJcbiAgc2VsZWN0b3JTdHJhdGVneTogJ2RhdGEtdGVzdGlkJyB8ICdkYXRhLWN5JyB8ICdpZCcgfCAnbmFtZScgfCAnY2xhc3MnIHwgJ3RleHQnIHwgJ250aCcgfCAnY29tYmluZWQnO1xyXG4gIHZhbHVlPzogc3RyaW5nO1xyXG4gIHVybDogc3RyaW5nO1xyXG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XHJcbiAgZWxlbWVudD86IEVsZW1lbnRJbmZvO1xyXG4gIHNjcmVlbnNob3REYXRhVXJsPzogc3RyaW5nO1xyXG4gIG5vdGU/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3JkaW5nU2Vzc2lvbiB7XHJcbiAgaWQ6IHN0cmluZztcclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XHJcbiAgc3RhcnRUaW1lOiBudW1iZXI7XHJcbiAgZW5kVGltZT86IG51bWJlcjtcclxuICBzdGFydFVybDogc3RyaW5nO1xyXG4gIGFjdGlvbnM6IFJlY29yZGVkQWN0aW9uW107XHJcbiAgdGFncz86IHN0cmluZ1tdO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEdlbmVyYXRlZFRlc3Qge1xyXG4gIGNvZGU6IHN0cmluZztcclxuICBnZW5lcmF0ZWRBdDogbnVtYmVyO1xyXG4gIG1vZGVsOiBzdHJpbmc7XHJcbiAgc2Vzc2lvbklkOiBzdHJpbmc7XHJcbiAgcHJvbXB0VG9rZW5zPzogbnVtYmVyO1xyXG4gIGNvbXBsZXRpb25Ub2tlbnM/OiBudW1iZXI7XHJcbn1cclxuIl19
|