angular-debug-recorder 1.0.0 → 1.0.2
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 +124 -13
- package/esm2022/lib/action-list/action-list.component.mjs +161 -161
- package/esm2022/lib/debug-panel/debug-panel.component.mjs +385 -385
- package/esm2022/lib/services/rrweb-recorder.service.mjs +32 -21
- package/esm2022/lib/session-replay/session-replay.component.mjs +85 -85
- package/esm2022/lib/settings-dialog/settings-dialog.component.mjs +75 -75
- package/esm2022/lib/test-preview/test-preview.component.mjs +59 -59
- package/fesm2022/angular-debug-recorder.mjs +791 -780
- package/fesm2022/angular-debug-recorder.mjs.map +1 -1
- package/lib/services/rrweb-recorder.service.d.ts +5 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,24 +1,135 @@
|
|
|
1
|
-
#
|
|
1
|
+
# angular-debug-recorder
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Floating Debug-Panel für Angular-Apps — aufzeichnen, wiedergeben, Cypress-Tests per KI generieren.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Ein einzeiliges Drop-in, das sich als überlagerndes Panel in jede Angular-App einbettet. Klicks, Eingaben und Navigationsschritte werden aufgezeichnet, lassen sich als rrweb-Session abspielen und per Webhook an einen KI-Endpunkt schicken, der daraus fertige Cypress-Tests erzeugt.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
> Note: Don't forget to add `--project debug-recorder` or else it will be added to the default project in your `angular.json` file.
|
|
7
|
+
---
|
|
9
8
|
|
|
10
|
-
##
|
|
9
|
+
## Installation
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
```bash
|
|
12
|
+
npm install angular-debug-recorder rrweb @rrweb/types
|
|
13
|
+
```
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
### Peer Dependencies
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
| Paket | Version |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `@angular/common` | >= 17 |
|
|
20
|
+
| `@angular/core` | >= 17 |
|
|
21
|
+
| `@angular/forms` | >= 17 |
|
|
22
|
+
| `rrweb` | ^2.0.0-alpha.4 |
|
|
23
|
+
| `@rrweb/types` | ^2.0.0-alpha.20 |
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
---
|
|
19
26
|
|
|
20
|
-
|
|
27
|
+
## Quick Start
|
|
21
28
|
|
|
22
|
-
|
|
29
|
+
### 1. rrweb-CSS einbinden
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
In `angular.json` unter `styles`:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
"styles": [
|
|
35
|
+
"node_modules/rrweb/dist/replay/rrweb-replay.css"
|
|
36
|
+
]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 2. Komponente importieren
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// app.component.ts
|
|
43
|
+
import { DebugPanelComponent } from 'angular-debug-recorder';
|
|
44
|
+
|
|
45
|
+
@Component({
|
|
46
|
+
standalone: true,
|
|
47
|
+
imports: [DebugPanelComponent],
|
|
48
|
+
template: `
|
|
49
|
+
<router-outlet />
|
|
50
|
+
<app-debug-panel />
|
|
51
|
+
`
|
|
52
|
+
})
|
|
53
|
+
export class AppComponent {}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 3. HttpClient bereitstellen
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// main.ts
|
|
60
|
+
import { provideHttpClient } from '@angular/common/http';
|
|
61
|
+
|
|
62
|
+
bootstrapApplication(AppComponent, {
|
|
63
|
+
providers: [provideHttpClient()]
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Das war's — das Panel erscheint als FAB-Button unten rechts.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Bedienung
|
|
72
|
+
|
|
73
|
+
| Aktion | Shortcut |
|
|
74
|
+
|---|---|
|
|
75
|
+
| Panel öffnen / schließen | `Ctrl+Shift+D` |
|
|
76
|
+
| Aufzeichnung starten / stoppen | `Ctrl+Shift+R` |
|
|
77
|
+
|
|
78
|
+
Das Panel hat 4 Tabs:
|
|
79
|
+
|
|
80
|
+
- **Aktionen** — Liste aller aufgezeichneten Events
|
|
81
|
+
- **📽️ Replay** — rrweb-Player: Session visuell abspielen
|
|
82
|
+
- **🤖 Test** — KI-generierten Cypress-Test anzeigen & kopieren
|
|
83
|
+
- **Sessions** — Gespeicherte Sessions verwalten
|
|
84
|
+
|
|
85
|
+
### Selektor-Priorität
|
|
86
|
+
|
|
87
|
+
`data-testid` > `data-cy` > `id` > `name` > `class`
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## KI-Konfiguration (Webhook)
|
|
92
|
+
|
|
93
|
+
Das Panel schickt die aufgezeichnete Session per HTTP-POST an eine konfigurierbare URL und erwartet den Cypress-Test als Plain-Text-Antwort.
|
|
94
|
+
|
|
95
|
+
**Request:**
|
|
96
|
+
```
|
|
97
|
+
POST <webhook-url>
|
|
98
|
+
Content-Type: application/json
|
|
99
|
+
|
|
100
|
+
{ /* RecordingSession JSON */ }
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Response:**
|
|
104
|
+
```
|
|
105
|
+
describe('Recorded session', () => {
|
|
106
|
+
it('should ...', () => {
|
|
107
|
+
cy.visit('/');
|
|
108
|
+
cy.get('[data-testid="btn"]').click();
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Die URL wird im Panel unter ⚙️ Settings eingetragen und in `localStorage` (`debugRecorder_webhookUrl`) gespeichert.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Exportierte API
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// Komponenten
|
|
121
|
+
import { DebugPanelComponent } from 'angular-debug-recorder';
|
|
122
|
+
|
|
123
|
+
// Services (optional, für direkte Nutzung)
|
|
124
|
+
import { RecorderService, AiGeneratorService } from 'angular-debug-recorder';
|
|
125
|
+
|
|
126
|
+
// Interfaces
|
|
127
|
+
import { RecordedAction, RecordingSession, GeneratedTest } from 'angular-debug-recorder';
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Requirements
|
|
133
|
+
|
|
134
|
+
- Angular 17+ (Standalone, Signals)
|
|
135
|
+
- Node.js >= 18
|
|
@@ -45,170 +45,170 @@ export class ActionListComponent {
|
|
|
45
45
|
return s < 60 ? `${s}s` : `${Math.floor(s / 60)}m ${s % 60}s`;
|
|
46
46
|
}
|
|
47
47
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ActionListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
48
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ActionListComponent, isStandalone: true, selector: "app-action-list", inputs: { session: "session" }, outputs: { removeAction: "removeAction", addNote: "addNote" }, ngImport: i0, template: `
|
|
49
|
-
<div class="action-list" data-debug-panel>
|
|
50
|
-
@if (!session || session.actions.length === 0) {
|
|
51
|
-
<div class="empty-state">
|
|
52
|
-
<div class="empty-icon">🎬</div>
|
|
53
|
-
<p>Noch keine Aktionen aufgezeichnet.</p>
|
|
54
|
-
<p class="hint">Starte die Aufnahme und interagiere mit der App.</p>
|
|
55
|
-
<div class="shortcuts-hint">
|
|
56
|
-
<kbd>Ctrl+Shift+D</kbd> Panel
|
|
57
|
-
<kbd>Ctrl+Shift+R</kbd> Record
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
} @else {
|
|
61
|
-
<div class="list-header">
|
|
62
|
-
<span class="list-count">{{ session.actions.length }} Aktionen</span>
|
|
63
|
-
<span class="list-duration">
|
|
64
|
-
@if (session.endTime) {
|
|
65
|
-
{{ formatDuration(session.startTime, session.endTime) }}
|
|
66
|
-
} @else {
|
|
67
|
-
Live
|
|
68
|
-
}
|
|
69
|
-
</span>
|
|
70
|
-
</div>
|
|
71
|
-
|
|
72
|
-
@for (action of session.actions; track action.id; let i = $index) {
|
|
73
|
-
<div class="action-item" [class.expanded]="expandedId() === action.id">
|
|
74
|
-
<div class="action-row" (click)="toggleExpand(action.id)">
|
|
75
|
-
<span class="action-index">{{ i + 1 }}</span>
|
|
76
|
-
<span class="action-type-badge" [class]="'type-' + action.type">
|
|
77
|
-
{{ getActionIcon(action.type) }}
|
|
78
|
-
</span>
|
|
79
|
-
<div class="action-info">
|
|
80
|
-
<span class="action-desc">{{ action.description }}</span>
|
|
81
|
-
<span class="action-selector">{{ action.selector }}</span>
|
|
82
|
-
</div>
|
|
83
|
-
<span class="action-time">{{ formatTime(action.timestamp) }}</span>
|
|
84
|
-
<button
|
|
85
|
-
class="remove-btn"
|
|
86
|
-
data-debug-panel
|
|
87
|
-
title="Aktion entfernen"
|
|
88
|
-
(click)="onRemove(action.id, $event)"
|
|
89
|
-
>✕</button>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
@if (expandedId() === action.id) {
|
|
93
|
-
<div class="action-detail" data-debug-panel>
|
|
94
|
-
<div class="detail-grid">
|
|
95
|
-
<span class="detail-label">Selector</span>
|
|
96
|
-
<code class="detail-value">{{ action.selector }}</code>
|
|
97
|
-
@if (action.value) {
|
|
98
|
-
<span class="detail-label">Wert</span>
|
|
99
|
-
<code class="detail-value">{{ action.value }}</code>
|
|
100
|
-
}
|
|
101
|
-
@if (action.element?.tagName) {
|
|
102
|
-
<span class="detail-label">Element</span>
|
|
103
|
-
<code class="detail-value"><{{ action.element?.tagName }}></code>
|
|
104
|
-
}
|
|
105
|
-
<span class="detail-label">Strategie</span>
|
|
106
|
-
<span class="detail-value strategy-badge" [class]="'strat-' + action.selectorStrategy">
|
|
107
|
-
{{ action.selectorStrategy }}
|
|
108
|
-
</span>
|
|
109
|
-
<span class="detail-label">URL</span>
|
|
110
|
-
<code class="detail-value url-val">{{ action.url }}</code>
|
|
111
|
-
</div>
|
|
112
|
-
<div class="note-area">
|
|
113
|
-
<textarea
|
|
114
|
-
data-debug-panel
|
|
115
|
-
class="note-input"
|
|
116
|
-
[(ngModel)]="noteMap[action.id]"
|
|
117
|
-
placeholder="Notiz zu dieser Aktion..."
|
|
118
|
-
rows="2"
|
|
119
|
-
(blur)="onAddNote(action.id)"
|
|
120
|
-
></textarea>
|
|
121
|
-
</div>
|
|
122
|
-
</div>
|
|
123
|
-
}
|
|
124
|
-
</div>
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
</div>
|
|
48
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ActionListComponent, isStandalone: true, selector: "app-action-list", inputs: { session: "session" }, outputs: { removeAction: "removeAction", addNote: "addNote" }, ngImport: i0, template: `
|
|
49
|
+
<div class="action-list" data-debug-panel>
|
|
50
|
+
@if (!session || session.actions.length === 0) {
|
|
51
|
+
<div class="empty-state">
|
|
52
|
+
<div class="empty-icon">🎬</div>
|
|
53
|
+
<p>Noch keine Aktionen aufgezeichnet.</p>
|
|
54
|
+
<p class="hint">Starte die Aufnahme und interagiere mit der App.</p>
|
|
55
|
+
<div class="shortcuts-hint">
|
|
56
|
+
<kbd>Ctrl+Shift+D</kbd> Panel
|
|
57
|
+
<kbd>Ctrl+Shift+R</kbd> Record
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
} @else {
|
|
61
|
+
<div class="list-header">
|
|
62
|
+
<span class="list-count">{{ session.actions.length }} Aktionen</span>
|
|
63
|
+
<span class="list-duration">
|
|
64
|
+
@if (session.endTime) {
|
|
65
|
+
{{ formatDuration(session.startTime, session.endTime) }}
|
|
66
|
+
} @else {
|
|
67
|
+
Live
|
|
68
|
+
}
|
|
69
|
+
</span>
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
@for (action of session.actions; track action.id; let i = $index) {
|
|
73
|
+
<div class="action-item" [class.expanded]="expandedId() === action.id">
|
|
74
|
+
<div class="action-row" (click)="toggleExpand(action.id)">
|
|
75
|
+
<span class="action-index">{{ i + 1 }}</span>
|
|
76
|
+
<span class="action-type-badge" [class]="'type-' + action.type">
|
|
77
|
+
{{ getActionIcon(action.type) }}
|
|
78
|
+
</span>
|
|
79
|
+
<div class="action-info">
|
|
80
|
+
<span class="action-desc">{{ action.description }}</span>
|
|
81
|
+
<span class="action-selector">{{ action.selector }}</span>
|
|
82
|
+
</div>
|
|
83
|
+
<span class="action-time">{{ formatTime(action.timestamp) }}</span>
|
|
84
|
+
<button
|
|
85
|
+
class="remove-btn"
|
|
86
|
+
data-debug-panel
|
|
87
|
+
title="Aktion entfernen"
|
|
88
|
+
(click)="onRemove(action.id, $event)"
|
|
89
|
+
>✕</button>
|
|
90
|
+
</div>
|
|
91
|
+
|
|
92
|
+
@if (expandedId() === action.id) {
|
|
93
|
+
<div class="action-detail" data-debug-panel>
|
|
94
|
+
<div class="detail-grid">
|
|
95
|
+
<span class="detail-label">Selector</span>
|
|
96
|
+
<code class="detail-value">{{ action.selector }}</code>
|
|
97
|
+
@if (action.value) {
|
|
98
|
+
<span class="detail-label">Wert</span>
|
|
99
|
+
<code class="detail-value">{{ action.value }}</code>
|
|
100
|
+
}
|
|
101
|
+
@if (action.element?.tagName) {
|
|
102
|
+
<span class="detail-label">Element</span>
|
|
103
|
+
<code class="detail-value"><{{ action.element?.tagName }}></code>
|
|
104
|
+
}
|
|
105
|
+
<span class="detail-label">Strategie</span>
|
|
106
|
+
<span class="detail-value strategy-badge" [class]="'strat-' + action.selectorStrategy">
|
|
107
|
+
{{ action.selectorStrategy }}
|
|
108
|
+
</span>
|
|
109
|
+
<span class="detail-label">URL</span>
|
|
110
|
+
<code class="detail-value url-val">{{ action.url }}</code>
|
|
111
|
+
</div>
|
|
112
|
+
<div class="note-area">
|
|
113
|
+
<textarea
|
|
114
|
+
data-debug-panel
|
|
115
|
+
class="note-input"
|
|
116
|
+
[(ngModel)]="noteMap[action.id]"
|
|
117
|
+
placeholder="Notiz zu dieser Aktion..."
|
|
118
|
+
rows="2"
|
|
119
|
+
(blur)="onAddNote(action.id)"
|
|
120
|
+
></textarea>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
}
|
|
124
|
+
</div>
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
</div>
|
|
128
128
|
`, isInline: true, styles: [".action-list{padding:0}.empty-state{text-align:center;padding:32px 20px;color:#64748b}.empty-icon{font-size:40px;margin-bottom:10px}.empty-state p{margin:4px 0;font-size:13px}.hint{font-size:11px;color:#475569}.shortcuts-hint{margin-top:12px;font-size:11px;color:#475569}kbd{background:#1e293b;border:1px solid #334155;color:#94a3b8;padding:2px 6px;border-radius:4px;font-size:10px}.list-header{display:flex;justify-content:space-between;padding:8px 14px;font-size:11px;color:#64748b;background:#0f172a;border-bottom:1px solid #1e293b;position:sticky;top:0}.action-item{border-bottom:1px solid #1e293b;transition:background .1s}.action-item:hover{background:#1e293b80}.action-item.expanded{background:#1e293b}.action-row{display:flex;align-items:center;padding:8px 10px;gap:8px;cursor:pointer}.action-index{color:#475569;font-size:10px;min-width:18px;text-align:right}.action-type-badge{font-size:14px;min-width:20px;text-align:center}.action-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.action-desc{font-size:12px;color:#cbd5e1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.action-selector{font-size:10px;color:#64748b;font-family:Cascadia Code,Consolas,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.action-time{font-size:10px;color:#475569;white-space:nowrap}.remove-btn{background:none;border:none;color:#475569;cursor:pointer;font-size:12px;padding:2px 5px;border-radius:3px;opacity:0;transition:opacity .15s,color .15s}.action-row:hover .remove-btn{opacity:1}.remove-btn:hover{color:#f87171}.action-detail{padding:10px 14px;background:#0f172ab3;border-top:1px solid #1e293b}.detail-grid{display:grid;grid-template-columns:auto 1fr;gap:4px 10px;margin-bottom:8px;align-items:start}.detail-label{font-size:10px;color:#64748b;padding-top:2px;white-space:nowrap}.detail-value{font-size:11px;color:#93c5fd;font-family:Cascadia Code,Consolas,monospace;word-break:break-all}.url-val{color:#6ee7b7}.strategy-badge{font-size:10px;padding:1px 6px;border-radius:3px;font-family:monospace}.strat-data-testid,.strat-data-cy{background:#064e3b;color:#34d399}.strat-id{background:#1e3a8a;color:#93c5fd}.strat-name{background:#44337a;color:#c4b5fd}.strat-class{background:#374151;color:#9ca3af}.strat-combined{background:#292524;color:#d6d3d1}.note-area{margin-top:6px}.note-input{width:100%;box-sizing:border-box;background:#0f172a;border:1px solid #334155;color:#e2e8f0;border-radius:5px;padding:6px 8px;font-size:11px;resize:vertical}.note-input:focus{outline:none;border-color:#3b82f6}\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"] }] }); }
|
|
129
129
|
}
|
|
130
130
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ActionListComponent, decorators: [{
|
|
131
131
|
type: Component,
|
|
132
|
-
args: [{ selector: 'app-action-list', standalone: true, imports: [CommonModule, FormsModule], template: `
|
|
133
|
-
<div class="action-list" data-debug-panel>
|
|
134
|
-
@if (!session || session.actions.length === 0) {
|
|
135
|
-
<div class="empty-state">
|
|
136
|
-
<div class="empty-icon">🎬</div>
|
|
137
|
-
<p>Noch keine Aktionen aufgezeichnet.</p>
|
|
138
|
-
<p class="hint">Starte die Aufnahme und interagiere mit der App.</p>
|
|
139
|
-
<div class="shortcuts-hint">
|
|
140
|
-
<kbd>Ctrl+Shift+D</kbd> Panel
|
|
141
|
-
<kbd>Ctrl+Shift+R</kbd> Record
|
|
142
|
-
</div>
|
|
143
|
-
</div>
|
|
144
|
-
} @else {
|
|
145
|
-
<div class="list-header">
|
|
146
|
-
<span class="list-count">{{ session.actions.length }} Aktionen</span>
|
|
147
|
-
<span class="list-duration">
|
|
148
|
-
@if (session.endTime) {
|
|
149
|
-
{{ formatDuration(session.startTime, session.endTime) }}
|
|
150
|
-
} @else {
|
|
151
|
-
Live
|
|
152
|
-
}
|
|
153
|
-
</span>
|
|
154
|
-
</div>
|
|
155
|
-
|
|
156
|
-
@for (action of session.actions; track action.id; let i = $index) {
|
|
157
|
-
<div class="action-item" [class.expanded]="expandedId() === action.id">
|
|
158
|
-
<div class="action-row" (click)="toggleExpand(action.id)">
|
|
159
|
-
<span class="action-index">{{ i + 1 }}</span>
|
|
160
|
-
<span class="action-type-badge" [class]="'type-' + action.type">
|
|
161
|
-
{{ getActionIcon(action.type) }}
|
|
162
|
-
</span>
|
|
163
|
-
<div class="action-info">
|
|
164
|
-
<span class="action-desc">{{ action.description }}</span>
|
|
165
|
-
<span class="action-selector">{{ action.selector }}</span>
|
|
166
|
-
</div>
|
|
167
|
-
<span class="action-time">{{ formatTime(action.timestamp) }}</span>
|
|
168
|
-
<button
|
|
169
|
-
class="remove-btn"
|
|
170
|
-
data-debug-panel
|
|
171
|
-
title="Aktion entfernen"
|
|
172
|
-
(click)="onRemove(action.id, $event)"
|
|
173
|
-
>✕</button>
|
|
174
|
-
</div>
|
|
175
|
-
|
|
176
|
-
@if (expandedId() === action.id) {
|
|
177
|
-
<div class="action-detail" data-debug-panel>
|
|
178
|
-
<div class="detail-grid">
|
|
179
|
-
<span class="detail-label">Selector</span>
|
|
180
|
-
<code class="detail-value">{{ action.selector }}</code>
|
|
181
|
-
@if (action.value) {
|
|
182
|
-
<span class="detail-label">Wert</span>
|
|
183
|
-
<code class="detail-value">{{ action.value }}</code>
|
|
184
|
-
}
|
|
185
|
-
@if (action.element?.tagName) {
|
|
186
|
-
<span class="detail-label">Element</span>
|
|
187
|
-
<code class="detail-value"><{{ action.element?.tagName }}></code>
|
|
188
|
-
}
|
|
189
|
-
<span class="detail-label">Strategie</span>
|
|
190
|
-
<span class="detail-value strategy-badge" [class]="'strat-' + action.selectorStrategy">
|
|
191
|
-
{{ action.selectorStrategy }}
|
|
192
|
-
</span>
|
|
193
|
-
<span class="detail-label">URL</span>
|
|
194
|
-
<code class="detail-value url-val">{{ action.url }}</code>
|
|
195
|
-
</div>
|
|
196
|
-
<div class="note-area">
|
|
197
|
-
<textarea
|
|
198
|
-
data-debug-panel
|
|
199
|
-
class="note-input"
|
|
200
|
-
[(ngModel)]="noteMap[action.id]"
|
|
201
|
-
placeholder="Notiz zu dieser Aktion..."
|
|
202
|
-
rows="2"
|
|
203
|
-
(blur)="onAddNote(action.id)"
|
|
204
|
-
></textarea>
|
|
205
|
-
</div>
|
|
206
|
-
</div>
|
|
207
|
-
}
|
|
208
|
-
</div>
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
</div>
|
|
132
|
+
args: [{ selector: 'app-action-list', standalone: true, imports: [CommonModule, FormsModule], template: `
|
|
133
|
+
<div class="action-list" data-debug-panel>
|
|
134
|
+
@if (!session || session.actions.length === 0) {
|
|
135
|
+
<div class="empty-state">
|
|
136
|
+
<div class="empty-icon">🎬</div>
|
|
137
|
+
<p>Noch keine Aktionen aufgezeichnet.</p>
|
|
138
|
+
<p class="hint">Starte die Aufnahme und interagiere mit der App.</p>
|
|
139
|
+
<div class="shortcuts-hint">
|
|
140
|
+
<kbd>Ctrl+Shift+D</kbd> Panel
|
|
141
|
+
<kbd>Ctrl+Shift+R</kbd> Record
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
} @else {
|
|
145
|
+
<div class="list-header">
|
|
146
|
+
<span class="list-count">{{ session.actions.length }} Aktionen</span>
|
|
147
|
+
<span class="list-duration">
|
|
148
|
+
@if (session.endTime) {
|
|
149
|
+
{{ formatDuration(session.startTime, session.endTime) }}
|
|
150
|
+
} @else {
|
|
151
|
+
Live
|
|
152
|
+
}
|
|
153
|
+
</span>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
@for (action of session.actions; track action.id; let i = $index) {
|
|
157
|
+
<div class="action-item" [class.expanded]="expandedId() === action.id">
|
|
158
|
+
<div class="action-row" (click)="toggleExpand(action.id)">
|
|
159
|
+
<span class="action-index">{{ i + 1 }}</span>
|
|
160
|
+
<span class="action-type-badge" [class]="'type-' + action.type">
|
|
161
|
+
{{ getActionIcon(action.type) }}
|
|
162
|
+
</span>
|
|
163
|
+
<div class="action-info">
|
|
164
|
+
<span class="action-desc">{{ action.description }}</span>
|
|
165
|
+
<span class="action-selector">{{ action.selector }}</span>
|
|
166
|
+
</div>
|
|
167
|
+
<span class="action-time">{{ formatTime(action.timestamp) }}</span>
|
|
168
|
+
<button
|
|
169
|
+
class="remove-btn"
|
|
170
|
+
data-debug-panel
|
|
171
|
+
title="Aktion entfernen"
|
|
172
|
+
(click)="onRemove(action.id, $event)"
|
|
173
|
+
>✕</button>
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
@if (expandedId() === action.id) {
|
|
177
|
+
<div class="action-detail" data-debug-panel>
|
|
178
|
+
<div class="detail-grid">
|
|
179
|
+
<span class="detail-label">Selector</span>
|
|
180
|
+
<code class="detail-value">{{ action.selector }}</code>
|
|
181
|
+
@if (action.value) {
|
|
182
|
+
<span class="detail-label">Wert</span>
|
|
183
|
+
<code class="detail-value">{{ action.value }}</code>
|
|
184
|
+
}
|
|
185
|
+
@if (action.element?.tagName) {
|
|
186
|
+
<span class="detail-label">Element</span>
|
|
187
|
+
<code class="detail-value"><{{ action.element?.tagName }}></code>
|
|
188
|
+
}
|
|
189
|
+
<span class="detail-label">Strategie</span>
|
|
190
|
+
<span class="detail-value strategy-badge" [class]="'strat-' + action.selectorStrategy">
|
|
191
|
+
{{ action.selectorStrategy }}
|
|
192
|
+
</span>
|
|
193
|
+
<span class="detail-label">URL</span>
|
|
194
|
+
<code class="detail-value url-val">{{ action.url }}</code>
|
|
195
|
+
</div>
|
|
196
|
+
<div class="note-area">
|
|
197
|
+
<textarea
|
|
198
|
+
data-debug-panel
|
|
199
|
+
class="note-input"
|
|
200
|
+
[(ngModel)]="noteMap[action.id]"
|
|
201
|
+
placeholder="Notiz zu dieser Aktion..."
|
|
202
|
+
rows="2"
|
|
203
|
+
(blur)="onAddNote(action.id)"
|
|
204
|
+
></textarea>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
}
|
|
208
|
+
</div>
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
</div>
|
|
212
212
|
`, styles: [".action-list{padding:0}.empty-state{text-align:center;padding:32px 20px;color:#64748b}.empty-icon{font-size:40px;margin-bottom:10px}.empty-state p{margin:4px 0;font-size:13px}.hint{font-size:11px;color:#475569}.shortcuts-hint{margin-top:12px;font-size:11px;color:#475569}kbd{background:#1e293b;border:1px solid #334155;color:#94a3b8;padding:2px 6px;border-radius:4px;font-size:10px}.list-header{display:flex;justify-content:space-between;padding:8px 14px;font-size:11px;color:#64748b;background:#0f172a;border-bottom:1px solid #1e293b;position:sticky;top:0}.action-item{border-bottom:1px solid #1e293b;transition:background .1s}.action-item:hover{background:#1e293b80}.action-item.expanded{background:#1e293b}.action-row{display:flex;align-items:center;padding:8px 10px;gap:8px;cursor:pointer}.action-index{color:#475569;font-size:10px;min-width:18px;text-align:right}.action-type-badge{font-size:14px;min-width:20px;text-align:center}.action-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.action-desc{font-size:12px;color:#cbd5e1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.action-selector{font-size:10px;color:#64748b;font-family:Cascadia Code,Consolas,monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.action-time{font-size:10px;color:#475569;white-space:nowrap}.remove-btn{background:none;border:none;color:#475569;cursor:pointer;font-size:12px;padding:2px 5px;border-radius:3px;opacity:0;transition:opacity .15s,color .15s}.action-row:hover .remove-btn{opacity:1}.remove-btn:hover{color:#f87171}.action-detail{padding:10px 14px;background:#0f172ab3;border-top:1px solid #1e293b}.detail-grid{display:grid;grid-template-columns:auto 1fr;gap:4px 10px;margin-bottom:8px;align-items:start}.detail-label{font-size:10px;color:#64748b;padding-top:2px;white-space:nowrap}.detail-value{font-size:11px;color:#93c5fd;font-family:Cascadia Code,Consolas,monospace;word-break:break-all}.url-val{color:#6ee7b7}.strategy-badge{font-size:10px;padding:1px 6px;border-radius:3px;font-family:monospace}.strat-data-testid,.strat-data-cy{background:#064e3b;color:#34d399}.strat-id{background:#1e3a8a;color:#93c5fd}.strat-name{background:#44337a;color:#c4b5fd}.strat-class{background:#374151;color:#9ca3af}.strat-combined{background:#292524;color:#d6d3d1}.note-area{margin-top:6px}.note-input{width:100%;box-sizing:border-box;background:#0f172a;border:1px solid #334155;color:#e2e8f0;border-radius:5px;padding:6px 8px;font-size:11px;resize:vertical}.note-input:focus{outline:none;border-color:#3b82f6}\n"] }]
|
|
213
213
|
}], propDecorators: { session: [{
|
|
214
214
|
type: Input
|
|
@@ -217,4 +217,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
217
217
|
}], addNote: [{
|
|
218
218
|
type: Output
|
|
219
219
|
}] } });
|
|
220
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVidWctcmVjb3JkZXIvc3JjL2xpYi9hY3Rpb24tbGlzdC9hY3Rpb24tbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBK083QyxNQUFNLE9BQU8sbUJBQW1CO0lBNU9oQztRQTZPVyxZQUFPLEdBQTRCLElBQUksQ0FBQztRQUN2QyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDMUMsWUFBTyxHQUFHLElBQUksWUFBWSxFQUFnQyxDQUFDO1FBRXJFLGVBQVUsR0FBRyxNQUFNLENBQWdCLElBQUksQ0FBQyxDQUFDO1FBQ3pDLFlBQU8sR0FBMkIsRUFBRSxDQUFDO0tBd0N0QztJQXRDQyxZQUFZLENBQUMsRUFBVTtRQUNyQixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELFFBQVEsQ0FBQyxFQUFVLEVBQUUsQ0FBUTtRQUMzQixDQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELFNBQVMsQ0FBQyxFQUFVO1FBQ2xCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELGFBQWEsQ0FBQyxJQUFZO1FBQ3hCLE1BQU0sS0FBSyxHQUEyQjtZQUNwQyxLQUFLLEVBQVEsSUFBSTtZQUNqQixRQUFRLEVBQUssTUFBTTtZQUNuQixLQUFLLEVBQVEsSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixVQUFVLEVBQUcsSUFBSTtZQUNqQixRQUFRLEVBQUssSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixLQUFLLEVBQVEsS0FBSztZQUNsQixTQUFTLEVBQUksR0FBRztZQUNoQixVQUFVLEVBQUcsSUFBSTtTQUNsQixDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDO0lBQzVCLENBQUM7SUFFRCxVQUFVLENBQUMsRUFBVTtRQUNuQixPQUFPLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztJQUM3RyxDQUFDO0lBRUQsY0FBYyxDQUFDLEtBQWEsRUFBRSxHQUFXO1FBQ3ZDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDM0MsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBQyxFQUFFLEdBQUcsQ0FBQztJQUM1RCxDQUFDOytHQTdDVSxtQkFBbUI7bUdBQW5CLG1CQUFtQiwwS0F4T3BCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdGVCxvakZBakZTLFlBQVksOEJBQUUsV0FBVzs7NEZBeU94QixtQkFBbUI7a0JBNU8vQixTQUFTOytCQUNFLGlCQUFpQixjQUNmLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsWUFDMUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0ZUOzhCQXlKUSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0ksWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxPQUFPO3NCQUFoQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUmVjb3JkZWRBY3Rpb24sIFJlY29yZGluZ1Nlc3Npb24gfSBmcm9tICcuLi9tb2RlbHMvcmVjb3JkZWQtYWN0aW9uLm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWFjdGlvbi1saXN0JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJhY3Rpb24tbGlzdFwiIGRhdGEtZGVidWctcGFuZWw+XG4gICAgICBAaWYgKCFzZXNzaW9uIHx8IHNlc3Npb24uYWN0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXN0YXRlXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LWljb25cIj7wn46sPC9kaXY+XG4gICAgICAgICAgPHA+Tm9jaCBrZWluZSBBa3Rpb25lbiBhdWZnZXplaWNobmV0LjwvcD5cbiAgICAgICAgICA8cCBjbGFzcz1cImhpbnRcIj5TdGFydGUgZGllIEF1Zm5haG1lIHVuZCBpbnRlcmFnaWVyZSBtaXQgZGVyIEFwcC48L3A+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNob3J0Y3V0cy1oaW50XCI+XG4gICAgICAgICAgICA8a2JkPkN0cmwrU2hpZnQrRDwva2JkPiBQYW5lbCAmbmJzcDtcbiAgICAgICAgICAgIDxrYmQ+Q3RybCtTaGlmdCtSPC9rYmQ+IFJlY29yZFxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH0gQGVsc2Uge1xuICAgICAgICA8ZGl2IGNsYXNzPVwibGlzdC1oZWFkZXJcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImxpc3QtY291bnRcIj57eyBzZXNzaW9uLmFjdGlvbnMubGVuZ3RoIH19IEFrdGlvbmVuPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGlzdC1kdXJhdGlvblwiPlxuICAgICAgICAgICAgQGlmIChzZXNzaW9uLmVuZFRpbWUpIHtcbiAgICAgICAgICAgICAge3sgZm9ybWF0RHVyYXRpb24oc2Vzc2lvbi5zdGFydFRpbWUsIHNlc3Npb24uZW5kVGltZSkgfX1cbiAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICBMaXZlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICBAZm9yIChhY3Rpb24gb2Ygc2Vzc2lvbi5hY3Rpb25zOyB0cmFjayBhY3Rpb24uaWQ7IGxldCBpID0gJGluZGV4KSB7XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1pdGVtXCIgW2NsYXNzLmV4cGFuZGVkXT1cImV4cGFuZGVkSWQoKSA9PT0gYWN0aW9uLmlkXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLXJvd1wiIChjbGljayk9XCJ0b2dnbGVFeHBhbmQoYWN0aW9uLmlkKVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi1pbmRleFwiPnt7IGkgKyAxIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi10eXBlLWJhZGdlXCIgW2NsYXNzXT1cIid0eXBlLScgKyBhY3Rpb24udHlwZVwiPlxuICAgICAgICAgICAgICAgIHt7IGdldEFjdGlvbkljb24oYWN0aW9uLnR5cGUpIH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1pbmZvXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhY3Rpb24tZGVzY1wiPnt7IGFjdGlvbi5kZXNjcmlwdGlvbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi1zZWxlY3RvclwiPnt7IGFjdGlvbi5zZWxlY3RvciB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWN0aW9uLXRpbWVcIj57eyBmb3JtYXRUaW1lKGFjdGlvbi50aW1lc3RhbXApIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJyZW1vdmUtYnRuXCJcbiAgICAgICAgICAgICAgICBkYXRhLWRlYnVnLXBhbmVsXG4gICAgICAgICAgICAgICAgdGl0bGU9XCJBa3Rpb24gZW50ZmVybmVuXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwib25SZW1vdmUoYWN0aW9uLmlkLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgPuKclTwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIEBpZiAoZXhwYW5kZWRJZCgpID09PSBhY3Rpb24uaWQpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1kZXRhaWxcIiBkYXRhLWRlYnVnLXBhbmVsPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtZ3JpZFwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5TZWxlY3Rvcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgYWN0aW9uLnNlbGVjdG9yIH19PC9jb2RlPlxuICAgICAgICAgICAgICAgICAgQGlmIChhY3Rpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5XZXJ0PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IGFjdGlvbi52YWx1ZSB9fTwvY29kZT5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIEBpZiAoYWN0aW9uLmVsZW1lbnQ/LnRhZ05hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5FbGVtZW50PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImRldGFpbC12YWx1ZVwiPiZsdDt7eyBhY3Rpb24uZWxlbWVudD8udGFnTmFtZSB9fSZndDs8L2NvZGU+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlN0cmF0ZWdpZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLXZhbHVlIHN0cmF0ZWd5LWJhZGdlXCIgW2NsYXNzXT1cIidzdHJhdC0nICsgYWN0aW9uLnNlbGVjdG9yU3RyYXRlZ3lcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgYWN0aW9uLnNlbGVjdG9yU3RyYXRlZ3kgfX1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+VVJMPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPGNvZGUgY2xhc3M9XCJkZXRhaWwtdmFsdWUgdXJsLXZhbFwiPnt7IGFjdGlvbi51cmwgfX08L2NvZGU+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm5vdGUtYXJlYVwiPlxuICAgICAgICAgICAgICAgICAgPHRleHRhcmVhXG4gICAgICAgICAgICAgICAgICAgIGRhdGEtZGVidWctcGFuZWxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJub3RlLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJub3RlTWFwW2FjdGlvbi5pZF1cIlxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIk5vdGl6IHp1IGRpZXNlciBBa3Rpb24uLi5cIlxuICAgICAgICAgICAgICAgICAgICByb3dzPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgIChibHVyKT1cIm9uQWRkTm90ZShhY3Rpb24uaWQpXCJcbiAgICAgICAgICAgICAgICAgID48L3RleHRhcmVhPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgfVxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgLmFjdGlvbi1saXN0IHsgcGFkZGluZzogMDsgfVxuXG4gICAgLmVtcHR5LXN0YXRlIHtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgIHBhZGRpbmc6IDMycHggMjBweDtcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xuICAgIH1cbiAgICAuZW1wdHktaWNvbiB7IGZvbnQtc2l6ZTogNDBweDsgbWFyZ2luLWJvdHRvbTogMTBweDsgfVxuICAgIC5lbXB0eS1zdGF0ZSBwIHsgbWFyZ2luOiA0cHggMDsgZm9udC1zaXplOiAxM3B4OyB9XG4gICAgLmhpbnQgeyBmb250LXNpemU6IDExcHg7IGNvbG9yOiAjNDc1NTY5OyB9XG4gICAgLnNob3J0Y3V0cy1oaW50IHtcbiAgICAgIG1hcmdpbi10b3A6IDEycHg7XG4gICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICBjb2xvcjogIzQ3NTU2OTtcbiAgICB9XG4gICAga2JkIHtcbiAgICAgIGJhY2tncm91bmQ6ICMxZTI5M2I7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjMzM0MTU1O1xuICAgICAgY29sb3I6ICM5NGEzYjg7XG4gICAgICBwYWRkaW5nOiAycHggNnB4O1xuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgZm9udC1zaXplOiAxMHB4O1xuICAgIH1cblxuICAgIC5saXN0LWhlYWRlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgcGFkZGluZzogOHB4IDE0cHg7XG4gICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICBjb2xvcjogIzY0NzQ4YjtcbiAgICAgIGJhY2tncm91bmQ6ICMwZjE3MmE7XG4gICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgIzFlMjkzYjtcbiAgICAgIHBvc2l0aW9uOiBzdGlja3k7XG4gICAgICB0b3A6IDA7XG4gICAgfVxuXG4gICAgLmFjdGlvbi1pdGVtIHtcbiAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjMWUyOTNiO1xuICAgICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjFzO1xuICAgIH1cbiAgICAuYWN0aW9uLWl0ZW06aG92ZXIgeyBiYWNrZ3JvdW5kOiByZ2JhKDMwLDQxLDU5LDAuNSk7IH1cbiAgICAuYWN0aW9uLWl0ZW0uZXhwYW5kZWQgeyBiYWNrZ3JvdW5kOiAjMWUyOTNiOyB9XG5cbiAgICAuYWN0aW9uLXJvdyB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIHBhZGRpbmc6IDhweCAxMHB4O1xuICAgICAgZ2FwOiA4cHg7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgfVxuICAgIC5hY3Rpb24taW5kZXgge1xuICAgICAgY29sb3I6ICM0NzU1Njk7XG4gICAgICBmb250LXNpemU6IDEwcHg7XG4gICAgICBtaW4td2lkdGg6IDE4cHg7XG4gICAgICB0ZXh0LWFsaWduOiByaWdodDtcbiAgICB9XG4gICAgLmFjdGlvbi10eXBlLWJhZGdlIHtcbiAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgIG1pbi13aWR0aDogMjBweDtcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB9XG4gICAgLmFjdGlvbi1pbmZvIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBtaW4td2lkdGg6IDA7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGdhcDogMXB4O1xuICAgIH1cbiAgICAuYWN0aW9uLWRlc2Mge1xuICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgY29sb3I6ICNjYmQ1ZTE7XG4gICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIH1cbiAgICAuYWN0aW9uLXNlbGVjdG9yIHtcbiAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xuICAgICAgZm9udC1mYW1pbHk6ICdDYXNjYWRpYSBDb2RlJywgJ0NvbnNvbGFzJywgbW9ub3NwYWNlO1xuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgICB9XG4gICAgLmFjdGlvbi10aW1lIHtcbiAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgIGNvbG9yOiAjNDc1NTY5O1xuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICB9XG4gICAgLnJlbW92ZS1idG4ge1xuICAgICAgYmFja2dyb3VuZDogbm9uZTtcbiAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgIGNvbG9yOiAjNDc1NTY5O1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgZm9udC1zaXplOiAxMnB4O1xuICAgICAgcGFkZGluZzogMnB4IDVweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICAgIG9wYWNpdHk6IDA7XG4gICAgICB0cmFuc2l0aW9uOiBvcGFjaXR5IDAuMTVzLCBjb2xvciAwLjE1cztcbiAgICB9XG4gICAgLmFjdGlvbi1yb3c6aG92ZXIgLnJlbW92ZS1idG4geyBvcGFjaXR5OiAxOyB9XG4gICAgLnJlbW92ZS1idG46aG92ZXIgeyBjb2xvcjogI2Y4NzE3MTsgfVxuXG4gICAgLmFjdGlvbi1kZXRhaWwge1xuICAgICAgcGFkZGluZzogMTBweCAxNHB4O1xuICAgICAgYmFja2dyb3VuZDogcmdiYSgxNSwyMyw0MiwwLjcpO1xuICAgICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICMxZTI5M2I7XG4gICAgfVxuICAgIC5kZXRhaWwtZ3JpZCB7XG4gICAgICBkaXNwbGF5OiBncmlkO1xuICAgICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiBhdXRvIDFmcjtcbiAgICAgIGdhcDogNHB4IDEwcHg7XG4gICAgICBtYXJnaW4tYm90dG9tOiA4cHg7XG4gICAgICBhbGlnbi1pdGVtczogc3RhcnQ7XG4gICAgfVxuICAgIC5kZXRhaWwtbGFiZWwgeyBmb250LXNpemU6IDEwcHg7IGNvbG9yOiAjNjQ3NDhiOyBwYWRkaW5nLXRvcDogMnB4OyB3aGl0ZS1zcGFjZTogbm93cmFwOyB9XG4gICAgLmRldGFpbC12YWx1ZSB7XG4gICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICBjb2xvcjogIzkzYzVmZDtcbiAgICAgIGZvbnQtZmFtaWx5OiAnQ2FzY2FkaWEgQ29kZScsICdDb25zb2xhcycsIG1vbm9zcGFjZTtcbiAgICAgIHdvcmQtYnJlYWs6IGJyZWFrLWFsbDtcbiAgICB9XG4gICAgLnVybC12YWwgeyBjb2xvcjogIzZlZTdiNzsgfVxuICAgIC5zdHJhdGVneS1iYWRnZSB7XG4gICAgICBmb250LXNpemU6IDEwcHg7XG4gICAgICBwYWRkaW5nOiAxcHggNnB4O1xuICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xuICAgICAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcbiAgICB9XG4gICAgLnN0cmF0LWRhdGEtdGVzdGlkIHsgYmFja2dyb3VuZDogIzA2NGUzYjsgY29sb3I6ICMzNGQzOTk7IH1cbiAgICAuc3RyYXQtZGF0YS1jeSAgICAgeyBiYWNrZ3JvdW5kOiAjMDY0ZTNiOyBjb2xvcjogIzM0ZDM5OTsgfVxuICAgIC5zdHJhdC1pZCAgICAgICAgICB7IGJhY2tncm91bmQ6ICMxZTNhOGE7IGNvbG9yOiAjOTNjNWZkOyB9XG4gICAgLnN0cmF0LW5hbWUgICAgICAgIHsgYmFja2dyb3VuZDogIzQ0MzM3YTsgY29sb3I6ICNjNGI1ZmQ7IH1cbiAgICAuc3RyYXQtY2xhc3MgICAgICAgeyBiYWNrZ3JvdW5kOiAjMzc0MTUxOyBjb2xvcjogIzljYTNhZjsgfVxuICAgIC5zdHJhdC1jb21iaW5lZCAgICB7IGJhY2tncm91bmQ6ICMyOTI1MjQ7IGNvbG9yOiAjZDZkM2QxOyB9XG5cbiAgICAubm90ZS1hcmVhIHsgbWFyZ2luLXRvcDogNnB4OyB9XG4gICAgLm5vdGUtaW5wdXQge1xuICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgICAgYmFja2dyb3VuZDogIzBmMTcyYTtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICMzMzQxNTU7XG4gICAgICBjb2xvcjogI2UyZThmMDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgICAgIHBhZGRpbmc6IDZweCA4cHg7XG4gICAgICBmb250LXNpemU6IDExcHg7XG4gICAgICByZXNpemU6IHZlcnRpY2FsO1xuICAgIH1cbiAgICAubm90ZS1pbnB1dDpmb2N1cyB7IG91dGxpbmU6IG5vbmU7IGJvcmRlci1jb2xvcjogIzNiODJmNjsgfVxuICBgXSxcbn0pXG5leHBvcnQgY2xhc3MgQWN0aW9uTGlzdENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIHNlc3Npb246IFJlY29yZGluZ1Nlc3Npb24gfCBudWxsID0gbnVsbDtcbiAgQE91dHB1dCgpIHJlbW92ZUFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICBAT3V0cHV0KCkgYWRkTm90ZSA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogc3RyaW5nOyBub3RlOiBzdHJpbmcgfT4oKTtcblxuICBleHBhbmRlZElkID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICBub3RlTWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgdG9nZ2xlRXhwYW5kKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmV4cGFuZGVkSWQudXBkYXRlKHYgPT4gdiA9PT0gaWQgPyBudWxsIDogaWQpO1xuICB9XG5cbiAgb25SZW1vdmUoaWQ6IHN0cmluZywgZTogRXZlbnQpOiB2b2lkIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMucmVtb3ZlQWN0aW9uLmVtaXQoaWQpO1xuICB9XG5cbiAgb25BZGROb3RlKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmFkZE5vdGUuZW1pdCh7IGlkLCBub3RlOiB0aGlzLm5vdGVNYXBbaWRdID8/ICcnIH0pO1xuICB9XG5cbiAgZ2V0QWN0aW9uSWNvbih0eXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGljb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgY2xpY2s6ICAgICAgICfwn5GGJyxcbiAgICAgIGRibGNsaWNrOiAgICAn8J+RhvCfkYYnLFxuICAgICAgaW5wdXQ6ICAgICAgICfijKjvuI8nLFxuICAgICAgc2VsZWN0OiAgICAgICfwn5OLJyxcbiAgICAgIHN1Ym1pdDogICAgICAn8J+TpCcsXG4gICAgICBuYXZpZ2F0aW9uOiAgJ/CflJcnLFxuICAgICAga2V5cHJlc3M6ICAgICfijKjvuI8nLFxuICAgICAgc2Nyb2xsOiAgICAgICfihpXvuI8nLFxuICAgICAgaG92ZXI6ICAgICAgICfwn5ax77iPJyxcbiAgICAgIGFzc2VydGlvbjogICAn4pyFJyxcbiAgICAgIHNjcmVlbnNob3Q6ICAn8J+TuCcsXG4gICAgfTtcbiAgICByZXR1cm4gaWNvbnNbdHlwZV0gPz8gJ+KAoic7XG4gIH1cblxuICBmb3JtYXRUaW1lKHRzOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBuZXcgRGF0ZSh0cykudG9Mb2NhbGVUaW1lU3RyaW5nKCdkZS1ERScsIHsgaG91cjogJzItZGlnaXQnLCBtaW51dGU6ICcyLWRpZ2l0Jywgc2Vjb25kOiAnMi1kaWdpdCcgfSk7XG4gIH1cblxuICBmb3JtYXREdXJhdGlvbihzdGFydDogbnVtYmVyLCBlbmQ6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgcyA9IE1hdGgucm91bmQoKGVuZCAtIHN0YXJ0KSAvIDEwMDApO1xuICAgIHJldHVybiBzIDwgNjAgPyBgJHtzfXNgIDogYCR7TWF0aC5mbG9vcihzLzYwKX1tICR7cyU2MH1zYDtcbiAgfVxufVxuIl19
|
|
220
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVidWctcmVjb3JkZXIvc3JjL2xpYi9hY3Rpb24tbGlzdC9hY3Rpb24tbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDL0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBK083QyxNQUFNLE9BQU8sbUJBQW1CO0lBNU9oQztRQTZPVyxZQUFPLEdBQTRCLElBQUksQ0FBQztRQUN2QyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFDMUMsWUFBTyxHQUFHLElBQUksWUFBWSxFQUFnQyxDQUFDO1FBRXJFLGVBQVUsR0FBRyxNQUFNLENBQWdCLElBQUksQ0FBQyxDQUFDO1FBQ3pDLFlBQU8sR0FBMkIsRUFBRSxDQUFDO0tBd0N0QztJQXRDQyxZQUFZLENBQUMsRUFBVTtRQUNyQixJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELFFBQVEsQ0FBQyxFQUFVLEVBQUUsQ0FBUTtRQUMzQixDQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUVELFNBQVMsQ0FBQyxFQUFVO1FBQ2xCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELGFBQWEsQ0FBQyxJQUFZO1FBQ3hCLE1BQU0sS0FBSyxHQUEyQjtZQUNwQyxLQUFLLEVBQVEsSUFBSTtZQUNqQixRQUFRLEVBQUssTUFBTTtZQUNuQixLQUFLLEVBQVEsSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixVQUFVLEVBQUcsSUFBSTtZQUNqQixRQUFRLEVBQUssSUFBSTtZQUNqQixNQUFNLEVBQU8sSUFBSTtZQUNqQixLQUFLLEVBQVEsS0FBSztZQUNsQixTQUFTLEVBQUksR0FBRztZQUNoQixVQUFVLEVBQUcsSUFBSTtTQUNsQixDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDO0lBQzVCLENBQUM7SUFFRCxVQUFVLENBQUMsRUFBVTtRQUNuQixPQUFPLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLENBQUMsQ0FBQztJQUM3RyxDQUFDO0lBRUQsY0FBYyxDQUFDLEtBQWEsRUFBRSxHQUFXO1FBQ3ZDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7UUFDM0MsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBQyxFQUFFLEdBQUcsQ0FBQztJQUM1RCxDQUFDOytHQTdDVSxtQkFBbUI7bUdBQW5CLG1CQUFtQiwwS0F4T3BCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdGVCxvakZBakZTLFlBQVksOEJBQUUsV0FBVzs7NEZBeU94QixtQkFBbUI7a0JBNU8vQixTQUFTOytCQUNFLGlCQUFpQixjQUNmLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxXQUFXLENBQUMsWUFDMUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0ZUOzhCQXlKUSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0ksWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxPQUFPO3NCQUFoQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgUmVjb3JkZWRBY3Rpb24sIFJlY29yZGluZ1Nlc3Npb24gfSBmcm9tICcuLi9tb2RlbHMvcmVjb3JkZWQtYWN0aW9uLm1vZGVsJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnYXBwLWFjdGlvbi1saXN0JyxcclxuICBzdGFuZGFsb25lOiB0cnVlLFxyXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEZvcm1zTW9kdWxlXSxcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgPGRpdiBjbGFzcz1cImFjdGlvbi1saXN0XCIgZGF0YS1kZWJ1Zy1wYW5lbD5cclxuICAgICAgQGlmICghc2Vzc2lvbiB8fCBzZXNzaW9uLmFjdGlvbnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImVtcHR5LXN0YXRlXCI+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktaWNvblwiPvCfjqw8L2Rpdj5cclxuICAgICAgICAgIDxwPk5vY2gga2VpbmUgQWt0aW9uZW4gYXVmZ2V6ZWljaG5ldC48L3A+XHJcbiAgICAgICAgICA8cCBjbGFzcz1cImhpbnRcIj5TdGFydGUgZGllIEF1Zm5haG1lIHVuZCBpbnRlcmFnaWVyZSBtaXQgZGVyIEFwcC48L3A+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2hvcnRjdXRzLWhpbnRcIj5cclxuICAgICAgICAgICAgPGtiZD5DdHJsK1NoaWZ0K0Q8L2tiZD4gUGFuZWwgJm5ic3A7XHJcbiAgICAgICAgICAgIDxrYmQ+Q3RybCtTaGlmdCtSPC9rYmQ+IFJlY29yZFxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJsaXN0LWhlYWRlclwiPlxyXG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJsaXN0LWNvdW50XCI+e3sgc2Vzc2lvbi5hY3Rpb25zLmxlbmd0aCB9fSBBa3Rpb25lbjwvc3Bhbj5cclxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGlzdC1kdXJhdGlvblwiPlxyXG4gICAgICAgICAgICBAaWYgKHNlc3Npb24uZW5kVGltZSkge1xyXG4gICAgICAgICAgICAgIHt7IGZvcm1hdER1cmF0aW9uKHNlc3Npb24uc3RhcnRUaW1lLCBzZXNzaW9uLmVuZFRpbWUpIH19XHJcbiAgICAgICAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgICAgICAgIExpdmVcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICBAZm9yIChhY3Rpb24gb2Ygc2Vzc2lvbi5hY3Rpb25zOyB0cmFjayBhY3Rpb24uaWQ7IGxldCBpID0gJGluZGV4KSB7XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLWl0ZW1cIiBbY2xhc3MuZXhwYW5kZWRdPVwiZXhwYW5kZWRJZCgpID09PSBhY3Rpb24uaWRcIj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1yb3dcIiAoY2xpY2spPVwidG9nZ2xlRXhwYW5kKGFjdGlvbi5pZClcIj5cclxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi1pbmRleFwiPnt7IGkgKyAxIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWN0aW9uLXR5cGUtYmFkZ2VcIiBbY2xhc3NdPVwiJ3R5cGUtJyArIGFjdGlvbi50eXBlXCI+XHJcbiAgICAgICAgICAgICAgICB7eyBnZXRBY3Rpb25JY29uKGFjdGlvbi50eXBlKSB9fVxyXG4gICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLWluZm9cIj5cclxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWN0aW9uLWRlc2NcIj57eyBhY3Rpb24uZGVzY3JpcHRpb24gfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi1zZWxlY3RvclwiPnt7IGFjdGlvbi5zZWxlY3RvciB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFjdGlvbi10aW1lXCI+e3sgZm9ybWF0VGltZShhY3Rpb24udGltZXN0YW1wKSB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInJlbW92ZS1idG5cIlxyXG4gICAgICAgICAgICAgICAgZGF0YS1kZWJ1Zy1wYW5lbFxyXG4gICAgICAgICAgICAgICAgdGl0bGU9XCJBa3Rpb24gZW50ZmVybmVuXCJcclxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvblJlbW92ZShhY3Rpb24uaWQsICRldmVudClcIlxyXG4gICAgICAgICAgICAgID7inJU8L2J1dHRvbj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICBAaWYgKGV4cGFuZGVkSWQoKSA9PT0gYWN0aW9uLmlkKSB7XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1kZXRhaWxcIiBkYXRhLWRlYnVnLXBhbmVsPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1ncmlkXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+U2VsZWN0b3I8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+e3sgYWN0aW9uLnNlbGVjdG9yIH19PC9jb2RlPlxyXG4gICAgICAgICAgICAgICAgICBAaWYgKGFjdGlvbi52YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWxhYmVsXCI+V2VydDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICA8Y29kZSBjbGFzcz1cImRldGFpbC12YWx1ZVwiPnt7IGFjdGlvbi52YWx1ZSB9fTwvY29kZT5cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICBAaWYgKGFjdGlvbi5lbGVtZW50Py50YWdOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5FbGVtZW50PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiZGV0YWlsLXZhbHVlXCI+Jmx0O3t7IGFjdGlvbi5lbGVtZW50Py50YWdOYW1lIH19Jmd0OzwvY29kZT5cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRldGFpbC1sYWJlbFwiPlN0cmF0ZWdpZTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtdmFsdWUgc3RyYXRlZ3ktYmFkZ2VcIiBbY2xhc3NdPVwiJ3N0cmF0LScgKyBhY3Rpb24uc2VsZWN0b3JTdHJhdGVneVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIHt7IGFjdGlvbi5zZWxlY3RvclN0cmF0ZWd5IH19XHJcbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtbGFiZWxcIj5VUkw8L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgIDxjb2RlIGNsYXNzPVwiZGV0YWlsLXZhbHVlIHVybC12YWxcIj57eyBhY3Rpb24udXJsIH19PC9jb2RlPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibm90ZS1hcmVhXCI+XHJcbiAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYVxyXG4gICAgICAgICAgICAgICAgICAgIGRhdGEtZGVidWctcGFuZWxcclxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cIm5vdGUtaW5wdXRcIlxyXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwibm90ZU1hcFthY3Rpb24uaWRdXCJcclxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIk5vdGl6IHp1IGRpZXNlciBBa3Rpb24uLi5cIlxyXG4gICAgICAgICAgICAgICAgICAgIHJvd3M9XCIyXCJcclxuICAgICAgICAgICAgICAgICAgICAoYmx1cik9XCJvbkFkZE5vdGUoYWN0aW9uLmlkKVwiXHJcbiAgICAgICAgICAgICAgICAgID48L3RleHRhcmVhPlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgPC9kaXY+XHJcbiAgYCxcclxuICBzdHlsZXM6IFtgXHJcbiAgICAuYWN0aW9uLWxpc3QgeyBwYWRkaW5nOiAwOyB9XHJcblxyXG4gICAgLmVtcHR5LXN0YXRlIHtcclxuICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG4gICAgICBwYWRkaW5nOiAzMnB4IDIwcHg7XHJcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xyXG4gICAgfVxyXG4gICAgLmVtcHR5LWljb24geyBmb250LXNpemU6IDQwcHg7IG1hcmdpbi1ib3R0b206IDEwcHg7IH1cclxuICAgIC5lbXB0eS1zdGF0ZSBwIHsgbWFyZ2luOiA0cHggMDsgZm9udC1zaXplOiAxM3B4OyB9XHJcbiAgICAuaGludCB7IGZvbnQtc2l6ZTogMTFweDsgY29sb3I6ICM0NzU1Njk7IH1cclxuICAgIC5zaG9ydGN1dHMtaGludCB7XHJcbiAgICAgIG1hcmdpbi10b3A6IDEycHg7XHJcbiAgICAgIGZvbnQtc2l6ZTogMTFweDtcclxuICAgICAgY29sb3I6ICM0NzU1Njk7XHJcbiAgICB9XHJcbiAgICBrYmQge1xyXG4gICAgICBiYWNrZ3JvdW5kOiAjMWUyOTNiO1xyXG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjMzM0MTU1O1xyXG4gICAgICBjb2xvcjogIzk0YTNiODtcclxuICAgICAgcGFkZGluZzogMnB4IDZweDtcclxuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xyXG4gICAgICBmb250LXNpemU6IDEwcHg7XHJcbiAgICB9XHJcblxyXG4gICAgLmxpc3QtaGVhZGVyIHtcclxuICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xyXG4gICAgICBwYWRkaW5nOiA4cHggMTRweDtcclxuICAgICAgZm9udC1zaXplOiAxMXB4O1xyXG4gICAgICBjb2xvcjogIzY0NzQ4YjtcclxuICAgICAgYmFja2dyb3VuZDogIzBmMTcyYTtcclxuICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICMxZTI5M2I7XHJcbiAgICAgIHBvc2l0aW9uOiBzdGlja3k7XHJcbiAgICAgIHRvcDogMDtcclxuICAgIH1cclxuXHJcbiAgICAuYWN0aW9uLWl0ZW0ge1xyXG4gICAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgIzFlMjkzYjtcclxuICAgICAgdHJhbnNpdGlvbjogYmFja2dyb3VuZCAwLjFzO1xyXG4gICAgfVxyXG4gICAgLmFjdGlvbi1pdGVtOmhvdmVyIHsgYmFja2dyb3VuZDogcmdiYSgzMCw0MSw1OSwwLjUpOyB9XHJcbiAgICAuYWN0aW9uLWl0ZW0uZXhwYW5kZWQgeyBiYWNrZ3JvdW5kOiAjMWUyOTNiOyB9XHJcblxyXG4gICAgLmFjdGlvbi1yb3cge1xyXG4gICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xyXG4gICAgICBwYWRkaW5nOiA4cHggMTBweDtcclxuICAgICAgZ2FwOiA4cHg7XHJcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcclxuICAgIH1cclxuICAgIC5hY3Rpb24taW5kZXgge1xyXG4gICAgICBjb2xvcjogIzQ3NTU2OTtcclxuICAgICAgZm9udC1zaXplOiAxMHB4O1xyXG4gICAgICBtaW4td2lkdGg6IDE4cHg7XHJcbiAgICAgIHRleHQtYWxpZ246IHJpZ2h0O1xyXG4gICAgfVxyXG4gICAgLmFjdGlvbi10eXBlLWJhZGdlIHtcclxuICAgICAgZm9udC1zaXplOiAxNHB4O1xyXG4gICAgICBtaW4td2lkdGg6IDIwcHg7XHJcbiAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcclxuICAgIH1cclxuICAgIC5hY3Rpb24taW5mbyB7XHJcbiAgICAgIGZsZXg6IDE7XHJcbiAgICAgIG1pbi13aWR0aDogMDtcclxuICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcclxuICAgICAgZ2FwOiAxcHg7XHJcbiAgICB9XHJcbiAgICAuYWN0aW9uLWRlc2Mge1xyXG4gICAgICBmb250LXNpemU6IDEycHg7XHJcbiAgICAgIGNvbG9yOiAjY2JkNWUxO1xyXG4gICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xyXG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xyXG4gICAgICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcclxuICAgIH1cclxuICAgIC5hY3Rpb24tc2VsZWN0b3Ige1xyXG4gICAgICBmb250LXNpemU6IDEwcHg7XHJcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xyXG4gICAgICBmb250LWZhbWlseTogJ0Nhc2NhZGlhIENvZGUnLCAnQ29uc29sYXMnLCBtb25vc3BhY2U7XHJcbiAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XHJcbiAgICAgIG92ZXJmbG93OiBoaWRkZW47XHJcbiAgICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xyXG4gICAgfVxyXG4gICAgLmFjdGlvbi10aW1lIHtcclxuICAgICAgZm9udC1zaXplOiAxMHB4O1xyXG4gICAgICBjb2xvcjogIzQ3NTU2OTtcclxuICAgICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcclxuICAgIH1cclxuICAgIC5yZW1vdmUtYnRuIHtcclxuICAgICAgYmFja2dyb3VuZDogbm9uZTtcclxuICAgICAgYm9yZGVyOiBub25lO1xyXG4gICAgICBjb2xvcjogIzQ3NTU2OTtcclxuICAgICAgY3Vyc29yOiBwb2ludGVyO1xyXG4gICAgICBmb250LXNpemU6IDEycHg7XHJcbiAgICAgIHBhZGRpbmc6IDJweCA1cHg7XHJcbiAgICAgIGJvcmRlci1yYWRpdXM6IDNweDtcclxuICAgICAgb3BhY2l0eTogMDtcclxuICAgICAgdHJhbnNpdGlvbjogb3BhY2l0eSAwLjE1cywgY29sb3IgMC4xNXM7XHJcbiAgICB9XHJcbiAgICAuYWN0aW9uLXJvdzpob3ZlciAucmVtb3ZlLWJ0biB7IG9wYWNpdHk6IDE7IH1cclxuICAgIC5yZW1vdmUtYnRuOmhvdmVyIHsgY29sb3I6ICNmODcxNzE7IH1cclxuXHJcbiAgICAuYWN0aW9uLWRldGFpbCB7XHJcbiAgICAgIHBhZGRpbmc6IDEwcHggMTRweDtcclxuICAgICAgYmFja2dyb3VuZDogcmdiYSgxNSwyMyw0MiwwLjcpO1xyXG4gICAgICBib3JkZXItdG9wOiAxcHggc29saWQgIzFlMjkzYjtcclxuICAgIH1cclxuICAgIC5kZXRhaWwtZ3JpZCB7XHJcbiAgICAgIGRpc3BsYXk6IGdyaWQ7XHJcbiAgICAgIGdyaWQtdGVtcGxhdGUtY29sdW1uczogYXV0byAxZnI7XHJcbiAgICAgIGdhcDogNHB4IDEwcHg7XHJcbiAgICAgIG1hcmdpbi1ib3R0b206IDhweDtcclxuICAgICAgYWxpZ24taXRlbXM6IHN0YXJ0O1xyXG4gICAgfVxyXG4gICAgLmRldGFpbC1sYWJlbCB7IGZvbnQtc2l6ZTogMTBweDsgY29sb3I6ICM2NDc0OGI7IHBhZGRpbmctdG9wOiAycHg7IHdoaXRlLXNwYWNlOiBub3dyYXA7IH1cclxuICAgIC5kZXRhaWwtdmFsdWUge1xyXG4gICAgICBmb250LXNpemU6IDExcHg7XHJcbiAgICAgIGNvbG9yOiAjOTNjNWZkO1xyXG4gICAgICBmb250LWZhbWlseTogJ0Nhc2NhZGlhIENvZGUnLCAnQ29uc29sYXMnLCBtb25vc3BhY2U7XHJcbiAgICAgIHdvcmQtYnJlYWs6IGJyZWFrLWFsbDtcclxuICAgIH1cclxuICAgIC51cmwtdmFsIHsgY29sb3I6ICM2ZWU3Yjc7IH1cclxuICAgIC5zdHJhdGVneS1iYWRnZSB7XHJcbiAgICAgIGZvbnQtc2l6ZTogMTBweDtcclxuICAgICAgcGFkZGluZzogMXB4IDZweDtcclxuICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xyXG4gICAgICBmb250LWZhbWlseTogbW9ub3NwYWNlO1xyXG4gICAgfVxyXG4gICAgLnN0cmF0LWRhdGEtdGVzdGlkIHsgYmFja2dyb3VuZDogIzA2NGUzYjsgY29sb3I6ICMzNGQzOTk7IH1cclxuICAgIC5zdHJhdC1kYXRhLWN5ICAgICB7IGJhY2tncm91bmQ6ICMwNjRlM2I7IGNvbG9yOiAjMzRkMzk5OyB9XHJcbiAgICAuc3RyYXQtaWQgICAgICAgICAgeyBiYWNrZ3JvdW5kOiAjMWUzYThhOyBjb2xvcjogIzkzYzVmZDsgfVxyXG4gICAgLnN0cmF0LW5hbWUgICAgICAgIHsgYmFja2dyb3VuZDogIzQ0MzM3YTsgY29sb3I6ICNjNGI1ZmQ7IH1cclxuICAgIC5zdHJhdC1jbGFzcyAgICAgICB7IGJhY2tncm91bmQ6ICMzNzQxNTE7IGNvbG9yOiAjOWNhM2FmOyB9XHJcbiAgICAuc3RyYXQtY29tYmluZWQgICAgeyBiYWNrZ3JvdW5kOiAjMjkyNTI0OyBjb2xvcjogI2Q2ZDNkMTsgfVxyXG5cclxuICAgIC5ub3RlLWFyZWEgeyBtYXJnaW4tdG9wOiA2cHg7IH1cclxuICAgIC5ub3RlLWlucHV0IHtcclxuICAgICAgd2lkdGg6IDEwMCU7XHJcbiAgICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XHJcbiAgICAgIGJhY2tncm91bmQ6ICMwZjE3MmE7XHJcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICMzMzQxNTU7XHJcbiAgICAgIGNvbG9yOiAjZTJlOGYwO1xyXG4gICAgICBib3JkZXItcmFkaXVzOiA1cHg7XHJcbiAgICAgIHBhZGRpbmc6IDZweCA4cHg7XHJcbiAgICAgIGZvbnQtc2l6ZTogMTFweDtcclxuICAgICAgcmVzaXplOiB2ZXJ0aWNhbDtcclxuICAgIH1cclxuICAgIC5ub3RlLWlucHV0OmZvY3VzIHsgb3V0bGluZTogbm9uZTsgYm9yZGVyLWNvbG9yOiAjM2I4MmY2OyB9XHJcbiAgYF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBY3Rpb25MaXN0Q29tcG9uZW50IHtcclxuICBASW5wdXQoKSBzZXNzaW9uOiBSZWNvcmRpbmdTZXNzaW9uIHwgbnVsbCA9IG51bGw7XHJcbiAgQE91dHB1dCgpIHJlbW92ZUFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xyXG4gIEBPdXRwdXQoKSBhZGROb3RlID0gbmV3IEV2ZW50RW1pdHRlcjx7IGlkOiBzdHJpbmc7IG5vdGU6IHN0cmluZyB9PigpO1xyXG5cclxuICBleHBhbmRlZElkID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xyXG4gIG5vdGVNYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcclxuXHJcbiAgdG9nZ2xlRXhwYW5kKGlkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuZXhwYW5kZWRJZC51cGRhdGUodiA9PiB2ID09PSBpZCA/IG51bGwgOiBpZCk7XHJcbiAgfVxyXG5cclxuICBvblJlbW92ZShpZDogc3RyaW5nLCBlOiBFdmVudCk6IHZvaWQge1xyXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIHRoaXMucmVtb3ZlQWN0aW9uLmVtaXQoaWQpO1xyXG4gIH1cclxuXHJcbiAgb25BZGROb3RlKGlkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuYWRkTm90ZS5lbWl0KHsgaWQsIG5vdGU6IHRoaXMubm90ZU1hcFtpZF0gPz8gJycgfSk7XHJcbiAgfVxyXG5cclxuICBnZXRBY3Rpb25JY29uKHR5cGU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBpY29uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcclxuICAgICAgY2xpY2s6ICAgICAgICfwn5GGJyxcclxuICAgICAgZGJsY2xpY2s6ICAgICfwn5GG8J+RhicsXHJcbiAgICAgIGlucHV0OiAgICAgICAn4oyo77iPJyxcclxuICAgICAgc2VsZWN0OiAgICAgICfwn5OLJyxcclxuICAgICAgc3VibWl0OiAgICAgICfwn5OkJyxcclxuICAgICAgbmF2aWdhdGlvbjogICfwn5SXJyxcclxuICAgICAga2V5cHJlc3M6ICAgICfijKjvuI8nLFxyXG4gICAgICBzY3JvbGw6ICAgICAgJ+KGle+4jycsXHJcbiAgICAgIGhvdmVyOiAgICAgICAn8J+Wse+4jycsXHJcbiAgICAgIGFzc2VydGlvbjogICAn4pyFJyxcclxuICAgICAgc2NyZWVuc2hvdDogICfwn5O4JyxcclxuICAgIH07XHJcbiAgICByZXR1cm4gaWNvbnNbdHlwZV0gPz8gJ+KAoic7XHJcbiAgfVxyXG5cclxuICBmb3JtYXRUaW1lKHRzOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIG5ldyBEYXRlKHRzKS50b0xvY2FsZVRpbWVTdHJpbmcoJ2RlLURFJywgeyBob3VyOiAnMi1kaWdpdCcsIG1pbnV0ZTogJzItZGlnaXQnLCBzZWNvbmQ6ICcyLWRpZ2l0JyB9KTtcclxuICB9XHJcblxyXG4gIGZvcm1hdER1cmF0aW9uKHN0YXJ0OiBudW1iZXIsIGVuZDogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHMgPSBNYXRoLnJvdW5kKChlbmQgLSBzdGFydCkgLyAxMDAwKTtcclxuICAgIHJldHVybiBzIDwgNjAgPyBgJHtzfXNgIDogYCR7TWF0aC5mbG9vcihzLzYwKX1tICR7cyU2MH1zYDtcclxuICB9XHJcbn1cclxuIl19
|