tango-app-ui-ai-audio 3.0.27 → 3.0.28
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.
|
@@ -42,6 +42,9 @@ export class TangoEchoComponent {
|
|
|
42
42
|
cardsLoading = false;
|
|
43
43
|
detailView = false;
|
|
44
44
|
analysisSearch = '';
|
|
45
|
+
get activeCohorts() {
|
|
46
|
+
return this.cohortList.filter((c) => c.metricsAdded > 0);
|
|
47
|
+
}
|
|
45
48
|
// Detail conversations (from cohort card click)
|
|
46
49
|
detailConversations = [];
|
|
47
50
|
detailPage = 1;
|
|
@@ -74,6 +77,31 @@ export class TangoEchoComponent {
|
|
|
74
77
|
}
|
|
75
78
|
this.waveformHeights = bars;
|
|
76
79
|
}
|
|
80
|
+
// ── Cohort Dropdown ─────────────────────────────────
|
|
81
|
+
cohortDropdownOpen = false;
|
|
82
|
+
cohortDropdownSearch = '';
|
|
83
|
+
toggleCohortDropdown() {
|
|
84
|
+
this.cohortDropdownOpen = !this.cohortDropdownOpen;
|
|
85
|
+
if (this.cohortDropdownOpen) {
|
|
86
|
+
this.cohortDropdownSearch = '';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
closeCohortDropdown() {
|
|
90
|
+
this.cohortDropdownOpen = false;
|
|
91
|
+
this.cohortDropdownSearch = '';
|
|
92
|
+
}
|
|
93
|
+
selectCohortFromDropdown(cohort) {
|
|
94
|
+
const id = cohort.cohortId || cohort.id || cohort._id || '';
|
|
95
|
+
this.cohortDropdownOpen = false;
|
|
96
|
+
this.cohortDropdownSearch = '';
|
|
97
|
+
this.onCohortDropdownChange(id);
|
|
98
|
+
}
|
|
99
|
+
get filteredDropdownCohorts() {
|
|
100
|
+
if (!this.cohortDropdownSearch)
|
|
101
|
+
return this.cohortList;
|
|
102
|
+
const q = this.cohortDropdownSearch.toLowerCase();
|
|
103
|
+
return this.cohortList.filter((c) => (c.cohortName || c.name || '').toLowerCase().includes(q));
|
|
104
|
+
}
|
|
77
105
|
// ── Filters Drawer ─────────────────────────────────
|
|
78
106
|
drawerOpen = false;
|
|
79
107
|
destroy$ = new Subject();
|
|
@@ -225,7 +253,9 @@ export class TangoEchoComponent {
|
|
|
225
253
|
cleanTranscription(text) {
|
|
226
254
|
if (!text)
|
|
227
255
|
return '';
|
|
228
|
-
return text
|
|
256
|
+
return text
|
|
257
|
+
.replace(/\[\d{2}:\d{2}\s*->\s*\d{2}:\d{2}\]\s*/g, '')
|
|
258
|
+
.replace(/\b(Staff|Customer)\s*:\s*/gi, '');
|
|
229
259
|
}
|
|
230
260
|
// Format duration from seconds (e.g. 514 → "8m 14s")
|
|
231
261
|
formatDuration(val) {
|
|
@@ -380,17 +410,16 @@ export class TangoEchoComponent {
|
|
|
380
410
|
this.audioService.listCohorts(this.clientId, 100, 0).pipe(takeUntil(this.destroy$)).subscribe({
|
|
381
411
|
next: (res) => {
|
|
382
412
|
this.cohortList = res?.data?.cohorts || [];
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
this.selectedCohortId = this.cohortList[0]?.cohortId || this.cohortList[0]?.id || this.cohortList[0]?._id || '';
|
|
386
|
-
}
|
|
413
|
+
// If a cohort was already selected (e.g. from dropdown), load its data
|
|
414
|
+
if (this.selectedCohortId) {
|
|
387
415
|
this.fetchCohortCards();
|
|
416
|
+
this.fetchDetailConversations();
|
|
388
417
|
}
|
|
389
418
|
},
|
|
390
419
|
error: () => { this.cohortList = []; }
|
|
391
420
|
});
|
|
392
421
|
}
|
|
393
|
-
//
|
|
422
|
+
// Select cohort from overview card click
|
|
394
423
|
selectCohortDetail(cohort) {
|
|
395
424
|
this.selectedCohortId = cohort.cohortId || cohort.id || cohort._id || '';
|
|
396
425
|
this.selectedCohortName = cohort.cohortName || cohort.name || '';
|
|
@@ -401,11 +430,20 @@ export class TangoEchoComponent {
|
|
|
401
430
|
this.fetchCohortCards();
|
|
402
431
|
this.fetchDetailConversations();
|
|
403
432
|
}
|
|
404
|
-
|
|
433
|
+
backToOverview() {
|
|
434
|
+
this.detailView = false;
|
|
435
|
+
this.selectedCohortId = '';
|
|
436
|
+
this.selectedCohortName = '';
|
|
437
|
+
this.cohortCards = [];
|
|
438
|
+
this.detailPageConvs = [];
|
|
439
|
+
this.detailConversations = [];
|
|
440
|
+
}
|
|
441
|
+
// Change cohort from dropdown
|
|
405
442
|
onCohortDropdownChange(cohortId) {
|
|
406
443
|
this.selectedCohortId = cohortId;
|
|
407
444
|
const cohort = this.cohortList.find((c) => (c.cohortId || c.id || c._id) === cohortId);
|
|
408
445
|
this.selectedCohortName = cohort?.cohortName || cohort?.name || '';
|
|
446
|
+
this.detailView = true;
|
|
409
447
|
this.selectedCardId = '';
|
|
410
448
|
this.selectedCardName = '';
|
|
411
449
|
this.detailPage = 1;
|
|
@@ -434,6 +472,7 @@ export class TangoEchoComponent {
|
|
|
434
472
|
// Parse cohort analysis (same as audio-page)
|
|
435
473
|
parseCohortAnalysis(analysis) {
|
|
436
474
|
const cards = [];
|
|
475
|
+
const numericRows = [];
|
|
437
476
|
const skipKeys = new Set(['totalAudioAvailable', 'cohortType', 'dateRange', 'uniquePitches']);
|
|
438
477
|
this.totalAudio = analysis.totalAudioAvailable || 0;
|
|
439
478
|
for (const key of Object.keys(analysis)) {
|
|
@@ -446,26 +485,42 @@ export class TangoEchoComponent {
|
|
|
446
485
|
const type = section.type;
|
|
447
486
|
if (!values.length)
|
|
448
487
|
continue;
|
|
488
|
+
// Common fields from section
|
|
489
|
+
const description = section.computation_note || section.computationNote || section.description || section.desc || '';
|
|
490
|
+
const shortDescription = section.shortDescription || section.short_description || '';
|
|
491
|
+
const status = section.status || section.sentiment || '';
|
|
492
|
+
const applicableCount = section.applicable_count ?? section.applicableCount ?? null;
|
|
449
493
|
if (type === 'BOOLEAN_BASKET') {
|
|
494
|
+
const cardName = section.name || key;
|
|
495
|
+
const isFunnel = cardName.toLowerCase().includes('funnel');
|
|
450
496
|
cards.push({
|
|
451
497
|
key,
|
|
452
|
-
name:
|
|
498
|
+
name: cardName,
|
|
453
499
|
type: 'BOOLEAN_BASKET',
|
|
500
|
+
isFunnel,
|
|
501
|
+
applicableCount,
|
|
502
|
+
description,
|
|
503
|
+
shortDescription,
|
|
504
|
+
status,
|
|
454
505
|
booleanRows: values.map((item) => ({
|
|
455
506
|
id: item._id || '',
|
|
456
507
|
label: item.name,
|
|
457
508
|
responses: item.Responses ?? item.count ?? 0,
|
|
458
509
|
score: item.score ?? 0
|
|
459
|
-
}))
|
|
510
|
+
})).sort((a, b) => b.responses - a.responses)
|
|
460
511
|
});
|
|
461
512
|
}
|
|
462
513
|
else if (type === 'NUMERIC_SCALAR' || type === 'NUMERIC_ARRAY') {
|
|
463
514
|
const item = values[0] || {};
|
|
464
|
-
|
|
515
|
+
const scale = section.scale || {};
|
|
516
|
+
numericRows.push({
|
|
465
517
|
key,
|
|
466
518
|
name: section.name || key,
|
|
467
|
-
|
|
468
|
-
|
|
519
|
+
description,
|
|
520
|
+
status,
|
|
521
|
+
avg: item.Avg ?? item.avg ?? 0,
|
|
522
|
+
min: item.Min ?? item.min ?? scale.min ?? section.min ?? null,
|
|
523
|
+
max: item.Max ?? item.max ?? scale.max ?? section.max ?? null
|
|
469
524
|
});
|
|
470
525
|
}
|
|
471
526
|
else if (type === 'SUBJECTIVE' || type === 'SUBJECTIVE_COUNT') {
|
|
@@ -473,6 +528,10 @@ export class TangoEchoComponent {
|
|
|
473
528
|
key,
|
|
474
529
|
name: section.name || key,
|
|
475
530
|
type,
|
|
531
|
+
applicableCount,
|
|
532
|
+
description,
|
|
533
|
+
shortDescription,
|
|
534
|
+
status,
|
|
476
535
|
subjectiveRows: values.map((item) => ({
|
|
477
536
|
_id: item._id || '',
|
|
478
537
|
reasoning: item.reasoning || '',
|
|
@@ -482,6 +541,25 @@ export class TangoEchoComponent {
|
|
|
482
541
|
});
|
|
483
542
|
}
|
|
484
543
|
}
|
|
544
|
+
// Group all numeric scores into one card
|
|
545
|
+
if (numericRows.length > 0) {
|
|
546
|
+
cards.push({
|
|
547
|
+
key: 'numericScores',
|
|
548
|
+
name: 'Average Scores',
|
|
549
|
+
type: 'NUMERIC_GROUP',
|
|
550
|
+
numericRows
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
// Insert unique pitches card if present (same as audio-page)
|
|
554
|
+
if (analysis.uniquePitches && Array.isArray(analysis.uniquePitches)) {
|
|
555
|
+
const pitchInsertIdx = cards.length >= 2 ? 2 : cards.length;
|
|
556
|
+
cards.splice(pitchInsertIdx, 0, {
|
|
557
|
+
key: 'uniquePitches',
|
|
558
|
+
name: 'Pitch Keywords Tracker',
|
|
559
|
+
type: 'UNIQUE_PITCHES',
|
|
560
|
+
pitchRows: analysis.uniquePitches.map((p) => ({ id: p.pitchId, desc: p.description }))
|
|
561
|
+
});
|
|
562
|
+
}
|
|
485
563
|
return cards;
|
|
486
564
|
}
|
|
487
565
|
// Card row click (same as audio-page onCardRowClick)
|
|
@@ -491,15 +569,9 @@ export class TangoEchoComponent {
|
|
|
491
569
|
onCardRowClick(id, name) {
|
|
492
570
|
this.selectedCardId = id || '';
|
|
493
571
|
this.selectedCardName = id ? '' : (name || '');
|
|
494
|
-
this.detailView = true;
|
|
495
572
|
this.detailPage = 1;
|
|
496
573
|
this.fetchDetailConversations();
|
|
497
574
|
}
|
|
498
|
-
backToCards() {
|
|
499
|
-
this.detailView = false;
|
|
500
|
-
this.selectedCardId = '';
|
|
501
|
-
this.selectedCardName = '';
|
|
502
|
-
}
|
|
503
575
|
fetchDetailConversations() {
|
|
504
576
|
this.detailLoading = true;
|
|
505
577
|
const payload = {
|
|
@@ -522,6 +594,7 @@ export class TangoEchoComponent {
|
|
|
522
594
|
this.detailPageConvs = this.detailConversations;
|
|
523
595
|
if (this.detailPageConvs.length > 0) {
|
|
524
596
|
this.detailOpenId = this.detailPageConvs[0].audioId;
|
|
597
|
+
this.loadConvDetail(this.detailPageConvs[0]);
|
|
525
598
|
}
|
|
526
599
|
this.detailLoading = false;
|
|
527
600
|
},
|
|
@@ -684,12 +757,57 @@ export class TangoEchoComponent {
|
|
|
684
757
|
trackById(index, item) {
|
|
685
758
|
return item?.id || item?._id || item?.doc_id || index;
|
|
686
759
|
}
|
|
760
|
+
getStatusBadge(status) {
|
|
761
|
+
if (!status)
|
|
762
|
+
return { bg: '', color: '' };
|
|
763
|
+
const s = status.toLowerCase();
|
|
764
|
+
if (s.includes('positive') || s.includes('strong') || s.includes('good') || s.includes('confident') || s.includes('excellent'))
|
|
765
|
+
return { bg: '#D1FAE5', color: '#065F46' };
|
|
766
|
+
if (s.includes('warning') || s.includes('moderate') || s.includes('room to improve') || s.includes('average'))
|
|
767
|
+
return { bg: '#FEF3C7', color: '#92400E' };
|
|
768
|
+
if (s.includes('negative') || s.includes('weak') || s.includes('poor') || s.includes('critical'))
|
|
769
|
+
return { bg: '#FEE2E2', color: '#991B1B' };
|
|
770
|
+
return { bg: '#F0F4FF', color: '#1A2B4B' };
|
|
771
|
+
}
|
|
772
|
+
formatMetricValue(v) {
|
|
773
|
+
if (v.score != null) {
|
|
774
|
+
const s = v.score;
|
|
775
|
+
if (typeof s === 'number')
|
|
776
|
+
return s + '%';
|
|
777
|
+
const str = String(s);
|
|
778
|
+
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
779
|
+
}
|
|
780
|
+
const val = v.Total ?? v.total ?? v.Avg ?? v.avg ?? v.count;
|
|
781
|
+
if (typeof val === 'string') {
|
|
782
|
+
return val.charAt(0).toUpperCase() + val.slice(1).toLowerCase();
|
|
783
|
+
}
|
|
784
|
+
return val != null ? String(val) : '';
|
|
785
|
+
}
|
|
786
|
+
getScoreColor(score) {
|
|
787
|
+
if (score >= 35)
|
|
788
|
+
return '#0077E6';
|
|
789
|
+
if (score >= 20)
|
|
790
|
+
return '#00A3FF';
|
|
791
|
+
if (score >= 10)
|
|
792
|
+
return '#4DC3FF';
|
|
793
|
+
if (score >= 5)
|
|
794
|
+
return '#8AD8FF';
|
|
795
|
+
if (score >= 2)
|
|
796
|
+
return '#BDE8FF';
|
|
797
|
+
return '#D9F1FF';
|
|
798
|
+
}
|
|
799
|
+
hasSearchMatch(list, search, key1, key2) {
|
|
800
|
+
if (!search)
|
|
801
|
+
return true;
|
|
802
|
+
const q = search.toLowerCase();
|
|
803
|
+
return list.some(item => (item[key1] || item[key2] || '').toLowerCase().includes(q));
|
|
804
|
+
}
|
|
687
805
|
Math = Math;
|
|
688
806
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TangoEchoComponent, deps: [{ token: i1.AudioService }, { token: i2.ActivatedRoute }, { token: i3.GlobalStateService }], target: i0.ɵɵFactoryTarget.Component });
|
|
689
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TangoEchoComponent, selector: "lib-tango-echo", ngImport: i0, template: "<div class=\"echo-page\">\n <div class=\"echo-content\">\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 CONVERSATIONS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'conversations'\">\n\n <!-- Tango AI Header -->\n <div class=\"tango-ai-header\">\n <div class=\"tango-ai-logo\">\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M12 2l2.09 6.26L20 10l-5.91 1.74L12 18l-2.09-6.26L4 10l5.91-1.74L12 2z\"/></svg>\n </div>\n <div style=\"text-align:center;\">\n <div class=\"tango-ai-title\">Tango AI</div>\n <div class=\"tango-ai-subtitle\">Analyse conversations, stores & staff performance</div>\n </div>\n </div>\n\n <!-- Search Card -->\n <div class=\"echo-search-card\">\n <input type=\"text\" class=\"echo-search-input\" placeholder=\"Ask anything... 'Which stores are not performing well?'\" [(ngModel)]=\"convSearchQuery\" (keyup.enter)=\"sendConvQuery()\">\n <button class=\"echo-search-send\" (click)=\"sendConvQuery()\" [disabled]=\"!convSearchQuery?.trim()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </div>\n\n <!-- AI Response -->\n <div class=\"echo-ai-response\" *ngIf=\"convAiLoading || convAiReply\">\n <div *ngIf=\"convAiLoading\" class=\"typing\">\n <span class=\"typing-dot\"></span><span class=\"typing-dot\"></span><span class=\"typing-dot\"></span>\n </div>\n <p *ngIf=\"!convAiLoading && convAiReply\" class=\"echo-ai-text\">{{ convAiReply }}</p>\n </div>\n\n <!-- Total count -->\n <div class=\"echo-conv-count\">{{ convTotal }} Conversations</div>\n\n <!-- Conversations list area -->\n <div class=\"conversations-section\">\n\n <!-- Loading -->\n <div *ngIf=\"convLoading\" style=\"text-align:center;padding:40px;color:#94A3B8;\">Loading conversations...</div>\n\n <!-- Conversation cards (dynamic from API \u2014 same pattern as transcript-list) -->\n <div *ngFor=\"let conv of conversations; trackBy: trackById\" class=\"conv-card\">\n <div class=\"conv-header\" (click)=\"toggleConvExpand(conv.audioId)\">\n <div style=\"flex:1;min-width:0;\">\n <div style=\"display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:4px;\">\n <span class=\"conv-id\">{{ conv.audioId }}</span>\n <span class=\"meta-tag brand\" *ngIf=\"conv.storeName\">{{ conv.storeName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.location\">{{ conv.location }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.userName\">{{ conv.userName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.date\">{{ conv.date }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.duration\" style=\"background:#EDE9FE;color:#8B5CF6;border-color:#DDD6FE;font-weight:700;\">{{ conv.duration }}</span>\n </div>\n <div style=\"font-size:12.5px;color:#94A3B8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;\">\n {{ conv.audioDescription || 'No description available' }}\n </div>\n </div>\n <div class=\"conv-chevron\" [class.open]=\"expandedConvIds[conv.audioId]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n </div>\n\n <!-- Expanded body (unified layout matching Agent Analysis design) -->\n <div *ngIf=\"expandedConvIds[conv.audioId]\" class=\"conv-body-expanded\">\n\n <!-- Waveform player -->\n <div class=\"echo-player\" *ngIf=\"conv.audioUrl\">\n <button class=\"echo-play-btn\" (click)=\"togglePlay(conv.audioId)\">\n <svg *ngIf=\"playingConvId !== conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M8 5v14l11-7z\"/></svg>\n <svg *ngIf=\"playingConvId === conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/></svg>\n </button>\n <div class=\"echo-waveform\" (click)=\"seekAudio($event, conv.audioId)\">\n <div class=\"echo-wf-bar\" *ngFor=\"let h of waveformHeights; let i = index\" [style.height.px]=\"h\"\n [class.played]=\"(playbackStates[conv.audioId]?.progress || 0) > i / waveformHeights.length\">\n </div>\n </div>\n <span class=\"echo-time\">{{ playbackStates[conv.audioId]?.totalTime || conv.duration || '--' }}</span>\n <audio [id]=\"'audio-' + conv.audioId\" [src]=\"conv.audioUrl\" preload=\"metadata\"\n (timeupdate)=\"onTimeUpdate(audioEl, conv.audioId)\"\n (loadedmetadata)=\"onLoadedMetadata(audioEl, conv.audioId, conv.duration)\"\n (ended)=\"playingConvId = null\" #audioEl></audio>\n </div>\n\n <!-- Tabs -->\n <div class=\"conv-tabs\">\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'summary'\" (click)=\"setConvTab(conv.audioId, 'summary', $event)\">Summary</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'transcript'\" (click)=\"setConvTab(conv.audioId, 'transcript', $event)\">Transcript</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'interaction'\" (click)=\"setConvTab(conv.audioId, 'interaction', $event)\">Interaction Quality</button>\n </div>\n\n <!-- Content: Left (Summary/Transcript/Interaction + AI Insights) + Right (Metrics) -->\n <div style=\"display:flex;\">\n <!-- Left side -->\n <div style=\"flex:1;padding:14px 16px;min-width:0;border-right:1px solid #e8edf3;\">\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'summary'\">\n <p class=\"summary-text\">{{ conv.audioDescription || conv.conversationDetails?.audioSummary || 'No summary available' }}</p>\n <!-- AI Insights -->\n <div *ngIf=\"conv.aiInsights?.summary?.length\" style=\"margin-top:16px;\">\n <div style=\"font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:10px;\">AI Insights</div>\n <div *ngFor=\"let insight of conv.aiInsights.summary\" style=\"display:flex;align-items:flex-start;gap:8px;margin-bottom:8px;\">\n <div style=\"width:6px;height:6px;border-radius:50%;margin-top:5px;flex-shrink:0;\" [style.background]=\"insight.type === 'positive' ? '#00A3FF' : insight.type === 'negative' ? '#EF4444' : '#F59E0B'\"></div>\n <span style=\"font-size:13px;color:#475467;line-height:1.5;\">{{ insight.text || insight }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'transcript'\">\n <p class=\"summary-text\" style=\"white-space:pre-wrap;\">{{ conv.conversationDetails?.transcription || 'No transcript available' }}</p>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'interaction'\">\n <div style=\"padding:8px 0;\">\n <div style=\"font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px;\">Interaction Quality</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" style=\"margin-bottom:12px;\">\n <div style=\"font-size:13px;font-weight:600;color:#344054;margin-bottom:6px;\">{{ m.name }}</div>\n <div *ngFor=\"let v of m.value\" style=\"display:flex;justify-content:space-between;align-items:center;padding:6px 0;border-bottom:1px solid #f0f4ff;\">\n <span style=\"font-size:13px;color:#475467;\">{{ v.name }}</span>\n <span style=\"font-size:13px;font-weight:700;\" [style.color]=\"v.score > 50 ? '#10B981' : v.score === 0 ? '#667085' : '#EF4444'\">{{ v.score !== undefined ? v.score + '%' : (v.Total || v.Avg || v.count || '\u2013') }}</span>\n </div>\n </div>\n </ng-container>\n <p *ngIf=\"!conv.metrics?.length\" style=\"font-size:13px;color:#94A3B8;\">No interaction quality data available.</p>\n </div>\n </ng-container>\n </div>\n <!-- Right side: Metrics -->\n <div style=\"width:200px;flex-shrink:0;padding:16px;\">\n <div style=\"font-size:10px;font-weight:700;color:#00A3FF;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px;\">Metrics</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" style=\"margin-bottom:8px;\">\n <div *ngFor=\"let v of m.value\" style=\"display:flex;justify-content:space-between;margin-bottom:4px;\">\n <span style=\"font-size:12px;color:#667085;\">{{ v.name || m.name }}</span>\n <span class=\"metric-value\" [style.color]=\"v.score > 50 ? '#10B981' : v.score === 0 ? '#667085' : (v.score !== undefined ? '#EF4444' : '#344054')\" style=\"font-size:12px;font-weight:700;\">{{ v.score !== undefined ? (v.score > 0 ? v.name : v.score) : (v.Total || v.Avg || v.count || '\u2013') }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!conv.metrics?.length\">\n <div *ngIf=\"conv.storeName\" style=\"display:flex;justify-content:space-between;margin-bottom:6px;\"><span style=\"font-size:12px;color:#667085;\">Store</span><span style=\"font-size:12px;font-weight:600;color:#344054;\">{{ conv.storeName }}</span></div>\n <div *ngIf=\"conv.duration\" style=\"display:flex;justify-content:space-between;margin-bottom:6px;\"><span style=\"font-size:12px;color:#667085;\">Duration</span><span style=\"font-size:12px;font-weight:600;color:#344054;\">{{ conv.duration }}</span></div>\n </ng-container>\n <div *ngIf=\"conv._detailLoading\" style=\"font-size:11px;color:#667085;\">Loading...</div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- No data -->\n <div *ngIf=\"!convLoading && conversations.length === 0\" style=\"text-align:center;padding:40px;color:#94A3B8;font-size:13px;\">No conversations found.</div>\n\n <!-- Pagination -->\n <lib-pagination *ngIf=\"convTotal > 0\" [itemsPerPage]=\"convPerPage\" [currentPage]=\"convPage\" [totalItems]=\"convTotal\"\n [paginationSizes]=\"convPaginationSizes\" [pageSize]=\"convPerPage\" (pageChange)=\"onConvPageChange($event)\"\n (pageSizeChange)=\"onConvPageSizeChange($event)\"></lib-pagination>\n </div> <!-- end conversations-section -->\n </ng-container>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 AGENT ANALYSIS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'agentanalysis'\">\n\n <!-- \u2500\u2500 OVERVIEW: Cohort List as Cards \u2500\u2500 -->\n <ng-container *ngIf=\"!detailView\">\n\n <!-- Header -->\n <div style=\"display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap;\">\n <div>\n <div style=\"font-size:17px;font-weight:700;color:#1a2b4b;\">Analytics Overview</div>\n <div style=\"font-size:12px;color:#667085;\">{{ cohortList.length }} active agents</div>\n </div>\n <span style=\"flex:1;\"></span>\n <div style=\"width:220px;display:flex;align-items:center;gap:8px;border:1px solid #D0D5DD;border-radius:8px;padding:6px 12px;background:#fff;\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#98A2B3\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"analysisSearch\" placeholder=\"Search agents\u2026\" style=\"flex:1;border:none;background:transparent;font-size:13px;color:#344054;outline:none;min-width:0;\">\n </div>\n </div>\n\n <!-- Loading -->\n <div *ngIf=\"cohortList.length === 0\" style=\"text-align:center;padding:40px;color:#667085;\">Loading agents...</div>\n\n <!-- Cohort Cards Grid -->\n <div class=\"analytics-grid\">\n <ng-container *ngFor=\"let cohort of cohortList; trackBy: trackById\">\n <div class=\"analytics-card\" *ngIf=\"!analysisSearch || (cohort.cohortName || cohort.name || '').toLowerCase().includes(analysisSearch.toLowerCase())\" (click)=\"selectCohortDetail(cohort)\">\n\n <!-- Card Header -->\n <div class=\"analytics-card-header\">\n <div style=\"display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:8px;\">\n <div style=\"font-size:13.5px;font-weight:700;color:#1a2b4b;flex:1;padding-right:8px;line-height:1.3;\">{{ cohort.cohortName || cohort.name }}</div>\n <span style=\"font-size:9px;font-weight:700;padding:2px 8px;border-radius:20px;background:#D1FAE5;color:#065F46;text-transform:uppercase;letter-spacing:.5px;flex-shrink:0;\">Active</span>\n </div>\n <div style=\"display:flex;gap:6px;\">\n <span style=\"font-size:11px;font-weight:600;padding:3px 9px;border-radius:20px;background:#fff;border:1px solid #e8edf3;color:#344054;\">{{ cohort.metricsAdded || 0 }} metrics</span>\n <span style=\"font-size:11px;font-weight:600;padding:3px 9px;border-radius:20px;background:#fff;border:1px solid #e8edf3;color:#344054;\">50 stores</span>\n </div>\n </div>\n\n <!-- Card Body -->\n <div style=\"padding:8px 14px;\"></div>\n\n <!-- Card Footer -->\n <div style=\"padding:8px 14px;border-top:1px solid #e8edf3;display:flex;justify-content:flex-end;\">\n <span class=\"analytics-hover-link\">View analytics \u2192</span>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- \u2500\u2500 DETAIL: Selected Cohort Metrics + Conversations \u2500\u2500 -->\n <ng-container *ngIf=\"detailView\">\n\n <!-- Header bar: \u2190 Name | Total Conversations | Dropdown -->\n <div style=\"display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:14px 20px;background:#fff;border-radius:10px;border:1px solid #e8edf3;\">\n <button style=\"background:none;border:none;cursor:pointer;color:#00A3FF;font-size:18px;padding:0;\" (click)=\"backToCards()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M15 18l-6-6 6-6\"/></svg>\n </button>\n <span style=\"font-size:16px;font-weight:700;color:#1a2b4b;\">{{ selectedCohortName }}</span>\n <span style=\"flex:1;\"></span>\n <span style=\"font-size:13px;color:#667085;\">Total Conversations: {{ totalAudio }}</span>\n <div style=\"display:flex;align-items:center;gap:6px;padding:6px 14px;border:1.5px solid #00A3FF;border-radius:8px;background:#fff;cursor:pointer;position:relative;\">\n <div style=\"width:8px;height:8px;border-radius:50%;background:#10B981;\"></div>\n <select [(ngModel)]=\"selectedCohortId\" (ngModelChange)=\"onCohortDropdownChange($event)\" style=\"border:none;background:transparent;font-size:13px;font-weight:600;color:#1a2b4b;outline:none;cursor:pointer;padding-right:16px;\">\n <option *ngFor=\"let c of cohortList\" [value]=\"c.cohortId || c.id || c._id\">{{ c.cohortName || c.name }}</option>\n </select>\n </div>\n </div>\n\n <!-- Loading -->\n <div *ngIf=\"cardsLoading\" style=\"text-align:center;padding:40px;color:#667085;\">Loading metrics...</div>\n\n <!-- Metric Cards (dynamic columns based on card count) -->\n <div *ngIf=\"!cardsLoading && cohortCards.length > 0\" class=\"metric-cards-dynamic\"\n [style.grid-template-columns]=\"'repeat(' + Math.min(cohortCards.length, 4) + ', 1fr)'\">\n <div *ngFor=\"let card of cohortCards; trackBy: trackById\" class=\"metric-card-dynamic\">\n <div class=\"metric-card-title\">{{ card.name }}</div>\n <div class=\"metric-card-subtitle\">{{ totalAudio }} conversations</div>\n\n <!-- BOOLEAN_BASKET \u2014 rows with progress bars -->\n <ng-container *ngIf=\"card.type === 'BOOLEAN_BASKET'\">\n <div *ngFor=\"let row of card.booleanRows\" class=\"metric-bool-row\" (click)=\"onCardRowClick(row.id, card.name)\">\n <div style=\"display:flex;align-items:center;gap:6px;margin-bottom:4px;\">\n <div class=\"metric-dot\"></div>\n <span style=\"font-size:13px;color:#344054;flex:1;\">{{ row.label }}</span>\n <span class=\"metric-score\">{{ row.score }}%</span>\n <span class=\"metric-count\">{{ row.responses }}</span>\n </div>\n <div class=\"metric-progress-track\">\n <div class=\"metric-progress-fill\" [style.width.%]=\"row.score\"></div>\n </div>\n </div>\n </ng-container>\n\n <!-- NUMERIC \u2014 big number -->\n <ng-container *ngIf=\"card.type === 'NUMERIC_SCALAR' || card.type === 'NUMERIC_ARRAY'\">\n <div style=\"cursor:pointer;\" (click)=\"onCardRowClick('', card.key)\">\n <span class=\"metric-big-number\">{{ card.numericData?.avg || card.numericData?.total || '\u2013' }}</span>\n <span class=\"metric-avg-label\">avg</span>\n </div>\n </ng-container>\n\n <!-- SUBJECTIVE -->\n <ng-container *ngIf=\"card.type === 'SUBJECTIVE' || card.type === 'SUBJECTIVE_COUNT'\">\n <div class=\"subjective-wrap\" (click)=\"onCardRowClick('', card.key)\">\n <div *ngFor=\"let row of card.subjectiveRows?.slice(0, 2)\" class=\"subjective-row\">\n \u2022 {{ row.reasoning || row.store_id }}\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- No cards -->\n <div *ngIf=\"!cardsLoading && cohortCards.length === 0\" style=\"text-align:center;padding:40px;color:#667085;font-size:13px;\">No analysis data available.</div>\n\n <!-- \u2500\u2500 Conversations Section \u2500\u2500 -->\n <div class=\"conversations-section\" *ngIf=\"detailPageConvs.length > 0 || detailLoading\">\n <div style=\"padding:16px 20px;display:flex;align-items:center;gap:8px;background:#fff;border-radius:10px;border:1px solid #e8edf3;margin-bottom:12px;\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#344054\" stroke-width=\"1.8\"><path d=\"M20 2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h11l5 3V4a2 2 0 0 0-2-2z\"/></svg>\n <span style=\"font-size:15px;font-weight:700;color:#1a2b4b;\">Conversations</span>\n </div>\n\n <div *ngIf=\"detailLoading\" style=\"text-align:center;padding:40px;color:#667085;\">Loading...</div>\n\n <div *ngFor=\"let conv of detailPageConvs; trackBy: trackById\" class=\"detail-conv-card\">\n <!-- Conv header -->\n <div class=\"conv-header\" (click)=\"toggleDetailConv(conv.audioId); loadConvDetail(conv)\">\n <span class=\"conv-id\">{{ conv.audioId }}</span>\n <div style=\"display:flex;align-items:center;gap:5px;flex:1;min-width:0;flex-wrap:wrap;\">\n <span class=\"meta-tag brand\" *ngIf=\"conv.storeName\">{{ conv.storeName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.location\">{{ conv.location }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.date\">{{ conv.date }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.time\">{{ conv.time }}</span>\n </div>\n <div class=\"conv-chevron\" [class.open]=\"detailOpenId === conv.audioId\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n </div>\n\n <!-- Expanded body -->\n <div *ngIf=\"detailOpenId === conv.audioId\" class=\"conv-body-expanded\">\n <!-- Waveform player -->\n <div class=\"echo-player\" *ngIf=\"conv.audioUrl\">\n <button class=\"echo-play-btn\" (click)=\"togglePlay(conv.audioId)\">\n <svg *ngIf=\"playingConvId !== conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M8 5v14l11-7z\"/></svg>\n <svg *ngIf=\"playingConvId === conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/></svg>\n </button>\n <div class=\"echo-waveform\" (click)=\"seekAudio($event, conv.audioId)\">\n <div class=\"echo-wf-bar\" *ngFor=\"let h of waveformHeights; let i = index\" [style.height.px]=\"h\"\n [class.played]=\"(playbackStates[conv.audioId]?.progress || 0) > i / waveformHeights.length\"></div>\n </div>\n <span class=\"echo-time\">{{ playbackStates[conv.audioId]?.totalTime || conv.duration || '--' }}</span>\n <audio [id]=\"'audio-' + conv.audioId\" [src]=\"conv.audioUrl\" preload=\"metadata\"\n (timeupdate)=\"onTimeUpdate(audioEl, conv.audioId)\"\n (loadedmetadata)=\"onLoadedMetadata(audioEl, conv.audioId, conv.duration)\"\n (ended)=\"playingConvId = null\" #audioEl></audio>\n </div>\n\n <!-- Tabs -->\n <div class=\"conv-tabs\">\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'summary'\" (click)=\"setConvTab(conv.audioId, 'summary', $event)\">Summary</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'transcript'\" (click)=\"setConvTab(conv.audioId, 'transcript', $event)\">Transcript</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'interaction'\" (click)=\"setConvTab(conv.audioId, 'interaction', $event)\">Interaction Quality</button>\n </div>\n\n <!-- Content: Left (Summary/Transcript + AI Insights) + Right (Metrics) -->\n <div style=\"display:flex;\">\n <!-- Left side -->\n <div style=\"flex:1;padding:14px 16px;min-width:0;border-right:1px solid #e8edf3;\">\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'summary'\">\n <p class=\"summary-text\">{{ conv.audioDescription || conv.conversationDetails?.audioSummary || 'No summary available' }}</p>\n <!-- AI Insights -->\n <div *ngIf=\"conv.aiInsights?.summary?.length\" style=\"margin-top:16px;\">\n <div style=\"font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:10px;\">AI Insights</div>\n <div *ngFor=\"let insight of conv.aiInsights.summary\" style=\"display:flex;align-items:flex-start;gap:8px;margin-bottom:8px;\">\n <div style=\"width:6px;height:6px;border-radius:50%;margin-top:5px;flex-shrink:0;\" [style.background]=\"insight.type === 'positive' ? '#00A3FF' : insight.type === 'negative' ? '#EF4444' : '#F59E0B'\"></div>\n <span style=\"font-size:13px;color:#475467;line-height:1.5;\">{{ insight.text || insight }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'transcript'\">\n <p class=\"summary-text\" style=\"white-space:pre-wrap;\">{{ conv.conversationDetails?.transcription || 'No transcript available' }}</p>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'interaction'\">\n <div style=\"padding:8px 0;\">\n <div style=\"font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px;\">Interaction Quality</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" style=\"margin-bottom:12px;\">\n <div style=\"font-size:13px;font-weight:600;color:#344054;margin-bottom:6px;\">{{ m.name }}</div>\n <div *ngFor=\"let v of m.value\" style=\"display:flex;justify-content:space-between;align-items:center;padding:6px 0;border-bottom:1px solid #f0f4ff;\">\n <span style=\"font-size:13px;color:#475467;\">{{ v.name }}</span>\n <span style=\"font-size:13px;font-weight:700;\" [style.color]=\"v.score > 50 ? '#10B981' : v.score === 0 ? '#667085' : '#EF4444'\">{{ v.score !== undefined ? v.score + '%' : (v.Total || v.Avg || v.count || '\u2013') }}</span>\n </div>\n </div>\n </ng-container>\n <p *ngIf=\"!conv.metrics?.length\" style=\"font-size:13px;color:#94A3B8;\">No interaction quality data available.</p>\n </div>\n </ng-container>\n </div>\n <!-- Right side: Metrics -->\n <div style=\"width:200px;flex-shrink:0;padding:16px;\">\n <div style=\"font-size:10px;font-weight:700;color:#00A3FF;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px;\">Metrics</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" style=\"margin-bottom:8px;\">\n <div *ngFor=\"let v of m.value\" style=\"display:flex;justify-content:space-between;margin-bottom:4px;\">\n <span style=\"font-size:12px;color:#667085;\">{{ v.name || m.name }}</span>\n <span style=\"font-size:12px;font-weight:700;\" [style.color]=\"v.score > 50 ? '#10B981' : v.score === 0 ? '#667085' : '#EF4444'\">{{ v.score !== undefined ? (v.score > 0 ? v.name : v.score) : (v.Total || v.Avg || v.count || '\u2013') }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!conv.metrics?.length\">\n <div *ngIf=\"conv.storeName\" style=\"display:flex;justify-content:space-between;margin-bottom:6px;\"><span style=\"font-size:12px;color:#667085;\">Store</span><span style=\"font-size:12px;font-weight:600;color:#344054;\">{{ conv.storeName }}</span></div>\n <div *ngIf=\"conv.duration\" style=\"display:flex;justify-content:space-between;margin-bottom:6px;\"><span style=\"font-size:12px;color:#667085;\">Duration</span><span style=\"font-size:12px;font-weight:600;color:#344054;\">{{ conv.duration }}</span></div>\n </ng-container>\n <div *ngIf=\"conv._detailLoading\" style=\"font-size:11px;color:#667085;\">Loading...</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!detailLoading && detailPageConvs.length === 0 && (selectedCardId || selectedCardName)\" style=\"text-align:center;padding:32px;color:#667085;font-size:13px;\">No conversations found.</div>\n\n <!-- Pagination -->\n <lib-pagination *ngIf=\"detailTotal > 0\" [itemsPerPage]=\"detailPerPage\" [currentPage]=\"detailPage\" [totalItems]=\"detailTotal\"\n [paginationSizes]=\"detailPaginationSizes\" [pageSize]=\"detailPerPage\" (pageChange)=\"onDetailPageChange($event)\"\n (pageSizeChange)=\"onDetailPageSizeChange($event)\"></lib-pagination>\n </ng-container>\n </ng-container>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 MANAGE TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'manage'\">\n <div style=\"display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap;\">\n <div>\n <div style=\"font-family:'Outfit',sans-serif;font-weight:700;font-size:17px;\">Agents</div>\n <div style=\"font-size:12px;color:#94A3B8;\">{{ manageTotal }} agents</div>\n </div>\n <span style=\"flex:1;\"></span>\n <div style=\"width:280px;display:flex;align-items:center;gap:8px;border:1px solid #E2E8F2;border-radius:8px;padding:6px 12px;background:#fff;\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"manageSearch\" (ngModelChange)=\"onManageSearch()\" placeholder=\"Search agents...\" style=\"flex:1;border:none;background:transparent;font-size:13px;font-family:'Nunito Sans',sans-serif;color:#0F172A;outline:none;min-width:0;\">\n </div>\n </div>\n\n <div *ngIf=\"manageLoading\" style=\"text-align:center;padding:40px;color:#94A3B8;\">Loading agents...</div>\n\n <!-- Agents table -->\n <div *ngIf=\"!manageLoading\" class=\"echo-card\">\n <div class=\"agents-table-header\" style=\"grid-template-columns:minmax(0,1fr) 120px 120px 80px;\">\n <div class=\"agents-table-cell\">Agent Name</div>\n <div class=\"agents-table-cell\" style=\"text-align:center;\">Metrics</div>\n <div class=\"agents-table-cell\" style=\"text-align:center;\">Source</div>\n <div class=\"agents-table-cell\" style=\"text-align:center;\">Action</div>\n </div>\n <div *ngFor=\"let cohort of manageCohorts; trackBy: trackById\" class=\"agents-table-row\" style=\"grid-template-columns:minmax(0,1fr) 120px 120px 80px;\">\n <div style=\"min-width:0;\">\n <div style=\"font-family:'Outfit',sans-serif;font-weight:700;font-size:13.5px;color:#0F172A;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">{{ cohort.cohortName || cohort.name }}</div>\n <div style=\"font-size:11px;color:#94A3B8;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">{{ cohort.cohortDescription || cohort.description || '' }}</div>\n </div>\n <div style=\"text-align:center;font-family:'Outfit',sans-serif;font-weight:700;font-size:13px;color:#0F172A;\">{{ cohort.metricsAdded || cohort.metricAdded || cohort.metrics?.length || 0 }}</div>\n <div style=\"text-align:center;font-size:11.5px;color:#334155;font-weight:600;\">{{ cohort.source?.join(', ') || '\u2013' }}</div>\n <div style=\"text-align:center;\">\n <button (click)=\"deleteCohort(cohort.cohortId || cohort.id || cohort._id)\" style=\"background:none;border:none;cursor:pointer;color:#EF4444;font-size:11px;font-weight:700;\">Delete</button>\n </div>\n </div>\n <div *ngIf=\"manageCohorts.length === 0\" style=\"padding:32px;text-align:center;color:#94A3B8;font-size:13px;\">No cohorts found.</div>\n </div>\n\n <!-- Manage pagination -->\n <lib-pagination *ngIf=\"manageTotal > 0\" [itemsPerPage]=\"managePerPage\" [currentPage]=\"managePage\" [totalItems]=\"manageTotal\"\n [paginationSizes]=\"managePaginationSizes\" [pageSize]=\"managePerPage\" (pageChange)=\"onManagePageChange($event)\"\n (pageSizeChange)=\"onManagePageSizeChange($event)\"></lib-pagination>\n </ng-container>\n\n </div>\n</div>\n\n<!-- \u2550\u2550\u2550 FILTERS DRAWER \u2550\u2550\u2550 -->\n<div class=\"drawer-overlay\" *ngIf=\"drawerOpen\" (click)=\"closeFilterDrawer()\"></div>\n<div class=\"af-drawer\" *ngIf=\"drawerOpen\">\n <div style=\"padding:16px;border-bottom:1px solid #E2E8F2;display:flex;align-items:center;justify-content:space-between;\">\n <span style=\"font-family:'Outfit',sans-serif;font-weight:700;font-size:15px;\">Filters</span>\n <button (click)=\"closeFilterDrawer()\" style=\"background:none;border:none;cursor:pointer;color:#94A3B8;font-size:18px;\">\u00D7</button>\n </div>\n <div style=\"padding:16px;flex:1;overflow-y:auto;\">\n <p style=\"font-size:13px;color:#94A3B8;\">Filter configuration coming soon. Uses the same filter APIs as the existing audio pages.</p>\n </div>\n <div class=\"af-footer\">\n <button class=\"af-cancel\" (click)=\"closeFilterDrawer()\">Close</button>\n </div>\n</div>\n", styles: [":host{display:block}.echo-page{padding:20px 24px;background-color:#f4f6fa}.conversations-section{background:#fff;border-radius:10px;padding:16px;margin-top:8px}.conv-card{border:1px solid #e8edf3;border-radius:10px;margin-bottom:12px;overflow:hidden;background:#fff}.conv-header{padding:14px 20px;display:flex;align-items:center;gap:8px;cursor:pointer;transition:background .15s}.conv-header:hover{background:#f8fafc}.conv-chevron{width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:transform .22s ease}.conv-chevron.open{transform:rotate(180deg)}.conv-id{font-size:13px;font-weight:600;color:#0ea5e9;border-radius:4px;padding:2px 8px}.meta-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:24px;font-size:12px;font-weight:500;border:1px solid #e8edf3;background:#f8fafc;color:#344054;white-space:nowrap}.meta-tag.purple{background:#f0f4ff;color:#1a73e8;border-color:#d0e0ff}.meta-tag.brand{font-weight:600}.conv-tabs{display:flex;border-bottom:1px solid #e8edf3;padding:0 20px}.conv-tab-btn{padding:10px 16px;font-size:13px;font-weight:600;border:none;background:transparent;cursor:pointer;color:#667085;border-bottom:2px solid transparent;transition:all .15s;margin-bottom:-1px}.conv-tab-btn.active{color:#00a3ff;border-bottom-color:#00a3ff}.transcript-content .transcript-section{margin-bottom:20px}.transcript-content .transcript-section:last-child{margin-bottom:0}.transcript-content .transcript-section-title{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:#344054;margin-bottom:10px;padding-bottom:6px;border-bottom:1px solid #f0f4ff}.transcript-content .transcript-summary-text,.summary-text{font-size:14px;color:#475467;line-height:1.7;margin:0}.detail-conv-card{border:1px solid #e8edf3;border-radius:10px;margin-bottom:12px;background:#fff;overflow:hidden}.detail-conv-card .conv-header{padding:12px 16px}.detail-conv-card .conv-tabs{padding:0 16px}.detail-conv-card .echo-player{padding:10px 16px}.conv-body-expanded{border-top:1px solid #e8edf3}.echo-player{display:flex;align-items:center;gap:12px;padding:12px 20px;background:#f2f4f7;border-bottom:1px solid #e8edf3}.echo-play-btn{width:36px;height:36px;min-width:36px;border-radius:50%;background:#00a3ff;border:none;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .2s}.echo-play-btn:hover{background:#0087d5}.echo-waveform{flex:1;display:flex;align-items:center;gap:1.5px;height:40px;cursor:pointer}.echo-wf-bar{width:2px;min-width:2px;border-radius:2px;min-height:3px;background:#cbd5e1;transition:background .15s}.echo-wf-bar.played{background:#00a3ff}.echo-time{font-size:13px;font-weight:600;color:#344054;flex-shrink:0;min-width:50px;text-align:right}.btn{padding:8px 16px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;border:none;transition:all .15s}.btn-primary{background:#1a73e8;color:#fff}.btn-primary:hover{background:#135cbc}.analytics-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}.analytics-card{background:#fff;border:1px solid #e8edf3;border-radius:10px;cursor:pointer;overflow:hidden;transition:box-shadow .2s,transform .2s,border-color .2s}.analytics-card:hover{box-shadow:0 4px 12px #00000014;transform:translateY(-2px);border-color:#00a3ff}.analytics-card:hover .analytics-hover-link{opacity:1}.analytics-card-header{padding:14px 16px;border-bottom:1px solid #e8edf3;background:linear-gradient(135deg,#f8fafc,#fff)}.analytics-hover-link{font-size:11px;color:#00a3ff;font-weight:700;opacity:0;transition:opacity .2s}.btn-outline{background:#fff;border:1px solid #D0D5DD;color:#344054}.btn-outline:hover{border-color:#1a73e8;color:#1a73e8}.btn-success{background:#10b981;color:#fff}.section-label{font-size:12px;font-weight:600;color:#98a2b3;letter-spacing:.5px;margin-bottom:8px;text-transform:uppercase}.echo-card{background:#fff;border-radius:10px;border:1px solid #e8edf3;overflow:hidden}.echo-card-header{padding:14px 20px;border-bottom:1px solid #e8edf3;display:flex;align-items:center;gap:8px}.echo-card-title{font-size:16px;font-weight:600;color:#1a2b4b}.echo-card-body{padding:20px}.metric-cards-dynamic{display:grid;gap:16px;margin-bottom:24px;align-items:stretch}.metric-card-dynamic{background:#fff;border:1px solid #e8edf3;border-radius:10px;padding:20px;display:flex;flex-direction:column;cursor:pointer;transition:border-color .2s,box-shadow .2s}.metric-card-dynamic:hover{border-color:#00a3ff;box-shadow:0 2px 8px #00a3ff14}.metric-card-title{font-size:14px;font-weight:700;color:#1a2b4b;margin-bottom:4px;line-height:1.3}.metric-card-subtitle{font-size:11px;color:#667085;margin-bottom:12px}.metric-bool-row{margin-bottom:10px;cursor:pointer}.metric-dot{width:7px;height:7px;border-radius:50%;background:#00a3ff;flex-shrink:0}.metric-score{font-weight:700;font-size:15px;color:#00a3ff}.metric-count{font-size:11px;color:#667085;min-width:20px;text-align:right}.metric-progress-track{height:6px;border-radius:4px;background:#e2e8f2;overflow:hidden}.metric-progress-fill{height:100%;background:#00a3ff;border-radius:4px;transition:width .5s ease}.metric-big-number{font-weight:800;font-size:36px;color:#00a3ff;line-height:1}.metric-avg-label{font-size:12px;color:#667085;margin-left:4px}@media (max-width: 992px){.metric-cards-dynamic{grid-template-columns:repeat(2,1fr)!important}}@media (max-width: 576px){.metric-cards-dynamic{grid-template-columns:1fr!important}}.subjective-wrap{cursor:pointer;max-height:120px;overflow:hidden}.subjective-row{padding:4px 0;font-size:12px;color:#475467;border-bottom:1px solid #f0f4ff;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical}.metric-card-name{font-size:14px;font-weight:600;color:#1a2b4b}.agents-table-header{display:grid;align-items:center;padding:10px 20px;border-bottom:1px solid #e8edf3;background:#f8fafc}.agents-table-cell{font-size:12px;font-weight:600;color:#98a2b3;letter-spacing:.5px;text-transform:uppercase}.agents-table-row{display:grid;align-items:center;padding:14px 20px;border-bottom:1px solid #e8edf3;cursor:pointer;transition:background .15s}.agents-table-row:hover{background:#f8fafc}.agents-table-row:last-child{border-bottom:none}.status-dot{width:8px;height:8px;border-radius:50%}.status-dot.active{background:#10b981}.status-dot.pending{background:#f59e0b}.status-dot.paused{background:#98a2b3}.tango-ai-header{display:flex;flex-direction:column;align-items:center;gap:10px;padding:20px 0}.tango-ai-logo{width:52px;height:52px;border-radius:16px;background:linear-gradient(135deg,#794fd9,#33b1f7);display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #794fd933}.tango-ai-title{font-size:22px;font-weight:800;color:#1a2b4b;line-height:1.2}.tango-ai-subtitle{font-size:13px;color:#667085;margin-top:4px}.echo-search-card{display:flex;align-items:center;background:#fff;border:1px solid #D0D5DD;border-radius:8px;padding:10px 12px 10px 20px;margin-bottom:20px;box-shadow:0 1px 2px #1018280d}.echo-search-input{flex:1;border:none;outline:none;font-size:14px;color:#101828}.echo-search-input::placeholder{color:#98a2b3}.echo-search-slash{width:28px;height:28px;border-radius:50%;border:1px solid #D0D5DD;background:#fff;font-size:14px;font-weight:600;color:#667085;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;margin-right:6px}.echo-search-send{width:32px;height:32px;border-radius:50%;background:#00a3ff;border:none;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s}.echo-search-send:hover{background:#0087d5}.echo-search-send:disabled{opacity:.5;cursor:not-allowed}.echo-ai-response{background:#fff;border:1px solid #e8edf3;border-radius:10px;padding:16px 20px;margin-bottom:16px}.echo-ai-text{font-size:14px;color:#475467;line-height:1.7;margin:0}.echo-conv-count{font-size:14px;font-weight:700;color:#00a3ff;margin-bottom:16px}.typing{display:flex;gap:4px;align-items:center;padding:4px 0}.typing-dot{width:6px;height:6px;border-radius:50%;background:#00a3ff;animation:pulse 1.2s ease-in-out infinite}.typing-dot:nth-child(2){animation-delay:.2s}.typing-dot:nth-child(3){animation-delay:.4s}@keyframes pulse{0%,to{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}:host ::ng-deep lib-pagination{margin-top:16px;display:block}.agent-dropdown-wrap{position:relative}.agent-dropdown-menu{position:absolute;top:calc(100% + 6px);right:0;background:#fff;border:1px solid #D0D5DD;border-radius:10px;box-shadow:0 4px 16px #0000001a;width:280px;z-index:300;overflow:hidden}.agent-dd-header{padding:8px 14px;font-size:11px;font-weight:600;color:#98a2b3;letter-spacing:.5px;border-bottom:1px solid #e8edf3;text-transform:uppercase}.agent-dd-item{display:flex;align-items:center;gap:10px;padding:10px 14px;cursor:pointer;transition:background .1s}.agent-dd-item:hover{background:#f8fafc}.agent-dd-item.selected{background:#f0f4ff}.agent-dd-name{font-size:13px;font-weight:600;color:#344054;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.agent-dd-meta{font-size:12px;color:#98a2b3;margin-top:1px}.fbar-pill{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #D0D5DD;border-radius:8px;background:#fff;font-size:13px;font-weight:600;color:#344054;cursor:pointer;transition:all .15s;white-space:nowrap}.fbar-pill:hover,.fbar-pill.active{border-color:#1a73e8;color:#1a73e8;background:#f0f4ff}.echo-sub-header{display:flex;align-items:center;padding:12px 0 16px;gap:10px}.btn-back{background:none;border:none;cursor:pointer;display:flex;align-items:center;color:#1a73e8;padding:4px 6px;border-radius:8px}.sub-header-title{font-size:15px;font-weight:600;color:#1a2b4b}.drawer-overlay{position:fixed;inset:0;background:#0000004d;z-index:200}.af-drawer{position:fixed;top:0;right:0;bottom:0;width:380px;max-width:95vw;background:#fff;z-index:201;display:flex;flex-direction:column;box-shadow:-8px 0 40px #00000026;animation:slideInRight .25s ease-out;overflow:hidden}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.af-footer{padding:14px 16px;border-top:1px solid #e8edf3;display:flex;align-items:center;justify-content:flex-end;background:#fff}.af-cancel{padding:9px 20px;border-radius:8px;border:1px solid #D0D5DD;background:#fff;font-size:14px;font-weight:500;cursor:pointer;color:#344054}@media (max-width: 768px){.metric-cards-grid{grid-template-columns:1fr}.agents-table-header,.agents-table-row{grid-template-columns:1fr 80px}}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i5.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: i5.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }] });
|
|
807
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TangoEchoComponent, selector: "lib-tango-echo", ngImport: i0, template: "<div class=\"echo-page\">\n <div class=\"echo-content\">\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 CONVERSATIONS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'conversations'\">\n\n <!-- Tango AI Header -->\n <div class=\"tango-ai-header\">\n <div class=\"tango-ai-logo\">\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M12 2l2.09 6.26L20 10l-5.91 1.74L12 18l-2.09-6.26L4 10l5.91-1.74L12 2z\"/></svg>\n </div>\n <div class=\"tango-ai-header-text\">\n <div class=\"tango-ai-title\">Tango AI</div>\n <div class=\"tango-ai-subtitle\">Analyse conversations, stores & staff performance</div>\n </div>\n </div>\n\n <!-- Search Card -->\n <div class=\"echo-search-card\">\n <input type=\"text\" class=\"echo-search-input\" placeholder=\"Ask anything... 'Which stores are not performing well?'\" [(ngModel)]=\"convSearchQuery\" (keyup.enter)=\"sendConvQuery()\">\n <button class=\"echo-search-send\" (click)=\"sendConvQuery()\" [disabled]=\"!convSearchQuery?.trim()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </div>\n\n <!-- AI Response -->\n <div class=\"echo-ai-response\" *ngIf=\"convAiLoading || convAiReply\">\n <div *ngIf=\"convAiLoading\" class=\"typing\">\n <span class=\"typing-dot\"></span><span class=\"typing-dot\"></span><span class=\"typing-dot\"></span>\n </div>\n <p *ngIf=\"!convAiLoading && convAiReply\" class=\"echo-ai-text\">{{ convAiReply }}</p>\n </div>\n\n <!-- Total count -->\n <div class=\"echo-conv-count\">{{ convTotal }} Conversations</div>\n\n <!-- Conversations list area -->\n <div class=\"conversations-section\">\n\n <!-- Loading -->\n <div *ngIf=\"convLoading\" class=\"echo-empty-state\">Loading conversations...</div>\n\n <!-- Conversation cards (dynamic from API \u2014 same pattern as transcript-list) -->\n <div *ngFor=\"let conv of conversations; trackBy: trackById\" class=\"conv-card\">\n <div class=\"conv-header\" (click)=\"toggleConvExpand(conv.audioId)\">\n <div class=\"conv-header-body\">\n <div class=\"conv-meta-row\">\n <span class=\"conv-id\">{{ conv.audioId }}</span>\n <span class=\"meta-tag brand\" *ngIf=\"conv.storeName\">{{ conv.storeName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.location\">{{ conv.location }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.userName\">{{ conv.userName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.date\">{{ conv.date }}</span>\n <span class=\"meta-tag meta-tag--duration\" *ngIf=\"conv.duration\">{{ conv.duration }}</span>\n </div>\n <div class=\"conv-description\">\n {{ conv.audioDescription || 'No description available' }}\n </div>\n </div>\n <div class=\"conv-chevron\" [class.open]=\"expandedConvIds[conv.audioId]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n </div>\n\n <!-- Expanded body (unified layout matching Agent Analysis design) -->\n <div *ngIf=\"expandedConvIds[conv.audioId]\" class=\"conv-body-expanded\">\n\n <!-- Waveform player -->\n <div class=\"echo-player\" *ngIf=\"conv.audioUrl\">\n <button class=\"echo-play-btn\" (click)=\"togglePlay(conv.audioId)\">\n <svg *ngIf=\"playingConvId !== conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M8 5v14l11-7z\"/></svg>\n <svg *ngIf=\"playingConvId === conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/></svg>\n </button>\n <div class=\"echo-waveform\" (click)=\"seekAudio($event, conv.audioId)\">\n <div class=\"echo-wf-bar\" *ngFor=\"let h of waveformHeights; let i = index\" [style.height.px]=\"h\"\n [class.played]=\"(playbackStates[conv.audioId]?.progress || 0) > i / waveformHeights.length\">\n </div>\n </div>\n <span class=\"echo-time\">{{ playbackStates[conv.audioId]?.totalTime || conv.duration || '--' }}</span>\n <audio [id]=\"'audio-' + conv.audioId\" [src]=\"conv.audioUrl\" preload=\"metadata\"\n (timeupdate)=\"onTimeUpdate(audioEl, conv.audioId)\"\n (loadedmetadata)=\"onLoadedMetadata(audioEl, conv.audioId, conv.duration)\"\n (ended)=\"playingConvId = null\" #audioEl></audio>\n </div>\n\n <!-- Summary Content -->\n <div class=\"conv-body-padding\">\n <p class=\"summary-text\">{{ conv.audioDescription || conv.conversationDetails?.audioSummary || 'No summary available' }}</p>\n <!-- AI Insights -->\n <div *ngIf=\"conv.aiInsights?.summary?.length\" class=\"ai-insights-section\">\n <div class=\"ai-insights-label\">AI Insights</div>\n <div *ngFor=\"let insight of conv.aiInsights.summary\" class=\"ai-insight-row\">\n <div class=\"ai-insight-dot\" [style.background]=\"insight.type === 'positive' ? '#00A3FF' : insight.type === 'negative' ? '#EF4444' : '#F59E0B'\"></div>\n <span class=\"ai-insight-text\">{{ insight.text || insight }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- No data -->\n <div *ngIf=\"!convLoading && conversations.length === 0\" class=\"echo-empty-state--sm\">No conversations found.</div>\n\n <!-- Pagination -->\n <lib-pagination *ngIf=\"convTotal > 0\" [itemsPerPage]=\"convPerPage\" [currentPage]=\"convPage\" [totalItems]=\"convTotal\"\n [paginationSizes]=\"convPaginationSizes\" [pageSize]=\"convPerPage\" (pageChange)=\"onConvPageChange($event)\"\n (pageSizeChange)=\"onConvPageSizeChange($event)\"></lib-pagination>\n </div> <!-- end conversations-section -->\n </ng-container>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 AGENT ANALYSIS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'agentanalysis'\">\n\n <!-- \u2500\u2500 OVERVIEW: Agent Cards Grid \u2500\u2500 -->\n <ng-container *ngIf=\"!detailView\">\n <div class=\"analytics-overview-header\">\n <div>\n <div class=\"analytics-overview-title\">Analytics Overview</div>\n <div class=\"analytics-overview-subtitle\">{{ activeCohorts.length }} active agents</div>\n </div>\n <span class=\"flex-spacer\"></span>\n <div class=\"echo-search-wrap\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#98A2B3\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"analysisSearch\" placeholder=\"Search agents\u2026\" class=\"echo-inline-input\">\n </div>\n </div>\n\n <div *ngIf=\"cohortList.length === 0\" class=\"echo-empty-state--muted\">Loading agents...</div>\n\n <div class=\"analytics-grid\" [style.grid-template-columns]=\"'repeat(' + Math.min(cohortList.length, 4) + ', 1fr)'\">\n <ng-container *ngFor=\"let cohort of cohortList; trackBy: trackById\">\n <div class=\"analytics-card\" *ngIf=\"!analysisSearch || (cohort.cohortName || cohort.name || '').toLowerCase().includes(analysisSearch.toLowerCase())\" (click)=\"selectCohortDetail(cohort)\">\n <div class=\"analytics-card-header\">\n <div class=\"analytics-card-top-row\">\n <div class=\"analytics-card-name\">{{ cohort.cohortName || cohort.name }}</div>\n <span class=\"analytics-card-badge-active\">Active</span>\n </div>\n <!-- metrics & stores badges hidden for now -->\n </div>\n <div class=\"analytics-card-spacer\"></div>\n <div class=\"analytics-card-footer\">\n <span class=\"analytics-hover-link\">View analytics \u2192</span>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- \u2500\u2500 DETAIL: Selected Cohort Metrics + Conversations \u2500\u2500 -->\n <ng-container *ngIf=\"detailView\">\n\n <!-- Header: \u2190 Back + Title + Conversations + Dropdown -->\n <div class=\"detail-header-bar\">\n <button class=\"detail-back-btn\" (click)=\"backToOverview()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M15 18l-6-6 6-6\"/></svg>\n </button>\n <span class=\"detail-header-title\">{{ selectedCohortName }}</span>\n <span class=\"flex-spacer\"></span>\n <span class=\"detail-header-conv-count\">Total Conversations: {{ totalAudio }}</span>\n\n <!-- Cohort Dropdown -->\n <div class=\"agent-dropdown-wrap\">\n <div class=\"agent-dropdown-trigger\" (click)=\"toggleCohortDropdown()\">\n <div class=\"cohort-dd-dot\"></div>\n <span class=\"cohort-dd-trigger-name\">{{ selectedCohortName || 'Select Agent' }}</span>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#667085\" stroke-width=\"2.5\" stroke-linecap=\"round\" [style.transform]=\"cohortDropdownOpen ? 'rotate(180deg)' : 'none'\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n <div class=\"agent-dropdown-menu\" *ngIf=\"cohortDropdownOpen\">\n <div class=\"cohort-dd-search-wrap\">\n <div class=\"cohort-dd-search-inner\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#98A2B3\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"cohortDropdownSearch\" placeholder=\"Search agents\u2026\" class=\"echo-inline-input--small\">\n </div>\n </div>\n <div class=\"cohort-dd-scroll\">\n <div *ngFor=\"let c of filteredDropdownCohorts; trackBy: trackById\" class=\"agent-dd-item\" [class.selected]=\"(c.cohortId || c.id || c._id) === selectedCohortId\" (click)=\"selectCohortFromDropdown(c)\">\n <div class=\"cohort-dd-item-dot\" [style.background]=\"c.metricsAdded > 0 ? '#10B981' : '#D0D5DD'\"></div>\n <div class=\"cohort-dd-item-body\">\n <div class=\"agent-dd-name\">{{ c.cohortName || c.name }}</div>\n <div class=\"agent-dd-meta\">{{ c.metricsAdded || 0 }} metrics</div>\n </div>\n <svg *ngIf=\"(c.cohortId || c.id || c._id) === selectedCohortId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00A3FF\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M20 6L9 17l-5-5\"/></svg>\n </div>\n <div *ngIf=\"filteredDropdownCohorts.length === 0\" class=\"cohort-dd-no-results\">No agents found</div>\n </div>\n </div>\n <div *ngIf=\"cohortDropdownOpen\" class=\"cohort-dd-backdrop\" (click)=\"closeCohortDropdown()\"></div>\n </div>\n </div>\n\n <!-- Loading -->\n <div *ngIf=\"cardsLoading\" class=\"echo-empty-state--muted\">Loading metrics...</div>\n\n <!-- Metric Cards (dynamic columns based on card count) -->\n <div *ngIf=\"!cardsLoading && cohortCards.length > 0\" class=\"metric-cards-dynamic\"\n [style.grid-template-columns]=\"'repeat(' + Math.min(cohortCards.length, 4) + ', 1fr)'\">\n <div *ngFor=\"let card of cohortCards; trackBy: trackById\" class=\"metric-card-dynamic\">\n <!-- Card Header: Title + Status Badge + Info -->\n <div class=\"metric-card-header-row\">\n <div class=\"metric-card-title\">{{ card.name }}</div>\n <div class=\"metric-card-actions\">\n <span *ngIf=\"card.status\" class=\"metric-status-badge\"\n [style.background]=\"getStatusBadge(card.status).bg\"\n [style.color]=\"getStatusBadge(card.status).color\">{{ card.status }}</span>\n <div class=\"metric-info-icon\" *ngIf=\"card.description\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/></svg>\n <div class=\"metric-info-tooltip\">\n <div>{{ card.description }}</div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"metric-card-subtitle\" *ngIf=\"card.type !== 'NUMERIC_SCALAR' && card.type !== 'NUMERIC_ARRAY'\">{{ card.applicableCount ?? totalAudio }} conversations</div>\n\n <div class=\"metric-card-content\">\n <!-- BOOLEAN_BASKET \u2014 Funnel Chart (left-aligned) -->\n <ng-container *ngIf=\"card.type === 'BOOLEAN_BASKET' && card.isFunnel\">\n <div class=\"funnel-chart\">\n <div *ngFor=\"let row of card.booleanRows; let i = index\" class=\"funnel-stage\" (click)=\"onCardRowClick(row.id, row.label)\">\n <div class=\"funnel-bar\"\n [style.width.%]=\"card.booleanRows[0]?.responses > 0 ? (row.responses / card.booleanRows[0].responses * 100) : 100\"\n [style.background]=\"getScoreColor(row.score)\">\n <span class=\"funnel-label-wrap\">\n <span class=\"funnel-label\">{{ row.label }}</span>\n <span class=\"funnel-tooltip\">{{ row.label }}</span>\n </span>\n <span class=\"funnel-value\"> <span class=\"funnel-value-count\">{{ row.responses }}</span> ({{ row.score }})% </span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- BOOLEAN_BASKET \u2014 rows with progress bars (non-funnel) -->\n <ng-container *ngIf=\"card.type === 'BOOLEAN_BASKET' && !card.isFunnel\">\n <div *ngFor=\"let row of card.booleanRows; let i = index\" class=\"metric-bool-row\" (click)=\"onCardRowClick(row.id, row.label)\">\n <div class=\"metric-row-flex\">\n <div class=\"metric-row-dot\"\n [style.background]=\"getScoreColor(row.score)\"></div>\n <span class=\"metric-row-label\">{{ row.label }}</span>\n <span class=\"metric-score metric-score--teal\">{{ row.score }}%</span>\n <span class=\"metric-count\">{{ row.responses }}</span>\n </div>\n <div class=\"metric-progress-track\">\n <div class=\"metric-progress-fill\" [style.width.%]=\"row.score\"\n [style.background]=\"getScoreColor(row.score)\"></div>\n </div>\n </div>\n </ng-container>\n\n <!-- NUMERIC_GROUP \u2014 all scores in one card -->\n <ng-container *ngIf=\"card.type === 'NUMERIC_GROUP'\">\n <div *ngFor=\"let row of card.numericRows\" class=\"numeric-score-row\" (click)=\"onCardRowClick('', row.key)\">\n <div class=\"numeric-row-header\">\n <span class=\"numeric-row-name\">{{ row.name }}</span>\n <span class=\"numeric-row-value\">{{ row.avg }}<span *ngIf=\"row.max !== null\" class=\"numeric-row-max\">/{{ row.max }}</span></span>\n </div>\n <div *ngIf=\"row.max !== null && row.min !== null\" class=\"numeric-progress-track\">\n <div class=\"numeric-progress-fill\"\n [style.width.%]=\"row.max > row.min ? ((row.avg - row.min) / (row.max - row.min) * 100) : 0\"></div>\n </div>\n </div>\n </ng-container>\n\n <!-- UNIQUE_PITCHES \u2014 pitch keywords tracker -->\n <ng-container *ngIf=\"card.type === 'UNIQUE_PITCHES'\">\n <div class=\"pitch-keyword-count\">{{ card.pitchRows?.length || 0 }} keywords</div>\n <div>\n <div *ngFor=\"let pitch of card.pitchRows; let i = index\" class=\"metric-bool-row\" (click)=\"onCardRowClick('', card.key)\">\n <div class=\"metric-row-flex\">\n <div class=\"metric-row-dot\"\n [style.background]=\"['#00A3FF','#10B981','#F59E0B','#EF4444','#8B5CF6','#EC4899','#06B6D4','#84CC16','#F97316','#6366F1'][i % 10]\"></div>\n <span class=\"pitch-row-label\">{{ pitch.id }}</span>\n <span class=\"pitch-row-desc\">{{ pitch.desc ? pitch.desc.slice(0, 60) : '\u2013' }}</span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- SUBJECTIVE -->\n <ng-container *ngIf=\"card.type === 'SUBJECTIVE' || card.type === 'SUBJECTIVE_COUNT'\">\n <div class=\"subjective-wrap\" (click)=\"onCardRowClick('', card.key)\">\n <div *ngFor=\"let row of card.subjectiveRows?.slice(0, 2)\" class=\"subjective-row\">\n \u2022 {{ row.reasoning || row.store_id }}\n </div>\n </div>\n </ng-container>\n </div><!-- end metric-card-content -->\n </div>\n </div>\n\n <!-- No cards -->\n <div *ngIf=\"!cardsLoading && cohortCards.length === 0\" class=\"echo-empty-state--muted-sm\">No analysis data available.</div>\n\n <!-- \u2500\u2500 Conversations Section \u2500\u2500 -->\n <div class=\"conversations-section\" *ngIf=\"detailPageConvs.length > 0 || detailLoading\">\n <div class=\"detail-conv-section-header\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#344054\" stroke-width=\"1.8\"><path d=\"M20 2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h11l5 3V4a2 2 0 0 0-2-2z\"/></svg>\n <span class=\"detail-conv-section-title\">Conversations</span>\n </div>\n\n <div *ngIf=\"detailLoading\" class=\"echo-empty-state--muted\">Loading...</div>\n\n <div *ngFor=\"let conv of detailPageConvs; trackBy: trackById\" class=\"detail-conv-card\">\n <!-- Conv header -->\n <div class=\"conv-header\" (click)=\"toggleDetailConv(conv.audioId); loadConvDetail(conv)\">\n <span class=\"conv-id\">{{ conv.audioId }}</span>\n <div class=\"detail-meta-row\">\n <span class=\"meta-tag brand\" *ngIf=\"conv.storeName\">{{ conv.storeName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.location\">{{ conv.location }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.date\">{{ conv.date }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.time\">{{ conv.time }}</span>\n </div>\n <div class=\"conv-chevron\" [class.open]=\"detailOpenId === conv.audioId\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n </div>\n\n <!-- Expanded body -->\n <div *ngIf=\"detailOpenId === conv.audioId\" class=\"conv-body-expanded\">\n <!-- Waveform player -->\n <div class=\"echo-player\" *ngIf=\"conv.audioUrl\">\n <button class=\"echo-play-btn\" (click)=\"togglePlay(conv.audioId)\">\n <svg *ngIf=\"playingConvId !== conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M8 5v14l11-7z\"/></svg>\n <svg *ngIf=\"playingConvId === conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/></svg>\n </button>\n <div class=\"echo-waveform\" (click)=\"seekAudio($event, conv.audioId)\">\n <div class=\"echo-wf-bar\" *ngFor=\"let h of waveformHeights; let i = index\" [style.height.px]=\"h\"\n [class.played]=\"(playbackStates[conv.audioId]?.progress || 0) > i / waveformHeights.length\"></div>\n </div>\n <span class=\"echo-time\">{{ playbackStates[conv.audioId]?.totalTime || conv.duration || '--' }}</span>\n <audio [id]=\"'audio-' + conv.audioId\" [src]=\"conv.audioUrl\" preload=\"metadata\"\n (timeupdate)=\"onTimeUpdate(audioEl, conv.audioId)\"\n (loadedmetadata)=\"onLoadedMetadata(audioEl, conv.audioId, conv.duration)\"\n (ended)=\"playingConvId = null\" #audioEl></audio>\n </div>\n\n <!-- Tabs -->\n <div class=\"conv-tabs\">\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'summary'\" (click)=\"setConvTab(conv.audioId, 'summary', $event)\">Summary</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'transcript'\" (click)=\"setConvTab(conv.audioId, 'transcript', $event)\">Transcript</button>\n </div>\n\n <!-- Content: Left (Summary/Transcript + AI Insights) + Right (Metrics) -->\n <div class=\"detail-content-split\">\n <!-- Left side -->\n <div class=\"detail-content-left\">\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'summary'\">\n <p class=\"summary-text\">{{ conv.audioDescription || conv.conversationDetails?.audioSummary || 'No summary available' }}</p>\n <!-- AI Insights -->\n <div *ngIf=\"conv.aiInsights?.summary?.length\" class=\"ai-insights-section\">\n <div class=\"ai-insights-label\">AI Insights</div>\n <div *ngFor=\"let insight of conv.aiInsights.summary\" class=\"ai-insight-row\">\n <div class=\"ai-insight-dot\" [style.background]=\"insight.type === 'positive' ? '#00A3FF' : insight.type === 'negative' ? '#EF4444' : '#F59E0B'\"></div>\n <span class=\"ai-insight-text\">{{ insight.text || insight }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'transcript'\">\n <p class=\"summary-text summary-text--prewrap\">{{ cleanTranscription(conv.conversationDetails?.transcription) || 'No transcript available' }}</p>\n </ng-container>\n </div>\n <!-- Right side: Metrics (only show values that have data) -->\n <div class=\"detail-content-right\">\n <div class=\"metrics-panel-label\">Metrics</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" class=\"metric-item-wrap\">\n <!-- Single value: name + value on same row -->\n <ng-container *ngIf=\"m.value?.length === 1\">\n <div class=\"metric-single-row\">\n <span class=\"metric-single-name\" [title]=\"m.name\">{{ m.name }}</span>\n <span class=\"metric-single-value\" [style.color]=\"m.value[0].score !== null && m.value[0].score !== undefined ? '#00A3FF' : '#344054'\">\n {{ formatMetricValue(m.value[0]) }}\n </span>\n </div>\n </ng-container>\n <!-- Multiple values: header + rows -->\n <ng-container *ngIf=\"m.value?.length > 1\">\n <div class=\"metric-multi-header\" [title]=\"m.name\">{{ m.name }}</div>\n <ng-container *ngFor=\"let v of m.value\">\n <div *ngIf=\"(v.score !== null && v.score !== undefined) || (v.Total !== null && v.Total !== undefined) || (v.Avg !== null && v.Avg !== undefined) || (v.total !== null && v.total !== undefined) || (v.avg !== null && v.avg !== undefined) || (v.count !== null && v.count !== undefined)\" class=\"metric-multi-row\">\n <span class=\"metric-multi-name\" [title]=\"v.name\">{{ v.name }}</span>\n <span class=\"metric-multi-value\"\n [style.color]=\"v.score !== null && v.score !== undefined ? '#00A3FF' : '#344054'\">\n {{ formatMetricValue(v) }}\n </span>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!conv.metrics?.length\">\n <div *ngIf=\"conv.storeName\" class=\"metric-fallback-row\"><span class=\"metric-fallback-label\">Store</span><span class=\"metric-fallback-value\">{{ conv.storeName }}</span></div>\n <div *ngIf=\"conv.duration\" class=\"metric-fallback-row\"><span class=\"metric-fallback-label\">Duration</span><span class=\"metric-fallback-value\">{{ conv.duration }}</span></div>\n </ng-container>\n <div *ngIf=\"conv._detailLoading\" class=\"metric-detail-loading\">Loading...</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!detailLoading && detailPageConvs.length === 0 && (selectedCardId || selectedCardName)\" class=\"echo-empty-state--compact\">No conversations found.</div>\n\n <!-- Pagination -->\n <lib-pagination *ngIf=\"detailTotal > 0\" [itemsPerPage]=\"detailPerPage\" [currentPage]=\"detailPage\" [totalItems]=\"detailTotal\"\n [paginationSizes]=\"detailPaginationSizes\" [pageSize]=\"detailPerPage\" (pageChange)=\"onDetailPageChange($event)\"\n (pageSizeChange)=\"onDetailPageSizeChange($event)\"></lib-pagination>\n </ng-container><!-- end detailView -->\n </ng-container><!-- end agentanalysis -->\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 MANAGE TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'manage'\">\n <div class=\"manage-header\">\n <div>\n <div class=\"manage-title\">Agents</div>\n <div class=\"manage-subtitle\">{{ manageTotal }} agents</div>\n </div>\n <span class=\"flex-spacer\"></span>\n <div class=\"echo-search-wrap--wide\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"manageSearch\" (ngModelChange)=\"onManageSearch()\" placeholder=\"Search agents...\" class=\"manage-search-input\">\n </div>\n </div>\n\n <div *ngIf=\"manageLoading\" class=\"echo-empty-state\">Loading agents...</div>\n\n <!-- Agents table -->\n <div *ngIf=\"!manageLoading\" class=\"echo-card\">\n <div class=\"agents-table-header agents-table-4col\">\n <div class=\"agents-table-cell\">Agent Name</div>\n <div class=\"agents-table-cell agents-table-cell--center\">Metrics</div>\n <div class=\"agents-table-cell agents-table-cell--center\">Source</div>\n <div class=\"agents-table-cell agents-table-cell--center\">Action</div>\n </div>\n <div *ngFor=\"let cohort of manageCohorts; trackBy: trackById\" class=\"agents-table-row agents-table-4col\">\n <div class=\"agent-cell-name-wrap\">\n <div class=\"agent-cell-name\">{{ cohort.cohortName || cohort.name }}</div>\n <div class=\"agent-cell-desc\">{{ cohort.cohortDescription || cohort.description || '' }}</div>\n </div>\n <div class=\"agent-cell-metrics\">{{ cohort.metricsAdded || cohort.metricAdded || cohort.metrics?.length || 0 }}</div>\n <div class=\"agent-cell-source\">{{ cohort.source?.join(', ') || '\u2013' }}</div>\n <div class=\"agent-cell-action\">\n <button (click)=\"deleteCohort(cohort.cohortId || cohort.id || cohort._id)\" class=\"agent-delete-btn\">Delete</button>\n </div>\n </div>\n <div *ngIf=\"manageCohorts.length === 0\" class=\"manage-no-results\">No cohorts found.</div>\n </div>\n\n <!-- Manage pagination -->\n <lib-pagination *ngIf=\"manageTotal > 0\" [itemsPerPage]=\"managePerPage\" [currentPage]=\"managePage\" [totalItems]=\"manageTotal\"\n [paginationSizes]=\"managePaginationSizes\" [pageSize]=\"managePerPage\" (pageChange)=\"onManagePageChange($event)\"\n (pageSizeChange)=\"onManagePageSizeChange($event)\"></lib-pagination>\n </ng-container>\n\n </div>\n</div>\n\n<!-- \u2550\u2550\u2550 FILTERS DRAWER \u2550\u2550\u2550 -->\n<div class=\"drawer-overlay\" *ngIf=\"drawerOpen\" (click)=\"closeFilterDrawer()\"></div>\n<div class=\"af-drawer\" *ngIf=\"drawerOpen\">\n <div class=\"drawer-header\">\n <span class=\"drawer-header-title\">Filters</span>\n <button (click)=\"closeFilterDrawer()\" class=\"drawer-close-btn\">\u00D7</button>\n </div>\n <div class=\"drawer-body\">\n <p class=\"drawer-placeholder-text\">Filter configuration coming soon. Uses the same filter APIs as the existing audio pages.</p>\n </div>\n <div class=\"af-footer\">\n <button class=\"af-cancel\" (click)=\"closeFilterDrawer()\">Close</button>\n </div>\n</div>\n", styles: [":host{display:block}.echo-page{padding:20px 24px;background-color:#f4f6fa}.conversations-section{background:#fff;border-radius:10px;padding:16px;margin-top:8px}.conv-card{border:1px solid #e8edf3;border-radius:10px;margin-bottom:12px;overflow:hidden;background:#fff}.conv-header{padding:14px 20px;display:flex;align-items:center;gap:8px;cursor:pointer;transition:background .15s}.conv-header:hover{background:#f8fafc}.conv-chevron{width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:transform .22s ease}.conv-chevron.open{transform:rotate(180deg)}.conv-id{font-size:13px;font-weight:600;color:#0ea5e9;border-radius:4px;padding:2px 8px}.meta-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:24px;font-size:12px;font-weight:500;border:1px solid #e8edf3;background:#f8fafc;color:#344054;white-space:nowrap}.meta-tag.purple{background:#f0f4ff;color:#1a73e8;border-color:#d0e0ff}.meta-tag.brand{font-weight:600}.conv-tabs{display:flex;border-bottom:1px solid #e8edf3;padding:0 20px}.conv-tab-btn{padding:10px 16px;font-size:13px;font-weight:600;border:none;background:transparent;cursor:pointer;color:#667085;border-bottom:2px solid transparent;transition:all .15s;margin-bottom:-1px}.conv-tab-btn.active{color:#00a3ff;border-bottom-color:#00a3ff}.transcript-content .transcript-section{margin-bottom:20px}.transcript-content .transcript-section:last-child{margin-bottom:0}.transcript-content .transcript-section-title{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:#344054;margin-bottom:10px;padding-bottom:6px;border-bottom:1px solid #f0f4ff}.transcript-content .transcript-summary-text,.summary-text{font-size:14px;color:#475467;line-height:1.7;margin:0}.detail-conv-card{border:1px solid #e8edf3;border-radius:10px;margin-bottom:12px;background:#fff;overflow:hidden}.detail-conv-card .conv-header{padding:12px 16px}.detail-conv-card .conv-tabs{padding:0 16px}.detail-conv-card .echo-player{padding:10px 16px}.conv-body-expanded{border-top:1px solid #e8edf3}.echo-player{display:flex;align-items:center;gap:12px;padding:12px 20px;background:#f2f4f7;border-bottom:1px solid #e8edf3}.echo-play-btn{width:36px;height:36px;min-width:36px;border-radius:50%;background:#00a3ff;border:none;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .2s}.echo-play-btn:hover{background:#0087d5}.echo-waveform{flex:1;display:flex;align-items:center;gap:1.5px;height:40px;cursor:pointer}.echo-wf-bar{width:2px;min-width:2px;border-radius:2px;min-height:3px;background:#cbd5e1;transition:background .15s}.echo-wf-bar.played{background:#00a3ff}.echo-time{font-size:13px;font-weight:600;color:#344054;flex-shrink:0;min-width:50px;text-align:right}.btn{padding:8px 16px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;border:none;transition:all .15s}.btn-primary{background:#1a73e8;color:#fff}.btn-primary:hover{background:#135cbc}.analytics-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}@media (max-width: 992px){.analytics-grid{grid-template-columns:repeat(2,1fr)!important}}@media (max-width: 576px){.analytics-grid{grid-template-columns:1fr!important}}.analytics-card{background:#fff;border:1px solid #e8edf3;border-radius:10px;cursor:pointer;overflow:hidden;transition:box-shadow .2s,transform .2s,border-color .2s}.analytics-card:hover{box-shadow:0 4px 12px #00000014;transform:translateY(-2px);border-color:#00a3ff}.analytics-card:hover .analytics-hover-link{opacity:1}.analytics-card-header{padding:14px 16px;border-bottom:1px solid #e8edf3;background:linear-gradient(135deg,#f8fafc,#fff)}.analytics-hover-link{font-size:11px;color:#00a3ff;font-weight:700;opacity:0;transition:opacity .2s}.btn-outline{background:#fff;border:1px solid #D0D5DD;color:#344054}.btn-outline:hover{border-color:#1a73e8;color:#1a73e8}.btn-success{background:#10b981;color:#fff}.section-label{font-size:12px;font-weight:600;color:#98a2b3;letter-spacing:.5px;margin-bottom:8px;text-transform:uppercase}.echo-card{background:#fff;border-radius:10px;border:1px solid #e8edf3;overflow:hidden}.echo-card-header{padding:14px 20px;border-bottom:1px solid #e8edf3;display:flex;align-items:center;gap:8px}.echo-card-title{font-size:16px;font-weight:600;color:#1a2b4b}.echo-card-body{padding:20px}.metric-cards-dynamic{display:grid;gap:16px;margin-bottom:24px;align-items:stretch}.metric-card-dynamic{background:#fff;border:1px solid #e8edf3;border-radius:10px;padding:20px;display:flex;flex-direction:column;max-height:420px;cursor:pointer;transition:border-color .2s,box-shadow .2s}.metric-card-dynamic:hover{border-color:#00a3ff;box-shadow:0 2px 8px #00a3ff14}.metric-card-content{flex:1;min-height:0;overflow-y:auto;padding-right:6px}.metric-card-content::-webkit-scrollbar{width:4px}.metric-card-content::-webkit-scrollbar-track{background:transparent}.metric-card-content::-webkit-scrollbar-thumb{background:#d0d5dd;border-radius:4px}.metric-card-title{font-size:14px;font-weight:700;color:#1a2b4b;margin-bottom:4px;line-height:1.3}.metric-card-subtitle{font-size:11px;color:#667085;margin-bottom:12px;font-weight:500}.metric-info-icon{position:relative;color:#98a2b3;cursor:pointer;flex-shrink:0;padding:2px;transition:color .15s}.metric-info-icon:hover{color:#00a3ff}.metric-info-icon:hover .metric-info-tooltip{opacity:1;visibility:visible;transform:translateY(0)}.metric-info-tooltip{position:absolute;top:calc(100% + 6px);right:0;z-index:100;min-width:200px;max-width:260px;padding:10px 12px;background:#1a2b4b;color:#fff;font-size:11.5px;line-height:1.5;border-radius:8px;box-shadow:0 4px 16px #0000002e;opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity .15s,visibility .15s,transform .15s;pointer-events:none}.metric-info-tooltip:before{content:\"\";position:absolute;top:-5px;right:6px;width:10px;height:10px;background:#1a2b4b;transform:rotate(45deg);border-radius:2px}.metric-bool-row{margin-bottom:10px;cursor:pointer}.metric-dot{width:7px;height:7px;border-radius:50%;background:#00a3ff;flex-shrink:0}.metric-score{font-weight:700;font-size:15px}.metric-status-badge{font-size:10px;font-weight:700;padding:3px 10px;border-radius:20px;text-transform:uppercase;letter-spacing:.5px;white-space:nowrap;flex-shrink:0}.metric-card-desc{font-size:13px;color:#475467;line-height:1.6;margin:12px 0 8px}.metric-card-short-desc{font-size:12px;color:#98a2b3;font-style:italic;line-height:1.5;margin:4px 0 0}.metric-count{font-size:11px;color:#667085;min-width:20px;text-align:right;font-weight:500}.metric-progress-track{height:6px;border-radius:4px;background:#e2e8f2;overflow:hidden}.metric-progress-fill{height:100%;background:#00a3ff;border-radius:4px;transition:width .5s ease}.funnel-chart{display:flex;flex-direction:column;align-items:flex-start;gap:6px;padding:4px 0}.funnel-stage{width:100%;display:flex;justify-content:flex-start;cursor:pointer}.funnel-bar{display:flex;align-items:center;justify-content:space-between;padding:8px 14px;border-radius:6px;min-height:36px;overflow:visible;transition:width .5s ease,opacity .2s}.funnel-bar:hover{opacity:.85}.funnel-label-wrap{position:relative;flex:1;min-width:0;overflow:visible}.funnel-label-wrap .funnel-tooltip{position:absolute;bottom:calc(100% + 10px);left:0;padding:6px 10px;background:#1a2b4b;color:#fff;font-size:11.5px;font-weight:600;border-radius:6px;white-space:nowrap;box-shadow:0 4px 12px #0000002e;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .15s,visibility .15s,transform .15s;pointer-events:none;z-index:100}.funnel-label-wrap .funnel-tooltip:after{content:\"\";position:absolute;top:100%;left:12px;width:8px;height:8px;background:#1a2b4b;transform:translateY(-50%) rotate(45deg);border-radius:1px}.funnel-label-wrap:hover .funnel-tooltip{opacity:1;visibility:visible;transform:translateY(0)}.funnel-label{font-size:12px;font-weight:600;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}.funnel-value{font-size:13px;font-weight:700;color:#fff;flex-shrink:0;margin-left:8px}.numeric-score-row{padding:10px 0;border-bottom:1px solid #f0f4ff;cursor:pointer;transition:background .15s}.numeric-score-row:last-child{border-bottom:none}.numeric-score-row:hover{background:#f8fafc;margin:0 -12px;padding:10px 12px;border-radius:6px}.metric-big-number{font-weight:800;font-size:36px;color:#00a3ff;line-height:1}.metric-avg-label{font-size:12px;color:#667085;margin-left:4px}@media (max-width: 992px){.metric-cards-dynamic{grid-template-columns:repeat(2,1fr)!important}}@media (max-width: 576px){.metric-cards-dynamic{grid-template-columns:1fr!important}}.subjective-wrap{cursor:pointer;max-height:120px;overflow:hidden}.subjective-row{padding:4px 0;font-size:12px;color:#475467;border-bottom:1px solid #f0f4ff;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical}.metric-card-name{font-size:14px;font-weight:600;color:#1a2b4b}.agents-table-header{display:grid;align-items:center;padding:10px 20px;border-bottom:1px solid #e8edf3;background:#f8fafc}.agents-table-cell{font-size:12px;font-weight:600;color:#98a2b3;letter-spacing:.5px;text-transform:uppercase}.agents-table-row{display:grid;align-items:center;padding:14px 20px;border-bottom:1px solid #e8edf3;cursor:pointer;transition:background .15s}.agents-table-row:hover{background:#f8fafc}.agents-table-row:last-child{border-bottom:none}.status-dot{width:8px;height:8px;border-radius:50%}.status-dot.active{background:#10b981}.status-dot.pending{background:#f59e0b}.status-dot.paused{background:#98a2b3}.tango-ai-header{display:flex;flex-direction:column;align-items:center;gap:10px;padding:20px 0}.tango-ai-logo{width:52px;height:52px;border-radius:16px;background:linear-gradient(135deg,#794fd9,#33b1f7);display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #794fd933}.tango-ai-title{font-size:22px;font-weight:800;color:#1a2b4b;line-height:1.2}.tango-ai-subtitle{font-size:13px;color:#667085;margin-top:4px}.echo-search-card{display:flex;align-items:center;background:#fff;border:1px solid #D0D5DD;border-radius:8px;padding:10px 12px 10px 20px;margin-bottom:20px;box-shadow:0 1px 2px #1018280d}.echo-search-input{flex:1;border:none;outline:none;font-size:14px;color:#101828}.echo-search-input::placeholder{color:#98a2b3}.echo-search-slash{width:28px;height:28px;border-radius:50%;border:1px solid #D0D5DD;background:#fff;font-size:14px;font-weight:600;color:#667085;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;margin-right:6px}.echo-search-send{width:32px;height:32px;border-radius:50%;background:#00a3ff;border:none;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s}.echo-search-send:hover{background:#0087d5}.echo-search-send:disabled{opacity:.5;cursor:not-allowed}.echo-ai-response{background:#fff;border:1px solid #e8edf3;border-radius:10px;padding:16px 20px;margin-bottom:16px}.echo-ai-text{font-size:14px;color:#475467;line-height:1.7;margin:0}.echo-conv-count{font-size:14px;font-weight:700;color:#00a3ff;margin-bottom:16px}.typing{display:flex;gap:4px;align-items:center;padding:4px 0}.typing-dot{width:6px;height:6px;border-radius:50%;background:#00a3ff;animation:pulse 1.2s ease-in-out infinite}.typing-dot:nth-child(2){animation-delay:.2s}.typing-dot:nth-child(3){animation-delay:.4s}@keyframes pulse{0%,to{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}:host ::ng-deep lib-pagination{margin-top:16px;display:block}.agent-dropdown-wrap{position:relative}.agent-dropdown-trigger{display:flex;align-items:center;gap:8px;padding:7px 12px;border:1.5px solid #D0D5DD;border-radius:8px;background:#fff;cursor:pointer;max-width:280px;transition:border-color .15s}.agent-dropdown-trigger:hover{border-color:#00a3ff}.agent-dropdown-menu{position:absolute;top:calc(100% + 6px);right:0;background:#fff;border:1px solid #D0D5DD;border-radius:10px;box-shadow:0 8px 24px #0000001f;width:300px;z-index:300;overflow:hidden}.agent-dd-header{padding:8px 14px;font-size:11px;font-weight:600;color:#98a2b3;letter-spacing:.5px;border-bottom:1px solid #e8edf3;text-transform:uppercase}.agent-dd-item{display:flex;align-items:center;gap:10px;padding:10px 14px;cursor:pointer;transition:background .1s}.agent-dd-item:hover{background:#f8fafc}.agent-dd-item.selected{background:#f0f4ff}.agent-dd-name{font-size:13px;font-weight:600;color:#344054;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.agent-dd-meta{font-size:12px;color:#98a2b3;margin-top:1px}.fbar-pill{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #D0D5DD;border-radius:8px;background:#fff;font-size:13px;font-weight:600;color:#344054;cursor:pointer;transition:all .15s;white-space:nowrap}.fbar-pill:hover,.fbar-pill.active{border-color:#1a73e8;color:#1a73e8;background:#f0f4ff}.echo-sub-header{display:flex;align-items:center;padding:12px 0 16px;gap:10px}.btn-back{background:none;border:none;cursor:pointer;display:flex;align-items:center;color:#1a73e8;padding:4px 6px;border-radius:8px}.sub-header-title{font-size:15px;font-weight:600;color:#1a2b4b}.drawer-overlay{position:fixed;inset:0;background:#0000004d;z-index:200}.af-drawer{position:fixed;top:0;right:0;bottom:0;width:380px;max-width:95vw;background:#fff;z-index:201;display:flex;flex-direction:column;box-shadow:-8px 0 40px #00000026;animation:slideInRight .25s ease-out;overflow:hidden}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.af-footer{padding:14px 16px;border-top:1px solid #e8edf3;display:flex;align-items:center;justify-content:flex-end;background:#fff}.af-cancel{padding:9px 20px;border-radius:8px;border:1px solid #D0D5DD;background:#fff;font-size:14px;font-weight:500;cursor:pointer;color:#344054}@media (max-width: 768px){.metric-cards-grid{grid-template-columns:1fr}.agents-table-header,.agents-table-row{grid-template-columns:1fr 80px}}.flex-spacer{flex:1}.text-center{text-align:center}.echo-empty-state{text-align:center;padding:40px;color:#94a3b8}.echo-empty-state--muted{text-align:center;padding:40px;color:#667085}.echo-empty-state--sm{text-align:center;padding:40px;color:#94a3b8;font-size:13px}.echo-empty-state--muted-sm{text-align:center;padding:40px;color:#667085;font-size:13px}.echo-empty-state--compact{text-align:center;padding:32px;color:#667085;font-size:13px}.tango-ai-header-text{text-align:center}.conv-header-body{flex:1;min-width:0}.conv-meta-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:4px}.meta-tag--duration{background:#ede9fe;color:#8b5cf6;border-color:#ddd6fe;font-weight:700}.conv-description{font-size:12.5px;color:#94a3b8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.conv-body-padding{padding:14px 16px}.ai-insights-section{margin-top:16px}.ai-insights-label{font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:10px}.ai-insight-row{display:flex;align-items:flex-start;gap:8px;margin-bottom:8px}.ai-insight-dot{width:6px;height:6px;border-radius:50%;margin-top:5px;flex-shrink:0}.ai-insight-text{font-size:13px;color:#475467;line-height:1.5}.analytics-overview-header{display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap}.analytics-overview-title{font-size:17px;font-weight:700;color:#1a2b4b}.analytics-overview-subtitle{font-size:12px;color:#667085}.echo-search-wrap{width:220px;display:flex;align-items:center;gap:8px;border:1px solid #D0D5DD;border-radius:8px;padding:6px 12px;background:#fff}.echo-search-wrap--wide{width:280px;display:flex;align-items:center;gap:8px;border:1px solid #E2E8F2;border-radius:8px;padding:6px 12px;background:#fff}.echo-inline-input{flex:1;border:none;background:transparent;font-size:13px;color:#344054;outline:none;min-width:0}.echo-inline-input--small{flex:1;border:none;background:transparent;font-size:12px;color:#344054;outline:none;min-width:0}.analytics-card-top-row{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:8px}.analytics-card-name{font-size:13.5px;font-weight:700;color:#1a2b4b;flex:1;padding-right:8px;line-height:1.3}.analytics-card-badge-active{font-size:9px;font-weight:700;padding:2px 8px;border-radius:20px;background:#d1fae5;color:#065f46;text-transform:uppercase;letter-spacing:.5px;flex-shrink:0}.analytics-card-spacer{padding:8px 14px}.analytics-card-footer{padding:8px 14px;border-top:1px solid #e8edf3;display:flex;justify-content:flex-end}.detail-header-bar{display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:14px 20px;background:#fff;border-radius:10px;border:1px solid #e8edf3}.detail-back-btn{background:none;border:none;cursor:pointer;color:#00a3ff;font-size:18px;padding:0}.detail-header-title{font-size:16px;font-weight:700;color:#1a2b4b}.detail-header-conv-count{font-size:13px;color:#667085}.cohort-dd-dot{width:8px;height:8px;border-radius:50%;background:#10b981;flex-shrink:0}.cohort-dd-trigger-name{font-size:13px;font-weight:600;color:#1a2b4b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cohort-dd-search-wrap{padding:8px 10px;border-bottom:1px solid #e8edf3}.cohort-dd-search-inner{display:flex;align-items:center;gap:6px;padding:6px 10px;border:1px solid #D0D5DD;border-radius:6px;background:#fff}.cohort-dd-scroll{max-height:240px;overflow-y:auto}.cohort-dd-item-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.cohort-dd-item-body{flex:1;min-width:0}.cohort-dd-no-results{padding:16px;text-align:center;font-size:12px;color:#667085}.cohort-dd-backdrop{position:fixed;inset:0;z-index:299}.metric-card-header-row{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.metric-card-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.metric-row-flex{display:flex;align-items:center;gap:6px;margin-bottom:4px}.metric-row-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.metric-row-label{font-size:13px;color:#344054;flex:1}.metric-score--teal{color:#00a3ff}.numeric-row-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}.numeric-row-name{font-size:13px;color:#344054;font-weight:600;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.numeric-row-value{font-size:15px;font-weight:800;color:#00a3ff;flex-shrink:0;margin-left:8px}.numeric-row-max{font-size:12px;font-weight:600;color:#98a2b3}.numeric-progress-track{position:relative;height:5px;border-radius:4px;background:#e2e8f2}.numeric-progress-fill{position:absolute;left:0;top:0;height:100%;border-radius:4px;background:linear-gradient(90deg,#00a3ff,#33b1f7)}.pitch-keyword-count{font-size:11px;color:#667085;margin-bottom:8px}.pitch-row-label{font-size:12.5px;color:#344054;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pitch-row-desc{font-size:12px;font-weight:700;color:#667085;flex-shrink:0}.funnel-value-count{opacity:.8;font-weight:500}.detail-conv-section-header{padding:16px 20px;display:flex;align-items:center;gap:8px;background:#fff;border-radius:10px;border:1px solid #e8edf3;margin-bottom:12px}.detail-conv-section-title{font-size:15px;font-weight:700;color:#1a2b4b}.detail-content-split{display:flex}.detail-content-left{flex:3;padding:14px 20px;min-width:0;border-right:1px solid #e8edf3}.detail-content-right{flex:1;min-width:220px;max-width:350px;padding:16px;overflow-y:auto;max-height:500px}.detail-meta-row{display:flex;align-items:center;gap:5px;flex:1;min-width:0;flex-wrap:wrap}.summary-text--prewrap{white-space:pre-wrap}.metrics-panel-label{font-size:10px;font-weight:700;color:#00a3ff;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px}.metric-item-wrap{margin-bottom:8px;padding:6px 0;border-bottom:1px solid #f0f4ff}.metric-single-row{display:flex;align-items:center;gap:8px}.metric-single-name{font-size:12px;font-weight:600;color:#344054;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.metric-single-value{font-size:12px;font-weight:700;flex-shrink:0}.metric-multi-header{font-size:11px;font-weight:700;color:#344054;margin-bottom:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.metric-multi-row{display:flex;align-items:center;gap:8px;padding:3px 0}.metric-multi-name{font-size:11px;color:#667085;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.metric-multi-value{font-size:11px;font-weight:700;flex-shrink:0}.metric-fallback-row{display:flex;justify-content:space-between;margin-bottom:6px}.metric-fallback-label{font-size:12px;color:#667085}.metric-fallback-value{font-size:12px;font-weight:600;color:#344054}.metric-detail-loading{font-size:11px;color:#667085}.manage-header{display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap}.manage-title{font-family:Outfit,sans-serif;font-weight:700;font-size:17px}.manage-subtitle{font-size:12px;color:#94a3b8}.manage-search-input{flex:1;border:none;background:transparent;font-size:13px;font-family:Nunito Sans,sans-serif;color:#0f172a;outline:none;min-width:0}.agents-table-4col{grid-template-columns:minmax(0,1fr) 120px 120px 80px}.agents-table-cell--center{text-align:center}.agent-cell-name-wrap{min-width:0}.agent-cell-name{font-family:Outfit,sans-serif;font-weight:700;font-size:13.5px;color:#0f172a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.agent-cell-desc{font-size:11px;color:#94a3b8;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.agent-cell-metrics{text-align:center;font-family:Outfit,sans-serif;font-weight:700;font-size:13px;color:#0f172a}.agent-cell-source{text-align:center;font-size:11.5px;color:#334155;font-weight:600}.agent-cell-action{text-align:center}.agent-delete-btn{background:none;border:none;cursor:pointer;color:#ef4444;font-size:11px;font-weight:700}.manage-no-results{padding:32px;text-align:center;color:#94a3b8;font-size:13px}.drawer-header{padding:16px;border-bottom:1px solid #E2E8F2;display:flex;align-items:center;justify-content:space-between}.drawer-header-title{font-family:Outfit,sans-serif;font-weight:700;font-size:15px}.drawer-close-btn{background:none;border:none;cursor:pointer;color:#94a3b8;font-size:18px}.drawer-body{padding:16px;flex:1;overflow-y:auto}.drawer-placeholder-text{font-size:13px;color:#94a3b8}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i6.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }] });
|
|
690
808
|
}
|
|
691
809
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TangoEchoComponent, decorators: [{
|
|
692
810
|
type: Component,
|
|
693
|
-
args: [{ selector: 'lib-tango-echo', template: "<div class=\"echo-page\">\n <div class=\"echo-content\">\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 CONVERSATIONS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'conversations'\">\n\n <!-- Tango AI Header -->\n <div class=\"tango-ai-header\">\n <div class=\"tango-ai-logo\">\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M12 2l2.09 6.26L20 10l-5.91 1.74L12 18l-2.09-6.26L4 10l5.91-1.74L12 2z\"/></svg>\n </div>\n <div style=\"text-align:center;\">\n <div class=\"tango-ai-title\">Tango AI</div>\n <div class=\"tango-ai-subtitle\">Analyse conversations, stores & staff performance</div>\n </div>\n </div>\n\n <!-- Search Card -->\n <div class=\"echo-search-card\">\n <input type=\"text\" class=\"echo-search-input\" placeholder=\"Ask anything... 'Which stores are not performing well?'\" [(ngModel)]=\"convSearchQuery\" (keyup.enter)=\"sendConvQuery()\">\n <button class=\"echo-search-send\" (click)=\"sendConvQuery()\" [disabled]=\"!convSearchQuery?.trim()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </div>\n\n <!-- AI Response -->\n <div class=\"echo-ai-response\" *ngIf=\"convAiLoading || convAiReply\">\n <div *ngIf=\"convAiLoading\" class=\"typing\">\n <span class=\"typing-dot\"></span><span class=\"typing-dot\"></span><span class=\"typing-dot\"></span>\n </div>\n <p *ngIf=\"!convAiLoading && convAiReply\" class=\"echo-ai-text\">{{ convAiReply }}</p>\n </div>\n\n <!-- Total count -->\n <div class=\"echo-conv-count\">{{ convTotal }} Conversations</div>\n\n <!-- Conversations list area -->\n <div class=\"conversations-section\">\n\n <!-- Loading -->\n <div *ngIf=\"convLoading\" style=\"text-align:center;padding:40px;color:#94A3B8;\">Loading conversations...</div>\n\n <!-- Conversation cards (dynamic from API \u2014 same pattern as transcript-list) -->\n <div *ngFor=\"let conv of conversations; trackBy: trackById\" class=\"conv-card\">\n <div class=\"conv-header\" (click)=\"toggleConvExpand(conv.audioId)\">\n <div style=\"flex:1;min-width:0;\">\n <div style=\"display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:4px;\">\n <span class=\"conv-id\">{{ conv.audioId }}</span>\n <span class=\"meta-tag brand\" *ngIf=\"conv.storeName\">{{ conv.storeName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.location\">{{ conv.location }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.userName\">{{ conv.userName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.date\">{{ conv.date }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.duration\" style=\"background:#EDE9FE;color:#8B5CF6;border-color:#DDD6FE;font-weight:700;\">{{ conv.duration }}</span>\n </div>\n <div style=\"font-size:12.5px;color:#94A3B8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;\">\n {{ conv.audioDescription || 'No description available' }}\n </div>\n </div>\n <div class=\"conv-chevron\" [class.open]=\"expandedConvIds[conv.audioId]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n </div>\n\n <!-- Expanded body (unified layout matching Agent Analysis design) -->\n <div *ngIf=\"expandedConvIds[conv.audioId]\" class=\"conv-body-expanded\">\n\n <!-- Waveform player -->\n <div class=\"echo-player\" *ngIf=\"conv.audioUrl\">\n <button class=\"echo-play-btn\" (click)=\"togglePlay(conv.audioId)\">\n <svg *ngIf=\"playingConvId !== conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M8 5v14l11-7z\"/></svg>\n <svg *ngIf=\"playingConvId === conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/></svg>\n </button>\n <div class=\"echo-waveform\" (click)=\"seekAudio($event, conv.audioId)\">\n <div class=\"echo-wf-bar\" *ngFor=\"let h of waveformHeights; let i = index\" [style.height.px]=\"h\"\n [class.played]=\"(playbackStates[conv.audioId]?.progress || 0) > i / waveformHeights.length\">\n </div>\n </div>\n <span class=\"echo-time\">{{ playbackStates[conv.audioId]?.totalTime || conv.duration || '--' }}</span>\n <audio [id]=\"'audio-' + conv.audioId\" [src]=\"conv.audioUrl\" preload=\"metadata\"\n (timeupdate)=\"onTimeUpdate(audioEl, conv.audioId)\"\n (loadedmetadata)=\"onLoadedMetadata(audioEl, conv.audioId, conv.duration)\"\n (ended)=\"playingConvId = null\" #audioEl></audio>\n </div>\n\n <!-- Tabs -->\n <div class=\"conv-tabs\">\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'summary'\" (click)=\"setConvTab(conv.audioId, 'summary', $event)\">Summary</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'transcript'\" (click)=\"setConvTab(conv.audioId, 'transcript', $event)\">Transcript</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'interaction'\" (click)=\"setConvTab(conv.audioId, 'interaction', $event)\">Interaction Quality</button>\n </div>\n\n <!-- Content: Left (Summary/Transcript/Interaction + AI Insights) + Right (Metrics) -->\n <div style=\"display:flex;\">\n <!-- Left side -->\n <div style=\"flex:1;padding:14px 16px;min-width:0;border-right:1px solid #e8edf3;\">\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'summary'\">\n <p class=\"summary-text\">{{ conv.audioDescription || conv.conversationDetails?.audioSummary || 'No summary available' }}</p>\n <!-- AI Insights -->\n <div *ngIf=\"conv.aiInsights?.summary?.length\" style=\"margin-top:16px;\">\n <div style=\"font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:10px;\">AI Insights</div>\n <div *ngFor=\"let insight of conv.aiInsights.summary\" style=\"display:flex;align-items:flex-start;gap:8px;margin-bottom:8px;\">\n <div style=\"width:6px;height:6px;border-radius:50%;margin-top:5px;flex-shrink:0;\" [style.background]=\"insight.type === 'positive' ? '#00A3FF' : insight.type === 'negative' ? '#EF4444' : '#F59E0B'\"></div>\n <span style=\"font-size:13px;color:#475467;line-height:1.5;\">{{ insight.text || insight }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'transcript'\">\n <p class=\"summary-text\" style=\"white-space:pre-wrap;\">{{ conv.conversationDetails?.transcription || 'No transcript available' }}</p>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'interaction'\">\n <div style=\"padding:8px 0;\">\n <div style=\"font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px;\">Interaction Quality</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" style=\"margin-bottom:12px;\">\n <div style=\"font-size:13px;font-weight:600;color:#344054;margin-bottom:6px;\">{{ m.name }}</div>\n <div *ngFor=\"let v of m.value\" style=\"display:flex;justify-content:space-between;align-items:center;padding:6px 0;border-bottom:1px solid #f0f4ff;\">\n <span style=\"font-size:13px;color:#475467;\">{{ v.name }}</span>\n <span style=\"font-size:13px;font-weight:700;\" [style.color]=\"v.score > 50 ? '#10B981' : v.score === 0 ? '#667085' : '#EF4444'\">{{ v.score !== undefined ? v.score + '%' : (v.Total || v.Avg || v.count || '\u2013') }}</span>\n </div>\n </div>\n </ng-container>\n <p *ngIf=\"!conv.metrics?.length\" style=\"font-size:13px;color:#94A3B8;\">No interaction quality data available.</p>\n </div>\n </ng-container>\n </div>\n <!-- Right side: Metrics -->\n <div style=\"width:200px;flex-shrink:0;padding:16px;\">\n <div style=\"font-size:10px;font-weight:700;color:#00A3FF;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px;\">Metrics</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" style=\"margin-bottom:8px;\">\n <div *ngFor=\"let v of m.value\" style=\"display:flex;justify-content:space-between;margin-bottom:4px;\">\n <span style=\"font-size:12px;color:#667085;\">{{ v.name || m.name }}</span>\n <span class=\"metric-value\" [style.color]=\"v.score > 50 ? '#10B981' : v.score === 0 ? '#667085' : (v.score !== undefined ? '#EF4444' : '#344054')\" style=\"font-size:12px;font-weight:700;\">{{ v.score !== undefined ? (v.score > 0 ? v.name : v.score) : (v.Total || v.Avg || v.count || '\u2013') }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!conv.metrics?.length\">\n <div *ngIf=\"conv.storeName\" style=\"display:flex;justify-content:space-between;margin-bottom:6px;\"><span style=\"font-size:12px;color:#667085;\">Store</span><span style=\"font-size:12px;font-weight:600;color:#344054;\">{{ conv.storeName }}</span></div>\n <div *ngIf=\"conv.duration\" style=\"display:flex;justify-content:space-between;margin-bottom:6px;\"><span style=\"font-size:12px;color:#667085;\">Duration</span><span style=\"font-size:12px;font-weight:600;color:#344054;\">{{ conv.duration }}</span></div>\n </ng-container>\n <div *ngIf=\"conv._detailLoading\" style=\"font-size:11px;color:#667085;\">Loading...</div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- No data -->\n <div *ngIf=\"!convLoading && conversations.length === 0\" style=\"text-align:center;padding:40px;color:#94A3B8;font-size:13px;\">No conversations found.</div>\n\n <!-- Pagination -->\n <lib-pagination *ngIf=\"convTotal > 0\" [itemsPerPage]=\"convPerPage\" [currentPage]=\"convPage\" [totalItems]=\"convTotal\"\n [paginationSizes]=\"convPaginationSizes\" [pageSize]=\"convPerPage\" (pageChange)=\"onConvPageChange($event)\"\n (pageSizeChange)=\"onConvPageSizeChange($event)\"></lib-pagination>\n </div> <!-- end conversations-section -->\n </ng-container>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 AGENT ANALYSIS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'agentanalysis'\">\n\n <!-- \u2500\u2500 OVERVIEW: Cohort List as Cards \u2500\u2500 -->\n <ng-container *ngIf=\"!detailView\">\n\n <!-- Header -->\n <div style=\"display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap;\">\n <div>\n <div style=\"font-size:17px;font-weight:700;color:#1a2b4b;\">Analytics Overview</div>\n <div style=\"font-size:12px;color:#667085;\">{{ cohortList.length }} active agents</div>\n </div>\n <span style=\"flex:1;\"></span>\n <div style=\"width:220px;display:flex;align-items:center;gap:8px;border:1px solid #D0D5DD;border-radius:8px;padding:6px 12px;background:#fff;\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#98A2B3\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"analysisSearch\" placeholder=\"Search agents\u2026\" style=\"flex:1;border:none;background:transparent;font-size:13px;color:#344054;outline:none;min-width:0;\">\n </div>\n </div>\n\n <!-- Loading -->\n <div *ngIf=\"cohortList.length === 0\" style=\"text-align:center;padding:40px;color:#667085;\">Loading agents...</div>\n\n <!-- Cohort Cards Grid -->\n <div class=\"analytics-grid\">\n <ng-container *ngFor=\"let cohort of cohortList; trackBy: trackById\">\n <div class=\"analytics-card\" *ngIf=\"!analysisSearch || (cohort.cohortName || cohort.name || '').toLowerCase().includes(analysisSearch.toLowerCase())\" (click)=\"selectCohortDetail(cohort)\">\n\n <!-- Card Header -->\n <div class=\"analytics-card-header\">\n <div style=\"display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:8px;\">\n <div style=\"font-size:13.5px;font-weight:700;color:#1a2b4b;flex:1;padding-right:8px;line-height:1.3;\">{{ cohort.cohortName || cohort.name }}</div>\n <span style=\"font-size:9px;font-weight:700;padding:2px 8px;border-radius:20px;background:#D1FAE5;color:#065F46;text-transform:uppercase;letter-spacing:.5px;flex-shrink:0;\">Active</span>\n </div>\n <div style=\"display:flex;gap:6px;\">\n <span style=\"font-size:11px;font-weight:600;padding:3px 9px;border-radius:20px;background:#fff;border:1px solid #e8edf3;color:#344054;\">{{ cohort.metricsAdded || 0 }} metrics</span>\n <span style=\"font-size:11px;font-weight:600;padding:3px 9px;border-radius:20px;background:#fff;border:1px solid #e8edf3;color:#344054;\">50 stores</span>\n </div>\n </div>\n\n <!-- Card Body -->\n <div style=\"padding:8px 14px;\"></div>\n\n <!-- Card Footer -->\n <div style=\"padding:8px 14px;border-top:1px solid #e8edf3;display:flex;justify-content:flex-end;\">\n <span class=\"analytics-hover-link\">View analytics \u2192</span>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- \u2500\u2500 DETAIL: Selected Cohort Metrics + Conversations \u2500\u2500 -->\n <ng-container *ngIf=\"detailView\">\n\n <!-- Header bar: \u2190 Name | Total Conversations | Dropdown -->\n <div style=\"display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:14px 20px;background:#fff;border-radius:10px;border:1px solid #e8edf3;\">\n <button style=\"background:none;border:none;cursor:pointer;color:#00A3FF;font-size:18px;padding:0;\" (click)=\"backToCards()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M15 18l-6-6 6-6\"/></svg>\n </button>\n <span style=\"font-size:16px;font-weight:700;color:#1a2b4b;\">{{ selectedCohortName }}</span>\n <span style=\"flex:1;\"></span>\n <span style=\"font-size:13px;color:#667085;\">Total Conversations: {{ totalAudio }}</span>\n <div style=\"display:flex;align-items:center;gap:6px;padding:6px 14px;border:1.5px solid #00A3FF;border-radius:8px;background:#fff;cursor:pointer;position:relative;\">\n <div style=\"width:8px;height:8px;border-radius:50%;background:#10B981;\"></div>\n <select [(ngModel)]=\"selectedCohortId\" (ngModelChange)=\"onCohortDropdownChange($event)\" style=\"border:none;background:transparent;font-size:13px;font-weight:600;color:#1a2b4b;outline:none;cursor:pointer;padding-right:16px;\">\n <option *ngFor=\"let c of cohortList\" [value]=\"c.cohortId || c.id || c._id\">{{ c.cohortName || c.name }}</option>\n </select>\n </div>\n </div>\n\n <!-- Loading -->\n <div *ngIf=\"cardsLoading\" style=\"text-align:center;padding:40px;color:#667085;\">Loading metrics...</div>\n\n <!-- Metric Cards (dynamic columns based on card count) -->\n <div *ngIf=\"!cardsLoading && cohortCards.length > 0\" class=\"metric-cards-dynamic\"\n [style.grid-template-columns]=\"'repeat(' + Math.min(cohortCards.length, 4) + ', 1fr)'\">\n <div *ngFor=\"let card of cohortCards; trackBy: trackById\" class=\"metric-card-dynamic\">\n <div class=\"metric-card-title\">{{ card.name }}</div>\n <div class=\"metric-card-subtitle\">{{ totalAudio }} conversations</div>\n\n <!-- BOOLEAN_BASKET \u2014 rows with progress bars -->\n <ng-container *ngIf=\"card.type === 'BOOLEAN_BASKET'\">\n <div *ngFor=\"let row of card.booleanRows\" class=\"metric-bool-row\" (click)=\"onCardRowClick(row.id, card.name)\">\n <div style=\"display:flex;align-items:center;gap:6px;margin-bottom:4px;\">\n <div class=\"metric-dot\"></div>\n <span style=\"font-size:13px;color:#344054;flex:1;\">{{ row.label }}</span>\n <span class=\"metric-score\">{{ row.score }}%</span>\n <span class=\"metric-count\">{{ row.responses }}</span>\n </div>\n <div class=\"metric-progress-track\">\n <div class=\"metric-progress-fill\" [style.width.%]=\"row.score\"></div>\n </div>\n </div>\n </ng-container>\n\n <!-- NUMERIC \u2014 big number -->\n <ng-container *ngIf=\"card.type === 'NUMERIC_SCALAR' || card.type === 'NUMERIC_ARRAY'\">\n <div style=\"cursor:pointer;\" (click)=\"onCardRowClick('', card.key)\">\n <span class=\"metric-big-number\">{{ card.numericData?.avg || card.numericData?.total || '\u2013' }}</span>\n <span class=\"metric-avg-label\">avg</span>\n </div>\n </ng-container>\n\n <!-- SUBJECTIVE -->\n <ng-container *ngIf=\"card.type === 'SUBJECTIVE' || card.type === 'SUBJECTIVE_COUNT'\">\n <div class=\"subjective-wrap\" (click)=\"onCardRowClick('', card.key)\">\n <div *ngFor=\"let row of card.subjectiveRows?.slice(0, 2)\" class=\"subjective-row\">\n \u2022 {{ row.reasoning || row.store_id }}\n </div>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- No cards -->\n <div *ngIf=\"!cardsLoading && cohortCards.length === 0\" style=\"text-align:center;padding:40px;color:#667085;font-size:13px;\">No analysis data available.</div>\n\n <!-- \u2500\u2500 Conversations Section \u2500\u2500 -->\n <div class=\"conversations-section\" *ngIf=\"detailPageConvs.length > 0 || detailLoading\">\n <div style=\"padding:16px 20px;display:flex;align-items:center;gap:8px;background:#fff;border-radius:10px;border:1px solid #e8edf3;margin-bottom:12px;\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#344054\" stroke-width=\"1.8\"><path d=\"M20 2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h11l5 3V4a2 2 0 0 0-2-2z\"/></svg>\n <span style=\"font-size:15px;font-weight:700;color:#1a2b4b;\">Conversations</span>\n </div>\n\n <div *ngIf=\"detailLoading\" style=\"text-align:center;padding:40px;color:#667085;\">Loading...</div>\n\n <div *ngFor=\"let conv of detailPageConvs; trackBy: trackById\" class=\"detail-conv-card\">\n <!-- Conv header -->\n <div class=\"conv-header\" (click)=\"toggleDetailConv(conv.audioId); loadConvDetail(conv)\">\n <span class=\"conv-id\">{{ conv.audioId }}</span>\n <div style=\"display:flex;align-items:center;gap:5px;flex:1;min-width:0;flex-wrap:wrap;\">\n <span class=\"meta-tag brand\" *ngIf=\"conv.storeName\">{{ conv.storeName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.location\">{{ conv.location }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.date\">{{ conv.date }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.time\">{{ conv.time }}</span>\n </div>\n <div class=\"conv-chevron\" [class.open]=\"detailOpenId === conv.audioId\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n </div>\n\n <!-- Expanded body -->\n <div *ngIf=\"detailOpenId === conv.audioId\" class=\"conv-body-expanded\">\n <!-- Waveform player -->\n <div class=\"echo-player\" *ngIf=\"conv.audioUrl\">\n <button class=\"echo-play-btn\" (click)=\"togglePlay(conv.audioId)\">\n <svg *ngIf=\"playingConvId !== conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M8 5v14l11-7z\"/></svg>\n <svg *ngIf=\"playingConvId === conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/></svg>\n </button>\n <div class=\"echo-waveform\" (click)=\"seekAudio($event, conv.audioId)\">\n <div class=\"echo-wf-bar\" *ngFor=\"let h of waveformHeights; let i = index\" [style.height.px]=\"h\"\n [class.played]=\"(playbackStates[conv.audioId]?.progress || 0) > i / waveformHeights.length\"></div>\n </div>\n <span class=\"echo-time\">{{ playbackStates[conv.audioId]?.totalTime || conv.duration || '--' }}</span>\n <audio [id]=\"'audio-' + conv.audioId\" [src]=\"conv.audioUrl\" preload=\"metadata\"\n (timeupdate)=\"onTimeUpdate(audioEl, conv.audioId)\"\n (loadedmetadata)=\"onLoadedMetadata(audioEl, conv.audioId, conv.duration)\"\n (ended)=\"playingConvId = null\" #audioEl></audio>\n </div>\n\n <!-- Tabs -->\n <div class=\"conv-tabs\">\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'summary'\" (click)=\"setConvTab(conv.audioId, 'summary', $event)\">Summary</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'transcript'\" (click)=\"setConvTab(conv.audioId, 'transcript', $event)\">Transcript</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'interaction'\" (click)=\"setConvTab(conv.audioId, 'interaction', $event)\">Interaction Quality</button>\n </div>\n\n <!-- Content: Left (Summary/Transcript + AI Insights) + Right (Metrics) -->\n <div style=\"display:flex;\">\n <!-- Left side -->\n <div style=\"flex:1;padding:14px 16px;min-width:0;border-right:1px solid #e8edf3;\">\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'summary'\">\n <p class=\"summary-text\">{{ conv.audioDescription || conv.conversationDetails?.audioSummary || 'No summary available' }}</p>\n <!-- AI Insights -->\n <div *ngIf=\"conv.aiInsights?.summary?.length\" style=\"margin-top:16px;\">\n <div style=\"font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:10px;\">AI Insights</div>\n <div *ngFor=\"let insight of conv.aiInsights.summary\" style=\"display:flex;align-items:flex-start;gap:8px;margin-bottom:8px;\">\n <div style=\"width:6px;height:6px;border-radius:50%;margin-top:5px;flex-shrink:0;\" [style.background]=\"insight.type === 'positive' ? '#00A3FF' : insight.type === 'negative' ? '#EF4444' : '#F59E0B'\"></div>\n <span style=\"font-size:13px;color:#475467;line-height:1.5;\">{{ insight.text || insight }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'transcript'\">\n <p class=\"summary-text\" style=\"white-space:pre-wrap;\">{{ conv.conversationDetails?.transcription || 'No transcript available' }}</p>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'interaction'\">\n <div style=\"padding:8px 0;\">\n <div style=\"font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px;\">Interaction Quality</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" style=\"margin-bottom:12px;\">\n <div style=\"font-size:13px;font-weight:600;color:#344054;margin-bottom:6px;\">{{ m.name }}</div>\n <div *ngFor=\"let v of m.value\" style=\"display:flex;justify-content:space-between;align-items:center;padding:6px 0;border-bottom:1px solid #f0f4ff;\">\n <span style=\"font-size:13px;color:#475467;\">{{ v.name }}</span>\n <span style=\"font-size:13px;font-weight:700;\" [style.color]=\"v.score > 50 ? '#10B981' : v.score === 0 ? '#667085' : '#EF4444'\">{{ v.score !== undefined ? v.score + '%' : (v.Total || v.Avg || v.count || '\u2013') }}</span>\n </div>\n </div>\n </ng-container>\n <p *ngIf=\"!conv.metrics?.length\" style=\"font-size:13px;color:#94A3B8;\">No interaction quality data available.</p>\n </div>\n </ng-container>\n </div>\n <!-- Right side: Metrics -->\n <div style=\"width:200px;flex-shrink:0;padding:16px;\">\n <div style=\"font-size:10px;font-weight:700;color:#00A3FF;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px;\">Metrics</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" style=\"margin-bottom:8px;\">\n <div *ngFor=\"let v of m.value\" style=\"display:flex;justify-content:space-between;margin-bottom:4px;\">\n <span style=\"font-size:12px;color:#667085;\">{{ v.name || m.name }}</span>\n <span style=\"font-size:12px;font-weight:700;\" [style.color]=\"v.score > 50 ? '#10B981' : v.score === 0 ? '#667085' : '#EF4444'\">{{ v.score !== undefined ? (v.score > 0 ? v.name : v.score) : (v.Total || v.Avg || v.count || '\u2013') }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!conv.metrics?.length\">\n <div *ngIf=\"conv.storeName\" style=\"display:flex;justify-content:space-between;margin-bottom:6px;\"><span style=\"font-size:12px;color:#667085;\">Store</span><span style=\"font-size:12px;font-weight:600;color:#344054;\">{{ conv.storeName }}</span></div>\n <div *ngIf=\"conv.duration\" style=\"display:flex;justify-content:space-between;margin-bottom:6px;\"><span style=\"font-size:12px;color:#667085;\">Duration</span><span style=\"font-size:12px;font-weight:600;color:#344054;\">{{ conv.duration }}</span></div>\n </ng-container>\n <div *ngIf=\"conv._detailLoading\" style=\"font-size:11px;color:#667085;\">Loading...</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!detailLoading && detailPageConvs.length === 0 && (selectedCardId || selectedCardName)\" style=\"text-align:center;padding:32px;color:#667085;font-size:13px;\">No conversations found.</div>\n\n <!-- Pagination -->\n <lib-pagination *ngIf=\"detailTotal > 0\" [itemsPerPage]=\"detailPerPage\" [currentPage]=\"detailPage\" [totalItems]=\"detailTotal\"\n [paginationSizes]=\"detailPaginationSizes\" [pageSize]=\"detailPerPage\" (pageChange)=\"onDetailPageChange($event)\"\n (pageSizeChange)=\"onDetailPageSizeChange($event)\"></lib-pagination>\n </ng-container>\n </ng-container>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 MANAGE TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'manage'\">\n <div style=\"display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap;\">\n <div>\n <div style=\"font-family:'Outfit',sans-serif;font-weight:700;font-size:17px;\">Agents</div>\n <div style=\"font-size:12px;color:#94A3B8;\">{{ manageTotal }} agents</div>\n </div>\n <span style=\"flex:1;\"></span>\n <div style=\"width:280px;display:flex;align-items:center;gap:8px;border:1px solid #E2E8F2;border-radius:8px;padding:6px 12px;background:#fff;\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"manageSearch\" (ngModelChange)=\"onManageSearch()\" placeholder=\"Search agents...\" style=\"flex:1;border:none;background:transparent;font-size:13px;font-family:'Nunito Sans',sans-serif;color:#0F172A;outline:none;min-width:0;\">\n </div>\n </div>\n\n <div *ngIf=\"manageLoading\" style=\"text-align:center;padding:40px;color:#94A3B8;\">Loading agents...</div>\n\n <!-- Agents table -->\n <div *ngIf=\"!manageLoading\" class=\"echo-card\">\n <div class=\"agents-table-header\" style=\"grid-template-columns:minmax(0,1fr) 120px 120px 80px;\">\n <div class=\"agents-table-cell\">Agent Name</div>\n <div class=\"agents-table-cell\" style=\"text-align:center;\">Metrics</div>\n <div class=\"agents-table-cell\" style=\"text-align:center;\">Source</div>\n <div class=\"agents-table-cell\" style=\"text-align:center;\">Action</div>\n </div>\n <div *ngFor=\"let cohort of manageCohorts; trackBy: trackById\" class=\"agents-table-row\" style=\"grid-template-columns:minmax(0,1fr) 120px 120px 80px;\">\n <div style=\"min-width:0;\">\n <div style=\"font-family:'Outfit',sans-serif;font-weight:700;font-size:13.5px;color:#0F172A;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">{{ cohort.cohortName || cohort.name }}</div>\n <div style=\"font-size:11px;color:#94A3B8;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">{{ cohort.cohortDescription || cohort.description || '' }}</div>\n </div>\n <div style=\"text-align:center;font-family:'Outfit',sans-serif;font-weight:700;font-size:13px;color:#0F172A;\">{{ cohort.metricsAdded || cohort.metricAdded || cohort.metrics?.length || 0 }}</div>\n <div style=\"text-align:center;font-size:11.5px;color:#334155;font-weight:600;\">{{ cohort.source?.join(', ') || '\u2013' }}</div>\n <div style=\"text-align:center;\">\n <button (click)=\"deleteCohort(cohort.cohortId || cohort.id || cohort._id)\" style=\"background:none;border:none;cursor:pointer;color:#EF4444;font-size:11px;font-weight:700;\">Delete</button>\n </div>\n </div>\n <div *ngIf=\"manageCohorts.length === 0\" style=\"padding:32px;text-align:center;color:#94A3B8;font-size:13px;\">No cohorts found.</div>\n </div>\n\n <!-- Manage pagination -->\n <lib-pagination *ngIf=\"manageTotal > 0\" [itemsPerPage]=\"managePerPage\" [currentPage]=\"managePage\" [totalItems]=\"manageTotal\"\n [paginationSizes]=\"managePaginationSizes\" [pageSize]=\"managePerPage\" (pageChange)=\"onManagePageChange($event)\"\n (pageSizeChange)=\"onManagePageSizeChange($event)\"></lib-pagination>\n </ng-container>\n\n </div>\n</div>\n\n<!-- \u2550\u2550\u2550 FILTERS DRAWER \u2550\u2550\u2550 -->\n<div class=\"drawer-overlay\" *ngIf=\"drawerOpen\" (click)=\"closeFilterDrawer()\"></div>\n<div class=\"af-drawer\" *ngIf=\"drawerOpen\">\n <div style=\"padding:16px;border-bottom:1px solid #E2E8F2;display:flex;align-items:center;justify-content:space-between;\">\n <span style=\"font-family:'Outfit',sans-serif;font-weight:700;font-size:15px;\">Filters</span>\n <button (click)=\"closeFilterDrawer()\" style=\"background:none;border:none;cursor:pointer;color:#94A3B8;font-size:18px;\">\u00D7</button>\n </div>\n <div style=\"padding:16px;flex:1;overflow-y:auto;\">\n <p style=\"font-size:13px;color:#94A3B8;\">Filter configuration coming soon. Uses the same filter APIs as the existing audio pages.</p>\n </div>\n <div class=\"af-footer\">\n <button class=\"af-cancel\" (click)=\"closeFilterDrawer()\">Close</button>\n </div>\n</div>\n", styles: [":host{display:block}.echo-page{padding:20px 24px;background-color:#f4f6fa}.conversations-section{background:#fff;border-radius:10px;padding:16px;margin-top:8px}.conv-card{border:1px solid #e8edf3;border-radius:10px;margin-bottom:12px;overflow:hidden;background:#fff}.conv-header{padding:14px 20px;display:flex;align-items:center;gap:8px;cursor:pointer;transition:background .15s}.conv-header:hover{background:#f8fafc}.conv-chevron{width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:transform .22s ease}.conv-chevron.open{transform:rotate(180deg)}.conv-id{font-size:13px;font-weight:600;color:#0ea5e9;border-radius:4px;padding:2px 8px}.meta-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:24px;font-size:12px;font-weight:500;border:1px solid #e8edf3;background:#f8fafc;color:#344054;white-space:nowrap}.meta-tag.purple{background:#f0f4ff;color:#1a73e8;border-color:#d0e0ff}.meta-tag.brand{font-weight:600}.conv-tabs{display:flex;border-bottom:1px solid #e8edf3;padding:0 20px}.conv-tab-btn{padding:10px 16px;font-size:13px;font-weight:600;border:none;background:transparent;cursor:pointer;color:#667085;border-bottom:2px solid transparent;transition:all .15s;margin-bottom:-1px}.conv-tab-btn.active{color:#00a3ff;border-bottom-color:#00a3ff}.transcript-content .transcript-section{margin-bottom:20px}.transcript-content .transcript-section:last-child{margin-bottom:0}.transcript-content .transcript-section-title{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:#344054;margin-bottom:10px;padding-bottom:6px;border-bottom:1px solid #f0f4ff}.transcript-content .transcript-summary-text,.summary-text{font-size:14px;color:#475467;line-height:1.7;margin:0}.detail-conv-card{border:1px solid #e8edf3;border-radius:10px;margin-bottom:12px;background:#fff;overflow:hidden}.detail-conv-card .conv-header{padding:12px 16px}.detail-conv-card .conv-tabs{padding:0 16px}.detail-conv-card .echo-player{padding:10px 16px}.conv-body-expanded{border-top:1px solid #e8edf3}.echo-player{display:flex;align-items:center;gap:12px;padding:12px 20px;background:#f2f4f7;border-bottom:1px solid #e8edf3}.echo-play-btn{width:36px;height:36px;min-width:36px;border-radius:50%;background:#00a3ff;border:none;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .2s}.echo-play-btn:hover{background:#0087d5}.echo-waveform{flex:1;display:flex;align-items:center;gap:1.5px;height:40px;cursor:pointer}.echo-wf-bar{width:2px;min-width:2px;border-radius:2px;min-height:3px;background:#cbd5e1;transition:background .15s}.echo-wf-bar.played{background:#00a3ff}.echo-time{font-size:13px;font-weight:600;color:#344054;flex-shrink:0;min-width:50px;text-align:right}.btn{padding:8px 16px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;border:none;transition:all .15s}.btn-primary{background:#1a73e8;color:#fff}.btn-primary:hover{background:#135cbc}.analytics-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}.analytics-card{background:#fff;border:1px solid #e8edf3;border-radius:10px;cursor:pointer;overflow:hidden;transition:box-shadow .2s,transform .2s,border-color .2s}.analytics-card:hover{box-shadow:0 4px 12px #00000014;transform:translateY(-2px);border-color:#00a3ff}.analytics-card:hover .analytics-hover-link{opacity:1}.analytics-card-header{padding:14px 16px;border-bottom:1px solid #e8edf3;background:linear-gradient(135deg,#f8fafc,#fff)}.analytics-hover-link{font-size:11px;color:#00a3ff;font-weight:700;opacity:0;transition:opacity .2s}.btn-outline{background:#fff;border:1px solid #D0D5DD;color:#344054}.btn-outline:hover{border-color:#1a73e8;color:#1a73e8}.btn-success{background:#10b981;color:#fff}.section-label{font-size:12px;font-weight:600;color:#98a2b3;letter-spacing:.5px;margin-bottom:8px;text-transform:uppercase}.echo-card{background:#fff;border-radius:10px;border:1px solid #e8edf3;overflow:hidden}.echo-card-header{padding:14px 20px;border-bottom:1px solid #e8edf3;display:flex;align-items:center;gap:8px}.echo-card-title{font-size:16px;font-weight:600;color:#1a2b4b}.echo-card-body{padding:20px}.metric-cards-dynamic{display:grid;gap:16px;margin-bottom:24px;align-items:stretch}.metric-card-dynamic{background:#fff;border:1px solid #e8edf3;border-radius:10px;padding:20px;display:flex;flex-direction:column;cursor:pointer;transition:border-color .2s,box-shadow .2s}.metric-card-dynamic:hover{border-color:#00a3ff;box-shadow:0 2px 8px #00a3ff14}.metric-card-title{font-size:14px;font-weight:700;color:#1a2b4b;margin-bottom:4px;line-height:1.3}.metric-card-subtitle{font-size:11px;color:#667085;margin-bottom:12px}.metric-bool-row{margin-bottom:10px;cursor:pointer}.metric-dot{width:7px;height:7px;border-radius:50%;background:#00a3ff;flex-shrink:0}.metric-score{font-weight:700;font-size:15px;color:#00a3ff}.metric-count{font-size:11px;color:#667085;min-width:20px;text-align:right}.metric-progress-track{height:6px;border-radius:4px;background:#e2e8f2;overflow:hidden}.metric-progress-fill{height:100%;background:#00a3ff;border-radius:4px;transition:width .5s ease}.metric-big-number{font-weight:800;font-size:36px;color:#00a3ff;line-height:1}.metric-avg-label{font-size:12px;color:#667085;margin-left:4px}@media (max-width: 992px){.metric-cards-dynamic{grid-template-columns:repeat(2,1fr)!important}}@media (max-width: 576px){.metric-cards-dynamic{grid-template-columns:1fr!important}}.subjective-wrap{cursor:pointer;max-height:120px;overflow:hidden}.subjective-row{padding:4px 0;font-size:12px;color:#475467;border-bottom:1px solid #f0f4ff;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical}.metric-card-name{font-size:14px;font-weight:600;color:#1a2b4b}.agents-table-header{display:grid;align-items:center;padding:10px 20px;border-bottom:1px solid #e8edf3;background:#f8fafc}.agents-table-cell{font-size:12px;font-weight:600;color:#98a2b3;letter-spacing:.5px;text-transform:uppercase}.agents-table-row{display:grid;align-items:center;padding:14px 20px;border-bottom:1px solid #e8edf3;cursor:pointer;transition:background .15s}.agents-table-row:hover{background:#f8fafc}.agents-table-row:last-child{border-bottom:none}.status-dot{width:8px;height:8px;border-radius:50%}.status-dot.active{background:#10b981}.status-dot.pending{background:#f59e0b}.status-dot.paused{background:#98a2b3}.tango-ai-header{display:flex;flex-direction:column;align-items:center;gap:10px;padding:20px 0}.tango-ai-logo{width:52px;height:52px;border-radius:16px;background:linear-gradient(135deg,#794fd9,#33b1f7);display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #794fd933}.tango-ai-title{font-size:22px;font-weight:800;color:#1a2b4b;line-height:1.2}.tango-ai-subtitle{font-size:13px;color:#667085;margin-top:4px}.echo-search-card{display:flex;align-items:center;background:#fff;border:1px solid #D0D5DD;border-radius:8px;padding:10px 12px 10px 20px;margin-bottom:20px;box-shadow:0 1px 2px #1018280d}.echo-search-input{flex:1;border:none;outline:none;font-size:14px;color:#101828}.echo-search-input::placeholder{color:#98a2b3}.echo-search-slash{width:28px;height:28px;border-radius:50%;border:1px solid #D0D5DD;background:#fff;font-size:14px;font-weight:600;color:#667085;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;margin-right:6px}.echo-search-send{width:32px;height:32px;border-radius:50%;background:#00a3ff;border:none;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s}.echo-search-send:hover{background:#0087d5}.echo-search-send:disabled{opacity:.5;cursor:not-allowed}.echo-ai-response{background:#fff;border:1px solid #e8edf3;border-radius:10px;padding:16px 20px;margin-bottom:16px}.echo-ai-text{font-size:14px;color:#475467;line-height:1.7;margin:0}.echo-conv-count{font-size:14px;font-weight:700;color:#00a3ff;margin-bottom:16px}.typing{display:flex;gap:4px;align-items:center;padding:4px 0}.typing-dot{width:6px;height:6px;border-radius:50%;background:#00a3ff;animation:pulse 1.2s ease-in-out infinite}.typing-dot:nth-child(2){animation-delay:.2s}.typing-dot:nth-child(3){animation-delay:.4s}@keyframes pulse{0%,to{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}:host ::ng-deep lib-pagination{margin-top:16px;display:block}.agent-dropdown-wrap{position:relative}.agent-dropdown-menu{position:absolute;top:calc(100% + 6px);right:0;background:#fff;border:1px solid #D0D5DD;border-radius:10px;box-shadow:0 4px 16px #0000001a;width:280px;z-index:300;overflow:hidden}.agent-dd-header{padding:8px 14px;font-size:11px;font-weight:600;color:#98a2b3;letter-spacing:.5px;border-bottom:1px solid #e8edf3;text-transform:uppercase}.agent-dd-item{display:flex;align-items:center;gap:10px;padding:10px 14px;cursor:pointer;transition:background .1s}.agent-dd-item:hover{background:#f8fafc}.agent-dd-item.selected{background:#f0f4ff}.agent-dd-name{font-size:13px;font-weight:600;color:#344054;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.agent-dd-meta{font-size:12px;color:#98a2b3;margin-top:1px}.fbar-pill{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #D0D5DD;border-radius:8px;background:#fff;font-size:13px;font-weight:600;color:#344054;cursor:pointer;transition:all .15s;white-space:nowrap}.fbar-pill:hover,.fbar-pill.active{border-color:#1a73e8;color:#1a73e8;background:#f0f4ff}.echo-sub-header{display:flex;align-items:center;padding:12px 0 16px;gap:10px}.btn-back{background:none;border:none;cursor:pointer;display:flex;align-items:center;color:#1a73e8;padding:4px 6px;border-radius:8px}.sub-header-title{font-size:15px;font-weight:600;color:#1a2b4b}.drawer-overlay{position:fixed;inset:0;background:#0000004d;z-index:200}.af-drawer{position:fixed;top:0;right:0;bottom:0;width:380px;max-width:95vw;background:#fff;z-index:201;display:flex;flex-direction:column;box-shadow:-8px 0 40px #00000026;animation:slideInRight .25s ease-out;overflow:hidden}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.af-footer{padding:14px 16px;border-top:1px solid #e8edf3;display:flex;align-items:center;justify-content:flex-end;background:#fff}.af-cancel{padding:9px 20px;border-radius:8px;border:1px solid #D0D5DD;background:#fff;font-size:14px;font-weight:500;cursor:pointer;color:#344054}@media (max-width: 768px){.metric-cards-grid{grid-template-columns:1fr}.agents-table-header,.agents-table-row{grid-template-columns:1fr 80px}}\n"] }]
|
|
811
|
+
args: [{ selector: 'lib-tango-echo', template: "<div class=\"echo-page\">\n <div class=\"echo-content\">\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 CONVERSATIONS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'conversations'\">\n\n <!-- Tango AI Header -->\n <div class=\"tango-ai-header\">\n <div class=\"tango-ai-logo\">\n <svg width=\"26\" height=\"26\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#fff\" stroke-width=\"1.8\" stroke-linecap=\"round\"><path d=\"M12 2l2.09 6.26L20 10l-5.91 1.74L12 18l-2.09-6.26L4 10l5.91-1.74L12 2z\"/></svg>\n </div>\n <div class=\"tango-ai-header-text\">\n <div class=\"tango-ai-title\">Tango AI</div>\n <div class=\"tango-ai-subtitle\">Analyse conversations, stores & staff performance</div>\n </div>\n </div>\n\n <!-- Search Card -->\n <div class=\"echo-search-card\">\n <input type=\"text\" class=\"echo-search-input\" placeholder=\"Ask anything... 'Which stores are not performing well?'\" [(ngModel)]=\"convSearchQuery\" (keyup.enter)=\"sendConvQuery()\">\n <button class=\"echo-search-send\" (click)=\"sendConvQuery()\" [disabled]=\"!convSearchQuery?.trim()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n </svg>\n </button>\n </div>\n\n <!-- AI Response -->\n <div class=\"echo-ai-response\" *ngIf=\"convAiLoading || convAiReply\">\n <div *ngIf=\"convAiLoading\" class=\"typing\">\n <span class=\"typing-dot\"></span><span class=\"typing-dot\"></span><span class=\"typing-dot\"></span>\n </div>\n <p *ngIf=\"!convAiLoading && convAiReply\" class=\"echo-ai-text\">{{ convAiReply }}</p>\n </div>\n\n <!-- Total count -->\n <div class=\"echo-conv-count\">{{ convTotal }} Conversations</div>\n\n <!-- Conversations list area -->\n <div class=\"conversations-section\">\n\n <!-- Loading -->\n <div *ngIf=\"convLoading\" class=\"echo-empty-state\">Loading conversations...</div>\n\n <!-- Conversation cards (dynamic from API \u2014 same pattern as transcript-list) -->\n <div *ngFor=\"let conv of conversations; trackBy: trackById\" class=\"conv-card\">\n <div class=\"conv-header\" (click)=\"toggleConvExpand(conv.audioId)\">\n <div class=\"conv-header-body\">\n <div class=\"conv-meta-row\">\n <span class=\"conv-id\">{{ conv.audioId }}</span>\n <span class=\"meta-tag brand\" *ngIf=\"conv.storeName\">{{ conv.storeName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.location\">{{ conv.location }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.userName\">{{ conv.userName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.date\">{{ conv.date }}</span>\n <span class=\"meta-tag meta-tag--duration\" *ngIf=\"conv.duration\">{{ conv.duration }}</span>\n </div>\n <div class=\"conv-description\">\n {{ conv.audioDescription || 'No description available' }}\n </div>\n </div>\n <div class=\"conv-chevron\" [class.open]=\"expandedConvIds[conv.audioId]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n </div>\n\n <!-- Expanded body (unified layout matching Agent Analysis design) -->\n <div *ngIf=\"expandedConvIds[conv.audioId]\" class=\"conv-body-expanded\">\n\n <!-- Waveform player -->\n <div class=\"echo-player\" *ngIf=\"conv.audioUrl\">\n <button class=\"echo-play-btn\" (click)=\"togglePlay(conv.audioId)\">\n <svg *ngIf=\"playingConvId !== conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M8 5v14l11-7z\"/></svg>\n <svg *ngIf=\"playingConvId === conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/></svg>\n </button>\n <div class=\"echo-waveform\" (click)=\"seekAudio($event, conv.audioId)\">\n <div class=\"echo-wf-bar\" *ngFor=\"let h of waveformHeights; let i = index\" [style.height.px]=\"h\"\n [class.played]=\"(playbackStates[conv.audioId]?.progress || 0) > i / waveformHeights.length\">\n </div>\n </div>\n <span class=\"echo-time\">{{ playbackStates[conv.audioId]?.totalTime || conv.duration || '--' }}</span>\n <audio [id]=\"'audio-' + conv.audioId\" [src]=\"conv.audioUrl\" preload=\"metadata\"\n (timeupdate)=\"onTimeUpdate(audioEl, conv.audioId)\"\n (loadedmetadata)=\"onLoadedMetadata(audioEl, conv.audioId, conv.duration)\"\n (ended)=\"playingConvId = null\" #audioEl></audio>\n </div>\n\n <!-- Summary Content -->\n <div class=\"conv-body-padding\">\n <p class=\"summary-text\">{{ conv.audioDescription || conv.conversationDetails?.audioSummary || 'No summary available' }}</p>\n <!-- AI Insights -->\n <div *ngIf=\"conv.aiInsights?.summary?.length\" class=\"ai-insights-section\">\n <div class=\"ai-insights-label\">AI Insights</div>\n <div *ngFor=\"let insight of conv.aiInsights.summary\" class=\"ai-insight-row\">\n <div class=\"ai-insight-dot\" [style.background]=\"insight.type === 'positive' ? '#00A3FF' : insight.type === 'negative' ? '#EF4444' : '#F59E0B'\"></div>\n <span class=\"ai-insight-text\">{{ insight.text || insight }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- No data -->\n <div *ngIf=\"!convLoading && conversations.length === 0\" class=\"echo-empty-state--sm\">No conversations found.</div>\n\n <!-- Pagination -->\n <lib-pagination *ngIf=\"convTotal > 0\" [itemsPerPage]=\"convPerPage\" [currentPage]=\"convPage\" [totalItems]=\"convTotal\"\n [paginationSizes]=\"convPaginationSizes\" [pageSize]=\"convPerPage\" (pageChange)=\"onConvPageChange($event)\"\n (pageSizeChange)=\"onConvPageSizeChange($event)\"></lib-pagination>\n </div> <!-- end conversations-section -->\n </ng-container>\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 AGENT ANALYSIS TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'agentanalysis'\">\n\n <!-- \u2500\u2500 OVERVIEW: Agent Cards Grid \u2500\u2500 -->\n <ng-container *ngIf=\"!detailView\">\n <div class=\"analytics-overview-header\">\n <div>\n <div class=\"analytics-overview-title\">Analytics Overview</div>\n <div class=\"analytics-overview-subtitle\">{{ activeCohorts.length }} active agents</div>\n </div>\n <span class=\"flex-spacer\"></span>\n <div class=\"echo-search-wrap\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#98A2B3\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"analysisSearch\" placeholder=\"Search agents\u2026\" class=\"echo-inline-input\">\n </div>\n </div>\n\n <div *ngIf=\"cohortList.length === 0\" class=\"echo-empty-state--muted\">Loading agents...</div>\n\n <div class=\"analytics-grid\" [style.grid-template-columns]=\"'repeat(' + Math.min(cohortList.length, 4) + ', 1fr)'\">\n <ng-container *ngFor=\"let cohort of cohortList; trackBy: trackById\">\n <div class=\"analytics-card\" *ngIf=\"!analysisSearch || (cohort.cohortName || cohort.name || '').toLowerCase().includes(analysisSearch.toLowerCase())\" (click)=\"selectCohortDetail(cohort)\">\n <div class=\"analytics-card-header\">\n <div class=\"analytics-card-top-row\">\n <div class=\"analytics-card-name\">{{ cohort.cohortName || cohort.name }}</div>\n <span class=\"analytics-card-badge-active\">Active</span>\n </div>\n <!-- metrics & stores badges hidden for now -->\n </div>\n <div class=\"analytics-card-spacer\"></div>\n <div class=\"analytics-card-footer\">\n <span class=\"analytics-hover-link\">View analytics \u2192</span>\n </div>\n </div>\n </ng-container>\n </div>\n </ng-container>\n\n <!-- \u2500\u2500 DETAIL: Selected Cohort Metrics + Conversations \u2500\u2500 -->\n <ng-container *ngIf=\"detailView\">\n\n <!-- Header: \u2190 Back + Title + Conversations + Dropdown -->\n <div class=\"detail-header-bar\">\n <button class=\"detail-back-btn\" (click)=\"backToOverview()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M15 18l-6-6 6-6\"/></svg>\n </button>\n <span class=\"detail-header-title\">{{ selectedCohortName }}</span>\n <span class=\"flex-spacer\"></span>\n <span class=\"detail-header-conv-count\">Total Conversations: {{ totalAudio }}</span>\n\n <!-- Cohort Dropdown -->\n <div class=\"agent-dropdown-wrap\">\n <div class=\"agent-dropdown-trigger\" (click)=\"toggleCohortDropdown()\">\n <div class=\"cohort-dd-dot\"></div>\n <span class=\"cohort-dd-trigger-name\">{{ selectedCohortName || 'Select Agent' }}</span>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#667085\" stroke-width=\"2.5\" stroke-linecap=\"round\" [style.transform]=\"cohortDropdownOpen ? 'rotate(180deg)' : 'none'\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n <div class=\"agent-dropdown-menu\" *ngIf=\"cohortDropdownOpen\">\n <div class=\"cohort-dd-search-wrap\">\n <div class=\"cohort-dd-search-inner\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#98A2B3\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"cohortDropdownSearch\" placeholder=\"Search agents\u2026\" class=\"echo-inline-input--small\">\n </div>\n </div>\n <div class=\"cohort-dd-scroll\">\n <div *ngFor=\"let c of filteredDropdownCohorts; trackBy: trackById\" class=\"agent-dd-item\" [class.selected]=\"(c.cohortId || c.id || c._id) === selectedCohortId\" (click)=\"selectCohortFromDropdown(c)\">\n <div class=\"cohort-dd-item-dot\" [style.background]=\"c.metricsAdded > 0 ? '#10B981' : '#D0D5DD'\"></div>\n <div class=\"cohort-dd-item-body\">\n <div class=\"agent-dd-name\">{{ c.cohortName || c.name }}</div>\n <div class=\"agent-dd-meta\">{{ c.metricsAdded || 0 }} metrics</div>\n </div>\n <svg *ngIf=\"(c.cohortId || c.id || c._id) === selectedCohortId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#00A3FF\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M20 6L9 17l-5-5\"/></svg>\n </div>\n <div *ngIf=\"filteredDropdownCohorts.length === 0\" class=\"cohort-dd-no-results\">No agents found</div>\n </div>\n </div>\n <div *ngIf=\"cohortDropdownOpen\" class=\"cohort-dd-backdrop\" (click)=\"closeCohortDropdown()\"></div>\n </div>\n </div>\n\n <!-- Loading -->\n <div *ngIf=\"cardsLoading\" class=\"echo-empty-state--muted\">Loading metrics...</div>\n\n <!-- Metric Cards (dynamic columns based on card count) -->\n <div *ngIf=\"!cardsLoading && cohortCards.length > 0\" class=\"metric-cards-dynamic\"\n [style.grid-template-columns]=\"'repeat(' + Math.min(cohortCards.length, 4) + ', 1fr)'\">\n <div *ngFor=\"let card of cohortCards; trackBy: trackById\" class=\"metric-card-dynamic\">\n <!-- Card Header: Title + Status Badge + Info -->\n <div class=\"metric-card-header-row\">\n <div class=\"metric-card-title\">{{ card.name }}</div>\n <div class=\"metric-card-actions\">\n <span *ngIf=\"card.status\" class=\"metric-status-badge\"\n [style.background]=\"getStatusBadge(card.status).bg\"\n [style.color]=\"getStatusBadge(card.status).color\">{{ card.status }}</span>\n <div class=\"metric-info-icon\" *ngIf=\"card.description\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"/><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"/></svg>\n <div class=\"metric-info-tooltip\">\n <div>{{ card.description }}</div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"metric-card-subtitle\" *ngIf=\"card.type !== 'NUMERIC_SCALAR' && card.type !== 'NUMERIC_ARRAY'\">{{ card.applicableCount ?? totalAudio }} conversations</div>\n\n <div class=\"metric-card-content\">\n <!-- BOOLEAN_BASKET \u2014 Funnel Chart (left-aligned) -->\n <ng-container *ngIf=\"card.type === 'BOOLEAN_BASKET' && card.isFunnel\">\n <div class=\"funnel-chart\">\n <div *ngFor=\"let row of card.booleanRows; let i = index\" class=\"funnel-stage\" (click)=\"onCardRowClick(row.id, row.label)\">\n <div class=\"funnel-bar\"\n [style.width.%]=\"card.booleanRows[0]?.responses > 0 ? (row.responses / card.booleanRows[0].responses * 100) : 100\"\n [style.background]=\"getScoreColor(row.score)\">\n <span class=\"funnel-label-wrap\">\n <span class=\"funnel-label\">{{ row.label }}</span>\n <span class=\"funnel-tooltip\">{{ row.label }}</span>\n </span>\n <span class=\"funnel-value\"> <span class=\"funnel-value-count\">{{ row.responses }}</span> ({{ row.score }})% </span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- BOOLEAN_BASKET \u2014 rows with progress bars (non-funnel) -->\n <ng-container *ngIf=\"card.type === 'BOOLEAN_BASKET' && !card.isFunnel\">\n <div *ngFor=\"let row of card.booleanRows; let i = index\" class=\"metric-bool-row\" (click)=\"onCardRowClick(row.id, row.label)\">\n <div class=\"metric-row-flex\">\n <div class=\"metric-row-dot\"\n [style.background]=\"getScoreColor(row.score)\"></div>\n <span class=\"metric-row-label\">{{ row.label }}</span>\n <span class=\"metric-score metric-score--teal\">{{ row.score }}%</span>\n <span class=\"metric-count\">{{ row.responses }}</span>\n </div>\n <div class=\"metric-progress-track\">\n <div class=\"metric-progress-fill\" [style.width.%]=\"row.score\"\n [style.background]=\"getScoreColor(row.score)\"></div>\n </div>\n </div>\n </ng-container>\n\n <!-- NUMERIC_GROUP \u2014 all scores in one card -->\n <ng-container *ngIf=\"card.type === 'NUMERIC_GROUP'\">\n <div *ngFor=\"let row of card.numericRows\" class=\"numeric-score-row\" (click)=\"onCardRowClick('', row.key)\">\n <div class=\"numeric-row-header\">\n <span class=\"numeric-row-name\">{{ row.name }}</span>\n <span class=\"numeric-row-value\">{{ row.avg }}<span *ngIf=\"row.max !== null\" class=\"numeric-row-max\">/{{ row.max }}</span></span>\n </div>\n <div *ngIf=\"row.max !== null && row.min !== null\" class=\"numeric-progress-track\">\n <div class=\"numeric-progress-fill\"\n [style.width.%]=\"row.max > row.min ? ((row.avg - row.min) / (row.max - row.min) * 100) : 0\"></div>\n </div>\n </div>\n </ng-container>\n\n <!-- UNIQUE_PITCHES \u2014 pitch keywords tracker -->\n <ng-container *ngIf=\"card.type === 'UNIQUE_PITCHES'\">\n <div class=\"pitch-keyword-count\">{{ card.pitchRows?.length || 0 }} keywords</div>\n <div>\n <div *ngFor=\"let pitch of card.pitchRows; let i = index\" class=\"metric-bool-row\" (click)=\"onCardRowClick('', card.key)\">\n <div class=\"metric-row-flex\">\n <div class=\"metric-row-dot\"\n [style.background]=\"['#00A3FF','#10B981','#F59E0B','#EF4444','#8B5CF6','#EC4899','#06B6D4','#84CC16','#F97316','#6366F1'][i % 10]\"></div>\n <span class=\"pitch-row-label\">{{ pitch.id }}</span>\n <span class=\"pitch-row-desc\">{{ pitch.desc ? pitch.desc.slice(0, 60) : '\u2013' }}</span>\n </div>\n </div>\n </div>\n </ng-container>\n\n <!-- SUBJECTIVE -->\n <ng-container *ngIf=\"card.type === 'SUBJECTIVE' || card.type === 'SUBJECTIVE_COUNT'\">\n <div class=\"subjective-wrap\" (click)=\"onCardRowClick('', card.key)\">\n <div *ngFor=\"let row of card.subjectiveRows?.slice(0, 2)\" class=\"subjective-row\">\n \u2022 {{ row.reasoning || row.store_id }}\n </div>\n </div>\n </ng-container>\n </div><!-- end metric-card-content -->\n </div>\n </div>\n\n <!-- No cards -->\n <div *ngIf=\"!cardsLoading && cohortCards.length === 0\" class=\"echo-empty-state--muted-sm\">No analysis data available.</div>\n\n <!-- \u2500\u2500 Conversations Section \u2500\u2500 -->\n <div class=\"conversations-section\" *ngIf=\"detailPageConvs.length > 0 || detailLoading\">\n <div class=\"detail-conv-section-header\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#344054\" stroke-width=\"1.8\"><path d=\"M20 2H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h11l5 3V4a2 2 0 0 0-2-2z\"/></svg>\n <span class=\"detail-conv-section-title\">Conversations</span>\n </div>\n\n <div *ngIf=\"detailLoading\" class=\"echo-empty-state--muted\">Loading...</div>\n\n <div *ngFor=\"let conv of detailPageConvs; trackBy: trackById\" class=\"detail-conv-card\">\n <!-- Conv header -->\n <div class=\"conv-header\" (click)=\"toggleDetailConv(conv.audioId); loadConvDetail(conv)\">\n <span class=\"conv-id\">{{ conv.audioId }}</span>\n <div class=\"detail-meta-row\">\n <span class=\"meta-tag brand\" *ngIf=\"conv.storeName\">{{ conv.storeName }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.location\">{{ conv.location }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.date\">{{ conv.date }}</span>\n <span class=\"meta-tag\" *ngIf=\"conv.time\">{{ conv.time }}</span>\n </div>\n <div class=\"conv-chevron\" [class.open]=\"detailOpenId === conv.audioId\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M6 9l6 6 6-6\"/></svg>\n </div>\n </div>\n\n <!-- Expanded body -->\n <div *ngIf=\"detailOpenId === conv.audioId\" class=\"conv-body-expanded\">\n <!-- Waveform player -->\n <div class=\"echo-player\" *ngIf=\"conv.audioUrl\">\n <button class=\"echo-play-btn\" (click)=\"togglePlay(conv.audioId)\">\n <svg *ngIf=\"playingConvId !== conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M8 5v14l11-7z\"/></svg>\n <svg *ngIf=\"playingConvId === conv.audioId\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"white\"><path d=\"M6 19h4V5H6v14zm8-14v14h4V5h-4z\"/></svg>\n </button>\n <div class=\"echo-waveform\" (click)=\"seekAudio($event, conv.audioId)\">\n <div class=\"echo-wf-bar\" *ngFor=\"let h of waveformHeights; let i = index\" [style.height.px]=\"h\"\n [class.played]=\"(playbackStates[conv.audioId]?.progress || 0) > i / waveformHeights.length\"></div>\n </div>\n <span class=\"echo-time\">{{ playbackStates[conv.audioId]?.totalTime || conv.duration || '--' }}</span>\n <audio [id]=\"'audio-' + conv.audioId\" [src]=\"conv.audioUrl\" preload=\"metadata\"\n (timeupdate)=\"onTimeUpdate(audioEl, conv.audioId)\"\n (loadedmetadata)=\"onLoadedMetadata(audioEl, conv.audioId, conv.duration)\"\n (ended)=\"playingConvId = null\" #audioEl></audio>\n </div>\n\n <!-- Tabs -->\n <div class=\"conv-tabs\">\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'summary'\" (click)=\"setConvTab(conv.audioId, 'summary', $event)\">Summary</button>\n <button class=\"conv-tab-btn\" [class.active]=\"getConvTab(conv.audioId) === 'transcript'\" (click)=\"setConvTab(conv.audioId, 'transcript', $event)\">Transcript</button>\n </div>\n\n <!-- Content: Left (Summary/Transcript + AI Insights) + Right (Metrics) -->\n <div class=\"detail-content-split\">\n <!-- Left side -->\n <div class=\"detail-content-left\">\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'summary'\">\n <p class=\"summary-text\">{{ conv.audioDescription || conv.conversationDetails?.audioSummary || 'No summary available' }}</p>\n <!-- AI Insights -->\n <div *ngIf=\"conv.aiInsights?.summary?.length\" class=\"ai-insights-section\">\n <div class=\"ai-insights-label\">AI Insights</div>\n <div *ngFor=\"let insight of conv.aiInsights.summary\" class=\"ai-insight-row\">\n <div class=\"ai-insight-dot\" [style.background]=\"insight.type === 'positive' ? '#00A3FF' : insight.type === 'negative' ? '#EF4444' : '#F59E0B'\"></div>\n <span class=\"ai-insight-text\">{{ insight.text || insight }}</span>\n </div>\n </div>\n </ng-container>\n <ng-container *ngIf=\"getConvTab(conv.audioId) === 'transcript'\">\n <p class=\"summary-text summary-text--prewrap\">{{ cleanTranscription(conv.conversationDetails?.transcription) || 'No transcript available' }}</p>\n </ng-container>\n </div>\n <!-- Right side: Metrics (only show values that have data) -->\n <div class=\"detail-content-right\">\n <div class=\"metrics-panel-label\">Metrics</div>\n <ng-container *ngIf=\"conv.metrics?.length\">\n <div *ngFor=\"let m of conv.metrics\" class=\"metric-item-wrap\">\n <!-- Single value: name + value on same row -->\n <ng-container *ngIf=\"m.value?.length === 1\">\n <div class=\"metric-single-row\">\n <span class=\"metric-single-name\" [title]=\"m.name\">{{ m.name }}</span>\n <span class=\"metric-single-value\" [style.color]=\"m.value[0].score !== null && m.value[0].score !== undefined ? '#00A3FF' : '#344054'\">\n {{ formatMetricValue(m.value[0]) }}\n </span>\n </div>\n </ng-container>\n <!-- Multiple values: header + rows -->\n <ng-container *ngIf=\"m.value?.length > 1\">\n <div class=\"metric-multi-header\" [title]=\"m.name\">{{ m.name }}</div>\n <ng-container *ngFor=\"let v of m.value\">\n <div *ngIf=\"(v.score !== null && v.score !== undefined) || (v.Total !== null && v.Total !== undefined) || (v.Avg !== null && v.Avg !== undefined) || (v.total !== null && v.total !== undefined) || (v.avg !== null && v.avg !== undefined) || (v.count !== null && v.count !== undefined)\" class=\"metric-multi-row\">\n <span class=\"metric-multi-name\" [title]=\"v.name\">{{ v.name }}</span>\n <span class=\"metric-multi-value\"\n [style.color]=\"v.score !== null && v.score !== undefined ? '#00A3FF' : '#344054'\">\n {{ formatMetricValue(v) }}\n </span>\n </div>\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngIf=\"!conv.metrics?.length\">\n <div *ngIf=\"conv.storeName\" class=\"metric-fallback-row\"><span class=\"metric-fallback-label\">Store</span><span class=\"metric-fallback-value\">{{ conv.storeName }}</span></div>\n <div *ngIf=\"conv.duration\" class=\"metric-fallback-row\"><span class=\"metric-fallback-label\">Duration</span><span class=\"metric-fallback-value\">{{ conv.duration }}</span></div>\n </ng-container>\n <div *ngIf=\"conv._detailLoading\" class=\"metric-detail-loading\">Loading...</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"!detailLoading && detailPageConvs.length === 0 && (selectedCardId || selectedCardName)\" class=\"echo-empty-state--compact\">No conversations found.</div>\n\n <!-- Pagination -->\n <lib-pagination *ngIf=\"detailTotal > 0\" [itemsPerPage]=\"detailPerPage\" [currentPage]=\"detailPage\" [totalItems]=\"detailTotal\"\n [paginationSizes]=\"detailPaginationSizes\" [pageSize]=\"detailPerPage\" (pageChange)=\"onDetailPageChange($event)\"\n (pageSizeChange)=\"onDetailPageSizeChange($event)\"></lib-pagination>\n </ng-container><!-- end detailView -->\n </ng-container><!-- end agentanalysis -->\n\n <!-- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 MANAGE TAB \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n <ng-container *ngIf=\"currentPage === 'manage'\">\n <div class=\"manage-header\">\n <div>\n <div class=\"manage-title\">Agents</div>\n <div class=\"manage-subtitle\">{{ manageTotal }} agents</div>\n </div>\n <span class=\"flex-spacer\"></span>\n <div class=\"echo-search-wrap--wide\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#94A3B8\" stroke-width=\"1.8\" stroke-linecap=\"round\"><circle cx=\"11\" cy=\"11\" r=\"7.5\"/><path d=\"M16.5 16.5L21 21\"/></svg>\n <input [(ngModel)]=\"manageSearch\" (ngModelChange)=\"onManageSearch()\" placeholder=\"Search agents...\" class=\"manage-search-input\">\n </div>\n </div>\n\n <div *ngIf=\"manageLoading\" class=\"echo-empty-state\">Loading agents...</div>\n\n <!-- Agents table -->\n <div *ngIf=\"!manageLoading\" class=\"echo-card\">\n <div class=\"agents-table-header agents-table-4col\">\n <div class=\"agents-table-cell\">Agent Name</div>\n <div class=\"agents-table-cell agents-table-cell--center\">Metrics</div>\n <div class=\"agents-table-cell agents-table-cell--center\">Source</div>\n <div class=\"agents-table-cell agents-table-cell--center\">Action</div>\n </div>\n <div *ngFor=\"let cohort of manageCohorts; trackBy: trackById\" class=\"agents-table-row agents-table-4col\">\n <div class=\"agent-cell-name-wrap\">\n <div class=\"agent-cell-name\">{{ cohort.cohortName || cohort.name }}</div>\n <div class=\"agent-cell-desc\">{{ cohort.cohortDescription || cohort.description || '' }}</div>\n </div>\n <div class=\"agent-cell-metrics\">{{ cohort.metricsAdded || cohort.metricAdded || cohort.metrics?.length || 0 }}</div>\n <div class=\"agent-cell-source\">{{ cohort.source?.join(', ') || '\u2013' }}</div>\n <div class=\"agent-cell-action\">\n <button (click)=\"deleteCohort(cohort.cohortId || cohort.id || cohort._id)\" class=\"agent-delete-btn\">Delete</button>\n </div>\n </div>\n <div *ngIf=\"manageCohorts.length === 0\" class=\"manage-no-results\">No cohorts found.</div>\n </div>\n\n <!-- Manage pagination -->\n <lib-pagination *ngIf=\"manageTotal > 0\" [itemsPerPage]=\"managePerPage\" [currentPage]=\"managePage\" [totalItems]=\"manageTotal\"\n [paginationSizes]=\"managePaginationSizes\" [pageSize]=\"managePerPage\" (pageChange)=\"onManagePageChange($event)\"\n (pageSizeChange)=\"onManagePageSizeChange($event)\"></lib-pagination>\n </ng-container>\n\n </div>\n</div>\n\n<!-- \u2550\u2550\u2550 FILTERS DRAWER \u2550\u2550\u2550 -->\n<div class=\"drawer-overlay\" *ngIf=\"drawerOpen\" (click)=\"closeFilterDrawer()\"></div>\n<div class=\"af-drawer\" *ngIf=\"drawerOpen\">\n <div class=\"drawer-header\">\n <span class=\"drawer-header-title\">Filters</span>\n <button (click)=\"closeFilterDrawer()\" class=\"drawer-close-btn\">\u00D7</button>\n </div>\n <div class=\"drawer-body\">\n <p class=\"drawer-placeholder-text\">Filter configuration coming soon. Uses the same filter APIs as the existing audio pages.</p>\n </div>\n <div class=\"af-footer\">\n <button class=\"af-cancel\" (click)=\"closeFilterDrawer()\">Close</button>\n </div>\n</div>\n", styles: [":host{display:block}.echo-page{padding:20px 24px;background-color:#f4f6fa}.conversations-section{background:#fff;border-radius:10px;padding:16px;margin-top:8px}.conv-card{border:1px solid #e8edf3;border-radius:10px;margin-bottom:12px;overflow:hidden;background:#fff}.conv-header{padding:14px 20px;display:flex;align-items:center;gap:8px;cursor:pointer;transition:background .15s}.conv-header:hover{background:#f8fafc}.conv-chevron{width:24px;height:24px;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:transform .22s ease}.conv-chevron.open{transform:rotate(180deg)}.conv-id{font-size:13px;font-weight:600;color:#0ea5e9;border-radius:4px;padding:2px 8px}.meta-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:24px;font-size:12px;font-weight:500;border:1px solid #e8edf3;background:#f8fafc;color:#344054;white-space:nowrap}.meta-tag.purple{background:#f0f4ff;color:#1a73e8;border-color:#d0e0ff}.meta-tag.brand{font-weight:600}.conv-tabs{display:flex;border-bottom:1px solid #e8edf3;padding:0 20px}.conv-tab-btn{padding:10px 16px;font-size:13px;font-weight:600;border:none;background:transparent;cursor:pointer;color:#667085;border-bottom:2px solid transparent;transition:all .15s;margin-bottom:-1px}.conv-tab-btn.active{color:#00a3ff;border-bottom-color:#00a3ff}.transcript-content .transcript-section{margin-bottom:20px}.transcript-content .transcript-section:last-child{margin-bottom:0}.transcript-content .transcript-section-title{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;color:#344054;margin-bottom:10px;padding-bottom:6px;border-bottom:1px solid #f0f4ff}.transcript-content .transcript-summary-text,.summary-text{font-size:14px;color:#475467;line-height:1.7;margin:0}.detail-conv-card{border:1px solid #e8edf3;border-radius:10px;margin-bottom:12px;background:#fff;overflow:hidden}.detail-conv-card .conv-header{padding:12px 16px}.detail-conv-card .conv-tabs{padding:0 16px}.detail-conv-card .echo-player{padding:10px 16px}.conv-body-expanded{border-top:1px solid #e8edf3}.echo-player{display:flex;align-items:center;gap:12px;padding:12px 20px;background:#f2f4f7;border-bottom:1px solid #e8edf3}.echo-play-btn{width:36px;height:36px;min-width:36px;border-radius:50%;background:#00a3ff;border:none;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .2s}.echo-play-btn:hover{background:#0087d5}.echo-waveform{flex:1;display:flex;align-items:center;gap:1.5px;height:40px;cursor:pointer}.echo-wf-bar{width:2px;min-width:2px;border-radius:2px;min-height:3px;background:#cbd5e1;transition:background .15s}.echo-wf-bar.played{background:#00a3ff}.echo-time{font-size:13px;font-weight:600;color:#344054;flex-shrink:0;min-width:50px;text-align:right}.btn{padding:8px 16px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;border:none;transition:all .15s}.btn-primary{background:#1a73e8;color:#fff}.btn-primary:hover{background:#135cbc}.analytics-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}@media (max-width: 992px){.analytics-grid{grid-template-columns:repeat(2,1fr)!important}}@media (max-width: 576px){.analytics-grid{grid-template-columns:1fr!important}}.analytics-card{background:#fff;border:1px solid #e8edf3;border-radius:10px;cursor:pointer;overflow:hidden;transition:box-shadow .2s,transform .2s,border-color .2s}.analytics-card:hover{box-shadow:0 4px 12px #00000014;transform:translateY(-2px);border-color:#00a3ff}.analytics-card:hover .analytics-hover-link{opacity:1}.analytics-card-header{padding:14px 16px;border-bottom:1px solid #e8edf3;background:linear-gradient(135deg,#f8fafc,#fff)}.analytics-hover-link{font-size:11px;color:#00a3ff;font-weight:700;opacity:0;transition:opacity .2s}.btn-outline{background:#fff;border:1px solid #D0D5DD;color:#344054}.btn-outline:hover{border-color:#1a73e8;color:#1a73e8}.btn-success{background:#10b981;color:#fff}.section-label{font-size:12px;font-weight:600;color:#98a2b3;letter-spacing:.5px;margin-bottom:8px;text-transform:uppercase}.echo-card{background:#fff;border-radius:10px;border:1px solid #e8edf3;overflow:hidden}.echo-card-header{padding:14px 20px;border-bottom:1px solid #e8edf3;display:flex;align-items:center;gap:8px}.echo-card-title{font-size:16px;font-weight:600;color:#1a2b4b}.echo-card-body{padding:20px}.metric-cards-dynamic{display:grid;gap:16px;margin-bottom:24px;align-items:stretch}.metric-card-dynamic{background:#fff;border:1px solid #e8edf3;border-radius:10px;padding:20px;display:flex;flex-direction:column;max-height:420px;cursor:pointer;transition:border-color .2s,box-shadow .2s}.metric-card-dynamic:hover{border-color:#00a3ff;box-shadow:0 2px 8px #00a3ff14}.metric-card-content{flex:1;min-height:0;overflow-y:auto;padding-right:6px}.metric-card-content::-webkit-scrollbar{width:4px}.metric-card-content::-webkit-scrollbar-track{background:transparent}.metric-card-content::-webkit-scrollbar-thumb{background:#d0d5dd;border-radius:4px}.metric-card-title{font-size:14px;font-weight:700;color:#1a2b4b;margin-bottom:4px;line-height:1.3}.metric-card-subtitle{font-size:11px;color:#667085;margin-bottom:12px;font-weight:500}.metric-info-icon{position:relative;color:#98a2b3;cursor:pointer;flex-shrink:0;padding:2px;transition:color .15s}.metric-info-icon:hover{color:#00a3ff}.metric-info-icon:hover .metric-info-tooltip{opacity:1;visibility:visible;transform:translateY(0)}.metric-info-tooltip{position:absolute;top:calc(100% + 6px);right:0;z-index:100;min-width:200px;max-width:260px;padding:10px 12px;background:#1a2b4b;color:#fff;font-size:11.5px;line-height:1.5;border-radius:8px;box-shadow:0 4px 16px #0000002e;opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity .15s,visibility .15s,transform .15s;pointer-events:none}.metric-info-tooltip:before{content:\"\";position:absolute;top:-5px;right:6px;width:10px;height:10px;background:#1a2b4b;transform:rotate(45deg);border-radius:2px}.metric-bool-row{margin-bottom:10px;cursor:pointer}.metric-dot{width:7px;height:7px;border-radius:50%;background:#00a3ff;flex-shrink:0}.metric-score{font-weight:700;font-size:15px}.metric-status-badge{font-size:10px;font-weight:700;padding:3px 10px;border-radius:20px;text-transform:uppercase;letter-spacing:.5px;white-space:nowrap;flex-shrink:0}.metric-card-desc{font-size:13px;color:#475467;line-height:1.6;margin:12px 0 8px}.metric-card-short-desc{font-size:12px;color:#98a2b3;font-style:italic;line-height:1.5;margin:4px 0 0}.metric-count{font-size:11px;color:#667085;min-width:20px;text-align:right;font-weight:500}.metric-progress-track{height:6px;border-radius:4px;background:#e2e8f2;overflow:hidden}.metric-progress-fill{height:100%;background:#00a3ff;border-radius:4px;transition:width .5s ease}.funnel-chart{display:flex;flex-direction:column;align-items:flex-start;gap:6px;padding:4px 0}.funnel-stage{width:100%;display:flex;justify-content:flex-start;cursor:pointer}.funnel-bar{display:flex;align-items:center;justify-content:space-between;padding:8px 14px;border-radius:6px;min-height:36px;overflow:visible;transition:width .5s ease,opacity .2s}.funnel-bar:hover{opacity:.85}.funnel-label-wrap{position:relative;flex:1;min-width:0;overflow:visible}.funnel-label-wrap .funnel-tooltip{position:absolute;bottom:calc(100% + 10px);left:0;padding:6px 10px;background:#1a2b4b;color:#fff;font-size:11.5px;font-weight:600;border-radius:6px;white-space:nowrap;box-shadow:0 4px 12px #0000002e;opacity:0;visibility:hidden;transform:translateY(4px);transition:opacity .15s,visibility .15s,transform .15s;pointer-events:none;z-index:100}.funnel-label-wrap .funnel-tooltip:after{content:\"\";position:absolute;top:100%;left:12px;width:8px;height:8px;background:#1a2b4b;transform:translateY(-50%) rotate(45deg);border-radius:1px}.funnel-label-wrap:hover .funnel-tooltip{opacity:1;visibility:visible;transform:translateY(0)}.funnel-label{font-size:12px;font-weight:600;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}.funnel-value{font-size:13px;font-weight:700;color:#fff;flex-shrink:0;margin-left:8px}.numeric-score-row{padding:10px 0;border-bottom:1px solid #f0f4ff;cursor:pointer;transition:background .15s}.numeric-score-row:last-child{border-bottom:none}.numeric-score-row:hover{background:#f8fafc;margin:0 -12px;padding:10px 12px;border-radius:6px}.metric-big-number{font-weight:800;font-size:36px;color:#00a3ff;line-height:1}.metric-avg-label{font-size:12px;color:#667085;margin-left:4px}@media (max-width: 992px){.metric-cards-dynamic{grid-template-columns:repeat(2,1fr)!important}}@media (max-width: 576px){.metric-cards-dynamic{grid-template-columns:1fr!important}}.subjective-wrap{cursor:pointer;max-height:120px;overflow:hidden}.subjective-row{padding:4px 0;font-size:12px;color:#475467;border-bottom:1px solid #f0f4ff;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical}.metric-card-name{font-size:14px;font-weight:600;color:#1a2b4b}.agents-table-header{display:grid;align-items:center;padding:10px 20px;border-bottom:1px solid #e8edf3;background:#f8fafc}.agents-table-cell{font-size:12px;font-weight:600;color:#98a2b3;letter-spacing:.5px;text-transform:uppercase}.agents-table-row{display:grid;align-items:center;padding:14px 20px;border-bottom:1px solid #e8edf3;cursor:pointer;transition:background .15s}.agents-table-row:hover{background:#f8fafc}.agents-table-row:last-child{border-bottom:none}.status-dot{width:8px;height:8px;border-radius:50%}.status-dot.active{background:#10b981}.status-dot.pending{background:#f59e0b}.status-dot.paused{background:#98a2b3}.tango-ai-header{display:flex;flex-direction:column;align-items:center;gap:10px;padding:20px 0}.tango-ai-logo{width:52px;height:52px;border-radius:16px;background:linear-gradient(135deg,#794fd9,#33b1f7);display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #794fd933}.tango-ai-title{font-size:22px;font-weight:800;color:#1a2b4b;line-height:1.2}.tango-ai-subtitle{font-size:13px;color:#667085;margin-top:4px}.echo-search-card{display:flex;align-items:center;background:#fff;border:1px solid #D0D5DD;border-radius:8px;padding:10px 12px 10px 20px;margin-bottom:20px;box-shadow:0 1px 2px #1018280d}.echo-search-input{flex:1;border:none;outline:none;font-size:14px;color:#101828}.echo-search-input::placeholder{color:#98a2b3}.echo-search-slash{width:28px;height:28px;border-radius:50%;border:1px solid #D0D5DD;background:#fff;font-size:14px;font-weight:600;color:#667085;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;margin-right:6px}.echo-search-send{width:32px;height:32px;border-radius:50%;background:#00a3ff;border:none;color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .2s}.echo-search-send:hover{background:#0087d5}.echo-search-send:disabled{opacity:.5;cursor:not-allowed}.echo-ai-response{background:#fff;border:1px solid #e8edf3;border-radius:10px;padding:16px 20px;margin-bottom:16px}.echo-ai-text{font-size:14px;color:#475467;line-height:1.7;margin:0}.echo-conv-count{font-size:14px;font-weight:700;color:#00a3ff;margin-bottom:16px}.typing{display:flex;gap:4px;align-items:center;padding:4px 0}.typing-dot{width:6px;height:6px;border-radius:50%;background:#00a3ff;animation:pulse 1.2s ease-in-out infinite}.typing-dot:nth-child(2){animation-delay:.2s}.typing-dot:nth-child(3){animation-delay:.4s}@keyframes pulse{0%,to{opacity:.3;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}:host ::ng-deep lib-pagination{margin-top:16px;display:block}.agent-dropdown-wrap{position:relative}.agent-dropdown-trigger{display:flex;align-items:center;gap:8px;padding:7px 12px;border:1.5px solid #D0D5DD;border-radius:8px;background:#fff;cursor:pointer;max-width:280px;transition:border-color .15s}.agent-dropdown-trigger:hover{border-color:#00a3ff}.agent-dropdown-menu{position:absolute;top:calc(100% + 6px);right:0;background:#fff;border:1px solid #D0D5DD;border-radius:10px;box-shadow:0 8px 24px #0000001f;width:300px;z-index:300;overflow:hidden}.agent-dd-header{padding:8px 14px;font-size:11px;font-weight:600;color:#98a2b3;letter-spacing:.5px;border-bottom:1px solid #e8edf3;text-transform:uppercase}.agent-dd-item{display:flex;align-items:center;gap:10px;padding:10px 14px;cursor:pointer;transition:background .1s}.agent-dd-item:hover{background:#f8fafc}.agent-dd-item.selected{background:#f0f4ff}.agent-dd-name{font-size:13px;font-weight:600;color:#344054;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.agent-dd-meta{font-size:12px;color:#98a2b3;margin-top:1px}.fbar-pill{display:flex;align-items:center;gap:6px;padding:6px 12px;border:1px solid #D0D5DD;border-radius:8px;background:#fff;font-size:13px;font-weight:600;color:#344054;cursor:pointer;transition:all .15s;white-space:nowrap}.fbar-pill:hover,.fbar-pill.active{border-color:#1a73e8;color:#1a73e8;background:#f0f4ff}.echo-sub-header{display:flex;align-items:center;padding:12px 0 16px;gap:10px}.btn-back{background:none;border:none;cursor:pointer;display:flex;align-items:center;color:#1a73e8;padding:4px 6px;border-radius:8px}.sub-header-title{font-size:15px;font-weight:600;color:#1a2b4b}.drawer-overlay{position:fixed;inset:0;background:#0000004d;z-index:200}.af-drawer{position:fixed;top:0;right:0;bottom:0;width:380px;max-width:95vw;background:#fff;z-index:201;display:flex;flex-direction:column;box-shadow:-8px 0 40px #00000026;animation:slideInRight .25s ease-out;overflow:hidden}@keyframes slideInRight{0%{transform:translate(100%)}to{transform:translate(0)}}.af-footer{padding:14px 16px;border-top:1px solid #e8edf3;display:flex;align-items:center;justify-content:flex-end;background:#fff}.af-cancel{padding:9px 20px;border-radius:8px;border:1px solid #D0D5DD;background:#fff;font-size:14px;font-weight:500;cursor:pointer;color:#344054}@media (max-width: 768px){.metric-cards-grid{grid-template-columns:1fr}.agents-table-header,.agents-table-row{grid-template-columns:1fr 80px}}.flex-spacer{flex:1}.text-center{text-align:center}.echo-empty-state{text-align:center;padding:40px;color:#94a3b8}.echo-empty-state--muted{text-align:center;padding:40px;color:#667085}.echo-empty-state--sm{text-align:center;padding:40px;color:#94a3b8;font-size:13px}.echo-empty-state--muted-sm{text-align:center;padding:40px;color:#667085;font-size:13px}.echo-empty-state--compact{text-align:center;padding:32px;color:#667085;font-size:13px}.tango-ai-header-text{text-align:center}.conv-header-body{flex:1;min-width:0}.conv-meta-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:4px}.meta-tag--duration{background:#ede9fe;color:#8b5cf6;border-color:#ddd6fe;font-weight:700}.conv-description{font-size:12.5px;color:#94a3b8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.conv-body-padding{padding:14px 16px}.ai-insights-section{margin-top:16px}.ai-insights-label{font-size:11px;font-weight:700;color:#667085;letter-spacing:.5px;text-transform:uppercase;margin-bottom:10px}.ai-insight-row{display:flex;align-items:flex-start;gap:8px;margin-bottom:8px}.ai-insight-dot{width:6px;height:6px;border-radius:50%;margin-top:5px;flex-shrink:0}.ai-insight-text{font-size:13px;color:#475467;line-height:1.5}.analytics-overview-header{display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap}.analytics-overview-title{font-size:17px;font-weight:700;color:#1a2b4b}.analytics-overview-subtitle{font-size:12px;color:#667085}.echo-search-wrap{width:220px;display:flex;align-items:center;gap:8px;border:1px solid #D0D5DD;border-radius:8px;padding:6px 12px;background:#fff}.echo-search-wrap--wide{width:280px;display:flex;align-items:center;gap:8px;border:1px solid #E2E8F2;border-radius:8px;padding:6px 12px;background:#fff}.echo-inline-input{flex:1;border:none;background:transparent;font-size:13px;color:#344054;outline:none;min-width:0}.echo-inline-input--small{flex:1;border:none;background:transparent;font-size:12px;color:#344054;outline:none;min-width:0}.analytics-card-top-row{display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:8px}.analytics-card-name{font-size:13.5px;font-weight:700;color:#1a2b4b;flex:1;padding-right:8px;line-height:1.3}.analytics-card-badge-active{font-size:9px;font-weight:700;padding:2px 8px;border-radius:20px;background:#d1fae5;color:#065f46;text-transform:uppercase;letter-spacing:.5px;flex-shrink:0}.analytics-card-spacer{padding:8px 14px}.analytics-card-footer{padding:8px 14px;border-top:1px solid #e8edf3;display:flex;justify-content:flex-end}.detail-header-bar{display:flex;align-items:center;gap:12px;margin-bottom:20px;padding:14px 20px;background:#fff;border-radius:10px;border:1px solid #e8edf3}.detail-back-btn{background:none;border:none;cursor:pointer;color:#00a3ff;font-size:18px;padding:0}.detail-header-title{font-size:16px;font-weight:700;color:#1a2b4b}.detail-header-conv-count{font-size:13px;color:#667085}.cohort-dd-dot{width:8px;height:8px;border-radius:50%;background:#10b981;flex-shrink:0}.cohort-dd-trigger-name{font-size:13px;font-weight:600;color:#1a2b4b;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.cohort-dd-search-wrap{padding:8px 10px;border-bottom:1px solid #e8edf3}.cohort-dd-search-inner{display:flex;align-items:center;gap:6px;padding:6px 10px;border:1px solid #D0D5DD;border-radius:6px;background:#fff}.cohort-dd-scroll{max-height:240px;overflow-y:auto}.cohort-dd-item-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}.cohort-dd-item-body{flex:1;min-width:0}.cohort-dd-no-results{padding:16px;text-align:center;font-size:12px;color:#667085}.cohort-dd-backdrop{position:fixed;inset:0;z-index:299}.metric-card-header-row{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.metric-card-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.metric-row-flex{display:flex;align-items:center;gap:6px;margin-bottom:4px}.metric-row-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.metric-row-label{font-size:13px;color:#344054;flex:1}.metric-score--teal{color:#00a3ff}.numeric-row-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}.numeric-row-name{font-size:13px;color:#344054;font-weight:600;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.numeric-row-value{font-size:15px;font-weight:800;color:#00a3ff;flex-shrink:0;margin-left:8px}.numeric-row-max{font-size:12px;font-weight:600;color:#98a2b3}.numeric-progress-track{position:relative;height:5px;border-radius:4px;background:#e2e8f2}.numeric-progress-fill{position:absolute;left:0;top:0;height:100%;border-radius:4px;background:linear-gradient(90deg,#00a3ff,#33b1f7)}.pitch-keyword-count{font-size:11px;color:#667085;margin-bottom:8px}.pitch-row-label{font-size:12.5px;color:#344054;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pitch-row-desc{font-size:12px;font-weight:700;color:#667085;flex-shrink:0}.funnel-value-count{opacity:.8;font-weight:500}.detail-conv-section-header{padding:16px 20px;display:flex;align-items:center;gap:8px;background:#fff;border-radius:10px;border:1px solid #e8edf3;margin-bottom:12px}.detail-conv-section-title{font-size:15px;font-weight:700;color:#1a2b4b}.detail-content-split{display:flex}.detail-content-left{flex:3;padding:14px 20px;min-width:0;border-right:1px solid #e8edf3}.detail-content-right{flex:1;min-width:220px;max-width:350px;padding:16px;overflow-y:auto;max-height:500px}.detail-meta-row{display:flex;align-items:center;gap:5px;flex:1;min-width:0;flex-wrap:wrap}.summary-text--prewrap{white-space:pre-wrap}.metrics-panel-label{font-size:10px;font-weight:700;color:#00a3ff;letter-spacing:.5px;text-transform:uppercase;margin-bottom:12px}.metric-item-wrap{margin-bottom:8px;padding:6px 0;border-bottom:1px solid #f0f4ff}.metric-single-row{display:flex;align-items:center;gap:8px}.metric-single-name{font-size:12px;font-weight:600;color:#344054;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.metric-single-value{font-size:12px;font-weight:700;flex-shrink:0}.metric-multi-header{font-size:11px;font-weight:700;color:#344054;margin-bottom:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.metric-multi-row{display:flex;align-items:center;gap:8px;padding:3px 0}.metric-multi-name{font-size:11px;color:#667085;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.metric-multi-value{font-size:11px;font-weight:700;flex-shrink:0}.metric-fallback-row{display:flex;justify-content:space-between;margin-bottom:6px}.metric-fallback-label{font-size:12px;color:#667085}.metric-fallback-value{font-size:12px;font-weight:600;color:#344054}.metric-detail-loading{font-size:11px;color:#667085}.manage-header{display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap}.manage-title{font-family:Outfit,sans-serif;font-weight:700;font-size:17px}.manage-subtitle{font-size:12px;color:#94a3b8}.manage-search-input{flex:1;border:none;background:transparent;font-size:13px;font-family:Nunito Sans,sans-serif;color:#0f172a;outline:none;min-width:0}.agents-table-4col{grid-template-columns:minmax(0,1fr) 120px 120px 80px}.agents-table-cell--center{text-align:center}.agent-cell-name-wrap{min-width:0}.agent-cell-name{font-family:Outfit,sans-serif;font-weight:700;font-size:13.5px;color:#0f172a;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.agent-cell-desc{font-size:11px;color:#94a3b8;margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.agent-cell-metrics{text-align:center;font-family:Outfit,sans-serif;font-weight:700;font-size:13px;color:#0f172a}.agent-cell-source{text-align:center;font-size:11.5px;color:#334155;font-weight:600}.agent-cell-action{text-align:center}.agent-delete-btn{background:none;border:none;cursor:pointer;color:#ef4444;font-size:11px;font-weight:700}.manage-no-results{padding:32px;text-align:center;color:#94a3b8;font-size:13px}.drawer-header{padding:16px;border-bottom:1px solid #E2E8F2;display:flex;align-items:center;justify-content:space-between}.drawer-header-title{font-family:Outfit,sans-serif;font-weight:700;font-size:15px}.drawer-close-btn{background:none;border:none;cursor:pointer;color:#94a3b8;font-size:18px}.drawer-body{padding:16px;flex:1;overflow-y:auto}.drawer-placeholder-text{font-size:13px;color:#94a3b8}\n"] }]
|
|
694
812
|
}], ctorParameters: () => [{ type: i1.AudioService }, { type: i2.ActivatedRoute }, { type: i3.GlobalStateService }] });
|
|
695
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFuZ28tZWNoby5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YW5nby1haS1hdWRpby9zcmMvbGliL2NvbXBvbmVudHMvdGFuZ28tZWNoby90YW5nby1lY2hvLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLWFpLWF1ZGlvL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1lY2hvL3RhbmdvLWVjaG8uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFFN0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7O0FBUzFDLE1BQU0sT0FBTyxrQkFBa0I7SUF1Rm5CO0lBQ0E7SUFDQTtJQXZGVixzREFBc0Q7SUFDdEQsV0FBVyxHQUFpRCxlQUFlLENBQUM7SUFFNUUsc0RBQXNEO0lBQ3RELFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDaEIsUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUN4QixTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ2YsT0FBTyxHQUFHLEVBQUUsQ0FBQztJQUNiLFVBQVUsR0FBUSxFQUFFLENBQUM7SUFDckIsS0FBSyxHQUFRLEVBQUUsQ0FBQztJQUVoQixzREFBc0Q7SUFDdEQsYUFBYSxHQUFVLEVBQUUsQ0FBQztJQUMxQixRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsV0FBVyxHQUFHLEVBQUUsQ0FBQztJQUNqQixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNuQixtQkFBbUIsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3hDLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsZUFBZSxHQUFHLEVBQUUsQ0FBQztJQUNyQixlQUFlLEdBQThCLEVBQUUsQ0FBQztJQUNoRCxRQUFRLEdBQWlDLEVBQUUsQ0FBQztJQUU1QyxVQUFVO0lBQ1YsV0FBVyxHQUFHLEVBQUUsQ0FBQztJQUNqQixhQUFhLEdBQUcsS0FBSyxDQUFDO0lBRXRCLHNEQUFzRDtJQUN0RCxVQUFVLEdBQVUsRUFBRSxDQUFDO0lBQ3ZCLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztJQUN0QixrQkFBa0IsR0FBRyxFQUFFLENBQUM7SUFDeEIsV0FBVyxHQUFVLEVBQUUsQ0FBQztJQUN4QixZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDbkIsY0FBYyxHQUFHLEVBQUUsQ0FBQztJQUVwQixnREFBZ0Q7SUFDaEQsbUJBQW1CLEdBQVUsRUFBRSxDQUFDO0lBQ2hDLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDZixhQUFhLEdBQUcsRUFBRSxDQUFDO0lBQ25CLGdCQUFnQixHQUFHLENBQUMsQ0FBQztJQUNyQixXQUFXLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLHFCQUFxQixHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDMUMsZUFBZSxHQUFVLEVBQUUsQ0FBQztJQUM1QixZQUFZLEdBQWtCLElBQUksQ0FBQztJQUNuQyxhQUFhLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLGdCQUFnQixHQUFRLElBQUksQ0FBQztJQUU3QixzREFBc0Q7SUFDdEQsYUFBYSxHQUFVLEVBQUUsQ0FBQztJQUMxQixhQUFhLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDZixhQUFhLEdBQUcsRUFBRSxDQUFDO0lBQ25CLFdBQVcsR0FBRyxDQUFDLENBQUM7SUFDaEIsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0lBQ3JCLHFCQUFxQixHQUFHLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNyQyxZQUFZLEdBQUcsRUFBRSxDQUFDO0lBRWxCLHNEQUFzRDtJQUN0RCxhQUFhLEdBQWtCLElBQUksQ0FBQztJQUNwQyxlQUFlLEdBQWEsRUFBRSxDQUFDO0lBRXZCLGdCQUFnQjtRQUN0QixtREFBbUQ7UUFDbkQsTUFBTSxJQUFJLEdBQWEsRUFBRSxDQUFDO1FBQzFCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDNUIsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0csSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDMUI7UUFDRCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztJQUM5QixDQUFDO0lBRUQsc0RBQXNEO0lBQ3RELFVBQVUsR0FBRyxLQUFLLENBQUM7SUFFWCxRQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztJQUV2QyxtRUFBbUU7SUFDM0QsYUFBYSxHQUFHO1FBQ3RCLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsU0FBUztRQUMvRCxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVE7UUFDNUQsUUFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRO0tBQzVCLENBQUM7SUFFRixZQUNVLFlBQTBCLEVBQzFCLEtBQXFCLEVBQ3JCLEVBQXNCO1FBRnRCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLFVBQUssR0FBTCxLQUFLLENBQWdCO1FBQ3JCLE9BQUUsR0FBRixFQUFFLENBQW9CO1FBRTlCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRCxRQUFRO1FBQ04sbUJBQW1CO1FBQ25CLElBQUksV0FBVyxJQUFJLFlBQVksRUFBRTtZQUMvQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQztZQUNuRSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxJQUFJLElBQUksQ0FBQztTQUM5QztRQUVELHVDQUF1QztRQUN2QyxJQUFJLGdCQUFnQixJQUFJLFlBQVksRUFBRTtZQUNwQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQztZQUNqRixJQUFJLENBQUMsUUFBUSxHQUFHLGFBQWEsRUFBRSxNQUFNLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQztZQUN2RCxJQUFJLGFBQWEsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO2dCQUNsQyxJQUFJLENBQUMsU0FBUyxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO2dCQUM5QyxJQUFJLENBQUMsT0FBTyxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO2FBQzNDO1lBQ0QsSUFBSSxhQUFhLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRTtnQkFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ2pFO1NBQ0Y7UUFFRCxrRkFBa0Y7UUFDbEYsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDdkUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztZQUNsQyxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUIsSUFBSSxHQUFHLEtBQUssVUFBVSxFQUFFO2dCQUN0QixJQUFJLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQzthQUNwQztpQkFBTSxJQUFJLEdBQUcsS0FBSyxRQUFRLEVBQUU7Z0JBQzNCLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDO2FBQzdCO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDO2FBQ3BDO1lBQ0Qsc0VBQXNFO1lBQ3RFLElBQUksUUFBUSxLQUFLLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ2pDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUN2QjtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgseUVBQXlFO1FBQ3pFLHNEQUFzRDtRQUN0RCxJQUFJLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFO1lBQzVFLElBQUksSUFBSSxFQUFFO2dCQUNSLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO2dCQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksRUFBRSxNQUFNLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQztnQkFDOUMsSUFBSSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRTtvQkFDekIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztvQkFDckMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztpQkFDbEM7Z0JBQ0QsSUFBSSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRTtvQkFDeEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2lCQUN4RDthQUNGO1lBQ0QscUVBQXFFO1lBQ3JFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLGVBQWUsRUFBRTtZQUN4QyxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztZQUNsQixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztTQUMzQjthQUFNLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxlQUFlLEVBQUU7WUFDL0MsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ3ZCO2FBQU0sSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtZQUN4QyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztZQUNwQixJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztTQUMxQjtJQUNILENBQUM7SUFFRCx1REFBdUQ7SUFDL0MsZUFBZSxDQUFDLElBQVM7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNsRCxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO1FBQ3pELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFLFlBQVksSUFBSSxFQUFFLENBQUM7UUFDdEgsT0FBTztZQUNMLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLEdBQUcsSUFBSSxFQUFFO1lBQ3RELE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxJQUFJLEVBQUU7WUFDM0IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLElBQUksRUFBRTtZQUMvQixRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxFQUFFO1lBQzdFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRTtZQUMzQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFO1lBQ3JCLElBQUksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQztZQUM5QixRQUFRLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxXQUFXLENBQUM7WUFDMUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQztZQUNsRCxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLEVBQUU7WUFDL0MsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixJQUFJLEVBQUUsWUFBWSxFQUFFLEVBQUUsRUFBRSxhQUFhLEVBQUUsRUFBRSxFQUFFO1lBQ3hGLE9BQU8sRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDeEMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLElBQUksRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUU7WUFDcEUsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDO1lBQzlELGNBQWMsRUFBRSxLQUFLO1NBQ3RCLENBQUM7SUFDSixDQUFDO0lBRUQsdURBQXVEO0lBQy9DLFlBQVksQ0FBQyxHQUFRO1FBQzNCLElBQUksQ0FBQyxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUTtZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQy9DLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFBRSxPQUFPLEdBQUcsQ0FBQztRQUNuQyxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO2FBQ3RCLE1BQU0sQ0FBQyxDQUFDLE9BQVksRUFBRSxFQUFFLENBQUMsT0FBTyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDO2FBQ2hGLEdBQUcsQ0FBQyxDQUFDLE9BQVksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0QixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxFQUFFO1lBQ3hCLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQUU7WUFDeEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLLElBQUksRUFBRTtTQUMzQixDQUFDLENBQUMsQ0FBQztJQUNSLENBQUM7SUFFRCwwREFBMEQ7SUFDMUQsY0FBYyxDQUFDLElBQVM7UUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxjQUFjO1lBQUUsT0FBTztRQUN6RSxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixNQUFNLE9BQU8sR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzVHLElBQUksQ0FBQyxZQUFZLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUN0RyxJQUFJLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQkFDakIsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFLElBQUksQ0FBQztnQkFDdEIsTUFBTSxNQUFNLEdBQUcsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUNsRixJQUFJLE1BQU0sQ0FBQyxPQUFPO29CQUFFLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3JFLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTTtvQkFBRSxJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUM7Z0JBQzVFLElBQUksTUFBTSxDQUFDLG1CQUFtQixFQUFFLFlBQVk7b0JBQUUsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQztnQkFDcEcsSUFBSSxNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxTQUFTO29CQUFFLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDO2dCQUM3RixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztnQkFDMUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUM7WUFDOUIsQ0FBQztZQUNELEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7U0FDOUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELCtEQUErRDtJQUN2RCxrQkFBa0IsQ0FBQyxJQUFZO1FBQ3JDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDckIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLDZCQUE2QixFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCxxREFBcUQ7SUFDN0MsY0FBYyxDQUFDLEdBQVE7UUFDN0IsSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNwQixNQUFNLFFBQVEsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDO1lBQUUsT0FBTyxHQUFHLENBQUM7UUFDaEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDLENBQUM7UUFDdkMsT0FBTyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksS0FBSyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNyRCxDQUFDO0lBRUQscUZBQXFGO0lBQzdFLFVBQVUsQ0FBQyxHQUFXO1FBQzVCLElBQUksQ0FBQyxHQUFHO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDcEIsSUFBSTtZQUNGLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzNCLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFBRSxPQUFPLEdBQUcsQ0FBQztZQUN0QyxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7U0FDL0Y7UUFBQyxNQUFNO1lBQ04sT0FBTyxHQUFHLENBQUM7U0FDWjtJQUNILENBQUM7SUFFRCxzREFBc0Q7SUFDOUMsb0JBQW9CLENBQUMsTUFBYTtRQUN4QyxtREFBbUQ7UUFDbkQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sS0FBSyxLQUFLLENBQUMsQ0FBQztRQUMvRCxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRU8sV0FBVztRQUNqQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUN2RSxDQUFDO0lBRU8sWUFBWTtRQUNsQixPQUFPLElBQUksQ0FBQyxTQUFTLElBQUksWUFBWSxDQUFDO0lBQ3hDLENBQUM7SUFFTyxVQUFVO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLE9BQU8sSUFBSSxZQUFZLENBQUM7SUFDdEMsQ0FBQztJQUVPLGdCQUFnQjtRQUN0QixPQUFPO1lBQ0wsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztZQUN6QixPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUMzQixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUM5QixPQUFPLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUMxQixJQUFJLEVBQUUsSUFBSTtZQUNWLGFBQWEsRUFBRSxPQUFPO1lBQ3RCLFFBQVEsRUFBRSxLQUFLO1NBQ2hCLENBQUM7SUFDSixDQUFDO0lBRUQsc0RBQXNEO0lBQ3RELCtDQUErQztJQUMvQyxzREFBc0Q7SUFDdEQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLE1BQU0sT0FBTyxHQUFHO1lBQ2QsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDMUIsSUFBSSxFQUFFLEtBQUs7WUFDWCxhQUFhLEVBQUUsWUFBWTtZQUMzQixXQUFXLEVBQUUsSUFBSSxDQUFDLGVBQWUsSUFBSSxFQUFFO1lBQ3ZDLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVztZQUN2QixHQUFHLEVBQUUsRUFBRTtZQUNQLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUM7U0FDMUIsQ0FBQztRQUVGLElBQUksQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ2xGLElBQUksRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUNqQixNQUFNLElBQUksR0FBRyxHQUFHLEVBQUUsSUFBSSxDQUFDO2dCQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksRUFBRSxhQUFhLElBQUksRUFBRSxDQUFDO2dCQUNyRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDekUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEVBQUUsS0FBSyxJQUFJLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDO2dCQUNyRixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDaEYsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQzVGLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEgsb0JBQW9CO2dCQUNwQixJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDakMsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQztpQkFDbEU7Z0JBQ0QsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7WUFDM0IsQ0FBQztZQUNELEtBQUssRUFBRSxHQUFHLEVBQUU7Z0JBQ1YsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO2dCQUNuQixJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7WUFDM0IsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxJQUFZO1FBQzNCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxJQUFTO1FBQzVCLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxFQUFVO1FBQ3pCLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUMsRUFBRTtZQUM1QixJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztTQUMzQjthQUFNO1lBQ0wsSUFBSSxDQUFDLGVBQWUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUM7U0FDdkM7SUFDSCxDQUFDO0lBRUQsU0FBUyxDQUFDLElBQVM7UUFDakIsT0FBTyxJQUFJLEVBQUUsTUFBTSxJQUFJLElBQUksRUFBRSxPQUFPLElBQUksSUFBSSxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUM7SUFDMUQsQ0FBQztJQUVELFVBQVUsQ0FBQyxNQUFjO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxTQUFTLENBQUM7SUFDNUMsQ0FBQztJQUVELFVBQVUsQ0FBQyxNQUFjLEVBQUUsR0FBVyxFQUFFLEtBQVk7UUFDbEQsS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBQzlCLENBQUM7SUFFRCxZQUFZO0lBQ1osYUFBYTtRQUNYLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRTtZQUFFLE9BQU87UUFDekMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDMUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFFdEIsTUFBTSxPQUFPLEdBQUc7WUFDZCxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLElBQUksTUFBTTtZQUNwQyxVQUFVLEVBQUUsUUFBUSxJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUU7WUFDaEMsWUFBWSxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQzVCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxRQUFRO1lBQ2xFLE9BQU8sRUFBRSxJQUFJLENBQUMsZUFBZTtZQUM3QixhQUFhLEVBQUUsWUFBWTtZQUMzQixNQUFNLEVBQUU7Z0JBQ04sZUFBZSxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ25DLFVBQVUsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFO2dCQUN4RCxpQkFBaUIsRUFBRSxDQUFDLE9BQU8sQ0FBQzthQUM3QjtTQUNGLENBQUM7UUFFRixJQUFJLENBQUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUM3RSxJQUFJLEVBQUUsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQkFDakIsSUFBSSxDQUFDLFdBQVcsR0FBRyxPQUFPLEdBQUcsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxhQUFhLENBQUMsQ0FBQztnQkFDbEgsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7WUFDN0IsQ0FBQztZQUNELEtBQUssRUFBRSxHQUFHLEVBQUU7Z0JBQ1YsSUFBSSxDQUFDLFdBQVcsR0FBRyxpREFBaUQsQ0FBQztnQkFDckUsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7WUFDN0IsQ0FBQztTQUNGLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRCxzREFBc0Q7SUFDdEQsd0NBQXdDO0lBQ3hDLHNEQUFzRDtJQUN0RCxjQUFjO1FBQ1osSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDNUYsSUFBSSxFQUFFLENBQUMsR0FBUSxFQUFFLEVBQUU7Z0JBQ2pCLElBQUksQ0FBQyxVQUFVLEdBQUcsR0FBRyxFQUFFLElBQUksRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDO2dCQUMzQyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTt3QkFDMUIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxJQUFJLEVBQUUsQ0FBQztxQkFDakg7b0JBQ0QsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7aUJBQ3pCO1lBQ0gsQ0FBQztZQUNELEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7U0FDdkMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELDZDQUE2QztJQUM3QyxrQkFBa0IsQ0FBQyxNQUFXO1FBQzVCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxFQUFFLElBQUksTUFBTSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDekUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxVQUFVLElBQUksTUFBTSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFDakUsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDdkIsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUNwQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsNkNBQTZDO0lBQzdDLHNCQUFzQixDQUFDLFFBQWdCO1FBQ3JDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxRQUFRLENBQUM7UUFDakMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQztRQUM1RixJQUFJLENBQUMsa0JBQWtCLEdBQUcsTUFBTSxFQUFFLFVBQVUsSUFBSSxNQUFNLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNuRSxJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxnQkFBZ0I7UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQjtZQUFFLE9BQU87UUFDbkMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsTUFBTSxPQUFPLEdBQUc7WUFDZCxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUMxQixVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7U0FDcEMsQ0FBQztRQUVGLElBQUksQ0FBQyxZQUFZLENBQUMscUJBQXFCLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDeEYsSUFBSSxFQUFFLENBQUMsR0FBUSxFQUFFLEVBQUU7Z0JBQ2pCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsY0FBYyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUM3RSxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztZQUM1QixDQUFDO1lBQ0QsS0FBSyxFQUFFLEdBQUcsRUFBRTtnQkFDVixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztnQkFDdEIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7WUFDNUIsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCw2Q0FBNkM7SUFDN0MsbUJBQW1CLENBQUMsUUFBYTtRQUMvQixNQUFNLEtBQUssR0FBVSxFQUFFLENBQUM7UUFDeEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxxQkFBcUIsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQyxDQUFDLENBQUM7UUFDOUYsSUFBSSxDQUFDLFVBQVUsR0FBRyxRQUFRLENBQUMsbUJBQW1CLElBQUksQ0FBQyxDQUFDO1FBRXBELEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUN2QyxJQUFJLFFBQVEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO2dCQUFFLFNBQVM7WUFDaEMsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlCLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUTtnQkFBRSxTQUFTO1lBRXRELE1BQU0sTUFBTSxHQUFVLE9BQU8sQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzFDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNO2dCQUFFLFNBQVM7WUFFN0IsSUFBSSxJQUFJLEtBQUssZ0JBQWdCLEVBQUU7Z0JBQzdCLEtBQUssQ0FBQyxJQUFJLENBQUM7b0JBQ1QsR0FBRztvQkFDSCxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxHQUFHO29CQUN6QixJQUFJLEVBQUUsZ0JBQWdCO29CQUN0QixXQUFXLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDdEMsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRTt3QkFDbEIsS0FBSyxFQUFFLElBQUksQ0FBQyxJQUFJO3dCQUNoQixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUM7d0JBQzVDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUM7cUJBQ3ZCLENBQUMsQ0FBQztpQkFDSixDQUFDLENBQUM7YUFDSjtpQkFBTSxJQUFJLElBQUksS0FBSyxnQkFBZ0IsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFO2dCQUNoRSxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUM3QixLQUFLLENBQUMsSUFBSSxDQUFDO29CQUNULEdBQUc7b0JBQ0gsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLElBQUksR0FBRztvQkFDekIsSUFBSTtvQkFDSixXQUFXLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFO2lCQUM1RCxDQUFDLENBQUM7YUFDSjtpQkFBTSxJQUFJLElBQUksS0FBSyxZQUFZLElBQUksSUFBSSxLQUFLLGtCQUFrQixFQUFFO2dCQUMvRCxLQUFLLENBQUMsSUFBSSxDQUFDO29CQUNULEdBQUc7b0JBQ0gsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLElBQUksR0FBRztvQkFDekIsSUFBSTtvQkFDSixjQUFjLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQzt3QkFDekMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRTt3QkFDbkIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLElBQUksRUFBRTt3QkFDL0IsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRTt3QkFDN0IsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksRUFBRTtxQkFDdEIsQ0FBQyxDQUFDO2lCQUNKLENBQUMsQ0FBQzthQUNKO1NBQ0Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxxREFBcUQ7SUFDckQsY0FBYyxHQUFHLEVBQUUsQ0FBQztJQUNwQixnQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUFDdEIsVUFBVSxHQUFHLENBQUMsQ0FBQztJQUVmLGNBQWMsQ0FBQyxFQUFPLEVBQUUsSUFBUztRQUMvQixJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUNwQixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxjQUFjLEdBQUcsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVELHdCQUF3QjtRQUN0QixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUMxQixNQUFNLE9BQU8sR0FBRztZQUNkLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQzFCLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztZQUNuQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGFBQWE7WUFDekIsR0FBRyxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ3JELElBQUksRUFBRSxJQUFJLENBQUMsZ0JBQWdCO1lBQzNCLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUM7U0FDNUIsQ0FBQztRQUVGLElBQUksQ0FBQyxZQUFZLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDdkYsSUFBSSxFQUFFLENBQUMsR0FBUSxFQUFFLEVBQUU7Z0JBQ2pCLE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRSxJQUFJLENBQUM7Z0JBQ3ZCLE1BQU0sSUFBSSxHQUFHLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLGFBQWEsSUFBSSxFQUFFLENBQUM7Z0JBQ3JELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBUyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQy9FLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxFQUFFLEtBQUssSUFBSSxJQUFJLEVBQUUsVUFBVSxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDO2dCQUM3RixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO2dCQUN0RixJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDbEcsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsSSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztnQkFDaEQsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7b0JBQ25DLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7aUJBQ3JEO2dCQUNELElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1lBQzdCLENBQUM7WUFDRCxLQUFLLEVBQUUsR0FBRyxFQUFFO2dCQUNWLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxFQUFFLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO2dCQUMxQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO2dCQUMxQixJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztZQUM3QixDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHNCQUFzQixDQUFDLElBQVM7UUFDOUIsTUFBTSxPQUFPLEdBQUcsSUFBSSxFQUFFLE1BQU0sSUFBSSxJQUFJLEVBQUUsT0FBTyxJQUFJLElBQUksRUFBRSxHQUFHLENBQUM7UUFDM0QsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRXJCLElBQUksQ0FBQyxZQUFZLENBQUMscUJBQXFCLENBQUMsT0FBTyxFQUFFO1lBQy9DLFFBQVEsRUFBRSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztZQUNqQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7U0FDeEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQzFDLElBQUksRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUNqQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsR0FBRyxFQUFFLElBQUksSUFBSSxHQUFHLENBQUM7WUFDM0MsQ0FBQztZQUNELEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUMvQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsRUFBVTtRQUN6QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUMzRCxDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBWTtRQUM3QixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN2QixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsc0JBQXNCLENBQUMsSUFBUztRQUM5QixJQUFJLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUNwQixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQsc0RBQXNEO0lBQ3RELGtEQUFrRDtJQUNsRCxzREFBc0Q7SUFDdEQsaUJBQWlCO1FBQ2YsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDMUIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFFMUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ2hILElBQUksRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUNqQixJQUFJLENBQUMsYUFBYSxHQUFHLEdBQUcsRUFBRSxJQUFJLEVBQUUsT0FBTyxJQUFJLEVBQUUsQ0FBQztnQkFDOUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUM7Z0JBQzdFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RGLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO1lBQzdCLENBQUM7WUFDRCxLQUFLLEVBQUUsR0FBRyxFQUFFO2dCQUNWLElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztnQkFDckIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLENBQUMsQ0FBQztnQkFDMUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7WUFDN0IsQ0FBQztTQUNGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxJQUFZO1FBQzdCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxzQkFBc0IsQ0FBQyxJQUFTO1FBQzlCLElBQUksQ0FBQyxhQUFhLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7UUFDcEIsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELFlBQVksQ0FBQyxRQUFnQjtRQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLDhDQUE4QyxDQUFDO1lBQUUsT0FBTztRQUNyRSxJQUFJLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUNoRixJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxLQUFLLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDcEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHNEQUFzRDtJQUN0RCxpREFBaUQ7SUFDakQsc0RBQXNEO0lBQ3RELGNBQWMsR0FBbUYsRUFBRSxDQUFDO0lBQ3BHLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFFaEIsVUFBVSxDQUFDLE1BQWM7UUFDdkIsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQyxTQUFTLE1BQU0sRUFBRSxDQUFxQixDQUFDO1FBQzdFLElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTztRQUNuQixJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssTUFBTSxFQUFFO1lBQ2pDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1NBQzNCO2FBQU07WUFDTCw4QkFBOEI7WUFDOUIsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUN0QixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLFNBQVMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFxQixDQUFDO2dCQUN6RixJQUFJLEtBQUs7b0JBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN6QixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQzthQUMzQjtZQUNELE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNqQyxJQUFJLFdBQVcsS0FBSyxTQUFTLEVBQUU7Z0JBQzdCLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUN0RztpQkFBTTtnQkFDTCxJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQzthQUM3QjtTQUNGO0lBQ0gsQ0FBQztJQUVELGdCQUFnQixDQUFDLEtBQXVCLEVBQUUsTUFBYyxFQUFFLFdBQW9CO1FBQzVFLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxDQUFDO1NBQ3ZGO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxDQUFDLFFBQVEsR0FBRyxDQUFDLEVBQUU7WUFDbEQsS0FBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUN4RDthQUFNLElBQUksV0FBVyxFQUFFO1lBQ3RCLEtBQUssQ0FBQyxTQUFTLEdBQUcsV0FBVyxDQUFDO1NBQy9CO0lBQ0gsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUF1QixFQUFFLE1BQWM7UUFDbEQsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDaEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUM7U0FDdkY7UUFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFDLEtBQUssQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDNUQsSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFO1lBQ2xELEtBQUssQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1NBQ3JEO0lBQ0gsQ0FBQztJQUVELFNBQVMsQ0FBQyxLQUFpQixFQUFFLE1BQWM7UUFDekMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLGFBQTRCLENBQUM7UUFDakQsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDO1FBQ2hELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUMsU0FBUyxNQUFNLEVBQUUsQ0FBcUIsQ0FBQztRQUM3RSxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBQ3RDLEtBQUssQ0FBQyxXQUFXLEdBQUcsS0FBSyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7SUFDN0MsQ0FBQztJQUVELFVBQVU7UUFDUixJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM3QixNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbEQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFTyxlQUFlLENBQUMsT0FBZTtRQUNyQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sTUFBTSxDQUFDO1FBQzVCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLE9BQU8sR0FBRyxJQUFJLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDcEQsQ0FBQztJQUVELHNEQUFzRDtJQUN0RCxpQkFBaUI7SUFDakIsc0RBQXNEO0lBQ3RELGdCQUFnQixLQUFXLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNwRCxpQkFBaUIsS0FBVyxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFdEQsc0RBQXNEO0lBQ3RELFVBQVU7SUFDVixzREFBc0Q7SUFDdEQsU0FBUyxDQUFDLEtBQWEsRUFBRSxJQUFTO1FBQ2hDLE9BQU8sSUFBSSxFQUFFLEVBQUUsSUFBSSxJQUFJLEVBQUUsR0FBRyxJQUFJLElBQUksRUFBRSxNQUFNLElBQUksS0FBSyxDQUFDO0lBQ3hELENBQUM7SUFFRCxJQUFJLEdBQUcsSUFBSSxDQUFDO3dHQTdzQkQsa0JBQWtCOzRGQUFsQixrQkFBa0Isc0RDWC9CLCt5aUNBb2NBOzs0RkR6YmEsa0JBQWtCO2tCQUw5QixTQUFTOytCQUNFLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQXVkaW9TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYXVkaW8uc2VydmljZSc7XG5pbXBvcnQgeyBHbG9iYWxTdGF0ZVNlcnZpY2UgfSBmcm9tICd0YW5nby1hcHAtdWktZ2xvYmFsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLXRhbmdvLWVjaG8nLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFuZ28tZWNoby5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RhbmdvLWVjaG8uY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBUYW5nb0VjaG9Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgLy8g4pSA4pSAIE5hdmlnYXRpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIGN1cnJlbnRQYWdlOiAnY29udmVyc2F0aW9ucycgfCAnYWdlbnRhbmFseXNpcycgfCAnbWFuYWdlJyA9ICdjb252ZXJzYXRpb25zJztcblxuICAvLyDilIDilIAgVXNlciAvIEdsb2JhbCBTdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgY2xpZW50SWQgPSAnMTEnO1xuICBzdG9yZUlkczogc3RyaW5nW10gPSBbXTtcbiAgc3RhcnREYXRlID0gJyc7XG4gIGVuZERhdGUgPSAnJztcbiAgaGVhZGVyRGF0YTogYW55ID0ge307XG4gIHVzZXJzOiBhbnkgPSB7fTtcblxuICAvLyDilIDilIAgQ29udmVyc2F0aW9ucyAodHJhbnNjcmlwdC1saXN0IEFQSSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIGNvbnZlcnNhdGlvbnM6IGFueVtdID0gW107XG4gIGNvbnZQYWdlID0gMTtcbiAgY29udlBlclBhZ2UgPSAxMDtcbiAgY29udlRvdGFsID0gMDtcbiAgY29udlRvdGFsUGFnZXMgPSAxO1xuICBjb252UGFnaW5hdGlvblNpemVzID0gWzEwLCAyMCwgNTAsIDEwMF07XG4gIGNvbnZMb2FkaW5nID0gZmFsc2U7XG4gIGNvbnZTZWFyY2hRdWVyeSA9ICcnO1xuICBleHBhbmRlZENvbnZJZHM6IHsgW2lkOiBzdHJpbmddOiBib29sZWFuIH0gPSB7fTtcbiAgY29udlRhYnM6IHsgW2NvbnZJZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcblxuICAvLyBBSSBDaGF0XG4gIGNvbnZBaVJlcGx5ID0gJyc7XG4gIGNvbnZBaUxvYWRpbmcgPSBmYWxzZTtcblxuICAvLyDilIDilIAgQWdlbnQgQW5hbHlzaXMgKGNvaG9ydC9hdWRpby1wYWdlIEFQSSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIGNvaG9ydExpc3Q6IGFueVtdID0gW107XG4gIHNlbGVjdGVkQ29ob3J0SWQgPSAnJztcbiAgc2VsZWN0ZWRDb2hvcnROYW1lID0gJyc7XG4gIGNvaG9ydENhcmRzOiBhbnlbXSA9IFtdO1xuICBjYXJkc0xvYWRpbmcgPSBmYWxzZTtcbiAgZGV0YWlsVmlldyA9IGZhbHNlO1xuICBhbmFseXNpc1NlYXJjaCA9ICcnO1xuXG4gIC8vIERldGFpbCBjb252ZXJzYXRpb25zIChmcm9tIGNvaG9ydCBjYXJkIGNsaWNrKVxuICBkZXRhaWxDb252ZXJzYXRpb25zOiBhbnlbXSA9IFtdO1xuICBkZXRhaWxQYWdlID0gMTtcbiAgZGV0YWlsUGVyUGFnZSA9IDEwO1xuICBkZXRhaWxUb3RhbFBhZ2VzID0gMTtcbiAgZGV0YWlsVG90YWwgPSAwO1xuICBkZXRhaWxQYWdpbmF0aW9uU2l6ZXMgPSBbMTAsIDIwLCA1MCwgMTAwXTtcbiAgZGV0YWlsUGFnZUNvbnZzOiBhbnlbXSA9IFtdO1xuICBkZXRhaWxPcGVuSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBkZXRhaWxMb2FkaW5nID0gZmFsc2U7XG4gIGRldGFpbENvbnZEZXRhaWw6IGFueSA9IG51bGw7XG5cbiAgLy8g4pSA4pSAIE1hbmFnZSAoY29ob3J0IENSVUQgQVBJKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgbWFuYWdlQ29ob3J0czogYW55W10gPSBbXTtcbiAgbWFuYWdlTG9hZGluZyA9IGZhbHNlO1xuICBtYW5hZ2VQYWdlID0gMTtcbiAgbWFuYWdlUGVyUGFnZSA9IDEwO1xuICBtYW5hZ2VUb3RhbCA9IDA7XG4gIG1hbmFnZVRvdGFsUGFnZXMgPSAxO1xuICBtYW5hZ2VQYWdpbmF0aW9uU2l6ZXMgPSBbMTAsIDIwLCAzMF07XG4gIG1hbmFnZVNlYXJjaCA9ICcnO1xuXG4gIC8vIOKUgOKUgCBBdWRpbyBQbGF5ZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIHBsYXlpbmdDb252SWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICB3YXZlZm9ybUhlaWdodHM6IG51bWJlcltdID0gW107XG5cbiAgcHJpdmF0ZSBnZW5lcmF0ZVdhdmVmb3JtKCk6IHZvaWQge1xuICAgIC8vIEdlbmVyYXRlIH4yMDAgYmFycyB3aXRoIG5hdHVyYWwgd2F2ZWZvcm0gcGF0dGVyblxuICAgIGNvbnN0IGJhcnM6IG51bWJlcltdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCAyMDA7IGkrKykge1xuICAgICAgY29uc3QgaCA9IE1hdGgubWF4KDMsIE1hdGguYWJzKE1hdGguc2luKGkgKiAwLjE1KSAqIDI4ICsgTWF0aC5zaW4oaSAqIDAuNCkgKiAxMiArIE1hdGguY29zKGkgKiAwLjA4KSAqIDgpKTtcbiAgICAgIGJhcnMucHVzaChNYXRoLnJvdW5kKGgpKTtcbiAgICB9XG4gICAgdGhpcy53YXZlZm9ybUhlaWdodHMgPSBiYXJzO1xuICB9XG5cbiAgLy8g4pSA4pSAIEZpbHRlcnMgRHJhd2VyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBkcmF3ZXJPcGVuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLy8gRGVmYXVsdCBzdG9yZSBsaXN0IChzYW1lIGFzIGV4aXN0aW5nIGF1ZGlvLXBhZ2UvdHJhbnNjcmlwdC1saXN0KVxuICBwcml2YXRlIGRlZmF1bHRTdG9yZXMgPSBbXG4gICAgJzExLTEwNjInLCAnMTEtMTA3OCcsICcxMS0xMDgzJywgJzExLTE1MTUnLCAnMTEtMTU0JywgJzExLTE2MjYnLFxuICAgICcxMS0xODEnLCAnMTEtMTk0NycsICcxMS0xOTk0JywgJzExLTIwMCcsICcxMS0yMDInLCAnMTEtMjE1JyxcbiAgICAnMTEtMjYwJywgJzExLTc4JywgJzExLTgxOSdcbiAgXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGF1ZGlvU2VydmljZTogQXVkaW9TZXJ2aWNlLFxuICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgZ3M6IEdsb2JhbFN0YXRlU2VydmljZVxuICApIHtcbiAgICB0aGlzLmdlbmVyYXRlV2F2ZWZvcm0oKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIDEuIEdldCB1c2VyIGluZm9cbiAgICBpZiAoJ3VzZXItaW5mbycgaW4gbG9jYWxTdG9yYWdlKSB7XG4gICAgICB0aGlzLnVzZXJzID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndXNlci1pbmZvJykgfHwgJ3t9Jyk7XG4gICAgICB0aGlzLmNsaWVudElkID0gdGhpcy51c2Vycz8uY2xpZW50SWQgfHwgJzExJztcbiAgICB9XG5cbiAgICAvLyAyLiBSZXN0b3JlIGZpbHRlcnMgZnJvbSBsb2NhbFN0b3JhZ2VcbiAgICBpZiAoJ2hlYWRlci1maWx0ZXJzJyBpbiBsb2NhbFN0b3JhZ2UpIHtcbiAgICAgIGNvbnN0IGhlYWRlckZpbHRlcnMgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdoZWFkZXItZmlsdGVycycpIHx8ICd7fScpO1xuICAgICAgdGhpcy5jbGllbnRJZCA9IGhlYWRlckZpbHRlcnM/LmNsaWVudCB8fCB0aGlzLmNsaWVudElkO1xuICAgICAgaWYgKGhlYWRlckZpbHRlcnM/LmRhdGU/LnN0YXJ0RGF0ZSkge1xuICAgICAgICB0aGlzLnN0YXJ0RGF0ZSA9IGhlYWRlckZpbHRlcnMuZGF0ZS5zdGFydERhdGU7XG4gICAgICAgIHRoaXMuZW5kRGF0ZSA9IGhlYWRlckZpbHRlcnMuZGF0ZS5lbmREYXRlO1xuICAgICAgfVxuICAgICAgaWYgKGhlYWRlckZpbHRlcnM/LnN0b3Jlcz8ubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVJZHMgPSB0aGlzLmV4dHJhY3RDaGVja2VkU3RvcmVzKGhlYWRlckZpbHRlcnMuc3RvcmVzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAzLiBTdWJzY3JpYmUgdG8gcXVlcnkgcGFyYW1zIGZvciB0YWIgc3dpdGNoaW5nIOKAlCBhbHNvIHJlbG9hZCBkYXRhIG9uIHRhYiBjaGFuZ2VcbiAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUocGFyYW1zID0+IHtcbiAgICAgIGNvbnN0IHByZXZQYWdlID0gdGhpcy5jdXJyZW50UGFnZTtcbiAgICAgIGNvbnN0IHRhYiA9IHBhcmFtc1sndGFiJ107XG4gICAgICBpZiAodGFiID09PSAnYW5hbHlzaXMnKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFBhZ2UgPSAnYWdlbnRhbmFseXNpcyc7XG4gICAgICB9IGVsc2UgaWYgKHRhYiA9PT0gJ21hbmFnZScpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9ICdtYW5hZ2UnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9ICdjb252ZXJzYXRpb25zJztcbiAgICAgIH1cbiAgICAgIC8vIE9ubHkgcmVsb2FkIGlmIHRhYiBhY3R1YWxseSBjaGFuZ2VkIChhdm9pZCBkdXBsaWNhdGUgY2FsbHMgb24gaW5pdClcbiAgICAgIGlmIChwcmV2UGFnZSAhPT0gdGhpcy5jdXJyZW50UGFnZSkge1xuICAgICAgICB0aGlzLmxvYWRDdXJyZW50VGFiKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyA0LiBTdWJzY3JpYmUgdG8gZ2xvYmFsIHRvb2xiYXIgY2hhbmdlcyDigJQgdGhpcyBpcyB0aGUgTUFJTiBkYXRhIHRyaWdnZXJcbiAgICAvLyAgICAoc2FtZSBwYXR0ZXJuIGFzIHRyYW5zY3JpcHQtbGlzdCBhbmQgYXVkaW8tcGFnZSlcbiAgICB0aGlzLmdzLmRhdGFSYW5nZVZhbHVlLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgdGhpcy5oZWFkZXJEYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5jbGllbnRJZCA9IGRhdGE/LmNsaWVudCB8fCB0aGlzLmNsaWVudElkO1xuICAgICAgICBpZiAoZGF0YT8uZGF0ZT8uc3RhcnREYXRlKSB7XG4gICAgICAgICAgdGhpcy5zdGFydERhdGUgPSBkYXRhLmRhdGUuc3RhcnREYXRlO1xuICAgICAgICAgIHRoaXMuZW5kRGF0ZSA9IGRhdGEuZGF0ZS5lbmREYXRlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRhPy5zdG9yZXM/Lmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuc3RvcmVJZHMgPSB0aGlzLmV4dHJhY3RDaGVja2VkU3RvcmVzKGRhdGEuc3RvcmVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRmV0Y2ggZGF0YSBmb3IgY3VycmVudCB0YWIgKGRhdGFSYW5nZVZhbHVlIGZpcmVzIG9uIHBhZ2UgbG9hZCB0b28pXG4gICAgICB0aGlzLmxvYWRDdXJyZW50VGFiKCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBsb2FkQ3VycmVudFRhYigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jdXJyZW50UGFnZSA9PT0gJ2NvbnZlcnNhdGlvbnMnKSB7XG4gICAgICB0aGlzLmNvbnZQYWdlID0gMTtcbiAgICAgIHRoaXMuZmV0Y2hDb252ZXJzYXRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRQYWdlID09PSAnYWdlbnRhbmFseXNpcycpIHtcbiAgICAgIHRoaXMubG9hZENvaG9ydExpc3QoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudFBhZ2UgPT09ICdtYW5hZ2UnKSB7XG4gICAgICB0aGlzLm1hbmFnZVBhZ2UgPSAxO1xuICAgICAgdGhpcy5sb2FkTWFuYWdlQ29ob3J0cygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBNYXBwaW5nIChzYW1lIGFzIHRyYW5zY3JpcHQtbGlzdCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIHByaXZhdGUgbWFwQ29udmVyc2F0aW9uKGl0ZW06IGFueSk6IGFueSB7XG4gICAgY29uc3QgcmF3VGltZSA9IGl0ZW0uVGltZXN0YW1wIHx8IGl0ZW0udGltZSB8fCAnJztcbiAgICBjb25zdCByYXdEdXJhdGlvbiA9IGl0ZW0uRHVyYXRpb24gfHwgaXRlbS5kdXJhdGlvbiB8fCAnJztcbiAgICBjb25zdCByYXdEZXNjID0gaXRlbS5TdW1tYXJ5IHx8IGl0ZW0uYXVkaW9EZXNjcmlwdGlvbiB8fCBpdGVtLnN1bW1hcnkgfHwgaXRlbS5jb252ZXJzYXRpb25EZXRhaWxzPy5hdWRpb1N1bW1hcnkgfHwgJyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGF1ZGlvSWQ6IGl0ZW0uZG9jX2lkIHx8IGl0ZW0uYXVkaW9JZCB8fCBpdGVtLl9pZCB8fCAnJyxcbiAgICAgIHN0b3JlSWQ6IGl0ZW0uc3RvcmVJZCB8fCAnJyxcbiAgICAgIHN0b3JlTmFtZTogaXRlbS5zdG9yZU5hbWUgfHwgJycsXG4gICAgICB1c2VyTmFtZTogaXRlbS5zdGFmZiB8fCBpdGVtLnN0YWZmSWQgfHwgaXRlbS51c2VyTmFtZSB8fCBpdGVtLnN0YWZmTmFtZSB8fCAnJyxcbiAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uIHx8IGl0ZW0uc3RhdGUgfHwgJycsXG4gICAgICBkYXRlOiBpdGVtLmRhdGUgfHwgJycsXG4gICAgICB0aW1lOiB0aGlzLmZvcm1hdFRpbWUocmF3VGltZSksXG4gICAgICBkdXJhdGlvbjogdGhpcy5mb3JtYXREdXJhdGlvbihyYXdEdXJhdGlvbiksXG4gICAgICBhdWRpb0Rlc2NyaXB0aW9uOiB0aGlzLmNsZWFuVHJhbnNjcmlwdGlvbihyYXdEZXNjKSxcbiAgICAgIGF1ZGlvVXJsOiBpdGVtLmF1ZGlvVXJsIHx8IGl0ZW0uYXVkaW9fdXJsIHx8ICcnLFxuICAgICAgY29udmVyc2F0aW9uRGV0YWlsczogaXRlbS5jb252ZXJzYXRpb25EZXRhaWxzIHx8IHsgYXVkaW9TdW1tYXJ5OiAnJywgdHJhbnNjcmlwdGlvbjogJycgfSxcbiAgICAgIG1ldHJpY3M6IHRoaXMucGFyc2VNZXRyaWNzKGl0ZW0ubWV0cmljcyksXG4gICAgICBhaUluc2lnaHRzOiBpdGVtLmFpSW5zaWdodHMgfHwgeyB0aXRsZTogJ0FJIEluc2lnaHRzJywgc3VtbWFyeTogW10gfSxcbiAgICAgIF9kZXRhaWxMb2FkZWQ6ICEhKGl0ZW0uYWlJbnNpZ2h0cyB8fCBpdGVtLmNvbnZlcnNhdGlvbkRldGFpbHMpLFxuICAgICAgX2RldGFpbExvYWRpbmc6IGZhbHNlLFxuICAgIH07XG4gIH1cblxuICAvLyBQYXJzZSBtZXRyaWNzIGZyb20gQVBJIHJlc3BvbnNlIChzYW1lIGFzIGF1ZGlvLXBhZ2UpXG4gIHByaXZhdGUgcGFyc2VNZXRyaWNzKHJhdzogYW55KTogYW55W10ge1xuICAgIGlmICghcmF3IHx8IHR5cGVvZiByYXcgIT09ICdvYmplY3QnKSByZXR1cm4gW107XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmF3KSkgcmV0dXJuIHJhdztcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhyYXcpXG4gICAgICAuZmlsdGVyKChzZWN0aW9uOiBhbnkpID0+IHNlY3Rpb24gJiYgdHlwZW9mIHNlY3Rpb24gPT09ICdvYmplY3QnICYmIHNlY3Rpb24udHlwZSlcbiAgICAgIC5tYXAoKHNlY3Rpb246IGFueSkgPT4gKHtcbiAgICAgICAgbmFtZTogc2VjdGlvbi5uYW1lIHx8ICcnLFxuICAgICAgICB0eXBlOiBzZWN0aW9uLnR5cGUgfHwgJycsXG4gICAgICAgIHZhbHVlOiBzZWN0aW9uLnZhbHVlIHx8IFtdXG4gICAgICB9KSk7XG4gIH1cblxuICAvLyBMb2FkIGNvbnZlcnNhdGlvbiBkZXRhaWwgb24gZXhwYW5kIChzYW1lIGFzIGF1ZGlvLXBhZ2UpXG4gIGxvYWRDb252RGV0YWlsKGNvbnY6IGFueSk6IHZvaWQge1xuICAgIGlmICgoY29udi5fZGV0YWlsTG9hZGVkICYmIGNvbnYuYXVkaW9VcmwpIHx8IGNvbnYuX2RldGFpbExvYWRpbmcpIHJldHVybjtcbiAgICBjb252Ll9kZXRhaWxMb2FkaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBwYXlsb2FkID0geyBjb2hvcnRJZDogdGhpcy5zZWxlY3RlZENvaG9ydElkID8gW3RoaXMuc2VsZWN0ZWRDb2hvcnRJZF0gOiBbXSwgY2xpZW50SWQ6IHRoaXMuY2xpZW50SWQgfTtcbiAgICB0aGlzLmF1ZGlvU2VydmljZS5nZXRDb252ZXJzYXRpb25EZXRhaWwoY29udi5hdWRpb0lkLCBwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCByYXcgPSByZXM/LmRhdGE7XG4gICAgICAgIGNvbnN0IGRldGFpbCA9IHJhdz8uYXVkaW9JZCA/IHJhdyA6IChyYXc/LmRhdGE/LmF1ZGlvSWQgPyByYXcuZGF0YSA6IChyYXcgfHwge30pKTtcbiAgICAgICAgaWYgKGRldGFpbC5tZXRyaWNzKSBjb252Lm1ldHJpY3MgPSB0aGlzLnBhcnNlTWV0cmljcyhkZXRhaWwubWV0cmljcyk7XG4gICAgICAgIGlmIChkZXRhaWwuYWlJbnNpZ2h0cz8uc3VtbWFyeT8ubGVuZ3RoKSBjb252LmFpSW5zaWdodHMgPSBkZXRhaWwuYWlJbnNpZ2h0cztcbiAgICAgICAgaWYgKGRldGFpbC5jb252ZXJzYXRpb25EZXRhaWxzPy5hdWRpb1N1bW1hcnkpIGNvbnYuY29udmVyc2F0aW9uRGV0YWlscyA9IGRldGFpbC5jb252ZXJzYXRpb25EZXRhaWxzO1xuICAgICAgICBpZiAoZGV0YWlsLmF1ZGlvVXJsIHx8IGRldGFpbC5hdWRpb191cmwpIGNvbnYuYXVkaW9VcmwgPSBkZXRhaWwuYXVkaW9VcmwgfHwgZGV0YWlsLmF1ZGlvX3VybDtcbiAgICAgICAgY29udi5fZGV0YWlsTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgY29udi5fZGV0YWlsTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7IGNvbnYuX2RldGFpbExvYWRpbmcgPSBmYWxzZTsgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gQ2xlYW4gXCJTdGFmZjpcIiwgXCJDdXN0b21lcjpcIiBwcmVmaXhlcyBmcm9tIHRyYW5zY3JpcHRpb24gdGV4dFxuICBwcml2YXRlIGNsZWFuVHJhbnNjcmlwdGlvbih0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghdGV4dCkgcmV0dXJuICcnO1xuICAgIHJldHVybiB0ZXh0LnJlcGxhY2UoL1xcYihTdGFmZnxDdXN0b21lcilcXHMqOlxccyovZ2ksICcnKTtcbiAgfVxuXG4gIC8vIEZvcm1hdCBkdXJhdGlvbiBmcm9tIHNlY29uZHMgKGUuZy4gNTE0IOKGkiBcIjhtIDE0c1wiKVxuICBwcml2YXRlIGZvcm1hdER1cmF0aW9uKHZhbDogYW55KTogc3RyaW5nIHtcbiAgICBpZiAoIXZhbCkgcmV0dXJuICcnO1xuICAgIGNvbnN0IHRvdGFsU2VjID0gcGFyc2VGbG9hdCh2YWwpO1xuICAgIGlmIChpc05hTih0b3RhbFNlYykpIHJldHVybiB2YWw7XG4gICAgY29uc3QgbWlucyA9IE1hdGguZmxvb3IodG90YWxTZWMgLyA2MCk7XG4gICAgY29uc3Qgc2VjcyA9IE1hdGguZmxvb3IodG90YWxTZWMgJSA2MCk7XG4gICAgcmV0dXJuIHNlY3MgPiAwID8gYCR7bWluc31tICR7c2Vjc31zYCA6IGAke21pbnN9bWA7XG4gIH1cblxuICAvLyBGb3JtYXQgdGltZSBmcm9tIElTTyBzdHJpbmcgKGUuZy4gXCIyMDI2LTA0LTA4VDIyOjAwOjQyLjk3Mjc4OSswNTozMFwiIOKGkiBcIjEwOjAwIFBNXCIpXG4gIHByaXZhdGUgZm9ybWF0VGltZSh2YWw6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCF2YWwpIHJldHVybiAnJztcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHZhbCk7XG4gICAgICBpZiAoaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSByZXR1cm4gdmFsO1xuICAgICAgcmV0dXJuIGRhdGUudG9Mb2NhbGVUaW1lU3RyaW5nKCdlbi1VUycsIHsgaG91cjogJzItZGlnaXQnLCBtaW51dGU6ICcyLWRpZ2l0JywgaG91cjEyOiB0cnVlIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHZhbDtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgSGVscGVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSBleHRyYWN0Q2hlY2tlZFN0b3JlcyhzdG9yZXM6IGFueVtdKTogc3RyaW5nW10ge1xuICAgIC8vIEZpbHRlciBvbmx5IGNoZWNrZWQgc3RvcmVzLCB0aGVuIGV4dHJhY3Qgc3RvcmVJZFxuICAgIGNvbnN0IGNoZWNrZWQgPSBzdG9yZXMuZmlsdGVyKChzOiBhbnkpID0+IHMuY2hlY2tlZCAhPT0gZmFsc2UpO1xuICAgIHJldHVybiBjaGVja2VkLm1hcCgoczogYW55KSA9PiBzLl9pZCB8fCBzLnN0b3JlSWQgfHwgcyk7XG4gIH1cblxuICBwcml2YXRlIGdldFN0b3JlSWRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5zdG9yZUlkcy5sZW5ndGggPiAwID8gdGhpcy5zdG9yZUlkcyA6IHRoaXMuZGVmYXVsdFN0b3JlcztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3RhcnREYXRlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc3RhcnREYXRlIHx8ICcyMDI2LTA0LTA4JztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RW5kRGF0ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmVuZERhdGUgfHwgJzIwMjYtMDQtMDgnO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZEJhc2VQYXlsb2FkKCk6IGFueSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsaWVudElkOiBbdGhpcy5jbGllbnRJZF0sXG4gICAgICBzdG9yZUlkOiB0aGlzLmdldFN0b3JlSWRzKCksXG4gICAgICBzdGFydERhdGU6IHRoaXMuZ2V0U3RhcnREYXRlKCksXG4gICAgICBlbmREYXRlOiB0aGlzLmdldEVuZERhdGUoKSxcbiAgICAgIGlzQUk6IHRydWUsXG4gICAgICBhbmFseXRpY3NUeXBlOiAnYXVkaW8nLFxuICAgICAgaXNFeHBvcnQ6IGZhbHNlXG4gICAgfTtcbiAgfVxuXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICAvLyBDT05WRVJTQVRJT05TIFRBQiAodXNlcyB0cmFuc2NyaXB0c0xpc3QgQVBJKVxuICAvLyDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZBcbiAgZmV0Y2hDb252ZXJzYXRpb25zKCk6IHZvaWQge1xuICAgIHRoaXMuY29udkxvYWRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IHBheWxvYWQgPSB7XG4gICAgICAuLi50aGlzLmJ1aWxkQmFzZVBheWxvYWQoKSxcbiAgICAgIGlzQUk6IGZhbHNlLFxuICAgICAgYW5hbHl0aWNzVHlwZTogJ3RyYW5zY3JpcHQnLFxuICAgICAgc2VhcmNoVmFsdWU6IHRoaXMuY29udlNlYXJjaFF1ZXJ5IHx8ICcnLFxuICAgICAgbGltaXQ6IHRoaXMuY29udlBlclBhZ2UsXG4gICAgICBfaWQ6IFtdLFxuICAgICAgb2Zmc2V0OiB0aGlzLmNvbnZQYWdlIC0gMVxuICAgIH07XG5cbiAgICB0aGlzLmF1ZGlvU2VydmljZS50cmFuc2NyaXB0c0xpc3QocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHJlcz8uZGF0YTtcbiAgICAgICAgY29uc3QgbGlzdCA9IGRhdGE/LmRhdGEgfHwgZGF0YT8uY29udmVyc2F0aW9ucyB8fCBbXTtcbiAgICAgICAgdGhpcy5jb252ZXJzYXRpb25zID0gbGlzdC5tYXAoKGl0ZW06IGFueSkgPT4gdGhpcy5tYXBDb252ZXJzYXRpb24oaXRlbSkpO1xuICAgICAgICB0aGlzLmNvbnZUb3RhbCA9IGRhdGE/LmNvdW50ID8/IGRhdGE/LnBhZ2luYXRpb24/LnRvdGFsID8/IHRoaXMuY29udmVyc2F0aW9ucy5sZW5ndGg7XG4gICAgICAgIHRoaXMuY29udlRvdGFsUGFnZXMgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodGhpcy5jb252VG90YWwgLyB0aGlzLmNvbnZQZXJQYWdlKSk7XG4gICAgICAgIHRoaXMuY29udlBhZ2luYXRpb25TaXplcyA9IHRoaXMuY29udlRvdGFsID4gMTAgPyBbMTAsIDIwLCA1MCwgMTAwXSA6IFt0aGlzLmNvbnZUb3RhbCB8fCAxMF07XG4gICAgICAgIHRoaXMuY29udlBlclBhZ2UgPSB0aGlzLmNvbnZQYWdpbmF0aW9uU2l6ZXMuaW5jbHVkZXModGhpcy5jb252UGVyUGFnZSkgPyB0aGlzLmNvbnZQZXJQYWdlIDogdGhpcy5jb252UGFnaW5hdGlvblNpemVzWzBdO1xuICAgICAgICAvLyBBdXRvLWV4cGFuZCBmaXJzdFxuICAgICAgICBpZiAodGhpcy5jb252ZXJzYXRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aGlzLmV4cGFuZGVkQ29udklkcyA9IHsgW3RoaXMuY29udmVyc2F0aW9uc1swXS5hdWRpb0lkXTogdHJ1ZSB9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29udkxvYWRpbmcgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmNvbnZlcnNhdGlvbnMgPSBbXTtcbiAgICAgICAgdGhpcy5jb252VG90YWwgPSAwO1xuICAgICAgICB0aGlzLmNvbnZUb3RhbFBhZ2VzID0gMTtcbiAgICAgICAgdGhpcy5jb252TG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb25Db252UGFnZUNoYW5nZShwYWdlOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnZQYWdlID0gcGFnZTtcbiAgICB0aGlzLmZldGNoQ29udmVyc2F0aW9ucygpO1xuICB9XG5cbiAgb25Db252UGFnZVNpemVDaGFuZ2Uoc2l6ZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy5jb252UGVyUGFnZSA9IHBhcnNlSW50KHNpemUpO1xuICAgIHRoaXMuY29udlBhZ2UgPSAxO1xuICAgIHRoaXMuZmV0Y2hDb252ZXJzYXRpb25zKCk7XG4gIH1cblxuICB0b2dnbGVDb252RXhwYW5kKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5leHBhbmRlZENvbnZJZHNbaWRdKSB7XG4gICAgICB0aGlzLmV4cGFuZGVkQ29udklkcyA9IHt9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmV4cGFuZGVkQ29udklkcyA9IHsgW2lkXTogdHJ1ZSB9O1xuICAgIH1cbiAgfVxuXG4gIGdldENvbnZJZChjb252OiBhbnkpOiBzdHJpbmcge1xuICAgIHJldHVybiBjb252Py5kb2NfaWQgfHwgY29udj8uYXVkaW9JZCB8fCBjb252Py5faWQgfHwgJyc7XG4gIH1cblxuICBnZXRDb252VGFiKGNvbnZJZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jb252VGFic1tjb252SWRdIHx8ICdzdW1tYXJ5JztcbiAgfVxuXG4gIHNldENvbnZUYWIoY29udklkOiBzdHJpbmcsIHRhYjogc3RyaW5nLCBldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmNvbnZUYWJzW2NvbnZJZF0gPSB0YWI7XG4gIH1cblxuICAvLyBBSSBTZWFyY2hcbiAgc2VuZENvbnZRdWVyeSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY29udlNlYXJjaFF1ZXJ5LnRyaW0oKSkgcmV0dXJuO1xuICAgIHRoaXMuY29udkFpTG9hZGluZyA9IHRydWU7XG4gICAgdGhpcy5jb252QWlSZXBseSA9ICcnO1xuXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIHVzZXJfaWQ6IHRoaXMudXNlcnM/LmVtYWlsIHx8ICd1c2VyJyxcbiAgICAgIHNlc3Npb25faWQ6IGBFQ0hPXyR7RGF0ZS5ub3coKX1gLFxuICAgICAgc2Vzc2lvbl9kYXRlOiB0aGlzLnN0YXJ0RGF0ZSxcbiAgICAgIHNlc3Npb25fdGltZXpvbmU6IEludGwuRGF0ZVRpbWVGb3JtYXQoKS5yZXNvbHZlZE9wdGlvbnMoKS50aW1lWm9uZSxcbiAgICAgIG1lc3NhZ2U6IHRoaXMuY29udlNlYXJjaFF1ZXJ5LFxuICAgICAgYW5hbHl0aWNzVHlwZTogJ3RyYW5zY3JpcHQnLFxuICAgICAgY29uZmlnOiB7XG4gICAgICAgIHNlbGVjdGVkX3N0b3JlczogdGhpcy5nZXRTdG9yZUlkcygpLFxuICAgICAgICBkYXRlX3JhbmdlOiB7IHN0YXJ0OiB0aGlzLnN0YXJ0RGF0ZSwgZW5kOiB0aGlzLmVuZERhdGUgfSxcbiAgICAgICAgc2VsZWN0ZWRfcHJvZHVjdHM6IFsnQXVkaW8nXVxuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLmF1ZGlvU2VydmljZS5jaGF0U3RyZWFtKHBheWxvYWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuY29udkFpUmVwbHkgPSB0eXBlb2YgcmVzID09PSAnc3RyaW5nJyA/IHJlcyA6IChyZXM/LmRhdGE/Lm1hcCgoZDogYW55KSA9PiBkLnRleHQpLmpvaW4oJycpIHx8ICdObyByZXNwb25zZScpO1xuICAgICAgICB0aGlzLmNvbnZBaUxvYWRpbmcgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmNvbnZBaVJlcGx5ID0gJ1VuYWJsZSB0byBwcm9jZXNzIHlvdXIgcXVlcnkuIFBsZWFzZSB0cnkgYWdhaW4uJztcbiAgICAgICAgdGhpcy5jb252QWlMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5jb252U2VhcmNoUXVlcnkgPSAnJztcbiAgfVxuXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICAvLyBBR0VOVCBBTkFMWVNJUyBUQUIgKHVzZXMgY29ob3J0IEFQSXMpXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICBsb2FkQ29ob3J0TGlzdCgpOiB2b2lkIHtcbiAgICB0aGlzLmF1ZGlvU2VydmljZS5saXN0Q29ob3J0cyh0aGlzLmNsaWVudElkLCAxMDAsIDApLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuY29ob3J0TGlzdCA9IHJlcz8uZGF0YT8uY29ob3J0cyB8fCBbXTtcbiAgICAgICAgaWYgKHRoaXMuY29ob3J0TGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkQ29ob3J0SWQpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDb2hvcnRJZCA9IHRoaXMuY29ob3J0TGlzdFswXT8uY29ob3J0SWQgfHwgdGhpcy5jb2hvcnRMaXN0WzBdPy5pZCB8fCB0aGlzLmNvaG9ydExpc3RbMF0/Ll9pZCB8fCAnJztcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5mZXRjaENvaG9ydENhcmRzKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4geyB0aGlzLmNvaG9ydExpc3QgPSBbXTsgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gQ2xpY2sgYSBjb2hvcnQgY2FyZCBmcm9tIHRoZSBvdmVydmlldyBncmlkXG4gIHNlbGVjdENvaG9ydERldGFpbChjb2hvcnQ6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRDb2hvcnRJZCA9IGNvaG9ydC5jb2hvcnRJZCB8fCBjb2hvcnQuaWQgfHwgY29ob3J0Ll9pZCB8fCAnJztcbiAgICB0aGlzLnNlbGVjdGVkQ29ob3J0TmFtZSA9IGNvaG9ydC5jb2hvcnROYW1lIHx8IGNvaG9ydC5uYW1lIHx8ICcnO1xuICAgIHRoaXMuZGV0YWlsVmlldyA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3RlZENhcmRJZCA9ICcnO1xuICAgIHRoaXMuc2VsZWN0ZWRDYXJkTmFtZSA9ICcnO1xuICAgIHRoaXMuZGV0YWlsUGFnZSA9IDE7XG4gICAgdGhpcy5mZXRjaENvaG9ydENhcmRzKCk7XG4gICAgdGhpcy5mZXRjaERldGFpbENvbnZlcnNhdGlvbnMoKTtcbiAgfVxuXG4gIC8vIENoYW5nZSBjb2hvcnQgZnJvbSBkcm9wZG93biBpbiBkZXRhaWwgdmlld1xuICBvbkNvaG9ydERyb3Bkb3duQ2hhbmdlKGNvaG9ydElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkQ29ob3J0SWQgPSBjb2hvcnRJZDtcbiAgICBjb25zdCBjb2hvcnQgPSB0aGlzLmNvaG9ydExpc3QuZmluZCgoYzogYW55KSA9PiAoYy5jb2hvcnRJZCB8fCBjLmlkIHx8IGMuX2lkKSA9PT0gY29ob3J0SWQpO1xuICAgIHRoaXMuc2VsZWN0ZWRDb2hvcnROYW1lID0gY29ob3J0Py5jb2hvcnROYW1lIHx8IGNvaG9ydD8ubmFtZSB8fCAnJztcbiAgICB0aGlzLnNlbGVjdGVkQ2FyZElkID0gJyc7XG4gICAgdGhpcy5zZWxlY3RlZENhcmROYW1lID0gJyc7XG4gICAgdGhpcy5kZXRhaWxQYWdlID0gMTtcbiAgICB0aGlzLmZldGNoQ29ob3J0Q2FyZHMoKTtcbiAgICB0aGlzLmZldGNoRGV0YWlsQ29udmVyc2F0aW9ucygpO1xuICB9XG5cbiAgZmV0Y2hDb2hvcnRDYXJkcygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2VsZWN0ZWRDb2hvcnRJZCkgcmV0dXJuO1xuICAgIHRoaXMuY2FyZHNMb2FkaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgLi4udGhpcy5idWlsZEJhc2VQYXlsb2FkKCksXG4gICAgICBjb2hvcnRUeXBlOiBbdGhpcy5zZWxlY3RlZENvaG9ydElkXVxuICAgIH07XG5cbiAgICB0aGlzLmF1ZGlvU2VydmljZS5nZXRDb2hvcnRBbmFseXNpc0NhcmQocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5jb2hvcnRDYXJkcyA9IHRoaXMucGFyc2VDb2hvcnRBbmFseXNpcyhyZXM/LmRhdGE/LmNvaG9ydEFuYWx5c2lzIHx8IHt9KTtcbiAgICAgICAgdGhpcy5jYXJkc0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmNvaG9ydENhcmRzID0gW107XG4gICAgICAgIHRoaXMuY2FyZHNMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBQYXJzZSBjb2hvcnQgYW5hbHlzaXMgKHNhbWUgYXMgYXVkaW8tcGFnZSlcbiAgcGFyc2VDb2hvcnRBbmFseXNpcyhhbmFseXNpczogYW55KTogYW55W10ge1xuICAgIGNvbnN0IGNhcmRzOiBhbnlbXSA9IFtdO1xuICAgIGNvbnN0IHNraXBLZXlzID0gbmV3IFNldChbJ3RvdGFsQXVkaW9BdmFpbGFibGUnLCAnY29ob3J0VHlwZScsICdkYXRlUmFuZ2UnLCAndW5pcXVlUGl0Y2hlcyddKTtcbiAgICB0aGlzLnRvdGFsQXVkaW8gPSBhbmFseXNpcy50b3RhbEF1ZGlvQXZhaWxhYmxlIHx8IDA7XG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhhbmFseXNpcykpIHtcbiAgICAgIGlmIChza2lwS2V5cy5oYXMoa2V5KSkgY29udGludWU7XG4gICAgICBjb25zdCBzZWN0aW9uID0gYW5hbHlzaXNba2V5XTtcbiAgICAgIGlmICghc2VjdGlvbiB8fCB0eXBlb2Ygc2VjdGlvbiAhPT0gJ29iamVjdCcpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCB2YWx1ZXM6IGFueVtdID0gc2VjdGlvbi52YWx1ZSB8fCBbXTtcbiAgICAgIGNvbnN0IHR5cGUgPSBzZWN0aW9uLnR5cGU7XG4gICAgICBpZiAoIXZhbHVlcy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgICBpZiAodHlwZSA9PT0gJ0JPT0xFQU5fQkFTS0VUJykge1xuICAgICAgICBjYXJkcy5wdXNoKHtcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgbmFtZTogc2VjdGlvbi5uYW1lIHx8IGtleSxcbiAgICAgICAgICB0eXBlOiAnQk9PTEVBTl9CQVNLRVQnLFxuICAgICAgICAgIGJvb2xlYW5Sb3dzOiB2YWx1ZXMubWFwKChpdGVtOiBhbnkpID0+ICh7XG4gICAgICAgICAgICBpZDogaXRlbS5faWQgfHwgJycsXG4gICAgICAgICAgICBsYWJlbDogaXRlbS5uYW1lLFxuICAgICAgICAgICAgcmVzcG9uc2VzOiBpdGVtLlJlc3BvbnNlcyA/PyBpdGVtLmNvdW50ID8/IDAsXG4gICAgICAgICAgICBzY29yZTogaXRlbS5zY29yZSA/PyAwXG4gICAgICAgICAgfSkpXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnTlVNRVJJQ19TQ0FMQVInIHx8IHR5cGUgPT09ICdOVU1FUklDX0FSUkFZJykge1xuICAgICAgICBjb25zdCBpdGVtID0gdmFsdWVzWzBdIHx8IHt9O1xuICAgICAgICBjYXJkcy5wdXNoKHtcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgbmFtZTogc2VjdGlvbi5uYW1lIHx8IGtleSxcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIG51bWVyaWNEYXRhOiB7IHRvdGFsOiBpdGVtLlRvdGFsID8/IDAsIGF2ZzogaXRlbS5BdmcgPz8gMCB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnU1VCSkVDVElWRScgfHwgdHlwZSA9PT0gJ1NVQkpFQ1RJVkVfQ09VTlQnKSB7XG4gICAgICAgIGNhcmRzLnB1c2goe1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICBuYW1lOiBzZWN0aW9uLm5hbWUgfHwga2V5LFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgc3ViamVjdGl2ZVJvd3M6IHZhbHVlcy5tYXAoKGl0ZW06IGFueSkgPT4gKHtcbiAgICAgICAgICAgIF9pZDogaXRlbS5faWQgfHwgJycsXG4gICAgICAgICAgICByZWFzb25pbmc6IGl0ZW0ucmVhc29uaW5nIHx8ICcnLFxuICAgICAgICAgICAgc3RvcmVfaWQ6IGl0ZW0uc3RvcmVfaWQgfHwgJycsXG4gICAgICAgICAgICBkYXRlOiBpdGVtLmRhdGUgfHwgJydcbiAgICAgICAgICB9KSlcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjYXJkcztcbiAgfVxuXG4gIC8vIENhcmQgcm93IGNsaWNrIChzYW1lIGFzIGF1ZGlvLXBhZ2Ugb25DYXJkUm93Q2xpY2spXG4gIHNlbGVjdGVkQ2FyZElkID0gJyc7XG4gIHNlbGVjdGVkQ2FyZE5hbWUgPSAnJztcbiAgdG90YWxBdWRpbyA9IDA7XG5cbiAgb25DYXJkUm93Q2xpY2soaWQ6IGFueSwgbmFtZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZENhcmRJZCA9IGlkIHx8ICcnO1xuICAgIHRoaXMuc2VsZWN0ZWRDYXJkTmFtZSA9IGlkID8gJycgOiAobmFtZSB8fCAnJyk7XG4gICAgdGhpcy5kZXRhaWxWaWV3ID0gdHJ1ZTtcbiAgICB0aGlzLmRldGFpbFBhZ2UgPSAxO1xuICAgIHRoaXMuZmV0Y2hEZXRhaWxDb252ZXJzYXRpb25zKCk7XG4gIH1cblxuICBiYWNrVG9DYXJkcygpOiB2b2lkIHtcbiAgICB0aGlzLmRldGFpbFZpZXcgPSBmYWxzZTtcbiAgICB0aGlzLnNlbGVjdGVkQ2FyZElkID0gJyc7XG4gICAgdGhpcy5zZWxlY3RlZENhcmROYW1lID0gJyc7XG4gIH1cblxuICBmZXRjaERldGFpbENvbnZlcnNhdGlvbnMoKTogdm9pZCB7XG4gICAgdGhpcy5kZXRhaWxMb2FkaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgLi4udGhpcy5idWlsZEJhc2VQYXlsb2FkKCksXG4gICAgICBjb2hvcnRUeXBlOiBbdGhpcy5zZWxlY3RlZENvaG9ydElkXSxcbiAgICAgIGxpbWl0OiB0aGlzLmRldGFpbFBlclBhZ2UsXG4gICAgICBfaWQ6IHRoaXMuc2VsZWN0ZWRDYXJkSWQgPyBbdGhpcy5zZWxlY3RlZENhcmRJZF0gOiBbXSxcbiAgICAgIG5hbWU6IHRoaXMuc2VsZWN0ZWRDYXJkTmFtZSxcbiAgICAgIG9mZnNldDogdGhpcy5kZXRhaWxQYWdlIC0gMVxuICAgIH07XG5cbiAgICB0aGlzLmF1ZGlvU2VydmljZS5nZXRDb252ZXJzYXRpb25zTGlzdChwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCBkYXRhID0gcmVzPy5kYXRhO1xuICAgICAgICBjb25zdCBsaXN0ID0gZGF0YT8uZGF0YSB8fCBkYXRhPy5jb252ZXJzYXRpb25zIHx8IFtdO1xuICAgICAgICB0aGlzLmRldGFpbENvbnZlcnNhdGlvbnMgPSBsaXN0Lm1hcCgoaXRlbTogYW55KSA9PiB0aGlzLm1hcENvbnZlcnNhdGlvbihpdGVtKSk7XG4gICAgICAgIHRoaXMuZGV0YWlsVG90YWwgPSBkYXRhPy5jb3VudCA/PyBkYXRhPy5wYWdpbmF0aW9uPy50b3RhbCA/PyB0aGlzLmRldGFpbENvbnZlcnNhdGlvbnMubGVuZ3RoO1xuICAgICAgICB0aGlzLmRldGFpbFRvdGFsUGFnZXMgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodGhpcy5kZXRhaWxUb3RhbCAvIHRoaXMuZGV0YWlsUGVyUGFnZSkpO1xuICAgICAgICB0aGlzLmRldGFpbFBhZ2luYXRpb25TaXplcyA9IHRoaXMuZGV0YWlsVG90YWwgPiAxMCA/IFsxMCwgMjAsIDUwLCAxMDBdIDogW3RoaXMuZGV0YWlsVG90YWwgfHwgMTBdO1xuICAgICAgICB0aGlzLmRldGFpbFBlclBhZ2UgPSB0aGlzLmRldGFpbFBhZ2luYXRpb25TaXplcy5pbmNsdWRlcyh0aGlzLmRldGFpbFBlclBhZ2UpID8gdGhpcy5kZXRhaWxQZXJQYWdlIDogdGhpcy5kZXRhaWxQYWdpbmF0aW9uU2l6ZXNbMF07XG4gICAgICAgIHRoaXMuZGV0YWlsUGFnZUNvbnZzID0gdGhpcy5kZXRhaWxDb252ZXJzYXRpb25zO1xuICAgICAgICBpZiAodGhpcy5kZXRhaWxQYWdlQ29udnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMuZGV0YWlsT3BlbklkID0gdGhpcy5kZXRhaWxQYWdlQ29udnNbMF0uYXVkaW9JZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRldGFpbExvYWRpbmcgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLmRldGFpbENvbnZlcnNhdGlvbnMgPSBbXTtcbiAgICAgICAgdGhpcy5kZXRhaWxQYWdlQ29udnMgPSBbXTtcbiAgICAgICAgdGhpcy5kZXRhaWxUb3RhbFBhZ2VzID0gMTtcbiAgICAgICAgdGhpcy5kZXRhaWxMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBsb2FkQ29udmVyc2F0aW9uRGV0YWlsKGNvbnY6IGFueSk6IHZvaWQge1xuICAgIGNvbnN0IGF1ZGlvSWQgPSBjb252Py5kb2NfaWQgfHwgY29udj8uYXVkaW9JZCB8fCBjb252Py5faWQ7XG4gICAgaWYgKCFhdWRpb0lkKSByZXR1cm47XG5cbiAgICB0aGlzLmF1ZGlvU2VydmljZS5nZXRDb252ZXJzYXRpb25EZXRhaWwoYXVkaW9JZCwge1xuICAgICAgY29ob3J0SWQ6IFt0aGlzLnNlbGVjdGVkQ29ob3J0SWRdLFxuICAgICAgY2xpZW50SWQ6IHRoaXMuY2xpZW50SWRcbiAgICB9KS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLmRldGFpbENvbnZEZXRhaWwgPSByZXM/LmRhdGEgfHwgcmVzO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7IHRoaXMuZGV0YWlsQ29udkRldGFpbCA9IG51bGw7IH1cbiAgICB9KTtcbiAgfVxuXG4gIHRvZ2dsZURldGFpbENvbnYoaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZGV0YWlsT3BlbklkID0gdGhpcy5kZXRhaWxPcGVuSWQgPT09IGlkID8gbnVsbCA6IGlkO1xuICB9XG5cbiAgb25EZXRhaWxQYWdlQ2hhbmdlKHBhZ2U6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZGV0YWlsUGFnZSA9IHBhZ2U7XG4gICAgdGhpcy5mZXRjaERldGFpbENvbnZlcnNhdGlvbnMoKTtcbiAgfVxuXG4gIG9uRGV0YWlsUGFnZVNpemVDaGFuZ2Uoc2l6ZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy5kZXRhaWxQZXJQYWdlID0gcGFyc2VJbnQoc2l6ZSk7XG4gICAgdGhpcy5kZXRhaWxQYWdlID0gMTtcbiAgICB0aGlzLmZldGNoRGV0YWlsQ29udmVyc2F0aW9ucygpO1xuICB9XG5cbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIC8vIE1BTkFHRSBUQUIgKHVzZXMgbGlzdENvaG9ydHMvZGVsZXRlQ29ob3J0IEFQSXMpXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICBsb2FkTWFuYWdlQ29ob3J0cygpOiB2b2lkIHtcbiAgICB0aGlzLm1hbmFnZUxvYWRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IG9mZnNldCA9ICh0aGlzLm1hbmFnZVBhZ2UgLSAxKSAqIHRoaXMubWFuYWdlUGVyUGFnZTtcblxuICAgIHRoaXMuYXVkaW9TZXJ2aWNlLmxpc3RDb2hvcnRzKHRoaXMuY2xpZW50SWQsIHRoaXMubWFuYWdlUGVyUGFnZSwgb2Zmc2V0KS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLm1hbmFnZUNvaG9ydHMgPSByZXM/LmRhdGE/LmNvaG9ydHMgfHwgW107XG4gICAgICAgIHRoaXMubWFuYWdlVG90YWwgPSByZXM/LmRhdGE/LnBhZ2luYXRpb24/LnRvdGFsID8/IHRoaXMubWFuYWdlQ29ob3J0cy5sZW5ndGg7XG4gICAgICAgIHRoaXMubWFuYWdlVG90YWxQYWdlcyA9IE1hdGgubWF4KDEsIE1hdGguY2VpbCh0aGlzLm1hbmFnZVRvdGFsIC8gdGhpcy5tYW5hZ2VQZXJQYWdlKSk7XG4gICAgICAgIHRoaXMubWFuYWdlTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgIHRoaXMubWFuYWdlQ29ob3J0cyA9IFtdO1xuICAgICAgICB0aGlzLm1hbmFnZVRvdGFsID0gMDtcbiAgICAgICAgdGhpcy5tYW5hZ2VUb3RhbFBhZ2VzID0gMTtcbiAgICAgICAgdGhpcy5tYW5hZ2VMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbk1hbmFnZVBhZ2VDaGFuZ2UocGFnZTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5tYW5hZ2VQYWdlID0gcGFnZTtcbiAgICB0aGlzLmxvYWRNYW5hZ2VDb2hvcnRzKCk7XG4gIH1cblxuICBvbk1hbmFnZVBhZ2VTaXplQ2hhbmdlKHNpemU6IGFueSk6IHZvaWQge1xuICAgIHRoaXMubWFuYWdlUGVyUGFnZSA9IHBhcnNlSW50KHNpemUpO1xuICAgIHRoaXMubWFuYWdlUGFnZSA9IDE7XG4gICAgdGhpcy5sb2FkTWFuYWdlQ29ob3J0cygpO1xuICB9XG5cbiAgb25NYW5hZ2VTZWFyY2goKTogdm9pZCB7XG4gICAgdGhpcy5tYW5hZ2VQYWdlID0gMTtcbiAgICB0aGlzLmxvYWRNYW5hZ2VDb2hvcnRzKCk7XG4gIH1cblxuICBkZWxldGVDb2hvcnQoY29ob3J0SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghY29uZmlybSgnQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSB0aGlzIGNvaG9ydD8nKSkgcmV0dXJuO1xuICAgIHRoaXMuYXVkaW9TZXJ2aWNlLmRlbGV0ZUNvaG9ydChjb2hvcnRJZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoKSA9PiB7IHRoaXMubG9hZE1hbmFnZUNvaG9ydHMoKTsgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7IGFsZXJ0KCdGYWlsZWQgdG8gZGVsZXRlIGNvaG9ydC4nKTsgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIC8vIEFVRElPIFBMQVlFUiAoc2FtZSBwYXR0ZXJuIGFzIHRyYW5zY3JpcHQtbGlzdClcbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIHBsYXliYWNrU3RhdGVzOiB7IFtpZDogc3RyaW5nXTogeyBjdXJyZW50VGltZTogc3RyaW5nOyB0b3RhbFRpbWU6IHN0cmluZzsgcHJvZ3Jlc3M6IG51bWJlciB9IH0gPSB7fTtcbiAgaXNNdXRlZCA9IGZhbHNlO1xuXG4gIHRvZ2dsZVBsYXkoY29udklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBhdWRpbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBhdWRpby0ke2NvbnZJZH1gKSBhcyBIVE1MQXVkaW9FbGVtZW50O1xuICAgIGlmICghYXVkaW8pIHJldHVybjtcbiAgICBpZiAodGhpcy5wbGF5aW5nQ29udklkID09PSBjb252SWQpIHtcbiAgICAgIGF1ZGlvLnBhdXNlKCk7XG4gICAgICB0aGlzLnBsYXlpbmdDb252SWQgPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBQYXVzZSBhbnkgY3VycmVudGx5IHBsYXlpbmdcbiAgICAgIGlmICh0aGlzLnBsYXlpbmdDb252SWQpIHtcbiAgICAgICAgY29uc3Qgb3RoZXIgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgYXVkaW8tJHt0aGlzLnBsYXlpbmdDb252SWR9YCkgYXMgSFRNTEF1ZGlvRWxlbWVudDtcbiAgICAgICAgaWYgKG90aGVyKSBvdGhlci5wYXVzZSgpO1xuICAgICAgICB0aGlzLnBsYXlpbmdDb252SWQgPSBudWxsO1xuICAgICAgfVxuICAgICAgY29uc3QgcGxheVByb21pc2UgPSBhdWRpby5wbGF5KCk7XG4gICAgICBpZiAocGxheVByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBwbGF5UHJvbWlzZS50aGVuKCgpID0+IHsgdGhpcy5wbGF5aW5nQ29udklkID0gY29udklkOyB9KS5jYXRjaCgoKSA9PiB7IHRoaXMucGxheWluZ0NvbnZJZCA9IG51bGw7IH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5wbGF5aW5nQ29udklkID0gY29udklkO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG9uTG9hZGVkTWV0YWRhdGEoYXVkaW86IEhUTUxBdWRpb0VsZW1lbnQsIGNvbnZJZDogc3RyaW5nLCBhcGlEdXJhdGlvbj86IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wbGF5YmFja1N0YXRlc1tjb252SWRdKSB7XG4gICAgICB0aGlzLnBsYXliYWNrU3RhdGVzW2NvbnZJZF0gPSB7IGN1cnJlbnRUaW1lOiAnMDowMCcsIHRvdGFsVGltZTogJzA6MDAnLCBwcm9ncmVzczogMCB9O1xuICAgIH1cbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMucGxheWJhY2tTdGF0ZXNbY29udklkXTtcbiAgICBpZiAoaXNGaW5pdGUoYXVkaW8uZHVyYXRpb24pICYmIGF1ZGlvLmR1cmF0aW9uID4gMCkge1xuICAgICAgc3RhdGUudG90YWxUaW1lID0gdGhpcy5mb3JtYXRBdWRpb1RpbWUoYXVkaW8uZHVyYXRpb24pO1xuICAgIH0gZWxzZSBpZiAoYXBpRHVyYXRpb24pIHtcbiAgICAgIHN0YXRlLnRvdGFsVGltZSA9IGFwaUR1cmF0aW9uO1xuICAgIH1cbiAgfVxuXG4gIG9uVGltZVVwZGF0ZShhdWRpbzogSFRNTEF1ZGlvRWxlbWVudCwgY29udklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucGxheWJhY2tTdGF0ZXNbY29udklkXSkge1xuICAgICAgdGhpcy5wbGF5YmFja1N0YXRlc1tjb252SWRdID0geyBjdXJyZW50VGltZTogJzA6MDAnLCB0b3RhbFRpbWU6ICcwOjAwJywgcHJvZ3Jlc3M6IDAgfTtcbiAgICB9XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLnBsYXliYWNrU3RhdGVzW2NvbnZJZF07XG4gICAgc3RhdGUuY3VycmVudFRpbWUgPSB0aGlzLmZvcm1hdEF1ZGlvVGltZShhdWRpby5jdXJyZW50VGltZSk7XG4gICAgaWYgKGlzRmluaXRlKGF1ZGlvLmR1cmF0aW9uKSAmJiBhdWRpby5kdXJhdGlvbiA+IDApIHtcbiAgICAgIHN0YXRlLnByb2dyZXNzID0gYXVkaW8uY3VycmVudFRpbWUgLyBhdWRpby5kdXJhdGlvbjtcbiAgICB9XG4gIH1cblxuICBzZWVrQXVkaW8oZXZlbnQ6IE1vdXNlRXZlbnQsIGNvbnZJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdHJhY2sgPSBldmVudC5jdXJyZW50VGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGNvbnN0IHJhdGlvID0gZXZlbnQub2Zmc2V0WCAvIHRyYWNrLm9mZnNldFdpZHRoO1xuICAgIGNvbnN0IGF1ZGlvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYGF1ZGlvLSR7Y29udklkfWApIGFzIEhUTUxBdWRpb0VsZW1lbnQ7XG4gICAgaWYgKCFhdWRpbyB8fCAhYXVkaW8uZHVyYXRpb24pIHJldHVybjtcbiAgICBhdWRpby5jdXJyZW50VGltZSA9IHJhdGlvICogYXVkaW8uZHVyYXRpb247XG4gIH1cblxuICB0b2dnbGVNdXRlKCk6IHZvaWQge1xuICAgIHRoaXMuaXNNdXRlZCA9ICF0aGlzLmlzTXV0ZWQ7XG4gICAgY29uc3QgYXVkaW9zID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnYXVkaW8nKTtcbiAgICBhdWRpb3MuZm9yRWFjaChhID0+IGEubXV0ZWQgPSB0aGlzLmlzTXV0ZWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRBdWRpb1RpbWUoc2Vjb25kczogbnVtYmVyKTogc3RyaW5nIHtcbiAgICBpZiAoIXNlY29uZHMpIHJldHVybiAnMDowMCc7XG4gICAgY29uc3QgbWlucyA9IE1hdGguZmxvb3Ioc2Vjb25kcyAvIDYwKTtcbiAgICBjb25zdCBzZWNzID0gTWF0aC5mbG9vcihzZWNvbmRzICUgNjApO1xuICAgIHJldHVybiBgJHttaW5zfToke3NlY3MgPCAxMCA/ICcwJyArIHNlY3MgOiBzZWNzfWA7XG4gIH1cblxuICAvLyDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZBcbiAgLy8gRklMVEVSUyBEUkFXRVJcbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIG9wZW5GaWx0ZXJEcmF3ZXIoKTogdm9pZCB7IHRoaXMuZHJhd2VyT3BlbiA9IHRydWU7IH1cbiAgY2xvc2VGaWx0ZXJEcmF3ZXIoKTogdm9pZCB7IHRoaXMuZHJhd2VyT3BlbiA9IGZhbHNlOyB9XG5cbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIC8vIFVUSUxJVFlcbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIHRyYWNrQnlJZChpbmRleDogbnVtYmVyLCBpdGVtOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiBpdGVtPy5pZCB8fCBpdGVtPy5faWQgfHwgaXRlbT8uZG9jX2lkIHx8IGluZGV4O1xuICB9XG5cbiAgTWF0aCA9IE1hdGg7XG59XG4iLCI8ZGl2IGNsYXNzPVwiZWNoby1wYWdlXCI+XG4gIDxkaXYgY2xhc3M9XCJlY2hvLWNvbnRlbnRcIj5cblxuICAgIDwhLS0g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIENPTlZFUlNBVElPTlMgVEFCIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAtLT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY3VycmVudFBhZ2UgPT09ICdjb252ZXJzYXRpb25zJ1wiPlxuXG4gICAgICA8IS0tIFRhbmdvIEFJIEhlYWRlciAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0YW5nby1haS1oZWFkZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRhbmdvLWFpLWxvZ29cIj5cbiAgICAgICAgICA8c3ZnIHdpZHRoPVwiMjZcIiBoZWlnaHQ9XCIyNlwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiNmZmZcIiBzdHJva2Utd2lkdGg9XCIxLjhcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCI+PHBhdGggZD1cIk0xMiAybDIuMDkgNi4yNkwyMCAxMGwtNS45MSAxLjc0TDEyIDE4bC0yLjA5LTYuMjZMNCAxMGw1LjkxLTEuNzRMMTIgMnpcIi8+PC9zdmc+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXI7XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRhbmdvLWFpLXRpdGxlXCI+VGFuZ28gQUk8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFuZ28tYWktc3VidGl0bGVcIj5BbmFseXNlIGNvbnZlcnNhdGlvbnMsIHN0b3JlcyAmIHN0YWZmIHBlcmZvcm1hbmNlPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU2VhcmNoIENhcmQgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZWNoby1zZWFyY2gtY2FyZFwiPlxuICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImVjaG8tc2VhcmNoLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJBc2sgYW55dGhpbmcuLi4gJ1doaWNoIHN0b3JlcyBhcmUgbm90IHBlcmZvcm1pbmcgd2VsbD8nXCIgWyhuZ01vZGVsKV09XCJjb252U2VhcmNoUXVlcnlcIiAoa2V5dXAuZW50ZXIpPVwic2VuZENvbnZRdWVyeSgpXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJlY2hvLXNlYXJjaC1zZW5kXCIgKGNsaWNrKT1cInNlbmRDb252UXVlcnkoKVwiIFtkaXNhYmxlZF09XCIhY29udlNlYXJjaFF1ZXJ5Py50cmltKClcIj5cbiAgICAgICAgICA8c3ZnIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj5cbiAgICAgICAgICAgIDxsaW5lIHgxPVwiMjJcIiB5MT1cIjJcIiB4Mj1cIjExXCIgeTI9XCIxM1wiPjwvbGluZT5cbiAgICAgICAgICAgIDxwb2x5Z29uIHBvaW50cz1cIjIyIDIgMTUgMjIgMTEgMTMgMiA5IDIyIDJcIj48L3BvbHlnb24+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQUkgUmVzcG9uc2UgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZWNoby1haS1yZXNwb25zZVwiICpuZ0lmPVwiY29udkFpTG9hZGluZyB8fCBjb252QWlSZXBseVwiPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udkFpTG9hZGluZ1wiIGNsYXNzPVwidHlwaW5nXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0eXBpbmctZG90XCI+PC9zcGFuPjxzcGFuIGNsYXNzPVwidHlwaW5nLWRvdFwiPjwvc3Bhbj48c3BhbiBjbGFzcz1cInR5cGluZy1kb3RcIj48L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cCAqbmdJZj1cIiFjb252QWlMb2FkaW5nICYmIGNvbnZBaVJlcGx5XCIgY2xhc3M9XCJlY2hvLWFpLXRleHRcIj57eyBjb252QWlSZXBseSB9fTwvcD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRvdGFsIGNvdW50IC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImVjaG8tY29udi1jb3VudFwiPnt7IGNvbnZUb3RhbCB9fSBDb252ZXJzYXRpb25zPC9kaXY+XG5cbiAgICAgIDwhLS0gQ29udmVyc2F0aW9ucyBsaXN0IGFyZWEgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29udmVyc2F0aW9ucy1zZWN0aW9uXCI+XG5cbiAgICAgIDwhLS0gTG9hZGluZyAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJjb252TG9hZGluZ1wiIHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZzo0MHB4O2NvbG9yOiM5NEEzQjg7XCI+TG9hZGluZyBjb252ZXJzYXRpb25zLi4uPC9kaXY+XG5cbiAgICAgIDwhLS0gQ29udmVyc2F0aW9uIGNhcmRzIChkeW5hbWljIGZyb20gQVBJIOKAlCBzYW1lIHBhdHRlcm4gYXMgdHJhbnNjcmlwdC1saXN0KSAtLT5cbiAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGNvbnYgb2YgY29udmVyc2F0aW9uczsgdHJhY2tCeTogdHJhY2tCeUlkXCIgY2xhc3M9XCJjb252LWNhcmRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnYtaGVhZGVyXCIgKGNsaWNrKT1cInRvZ2dsZUNvbnZFeHBhbmQoY29udi5hdWRpb0lkKVwiPlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJmbGV4OjE7bWluLXdpZHRoOjA7XCI+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTpmbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6NnB4O2ZsZXgtd3JhcDp3cmFwO21hcmdpbi1ib3R0b206NHB4O1wiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbnYtaWRcIj57eyBjb252LmF1ZGlvSWQgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWV0YS10YWcgYnJhbmRcIiAqbmdJZj1cImNvbnYuc3RvcmVOYW1lXCI+e3sgY29udi5zdG9yZU5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWV0YS10YWdcIiAqbmdJZj1cImNvbnYubG9jYXRpb25cIj57eyBjb252LmxvY2F0aW9uIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldGEtdGFnXCIgKm5nSWY9XCJjb252LnVzZXJOYW1lXCI+e3sgY29udi51c2VyTmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRhLXRhZ1wiICpuZ0lmPVwiY29udi5kYXRlXCI+e3sgY29udi5kYXRlIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldGEtdGFnXCIgKm5nSWY9XCJjb252LmR1cmF0aW9uXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOiNFREU5RkU7Y29sb3I6IzhCNUNGNjtib3JkZXItY29sb3I6I0RERDZGRTtmb250LXdlaWdodDo3MDA7XCI+e3sgY29udi5kdXJhdGlvbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZToxMi41cHg7Y29sb3I6Izk0QTNCODt3aGl0ZS1zcGFjZTpub3dyYXA7b3ZlcmZsb3c6aGlkZGVuO3RleHQtb3ZlcmZsb3c6ZWxsaXBzaXM7XCI+XG4gICAgICAgICAgICAgIHt7IGNvbnYuYXVkaW9EZXNjcmlwdGlvbiB8fCAnTm8gZGVzY3JpcHRpb24gYXZhaWxhYmxlJyB9fVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnYtY2hldnJvblwiIFtjbGFzcy5vcGVuXT1cImV4cGFuZGVkQ29udklkc1tjb252LmF1ZGlvSWRdXCI+XG4gICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiM5NEEzQjhcIiBzdHJva2Utd2lkdGg9XCIyLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCI+PHBhdGggZD1cIk02IDlsNiA2IDYtNlwiLz48L3N2Zz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBFeHBhbmRlZCBib2R5ICh1bmlmaWVkIGxheW91dCBtYXRjaGluZyBBZ2VudCBBbmFseXNpcyBkZXNpZ24pIC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiZXhwYW5kZWRDb252SWRzW2NvbnYuYXVkaW9JZF1cIiBjbGFzcz1cImNvbnYtYm9keS1leHBhbmRlZFwiPlxuXG4gICAgICAgICAgPCEtLSBXYXZlZm9ybSBwbGF5ZXIgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImVjaG8tcGxheWVyXCIgKm5nSWY9XCJjb252LmF1ZGlvVXJsXCI+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiZWNoby1wbGF5LWJ0blwiIChjbGljayk9XCJ0b2dnbGVQbGF5KGNvbnYuYXVkaW9JZClcIj5cbiAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cInBsYXlpbmdDb252SWQgIT09IGNvbnYuYXVkaW9JZFwiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwid2hpdGVcIj48cGF0aCBkPVwiTTggNXYxNGwxMS03elwiLz48L3N2Zz5cbiAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cInBsYXlpbmdDb252SWQgPT09IGNvbnYuYXVkaW9JZFwiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwid2hpdGVcIj48cGF0aCBkPVwiTTYgMTloNFY1SDZ2MTR6bTgtMTR2MTRoNFY1aC00elwiLz48L3N2Zz5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVjaG8td2F2ZWZvcm1cIiAoY2xpY2spPVwic2Vla0F1ZGlvKCRldmVudCwgY29udi5hdWRpb0lkKVwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZWNoby13Zi1iYXJcIiAqbmdGb3I9XCJsZXQgaCBvZiB3YXZlZm9ybUhlaWdodHM7IGxldCBpID0gaW5kZXhcIiBbc3R5bGUuaGVpZ2h0LnB4XT1cImhcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5wbGF5ZWRdPVwiKHBsYXliYWNrU3RhdGVzW2NvbnYuYXVkaW9JZF0/LnByb2dyZXNzIHx8IDApID4gaSAvIHdhdmVmb3JtSGVpZ2h0cy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZWNoby10aW1lXCI+e3sgcGxheWJhY2tTdGF0ZXNbY29udi5hdWRpb0lkXT8udG90YWxUaW1lIHx8IGNvbnYuZHVyYXRpb24gfHwgJy0tJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxhdWRpbyBbaWRdPVwiJ2F1ZGlvLScgKyBjb252LmF1ZGlvSWRcIiBbc3JjXT1cImNvbnYuYXVkaW9VcmxcIiBwcmVsb2FkPVwibWV0YWRhdGFcIlxuICAgICAgICAgICAgICAodGltZXVwZGF0ZSk9XCJvblRpbWVVcGRhdGUoYXVkaW9FbCwgY29udi5hdWRpb0lkKVwiXG4gICAgICAgICAgICAgIChsb2FkZWRtZXRhZGF0YSk9XCJvbkxvYWRlZE1ldGFkYXRhKGF1ZGlvRWwsIGNvbnYuYXVkaW9JZCwgY29udi5kdXJhdGlvbilcIlxuICAgICAgICAgICAgICAoZW5kZWQpPVwicGxheWluZ0NvbnZJZCA9IG51bGxcIiAjYXVkaW9FbD48L2F1ZGlvPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBUYWJzIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb252LXRhYnNcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjb252LXRhYi1idG5cIiBbY2xhc3MuYWN0aXZlXT1cImdldENvbnZUYWIoY29udi5hdWRpb0lkKSA9PT0gJ3N1bW1hcnknXCIgKGNsaWNrKT1cInNldENvbnZUYWIoY29udi5hdWRpb0lkLCAnc3VtbWFyeScsICRldmVudClcIj5TdW1tYXJ5PC9idXR0b24+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY29udi10YWItYnRuXCIgW2NsYXNzLmFjdGl2ZV09XCJnZXRDb252VGFiKGNvbnYuYXVkaW9JZCkgPT09ICd0cmFuc2NyaXB0J1wiIChjbGljayk9XCJzZXRDb252VGFiKGNvbnYuYXVkaW9JZCwgJ3RyYW5zY3JpcHQnLCAkZXZlbnQpXCI+VHJhbnNjcmlwdDwvYnV0dG9uPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImNvbnYtdGFiLWJ0blwiIFtjbGFzcy5hY3RpdmVdPVwiZ2V0Q29udlRhYihjb252LmF1ZGlvSWQpID09PSAnaW50ZXJhY3Rpb24nXCIgKGNsaWNrKT1cInNldENvbnZUYWIoY29udi5hdWRpb0lkLCAnaW50ZXJhY3Rpb24nLCAkZXZlbnQpXCI+SW50ZXJhY3Rpb24gUXVhbGl0eTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBDb250ZW50OiBMZWZ0IChTdW1tYXJ5L1RyYW5zY3JpcHQvSW50ZXJhY3Rpb24gKyBBSSBJbnNpZ2h0cykgKyBSaWdodCAoTWV0cmljcykgLS0+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6ZmxleDtcIj5cbiAgICAgICAgICAgIDwhLS0gTGVmdCBzaWRlIC0tPlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZsZXg6MTtwYWRkaW5nOjE0cHggMTZweDttaW4td2lkdGg6MDtib3JkZXItcmlnaHQ6MXB4IHNvbGlkICNlOGVkZjM7XCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb252VGFiKGNvbnYuYXVkaW9JZCkgPT09ICdzdW1tYXJ5J1wiPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwic3VtbWFyeS10ZXh0XCI+e3sgY29udi5hdWRpb0Rlc2NyaXB0aW9uIHx8IGNvbnYuY29udmVyc2F0aW9uRGV0YWlscz8uYXVkaW9TdW1tYXJ5IHx8ICdObyBzdW1tYXJ5IGF2YWlsYWJsZScgfX08L3A+XG4gICAgICAgICAgICAgICAgPCEtLSBBSSBJbnNpZ2h0cyAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udi5haUluc2lnaHRzPy5zdW1tYXJ5Py5sZW5ndGhcIiBzdHlsZT1cIm1hcmdpbi10b3A6MTZweDtcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6MTFweDtmb250LXdlaWdodDo3MDA7Y29sb3I6IzY2NzA4NTtsZXR0ZXItc3BhY2luZzouNXB4O3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTttYXJnaW4tYm90dG9tOjEwcHg7XCI+QUkgSW5zaWdodHM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGluc2lnaHQgb2YgY29udi5haUluc2lnaHRzLnN1bW1hcnlcIiBzdHlsZT1cImRpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpmbGV4LXN0YXJ0O2dhcDo4cHg7bWFyZ2luLWJvdHRvbTo4cHg7XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJ3aWR0aDo2cHg7aGVpZ2h0OjZweDtib3JkZXItcmFkaXVzOjUwJTttYXJnaW4tdG9wOjVweDtmbGV4LXNocmluazowO1wiIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImluc2lnaHQudHlwZSA9PT0gJ3Bvc2l0aXZlJyA/ICcjMDBBM0ZGJyA6IGluc2lnaHQudHlwZSA9PT0gJ25lZ2F0aXZlJyA/ICcjRUY0NDQ0JyA6ICcjRjU5RTBCJ1wiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxM3B4O2NvbG9yOiM0NzU0Njc7bGluZS1oZWlnaHQ6MS41O1wiPnt7IGluc2lnaHQudGV4dCB8fCBpbnNpZ2h0IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29udlRhYihjb252LmF1ZGlvSWQpID09PSAndHJhbnNjcmlwdCdcIj5cbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInN1bW1hcnktdGV4dFwiIHN0eWxlPVwid2hpdGUtc3BhY2U6cHJlLXdyYXA7XCI+e3sgY29udi5jb252ZXJzYXRpb25EZXRhaWxzPy50cmFuc2NyaXB0aW9uIHx8ICdObyB0cmFuc2NyaXB0IGF2YWlsYWJsZScgfX08L3A+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29udlRhYihjb252LmF1ZGlvSWQpID09PSAnaW50ZXJhY3Rpb24nXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cInBhZGRpbmc6OHB4IDA7XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOjExcHg7Zm9udC13ZWlnaHQ6NzAwO2NvbG9yOiM2NjcwODU7bGV0dGVyLXNwYWNpbmc6LjVweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7bWFyZ2luLWJvdHRvbToxMnB4O1wiPkludGVyYWN0aW9uIFF1YWxpdHk8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb252Lm1ldHJpY3M/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtIG9mIGNvbnYubWV0cmljc1wiIHN0eWxlPVwibWFyZ2luLWJvdHRvbToxMnB4O1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6MTNweDtmb250LXdlaWdodDo2MDA7Y29sb3I6IzM0NDA1NDttYXJnaW4tYm90dG9tOjZweDtcIj57eyBtLm5hbWUgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCB2IG9mIG0udmFsdWVcIiBzdHlsZT1cImRpc3BsYXk6ZmxleDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjthbGlnbi1pdGVtczpjZW50ZXI7cGFkZGluZzo2cHggMDtib3JkZXItYm90dG9tOjFweCBzb2xpZCAjZjBmNGZmO1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6MTNweDtjb2xvcjojNDc1NDY3O1wiPnt7IHYubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjEzcHg7Zm9udC13ZWlnaHQ6NzAwO1wiIFtzdHlsZS5jb2xvcl09XCJ2LnNjb3JlID4gNTAgPyAnIzEwQjk4MScgOiB2LnNjb3JlID09PSAwID8gJyM2NjcwODUnIDogJyNFRjQ0NDQnXCI+e3sgdi5zY29yZSAhPT0gdW5kZWZpbmVkID8gdi5zY29yZSArICclJyA6ICh2LlRvdGFsIHx8IHYuQXZnIHx8IHYuY291bnQgfHwgJ+KAkycpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgPHAgKm5nSWY9XCIhY29udi5tZXRyaWNzPy5sZW5ndGhcIiBzdHlsZT1cImZvbnQtc2l6ZToxM3B4O2NvbG9yOiM5NEEzQjg7XCI+Tm8gaW50ZXJhY3Rpb24gcXVhbGl0eSBkYXRhIGF2YWlsYWJsZS48L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8IS0tIFJpZ2h0IHNpZGU6IE1ldHJpY3MgLS0+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwid2lkdGg6MjAwcHg7ZmxleC1zaHJpbms6MDtwYWRkaW5nOjE2cHg7XCI+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6MTBweDtmb250LXdlaWdodDo3MDA7Y29sb3I6IzAwQTNGRjtsZXR0ZXItc3BhY2luZzouNXB4O3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTttYXJnaW4tYm90dG9tOjEycHg7XCI+TWV0cmljczwvZGl2PlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udi5tZXRyaWNzPy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtIG9mIGNvbnYubWV0cmljc1wiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTo4cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCB2IG9mIG0udmFsdWVcIiBzdHlsZT1cImRpc3BsYXk6ZmxleDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjttYXJnaW4tYm90dG9tOjRweDtcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6MTJweDtjb2xvcjojNjY3MDg1O1wiPnt7IHYubmFtZSB8fCBtLm5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWV0cmljLXZhbHVlXCIgW3N0eWxlLmNvbG9yXT1cInYuc2NvcmUgPiA1MCA/ICcjMTBCOTgxJyA6IHYuc2NvcmUgPT09IDAgPyAnIzY2NzA4NScgOiAodi5zY29yZSAhPT0gdW5kZWZpbmVkID8gJyNFRjQ0NDQnIDogJyMzNDQwNTQnKVwiIHN0eWxlPVwiZm9udC1zaXplOjEycHg7Zm9udC13ZWlnaHQ6NzAwO1wiPnt7IHYuc2NvcmUgIT09IHVuZGVmaW5lZCA/ICh2LnNjb3JlID4gMCA/IHYubmFtZSA6IHYuc2NvcmUpIDogKHYuVG90YWwgfHwgdi5BdmcgfHwgdi5jb3VudCB8fCAn4oCTJykgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY29udi5tZXRyaWNzPy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udi5zdG9yZU5hbWVcIiBzdHlsZT1cImRpc3BsYXk6ZmxleDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjttYXJnaW4tYm90dG9tOjZweDtcIj48c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxMnB4O2NvbG9yOiM2NjcwODU7XCI+U3RvcmU8L3NwYW4+PHNwYW4gc3R5bGU9XCJmb250LXNpemU6MTJweDtmb250LXdlaWdodDo2MDA7Y29sb3I6IzM0NDA1NDtcIj57eyBjb252LnN0b3JlTmFtZSB9fTwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udi5kdXJhdGlvblwiIHN0eWxlPVwiZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpzcGFjZS1iZXR3ZWVuO21hcmdpbi1ib3R0b206NnB4O1wiPjxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjEycHg7Y29sb3I6IzY2NzA4NTtcIj5EdXJhdGlvbjwvc3Bhbj48c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxMnB4O2ZvbnQtd2VpZ2h0OjYwMDtjb2xvcjojMzQ0MDU0O1wiPnt7IGNvbnYuZHVyYXRpb24gfX08L3NwYW4+PC9kaXY+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udi5fZGV0YWlsTG9hZGluZ1wiIHN0eWxlPVwiZm9udC1zaXplOjExcHg7Y29sb3I6IzY2NzA4NTtcIj5Mb2FkaW5nLi4uPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBObyBkYXRhIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cIiFjb252TG9hZGluZyAmJiBjb252ZXJzYXRpb25zLmxlbmd0aCA9PT0gMFwiIHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZzo0MHB4O2NvbG9yOiM5NEEzQjg7Zm9udC1zaXplOjEzcHg7XCI+Tm8gY29udmVyc2F0aW9ucyBmb3VuZC48L2Rpdj5cblxuICAgICAgPCEtLSBQYWdpbmF0aW9uIC0tPlxuICAgICAgPGxpYi1wYWdpbmF0aW9uICpuZ0lmPVwiY29udlRvdGFsID4gMFwiIFtpdGVtc1BlclBhZ2VdPVwiY29udlBlclBhZ2VcIiBbY3VycmVudFBhZ2VdPVwiY29udlBhZ2VcIiBbdG90YWxJdGVtc109XCJjb252VG90YWxcIlxuICAgICAgICBbcGFnaW5hdGlvblNpemVzXT1cImNvbnZQYWdpbmF0aW9uU2l6ZXNcIiBbcGFnZVNpemVdPVwiY29udlBlclBhZ2VcIiAocGFnZUNoYW5nZSk9XCJvbkNvbnZQYWdlQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAocGFnZVNpemVDaGFuZ2UpPVwib25Db252UGFnZVNpemVDaGFuZ2UoJGV2ZW50KVwiPjwvbGliLXBhZ2luYXRpb24+XG4gICAgICA8L2Rpdj4gPCEtLSBlbmQgY29udmVyc2F0aW9ucy1zZWN0aW9uIC0tPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPCEtLSDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgQUdFTlQgQU5BTFlTSVMgVEFCIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAtLT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY3VycmVudFBhZ2UgPT09ICdhZ2VudGFuYWx5c2lzJ1wiPlxuXG4gICAgICA8IS0tIOKUgOKUgCBPVkVSVklFVzogQ29ob3J0IExpc3QgYXMgQ2FyZHMg4pSA4pSAIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFkZXRhaWxWaWV3XCI+XG5cbiAgICAgICAgPCEtLSBIZWFkZXIgLS0+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OmZsZXg7YWxpZ24taXRlbXM6Y2VudGVyO2dhcDoxMHB4O21hcmdpbi1ib3R0b206MTZweDtmbGV4LXdyYXA6d3JhcDtcIj5cbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZToxN3B4O2ZvbnQtd2VpZ2h0OjcwMDtjb2xvcjojMWEyYjRiO1wiPkFuYWx5dGljcyBPdmVydmlldzwvZGl2PlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZToxMnB4O2NvbG9yOiM2NjcwODU7XCI+e3sgY29ob3J0TGlzdC5sZW5ndGggfX0gYWN0aXZlIGFnZW50czwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZmxleDoxO1wiPjwvc3Bhbj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwid2lkdGg6MjIwcHg7ZGlzcGxheTpmbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6OHB4O2JvcmRlcjoxcHggc29saWQgI0QwRDVERDtib3JkZXItcmFkaXVzOjhweDtwYWRkaW5nOjZweCAxMnB4O2JhY2tncm91bmQ6I2ZmZjtcIj5cbiAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxM1wiIGhlaWdodD1cIjEzXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJub25lXCIgc3Ryb2tlPVwiIzk4QTJCM1wiIHN0cm9rZS13aWR0aD1cIjEuOFwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIj48Y2lyY2xlIGN4PVwiMTFcIiBjeT1cIjExXCIgcj1cIjcuNVwiLz48cGF0aCBkPVwiTTE2LjUgMTYuNUwyMSAyMVwiLz48L3N2Zz5cbiAgICAgICAgICAgIDxpbnB1dCBbKG5nTW9kZWwpXT1cImFuYWx5c2lzU2VhcmNoXCIgcGxhY2Vob2xkZXI9XCJTZWFyY2ggYWdlbnRz4oCmXCIgc3R5bGU9XCJmbGV4OjE7Ym9yZGVyOm5vbmU7YmFja2dyb3VuZDp0cmFuc3BhcmVudDtmb250LXNpemU6MTNweDtjb2xvcjojMzQ0MDU0O291dGxpbmU6bm9uZTttaW4td2lkdGg6MDtcIj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBMb2FkaW5nIC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiY29ob3J0TGlzdC5sZW5ndGggPT09IDBcIiBzdHlsZT1cInRleHQtYWxpZ246Y2VudGVyO3BhZGRpbmc6NDBweDtjb2xvcjojNjY3MDg1O1wiPkxvYWRpbmcgYWdlbnRzLi4uPC9kaXY+XG5cbiAgICAgICAgPCEtLSBDb2hvcnQgQ2FyZHMgR3JpZCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFuYWx5dGljcy1ncmlkXCI+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgY29ob3J0IG9mIGNvaG9ydExpc3Q7IHRyYWNrQnk6IHRyYWNrQnlJZFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFuYWx5dGljcy1jYXJkXCIgKm5nSWY9XCIhYW5hbHlzaXNTZWFyY2ggfHwgKGNvaG9ydC5jb2hvcnROYW1lIHx8IGNvaG9ydC5uYW1lIHx8ICcnKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKGFuYWx5c2lzU2VhcmNoLnRvTG93ZXJDYXNlKCkpXCIgKGNsaWNrKT1cInNlbGVjdENvaG9ydERldGFpbChjb2hvcnQpXCI+XG5cbiAgICAgICAgICAgICAgPCEtLSBDYXJkIEhlYWRlciAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFuYWx5dGljcy1jYXJkLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OmZsZXg7YWxpZ24taXRlbXM6ZmxleC1zdGFydDtqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjttYXJnaW4tYm90dG9tOjhweDtcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6MTMuNXB4O2ZvbnQtd2VpZ2h0OjcwMDtjb2xvcjojMWEyYjRiO2ZsZXg6MTtwYWRkaW5nLXJpZ2h0OjhweDtsaW5lLWhlaWdodDoxLjM7XCI+e3sgY29ob3J0LmNvaG9ydE5hbWUgfHwgY29ob3J0Lm5hbWUgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjlweDtmb250LXdlaWdodDo3MDA7cGFkZGluZzoycHggOHB4O2JvcmRlci1yYWRpdXM6MjBweDtiYWNrZ3JvdW5kOiNEMUZBRTU7Y29sb3I6IzA2NUY0Njt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7bGV0dGVyLXNwYWNpbmc6LjVweDtmbGV4LXNocmluazowO1wiPkFjdGl2ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTpmbGV4O2dhcDo2cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxMXB4O2ZvbnQtd2VpZ2h0OjYwMDtwYWRkaW5nOjNweCA5cHg7Ym9yZGVyLXJhZGl1czoyMHB4O2JhY2tncm91bmQ6I2ZmZjtib3JkZXI6MXB4IHNvbGlkICNlOGVkZjM7Y29sb3I6IzM0NDA1NDtcIj57eyBjb2hvcnQubWV0cmljc0FkZGVkIHx8IDAgfX0gbWV0cmljczwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjExcHg7Zm9udC13ZWlnaHQ6NjAwO3BhZGRpbmc6M3B4IDlweDtib3JkZXItcmFkaXVzOjIwcHg7YmFja2dyb3VuZDojZmZmO2JvcmRlcjoxcHggc29saWQgI2U4ZWRmMztjb2xvcjojMzQ0MDU0O1wiPjUwIHN0b3Jlczwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgPCEtLSBDYXJkIEJvZHkgLS0+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJwYWRkaW5nOjhweCAxNHB4O1wiPjwvZGl2PlxuXG4gICAgICAgICAgICAgIDwhLS0gQ2FyZCBGb290ZXIgLS0+XG4gICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJwYWRkaW5nOjhweCAxNHB4O2JvcmRlci10b3A6MXB4IHNvbGlkICNlOGVkZjM7ZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpmbGV4LWVuZDtcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFuYWx5dGljcy1ob3Zlci1saW5rXCI+VmlldyBhbmFseXRpY3Mg4oaSPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIOKUgOKUgCBERVRBSUw6IFNlbGVjdGVkIENvaG9ydCBNZXRyaWNzICsgQ29udmVyc2F0aW9ucyDilIDilIAgLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGV0YWlsVmlld1wiPlxuXG4gICAgICAgIDwhLS0gSGVhZGVyIGJhcjog4oaQIE5hbWUgfCBUb3RhbCBDb252ZXJzYXRpb25zIHwgRHJvcGRvd24gLS0+XG4gICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OmZsZXg7YWxpZ24taXRlbXM6Y2VudGVyO2dhcDoxMnB4O21hcmdpbi1ib3R0b206MjBweDtwYWRkaW5nOjE0cHggMjBweDtiYWNrZ3JvdW5kOiNmZmY7Ym9yZGVyLXJhZGl1czoxMHB4O2JvcmRlcjoxcHggc29saWQgI2U4ZWRmMztcIj5cbiAgICAgICAgICA8YnV0dG9uIHN0eWxlPVwiYmFja2dyb3VuZDpub25lO2JvcmRlcjpub25lO2N1cnNvcjpwb2ludGVyO2NvbG9yOiMwMEEzRkY7Zm9udC1zaXplOjE4cHg7cGFkZGluZzowO1wiIChjbGljayk9XCJiYWNrVG9DYXJkcygpXCI+XG4gICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjIuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIj48cGF0aCBkPVwiTTE1IDE4bC02LTYgNi02XCIvPjwvc3ZnPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjE2cHg7Zm9udC13ZWlnaHQ6NzAwO2NvbG9yOiMxYTJiNGI7XCI+e3sgc2VsZWN0ZWRDb2hvcnROYW1lIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZmxleDoxO1wiPjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxM3B4O2NvbG9yOiM2NjcwODU7XCI+VG90YWwgQ29udmVyc2F0aW9uczoge3sgdG90YWxBdWRpbyB9fTwvc3Bhbj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTpmbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6NnB4O3BhZGRpbmc6NnB4IDE0cHg7Ym9yZGVyOjEuNXB4IHNvbGlkICMwMEEzRkY7Ym9yZGVyLXJhZGl1czo4cHg7YmFja2dyb3VuZDojZmZmO2N1cnNvcjpwb2ludGVyO3Bvc2l0aW9uOnJlbGF0aXZlO1wiPlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cIndpZHRoOjhweDtoZWlnaHQ6OHB4O2JvcmRlci1yYWRpdXM6NTAlO2JhY2tncm91bmQ6IzEwQjk4MTtcIj48L2Rpdj5cbiAgICAgICAgICAgIDxzZWxlY3QgWyhuZ01vZGVsKV09XCJzZWxlY3RlZENvaG9ydElkXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25Db2hvcnREcm9wZG93bkNoYW5nZSgkZXZlbnQpXCIgc3R5bGU9XCJib3JkZXI6bm9uZTtiYWNrZ3JvdW5kOnRyYW5zcGFyZW50O2ZvbnQtc2l6ZToxM3B4O2ZvbnQtd2VpZ2h0OjYwMDtjb2xvcjojMWEyYjRiO291dGxpbmU6bm9uZTtjdXJzb3I6cG9pbnRlcjtwYWRkaW5nLXJpZ2h0OjE2cHg7XCI+XG4gICAgICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGMgb2YgY29ob3J0TGlzdFwiIFt2YWx1ZV09XCJjLmNvaG9ydElkIHx8IGMuaWQgfHwgYy5faWRcIj57eyBjLmNvaG9ydE5hbWUgfHwgYy5uYW1lIH19PC9vcHRpb24+XG4gICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBMb2FkaW5nIC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiY2FyZHNMb2FkaW5nXCIgc3R5bGU9XCJ0ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nOjQwcHg7Y29sb3I6IzY2NzA4NTtcIj5Mb2FkaW5nIG1ldHJpY3MuLi48L2Rpdj5cblxuICAgICAgICA8IS0tIE1ldHJpYyBDYXJkcyAoZHluYW1pYyBjb2x1bW5zIGJhc2VkIG9uIGNhcmQgY291bnQpIC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiIWNhcmRzTG9hZGluZyAmJiBjb2hvcnRDYXJkcy5sZW5ndGggPiAwXCIgY2xhc3M9XCJtZXRyaWMtY2FyZHMtZHluYW1pY1wiXG4gICAgICAgICAgW3N0eWxlLmdyaWQtdGVtcGxhdGUtY29sdW1uc109XCIncmVwZWF0KCcgKyBNYXRoLm1pbihjb2hvcnRDYXJkcy5sZW5ndGgsIDQpICsgJywgMWZyKSdcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjYXJkIG9mIGNvaG9ydENhcmRzOyB0cmFja0J5OiB0cmFja0J5SWRcIiBjbGFzcz1cIm1ldHJpYy1jYXJkLWR5bmFtaWNcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtY2FyZC10aXRsZVwiPnt7IGNhcmQubmFtZSB9fTwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldHJpYy1jYXJkLXN1YnRpdGxlXCI+e3sgdG90YWxBdWRpbyB9fSBjb252ZXJzYXRpb25zPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gQk9PTEVBTl9CQVNLRVQg4oCUIHJvd3Mgd2l0aCBwcm9ncmVzcyBiYXJzIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNhcmQudHlwZSA9PT0gJ0JPT0xFQU5fQkFTS0VUJ1wiPlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCByb3cgb2YgY2FyZC5ib29sZWFuUm93c1wiIGNsYXNzPVwibWV0cmljLWJvb2wtcm93XCIgKGNsaWNrKT1cIm9uQ2FyZFJvd0NsaWNrKHJvdy5pZCwgY2FyZC5uYW1lKVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OmZsZXg7YWxpZ24taXRlbXM6Y2VudGVyO2dhcDo2cHg7bWFyZ2luLWJvdHRvbTo0cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWV0cmljLWRvdFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9XCJmb250LXNpemU6MTNweDtjb2xvcjojMzQ0MDU0O2ZsZXg6MTtcIj57eyByb3cubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldHJpYy1zY29yZVwiPnt7IHJvdy5zY29yZSB9fSU8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldHJpYy1jb3VudFwiPnt7IHJvdy5yZXNwb25zZXMgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldHJpYy1wcm9ncmVzcy10cmFja1wiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldHJpYy1wcm9ncmVzcy1maWxsXCIgW3N0eWxlLndpZHRoLiVdPVwicm93LnNjb3JlXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDwhLS0gTlVNRVJJQyDigJQgYmlnIG51bWJlciAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjYXJkLnR5cGUgPT09ICdOVU1FUklDX1NDQUxBUicgfHwgY2FyZC50eXBlID09PSAnTlVNRVJJQ19BUlJBWSdcIj5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImN1cnNvcjpwb2ludGVyO1wiIChjbGljayk9XCJvbkNhcmRSb3dDbGljaygnJywgY2FyZC5rZXkpXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRyaWMtYmlnLW51bWJlclwiPnt7IGNhcmQubnVtZXJpY0RhdGE/LmF2ZyB8fCBjYXJkLm51bWVyaWNEYXRhPy50b3RhbCB8fCAn4oCTJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldHJpYy1hdmctbGFiZWxcIj5hdmc8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgIDwhLS0gU1VCSkVDVElWRSAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjYXJkLnR5cGUgPT09ICdTVUJKRUNUSVZFJyB8fCBjYXJkLnR5cGUgPT09ICdTVUJKRUNUSVZFX0NPVU5UJ1wiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3ViamVjdGl2ZS13cmFwXCIgKGNsaWNrKT1cIm9uQ2FyZFJvd0NsaWNrKCcnLCBjYXJkLmtleSlcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCByb3cgb2YgY2FyZC5zdWJqZWN0aXZlUm93cz8uc2xpY2UoMCwgMilcIiBjbGFzcz1cInN1YmplY3RpdmUtcm93XCI+XG4gICAgICAgICAgICAgICAgICDigKIge3sgcm93LnJlYXNvbmluZyB8fCByb3cuc3RvcmVfaWQgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBObyBjYXJkcyAtLT5cbiAgICAgICAgPGRpdiAqbmdJZj1cIiFjYXJkc0xvYWRpbmcgJiYgY29ob3J0Q2FyZHMubGVuZ3RoID09PSAwXCIgc3R5bGU9XCJ0ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nOjQwcHg7Y29sb3I6IzY2NzA4NTtmb250LXNpemU6MTNweDtcIj5ObyBhbmFseXNpcyBkYXRhIGF2YWlsYWJsZS48L2Rpdj5cblxuICAgICAgICA8IS0tIOKUgOKUgCBDb252ZXJzYXRpb25zIFNlY3Rpb24g4pSA4pSAIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29udmVyc2F0aW9ucy1zZWN0aW9uXCIgKm5nSWY9XCJkZXRhaWxQYWdlQ29udnMubGVuZ3RoID4gMCB8fCBkZXRhaWxMb2FkaW5nXCI+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cInBhZGRpbmc6MTZweCAyMHB4O2Rpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7Z2FwOjhweDtiYWNrZ3JvdW5kOiNmZmY7Ym9yZGVyLXJhZGl1czoxMHB4O2JvcmRlcjoxcHggc29saWQgI2U4ZWRmMzttYXJnaW4tYm90dG9tOjEycHg7XCI+XG4gICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiMzNDQwNTRcIiBzdHJva2Utd2lkdGg9XCIxLjhcIj48cGF0aCBkPVwiTTIwIDJINGEyIDIgMCAwIDAtMiAydjEzYTIgMiAwIDAgMCAyIDJoMTFsNSAzVjRhMiAyIDAgMCAwLTItMnpcIi8+PC9zdmc+XG4gICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxNXB4O2ZvbnQtd2VpZ2h0OjcwMDtjb2xvcjojMWEyYjRiO1wiPkNvbnZlcnNhdGlvbnM8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZGV0YWlsTG9hZGluZ1wiIHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZzo0MHB4O2NvbG9yOiM2NjcwODU7XCI+TG9hZGluZy4uLjwvZGl2PlxuXG4gICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY29udiBvZiBkZXRhaWxQYWdlQ29udnM7IHRyYWNrQnk6IHRyYWNrQnlJZFwiIGNsYXNzPVwiZGV0YWlsLWNvbnYtY2FyZFwiPlxuICAgICAgICAgICAgPCEtLSBDb252IGhlYWRlciAtLT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb252LWhlYWRlclwiIChjbGljayk9XCJ0b2dnbGVEZXRhaWxDb252KGNvbnYuYXVkaW9JZCk7IGxvYWRDb252RGV0YWlsKGNvbnYpXCI+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29udi1pZFwiPnt7IGNvbnYuYXVkaW9JZCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6ZmxleDthbGlnbi1pdGVtczpjZW50ZXI7Z2FwOjVweDtmbGV4OjE7bWluLXdpZHRoOjA7ZmxleC13cmFwOndyYXA7XCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRhLXRhZyBicmFuZFwiICpuZ0lmPVwiY29udi5zdG9yZU5hbWVcIj57eyBjb252LnN0b3JlTmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldGEtdGFnXCIgKm5nSWY9XCJjb252LmxvY2F0aW9uXCI+e3sgY29udi5sb2NhdGlvbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldGEtdGFnXCIgKm5nSWY9XCJjb252LmRhdGVcIj57eyBjb252LmRhdGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRhLXRhZ1wiICpuZ0lmPVwiY29udi50aW1lXCI+e3sgY29udi50aW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnYtY2hldnJvblwiIFtjbGFzcy5vcGVuXT1cImRldGFpbE9wZW5JZCA9PT0gY29udi5hdWRpb0lkXCI+XG4gICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiMTJcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjOTRBM0I4XCIgc3Ryb2tlLXdpZHRoPVwiMi41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiPjxwYXRoIGQ9XCJNNiA5bDYgNiA2LTZcIi8+PC9zdmc+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gRXhwYW5kZWQgYm9keSAtLT5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJkZXRhaWxPcGVuSWQgPT09IGNvbnYuYXVkaW9JZFwiIGNsYXNzPVwiY29udi1ib2R5LWV4cGFuZGVkXCI+XG4gICAgICAgICAgICAgIDwhLS0gV2F2ZWZvcm0gcGxheWVyIC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZWNoby1wbGF5ZXJcIiAqbmdJZj1cImNvbnYuYXVkaW9VcmxcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiZWNoby1wbGF5LWJ0blwiIChjbGljayk9XCJ0b2dnbGVQbGF5KGNvbnYuYXVkaW9JZClcIj5cbiAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJwbGF5aW5nQ29udklkICE9PSBjb252LmF1ZGlvSWRcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIndoaXRlXCI+PHBhdGggZD1cIk04IDV2MTRsMTEtN3pcIi8+PC9zdmc+XG4gICAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwicGxheWluZ0NvbnZJZCA9PT0gY29udi5hdWRpb0lkXCIgd2lkdGg9XCIxNFwiIGhlaWdodD1cIjE0XCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIGZpbGw9XCJ3aGl0ZVwiPjxwYXRoIGQ9XCJNNiAxOWg0VjVINnYxNHptOC0xNHYxNGg0VjVoLTR6XCIvPjwvc3ZnPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlY2hvLXdhdmVmb3JtXCIgKGNsaWNrKT1cInNlZWtBdWRpbygkZXZlbnQsIGNvbnYuYXVkaW9JZClcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlY2hvLXdmLWJhclwiICpuZ0Zvcj1cImxldCBoIG9mIHdhdmVmb3JtSGVpZ2h0czsgbGV0IGkgPSBpbmRleFwiIFtzdHlsZS5oZWlnaHQucHhdPVwiaFwiXG4gICAgICAgICAgICAgICAgICAgIFtjbGFzcy5wbGF5ZWRdPVwiKHBsYXliYWNrU3RhdGVzW2NvbnYuYXVkaW9JZF0/LnByb2dyZXNzIHx8IDApID4gaSAvIHdhdmVmb3JtSGVpZ2h0cy5sZW5ndGhcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVjaG8tdGltZVwiPnt7IHBsYXliYWNrU3RhdGVzW2NvbnYuYXVkaW9JZF0/LnRvdGFsVGltZSB8fCBjb252LmR1cmF0aW9uIHx8ICctLScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPGF1ZGlvIFtpZF09XCInYXVkaW8tJyArIGNvbnYuYXVkaW9JZFwiIFtzcmNdPVwiY29udi5hdWRpb1VybFwiIHByZWxvYWQ9XCJtZXRhZGF0YVwiXG4gICAgICAgICAgICAgICAgICAodGltZXVwZGF0ZSk9XCJvblRpbWVVcGRhdGUoYXVkaW9FbCwgY29udi5hdWRpb0lkKVwiXG4gICAgICAgICAgICAgICAgICAobG9hZGVkbWV0YWRhdGEpPVwib25Mb2FkZWRNZXRhZGF0YShhdWRpb0VsLCBjb252LmF1ZGlvSWQsIGNvbnYuZHVyYXRpb24pXCJcbiAgICAgICAgICAgICAgICAgIChlbmRlZCk9XCJwbGF5aW5nQ29udklkID0gbnVsbFwiICNhdWRpb0VsPjwvYXVkaW8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIDwhLS0gVGFicyAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnYtdGFic1wiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJjb252LXRhYi1idG5cIiBbY2xhc3MuYWN0aXZlXT1cImdldENvbnZUYWIoY29udi5hdWRpb0lkKSA9PT0gJ3N1bW1hcnknXCIgKGNsaWNrKT1cInNldENvbnZUYWIoY29udi5hdWRpb0lkLCAnc3VtbWFyeScsICRldmVudClcIj5TdW1tYXJ5PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImNvbnYtdGFiLWJ0blwiIFtjbGFzcy5hY3RpdmVdPVwiZ2V0Q29udlRhYihjb252LmF1ZGlvSWQpID09PSAndHJhbnNjcmlwdCdcIiAoY2xpY2spPVwic2V0Q29udlRhYihjb252LmF1ZGlvSWQsICd0cmFuc2NyaXB0JywgJGV2ZW50KVwiPlRyYW5zY3JpcHQ8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY29udi10YWItYnRuXCIgW2NsYXNzLmFjdGl2ZV09XCJnZXRDb252VGFiKGNvbnYuYXVkaW9JZCkgPT09ICdpbnRlcmFjdGlvbidcIiAoY2xpY2spPVwic2V0Q29udlRhYihjb252LmF1ZGlvSWQsICdpbnRlcmFjdGlvbicsICRldmVudClcIj5JbnRlcmFjdGlvbiBRdWFsaXR5PC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIDwhLS0gQ29udGVudDogTGVmdCAoU3VtbWFyeS9UcmFuc2NyaXB0ICsgQUkgSW5zaWdodHMpICsgUmlnaHQgKE1ldHJpY3MpIC0tPlxuICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTpmbGV4O1wiPlxuICAgICAgICAgICAgICAgIDwhLS0gTGVmdCBzaWRlIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmbGV4OjE7cGFkZGluZzoxNHB4IDE2cHg7bWluLXdpZHRoOjA7Ym9yZGVyLXJpZ2h0OjFweCBzb2xpZCAjZThlZGYzO1wiPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbnZUYWIoY29udi5hdWRpb0lkKSA9PT0gJ3N1bW1hcnknXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwic3VtbWFyeS10ZXh0XCI+e3sgY29udi5hdWRpb0Rlc2NyaXB0aW9uIHx8IGNvbnYuY29udmVyc2F0aW9uRGV0YWlscz8uYXVkaW9TdW1tYXJ5IHx8ICdObyBzdW1tYXJ5IGF2YWlsYWJsZScgfX08L3A+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gQUkgSW5zaWdodHMgLS0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjb252LmFpSW5zaWdodHM/LnN1bW1hcnk/Lmxlbmd0aFwiIHN0eWxlPVwibWFyZ2luLXRvcDoxNnB4O1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6MTFweDtmb250LXdlaWdodDo3MDA7Y29sb3I6IzY2NzA4NTtsZXR0ZXItc3BhY2luZzouNXB4O3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZTttYXJnaW4tYm90dG9tOjEwcHg7XCI+QUkgSW5zaWdodHM8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBpbnNpZ2h0IG9mIGNvbnYuYWlJbnNpZ2h0cy5zdW1tYXJ5XCIgc3R5bGU9XCJkaXNwbGF5OmZsZXg7YWxpZ24taXRlbXM6ZmxleC1zdGFydDtnYXA6OHB4O21hcmdpbi1ib3R0b206OHB4O1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cIndpZHRoOjZweDtoZWlnaHQ6NnB4O2JvcmRlci1yYWRpdXM6NTAlO21hcmdpbi10b3A6NXB4O2ZsZXgtc2hyaW5rOjA7XCIgW3N0eWxlLmJhY2tncm91bmRdPVwiaW5zaWdodC50eXBlID09PSAncG9zaXRpdmUnID8gJyMwMEEzRkYnIDogaW5zaWdodC50eXBlID09PSAnbmVnYXRpdmUnID8gJyNFRjQ0NDQnIDogJyNGNTlFMEInXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxM3B4O2NvbG9yOiM0NzU0Njc7bGluZS1oZWlnaHQ6MS41O1wiPnt7IGluc2lnaHQudGV4dCB8fCBpbnNpZ2h0IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbnZUYWIoY29udi5hdWRpb0lkKSA9PT0gJ3RyYW5zY3JpcHQnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwic3VtbWFyeS10ZXh0XCIgc3R5bGU9XCJ3aGl0ZS1zcGFjZTpwcmUtd3JhcDtcIj57eyBjb252LmNvbnZlcnNhdGlvbkRldGFpbHM/LnRyYW5zY3JpcHRpb24gfHwgJ05vIHRyYW5zY3JpcHQgYXZhaWxhYmxlJyB9fTwvcD5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImdldENvbnZUYWIoY29udi5hdWRpb0lkKSA9PT0gJ2ludGVyYWN0aW9uJ1wiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwicGFkZGluZzo4cHggMDtcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOjExcHg7Zm9udC13ZWlnaHQ6NzAwO2NvbG9yOiM2NjcwODU7bGV0dGVyLXNwYWNpbmc6LjVweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7bWFyZ2luLWJvdHRvbToxMnB4O1wiPkludGVyYWN0aW9uIFF1YWxpdHk8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udi5tZXRyaWNzPy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IG0gb2YgY29udi5tZXRyaWNzXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOjEycHg7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6MTNweDtmb250LXdlaWdodDo2MDA7Y29sb3I6IzM0NDA1NDttYXJnaW4tYm90dG9tOjZweDtcIj57eyBtLm5hbWUgfX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgdiBvZiBtLnZhbHVlXCIgc3R5bGU9XCJkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW47YWxpZ24taXRlbXM6Y2VudGVyO3BhZGRpbmc6NnB4IDA7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI2YwZjRmZjtcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxM3B4O2NvbG9yOiM0NzU0Njc7XCI+e3sgdi5uYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjEzcHg7Zm9udC13ZWlnaHQ6NzAwO1wiIFtzdHlsZS5jb2xvcl09XCJ2LnNjb3JlID4gNTAgPyAnIzEwQjk4MScgOiB2LnNjb3JlID09PSAwID8gJyM2NjcwODUnIDogJyNFRjQ0NDQnXCI+e3sgdi5zY29yZSAhPT0gdW5kZWZpbmVkID8gdi5zY29yZSArICclJyA6ICh2LlRvdGFsIHx8IHYuQXZnIHx8IHYuY291bnQgfHwgJ+KAkycpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDxwICpuZ0lmPVwiIWNvbnYubWV0cmljcz8ubGVuZ3RoXCIgc3R5bGU9XCJmb250LXNpemU6MTNweDtjb2xvcjojOTRBM0I4O1wiPk5vIGludGVyYWN0aW9uIHF1YWxpdHkgZGF0YSBhdmFpbGFibGUuPC9wPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwhLS0gUmlnaHQgc2lkZTogTWV0cmljcyAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwid2lkdGg6MjAwcHg7ZmxleC1zaHJpbms6MDtwYWRkaW5nOjE2cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1zaXplOjEwcHg7Zm9udC13ZWlnaHQ6NzAwO2NvbG9yOiMwMEEzRkY7bGV0dGVyLXNwYWNpbmc6LjVweDt0ZXh0LXRyYW5zZm9ybTp1cHBlcmNhc2U7bWFyZ2luLWJvdHRvbToxMnB4O1wiPk1ldHJpY3M8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb252Lm1ldHJpY3M/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtIG9mIGNvbnYubWV0cmljc1wiIHN0eWxlPVwibWFyZ2luLWJvdHRvbTo4cHg7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgdiBvZiBtLnZhbHVlXCIgc3R5bGU9XCJkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW47bWFyZ2luLWJvdHRvbTo0cHg7XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT1cImZvbnQtc2l6ZToxMnB4O2NvbG9yOiM2NjcwODU7XCI+e3sgdi5uYW1lIHx8IG0ubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjEycHg7Zm9udC13ZWlnaHQ6NzAwO1wiIFtzdHlsZS5jb2xvcl09XCJ2LnNjb3JlID4gNTAgPyAnIzEwQjk4MScgOiB2LnNjb3JlID09PSAwID8gJyM2NjcwODUnIDogJyNFRjQ0NDQnXCI+e3sgdi5zY29yZSAhPT0gdW5kZWZpbmVkID8gKHYuc2NvcmUgPiAwID8gdi5uYW1lIDogdi5zY29yZSkgOiAodi5Ub3RhbCB8fCB2LkF2ZyB8fCB2LmNvdW50IHx8ICfigJMnKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY29udi5tZXRyaWNzPy5sZW5ndGhcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImNvbnYuc3RvcmVOYW1lXCIgc3R5bGU9XCJkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW47bWFyZ2luLWJvdHRvbTo2cHg7XCI+PHNwYW4gc3R5bGU9XCJmb250LXNpemU6MTJweDtjb2xvcjojNjY3MDg1O1wiPlN0b3JlPC9zcGFuPjxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjEycHg7Zm9udC13ZWlnaHQ6NjAwO2NvbG9yOiMzNDQwNTQ7XCI+e3sgY29udi5zdG9yZU5hbWUgfX08L3NwYW4+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjb252LmR1cmF0aW9uXCIgc3R5bGU9XCJkaXNwbGF5OmZsZXg7anVzdGlmeS1jb250ZW50OnNwYWNlLWJldHdlZW47bWFyZ2luLWJvdHRvbTo2cHg7XCI+PHNwYW4gc3R5bGU9XCJmb250LXNpemU6MTJweDtjb2xvcjojNjY3MDg1O1wiPkR1cmF0aW9uPC9zcGFuPjxzcGFuIHN0eWxlPVwiZm9udC1zaXplOjEycHg7Zm9udC13ZWlnaHQ6NjAwO2NvbG9yOiMzNDQwNTQ7XCI+e3sgY29udi5kdXJhdGlvbiB9fTwvc3Bhbj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImNvbnYuX2RldGFpbExvYWRpbmdcIiBzdHlsZT1cImZvbnQtc2l6ZToxMXB4O2NvbG9yOiM2NjcwODU7XCI+TG9hZGluZy4uLjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2ICpuZ0lmPVwiIWRldGFpbExvYWRpbmcgJiYgZGV0YWlsUGFnZUNvbnZzLmxlbmd0aCA9PT0gMCAmJiAoc2VsZWN0ZWRDYXJkSWQgfHwgc2VsZWN0ZWRDYXJkTmFtZSlcIiBzdHlsZT1cInRleHQtYWxpZ246Y2VudGVyO3BhZGRpbmc6MzJweDtjb2xvcjojNjY3MDg1O2ZvbnQtc2l6ZToxM3B4O1wiPk5vIGNvbnZlcnNhdGlvbnMgZm91bmQuPC9kaXY+XG5cbiAgICAgICAgPCEtLSBQYWdpbmF0aW9uIC0tPlxuICAgICAgICA8bGliLXBhZ2luYXRpb24gKm5nSWY9XCJkZXRhaWxUb3RhbCA+IDBcIiBbaXRlbXNQZXJQYWdlXT1cImRldGFpbFBlclBhZ2VcIiBbY3VycmVudFBhZ2VdPVwiZGV0YWlsUGFnZVwiIFt0b3RhbEl0ZW1zXT1cImRldGFpbFRvdGFsXCJcbiAgICAgICAgICBbcGFnaW5hdGlvblNpemVzXT1cImRldGFpbFBhZ2luYXRpb25TaXplc1wiIFtwYWdlU2l6ZV09XCJkZXRhaWxQZXJQYWdlXCIgKHBhZ2VDaGFuZ2UpPVwib25EZXRhaWxQYWdlQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgIChwYWdlU2l6ZUNoYW5nZSk9XCJvbkRldGFpbFBhZ2VTaXplQ2hhbmdlKCRldmVudClcIj48L2xpYi1wYWdpbmF0aW9uPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCBNQU5BR0UgVEFCIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCAtLT5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY3VycmVudFBhZ2UgPT09ICdtYW5hZ2UnXCI+XG4gICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTpmbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6MTBweDttYXJnaW4tYm90dG9tOjE2cHg7ZmxleC13cmFwOndyYXA7XCI+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtZmFtaWx5OidPdXRmaXQnLHNhbnMtc2VyaWY7Zm9udC13ZWlnaHQ6NzAwO2ZvbnQtc2l6ZToxN3B4O1wiPkFnZW50czwvZGl2PlxuICAgICAgICAgIDxkaXYgc3R5bGU9XCJmb250LXNpemU6MTJweDtjb2xvcjojOTRBM0I4O1wiPnt7IG1hbmFnZVRvdGFsIH19IGFnZW50czwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNwYW4gc3R5bGU9XCJmbGV4OjE7XCI+PC9zcGFuPlxuICAgICAgICA8ZGl2IHN0eWxlPVwid2lkdGg6MjgwcHg7ZGlzcGxheTpmbGV4O2FsaWduLWl0ZW1zOmNlbnRlcjtnYXA6OHB4O2JvcmRlcjoxcHggc29saWQgI0UyRThGMjtib3JkZXItcmFkaXVzOjhweDtwYWRkaW5nOjZweCAxMnB4O2JhY2tncm91bmQ6I2ZmZjtcIj5cbiAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxM1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiM5NEEzQjhcIiBzdHJva2Utd2lkdGg9XCIxLjhcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCI+PGNpcmNsZSBjeD1cIjExXCIgY3k9XCIxMVwiIHI9XCI3LjVcIi8+PHBhdGggZD1cIk0xNi41IDE2LjVMMjEgMjFcIi8+PC9zdmc+XG4gICAgICAgICAgPGlucHV0IFsobmdNb2RlbCldPVwibWFuYWdlU2VhcmNoXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25NYW5hZ2VTZWFyY2goKVwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGFnZW50cy4uLlwiIHN0eWxlPVwiZmxleDoxO2JvcmRlcjpub25lO2JhY2tncm91bmQ6dHJhbnNwYXJlbnQ7Zm9udC1zaXplOjEzcHg7Zm9udC1mYW1pbHk6J051bml0byBTYW5zJyxzYW5zLXNlcmlmO2NvbG9yOiMwRjE3MkE7b3V0bGluZTpub25lO21pbi13aWR0aDowO1wiPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2ICpuZ0lmPVwibWFuYWdlTG9hZGluZ1wiIHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZzo0MHB4O2NvbG9yOiM5NEEzQjg7XCI+TG9hZGluZyBhZ2VudHMuLi48L2Rpdj5cblxuICAgICAgPCEtLSBBZ2VudHMgdGFibGUgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIW1hbmFnZUxvYWRpbmdcIiBjbGFzcz1cImVjaG8tY2FyZFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnRzLXRhYmxlLWhlYWRlclwiIHN0eWxlPVwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOm1pbm1heCgwLDFmcikgMTIwcHggMTIwcHggODBweDtcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnRzLXRhYmxlLWNlbGxcIj5BZ2VudCBOYW1lPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFnZW50cy10YWJsZS1jZWxsXCIgc3R5bGU9XCJ0ZXh0LWFsaWduOmNlbnRlcjtcIj5NZXRyaWNzPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFnZW50cy10YWJsZS1jZWxsXCIgc3R5bGU9XCJ0ZXh0LWFsaWduOmNlbnRlcjtcIj5Tb3VyY2U8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnRzLXRhYmxlLWNlbGxcIiBzdHlsZT1cInRleHQtYWxpZ246Y2VudGVyO1wiPkFjdGlvbjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY29ob3J0IG9mIG1hbmFnZUNvaG9ydHM7IHRyYWNrQnk6IHRyYWNrQnlJZFwiIGNsYXNzPVwiYWdlbnRzLXRhYmxlLXJvd1wiIHN0eWxlPVwiZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOm1pbm1heCgwLDFmcikgMTIwcHggMTIwcHggODBweDtcIj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwibWluLXdpZHRoOjA7XCI+XG4gICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZm9udC1mYW1pbHk6J091dGZpdCcsc2Fucy1zZXJpZjtmb250LXdlaWdodDo3MDA7Zm9udC1zaXplOjEzLjVweDtjb2xvcjojMEYxNzJBO292ZXJmbG93OmhpZGRlbjt0ZXh0LW92ZXJmbG93OmVsbGlwc2lzO3doaXRlLXNwYWNlOm5vd3JhcDtcIj57eyBjb2hvcnQuY29ob3J0TmFtZSB8fCBjb2hvcnQubmFtZSB9fTwvZGl2PlxuICAgICAgICAgICAgPGRpdiBzdHlsZT1cImZvbnQtc2l6ZToxMXB4O2NvbG9yOiM5NEEzQjg7bWFyZ2luLXRvcDoycHg7b3ZlcmZsb3c6aGlkZGVuO3RleHQtb3ZlcmZsb3c6ZWxsaXBzaXM7d2hpdGUtc3BhY2U6bm93cmFwO1wiPnt7IGNvaG9ydC5jb2hvcnREZXNjcmlwdGlvbiB8fCBjb2hvcnQuZGVzY3JpcHRpb24gfHwgJycgfX08L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXI7Zm9udC1mYW1pbHk6J091dGZpdCcsc2Fucy1zZXJpZjtmb250LXdlaWdodDo3MDA7Zm9udC1zaXplOjEzcHg7Y29sb3I6IzBGMTcyQTtcIj57eyBjb2hvcnQubWV0cmljc0FkZGVkIHx8IGNvaG9ydC5tZXRyaWNBZGRlZCB8fCBjb2hvcnQubWV0cmljcz8ubGVuZ3RoIHx8IDAgfX08L2Rpdj5cbiAgICAgICAgICA8ZGl2IHN0eWxlPVwidGV4dC1hbGlnbjpjZW50ZXI7Zm9udC1zaXplOjExLjVweDtjb2xvcjojMzM0MTU1O2ZvbnQtd2VpZ2h0OjYwMDtcIj57eyBjb2hvcnQuc291cmNlPy5qb2luKCcsICcpIHx8ICfigJMnIH19PC9kaXY+XG4gICAgICAgICAgPGRpdiBzdHlsZT1cInRleHQtYWxpZ246Y2VudGVyO1wiPlxuICAgICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiZGVsZXRlQ29ob3J0KGNvaG9ydC5jb2hvcnRJZCB8fCBjb2hvcnQuaWQgfHwgY29ob3J0Ll9pZClcIiBzdHlsZT1cImJhY2tncm91bmQ6bm9uZTtib3JkZXI6bm9uZTtjdXJzb3I6cG9pbnRlcjtjb2xvcjojRUY0NDQ0O2ZvbnQtc2l6ZToxMXB4O2ZvbnQtd2VpZ2h0OjcwMDtcIj5EZWxldGU8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJtYW5hZ2VDb2hvcnRzLmxlbmd0aCA9PT0gMFwiIHN0eWxlPVwicGFkZGluZzozMnB4O3RleHQtYWxpZ246Y2VudGVyO2NvbG9yOiM5NEEzQjg7Zm9udC1zaXplOjEzcHg7XCI+Tm8gY29ob3J0cyBmb3VuZC48L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIE1hbmFnZSBwYWdpbmF0aW9uIC0tPlxuICAgICAgPGxpYi1wYWdpbmF0aW9uICpuZ0lmPVwibWFuYWdlVG90YWwgPiAwXCIgW2l0ZW1zUGVyUGFnZV09XCJtYW5hZ2VQZXJQYWdlXCIgW2N1cnJlbnRQYWdlXT1cIm1hbmFnZVBhZ2VcIiBbdG90YWxJdGVtc109XCJtYW5hZ2VUb3RhbFwiXG4gICAgICAgIFtwYWdpbmF0aW9uU2l6ZXNdPVwibWFuYWdlUGFnaW5hdGlvblNpemVzXCIgW3BhZ2VTaXplXT1cIm1hbmFnZVBlclBhZ2VcIiAocGFnZUNoYW5nZSk9XCJvbk1hbmFnZVBhZ2VDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgIChwYWdlU2l6ZUNoYW5nZSk9XCJvbk1hbmFnZVBhZ2VTaXplQ2hhbmdlKCRldmVudClcIj48L2xpYi1wYWdpbmF0aW9uPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gIDwvZGl2PlxuPC9kaXY+XG5cbjwhLS0g4pWQ4pWQ4pWQIEZJTFRFUlMgRFJBV0VSIOKVkOKVkOKVkCAtLT5cbjxkaXYgY2xhc3M9XCJkcmF3ZXItb3ZlcmxheVwiICpuZ0lmPVwiZHJhd2VyT3BlblwiIChjbGljayk9XCJjbG9zZUZpbHRlckRyYXdlcigpXCI+PC9kaXY+XG48ZGl2IGNsYXNzPVwiYWYtZHJhd2VyXCIgKm5nSWY9XCJkcmF3ZXJPcGVuXCI+XG4gIDxkaXYgc3R5bGU9XCJwYWRkaW5nOjE2cHg7Ym9yZGVyLWJvdHRvbToxcHggc29saWQgI0UyRThGMjtkaXNwbGF5OmZsZXg7YWxpZ24taXRlbXM6Y2VudGVyO2p1c3RpZnktY29udGVudDpzcGFjZS1iZXR3ZWVuO1wiPlxuICAgIDxzcGFuIHN0eWxlPVwiZm9udC1mYW1pbHk6J091dGZpdCcsc2Fucy1zZXJpZjtmb250LXdlaWdodDo3MDA7Zm9udC1zaXplOjE1cHg7XCI+RmlsdGVyczwvc3Bhbj5cbiAgICA8YnV0dG9uIChjbGljayk9XCJjbG9zZUZpbHRlckRyYXdlcigpXCIgc3R5bGU9XCJiYWNrZ3JvdW5kOm5vbmU7Ym9yZGVyOm5vbmU7Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Izk0QTNCODtmb250LXNpemU6MThweDtcIj7DlzwvYnV0dG9uPlxuICA8L2Rpdj5cbiAgPGRpdiBzdHlsZT1cInBhZGRpbmc6MTZweDtmbGV4OjE7b3ZlcmZsb3cteTphdXRvO1wiPlxuICAgIDxwIHN0eWxlPVwiZm9udC1zaXplOjEzcHg7Y29sb3I6Izk0QTNCODtcIj5GaWx0ZXIgY29uZmlndXJhdGlvbiBjb21pbmcgc29vbi4gVXNlcyB0aGUgc2FtZSBmaWx0ZXIgQVBJcyBhcyB0aGUgZXhpc3RpbmcgYXVkaW8gcGFnZXMuPC9wPlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImFmLWZvb3RlclwiPlxuICAgIDxidXR0b24gY2xhc3M9XCJhZi1jYW5jZWxcIiAoY2xpY2spPVwiY2xvc2VGaWx0ZXJEcmF3ZXIoKVwiPkNsb3NlPC9idXR0b24+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=
|
|
813
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFuZ28tZWNoby5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90YW5nby1haS1hdWRpby9zcmMvbGliL2NvbXBvbmVudHMvdGFuZ28tZWNoby90YW5nby1lY2hvLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RhbmdvLWFpLWF1ZGlvL3NyYy9saWIvY29tcG9uZW50cy90YW5nby1lY2hvL3RhbmdvLWVjaG8uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFFN0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7Ozs7O0FBUzFDLE1BQU0sT0FBTyxrQkFBa0I7SUF3SG5CO0lBQ0E7SUFDQTtJQXhIVixzREFBc0Q7SUFDdEQsV0FBVyxHQUFpRCxlQUFlLENBQUM7SUFFNUUsc0RBQXNEO0lBQ3RELFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDaEIsUUFBUSxHQUFhLEVBQUUsQ0FBQztJQUN4QixTQUFTLEdBQUcsRUFBRSxDQUFDO0lBQ2YsT0FBTyxHQUFHLEVBQUUsQ0FBQztJQUNiLFVBQVUsR0FBUSxFQUFFLENBQUM7SUFDckIsS0FBSyxHQUFRLEVBQUUsQ0FBQztJQUVoQixzREFBc0Q7SUFDdEQsYUFBYSxHQUFVLEVBQUUsQ0FBQztJQUMxQixRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ2IsV0FBVyxHQUFHLEVBQUUsQ0FBQztJQUNqQixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNuQixtQkFBbUIsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3hDLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsZUFBZSxHQUFHLEVBQUUsQ0FB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QUFDLE1BQU07WUFBRSxPQUFPLElBQUksQ0FBQztRQUN6QixNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDL0IsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBWSxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ25HLENBQUM7SUFFRCxJQUFJLEdBQUcsSUFBSSxDQUFDO3dHQXgwQkQsa0JBQWtCOzRGQUFsQixrQkFBa0Isc0RDWC9CLDYzOEJBeWRBOzs0RkQ5Y2Esa0JBQWtCO2tCQUw5QixTQUFTOytCQUNFLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQXVkaW9TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYXVkaW8uc2VydmljZSc7XG5pbXBvcnQgeyBHbG9iYWxTdGF0ZVNlcnZpY2UgfSBmcm9tICd0YW5nby1hcHAtdWktZ2xvYmFsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLXRhbmdvLWVjaG8nLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFuZ28tZWNoby5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RhbmdvLWVjaG8uY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBUYW5nb0VjaG9Db21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG5cbiAgLy8g4pSA4pSAIE5hdmlnYXRpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIGN1cnJlbnRQYWdlOiAnY29udmVyc2F0aW9ucycgfCAnYWdlbnRhbmFseXNpcycgfCAnbWFuYWdlJyA9ICdjb252ZXJzYXRpb25zJztcblxuICAvLyDilIDilIAgVXNlciAvIEdsb2JhbCBTdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgY2xpZW50SWQgPSAnMTEnO1xuICBzdG9yZUlkczogc3RyaW5nW10gPSBbXTtcbiAgc3RhcnREYXRlID0gJyc7XG4gIGVuZERhdGUgPSAnJztcbiAgaGVhZGVyRGF0YTogYW55ID0ge307XG4gIHVzZXJzOiBhbnkgPSB7fTtcblxuICAvLyDilIDilIAgQ29udmVyc2F0aW9ucyAodHJhbnNjcmlwdC1saXN0IEFQSSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIGNvbnZlcnNhdGlvbnM6IGFueVtdID0gW107XG4gIGNvbnZQYWdlID0gMTtcbiAgY29udlBlclBhZ2UgPSAxMDtcbiAgY29udlRvdGFsID0gMDtcbiAgY29udlRvdGFsUGFnZXMgPSAxO1xuICBjb252UGFnaW5hdGlvblNpemVzID0gWzEwLCAyMCwgNTAsIDEwMF07XG4gIGNvbnZMb2FkaW5nID0gZmFsc2U7XG4gIGNvbnZTZWFyY2hRdWVyeSA9ICcnO1xuICBleHBhbmRlZENvbnZJZHM6IHsgW2lkOiBzdHJpbmddOiBib29sZWFuIH0gPSB7fTtcbiAgY29udlRhYnM6IHsgW2NvbnZJZDogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcblxuICAvLyBBSSBDaGF0XG4gIGNvbnZBaVJlcGx5ID0gJyc7XG4gIGNvbnZBaUxvYWRpbmcgPSBmYWxzZTtcblxuICAvLyDilIDilIAgQWdlbnQgQW5hbHlzaXMgKGNvaG9ydC9hdWRpby1wYWdlIEFQSSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIGNvaG9ydExpc3Q6IGFueVtdID0gW107XG4gIHNlbGVjdGVkQ29ob3J0SWQgPSAnJztcbiAgc2VsZWN0ZWRDb2hvcnROYW1lID0gJyc7XG4gIGNvaG9ydENhcmRzOiBhbnlbXSA9IFtdO1xuICBjYXJkc0xvYWRpbmcgPSBmYWxzZTtcbiAgZGV0YWlsVmlldyA9IGZhbHNlO1xuICBhbmFseXNpc1NlYXJjaCA9ICcnO1xuXG4gIGdldCBhY3RpdmVDb2hvcnRzKCk6IGFueVtdIHtcbiAgICByZXR1cm4gdGhpcy5jb2hvcnRMaXN0LmZpbHRlcigoYzogYW55KSA9PiBjLm1ldHJpY3NBZGRlZCA+IDApO1xuICB9XG5cbiAgLy8gRGV0YWlsIGNvbnZlcnNhdGlvbnMgKGZyb20gY29ob3J0IGNhcmQgY2xpY2spXG4gIGRldGFpbENvbnZlcnNhdGlvbnM6IGFueVtdID0gW107XG4gIGRldGFpbFBhZ2UgPSAxO1xuICBkZXRhaWxQZXJQYWdlID0gMTA7XG4gIGRldGFpbFRvdGFsUGFnZXMgPSAxO1xuICBkZXRhaWxUb3RhbCA9IDA7XG4gIGRldGFpbFBhZ2luYXRpb25TaXplcyA9IFsxMCwgMjAsIDUwLCAxMDBdO1xuICBkZXRhaWxQYWdlQ29udnM6IGFueVtdID0gW107XG4gIGRldGFpbE9wZW5JZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIGRldGFpbExvYWRpbmcgPSBmYWxzZTtcbiAgZGV0YWlsQ29udkRldGFpbDogYW55ID0gbnVsbDtcblxuICAvLyDilIDilIAgTWFuYWdlIChjb2hvcnQgQ1JVRCBBUEkpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBtYW5hZ2VDb2hvcnRzOiBhbnlbXSA9IFtdO1xuICBtYW5hZ2VMb2FkaW5nID0gZmFsc2U7XG4gIG1hbmFnZVBhZ2UgPSAxO1xuICBtYW5hZ2VQZXJQYWdlID0gMTA7XG4gIG1hbmFnZVRvdGFsID0gMDtcbiAgbWFuYWdlVG90YWxQYWdlcyA9IDE7XG4gIG1hbmFnZVBhZ2luYXRpb25TaXplcyA9IFsxMCwgMjAsIDMwXTtcbiAgbWFuYWdlU2VhcmNoID0gJyc7XG5cbiAgLy8g4pSA4pSAIEF1ZGlvIFBsYXllciDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcGxheWluZ0NvbnZJZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIHdhdmVmb3JtSGVpZ2h0czogbnVtYmVyW10gPSBbXTtcblxuICBwcml2YXRlIGdlbmVyYXRlV2F2ZWZvcm0oKTogdm9pZCB7XG4gICAgLy8gR2VuZXJhdGUgfjIwMCBiYXJzIHdpdGggbmF0dXJhbCB3YXZlZm9ybSBwYXR0ZXJuXG4gICAgY29uc3QgYmFyczogbnVtYmVyW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IDIwMDsgaSsrKSB7XG4gICAgICBjb25zdCBoID0gTWF0aC5tYXgoMywgTWF0aC5hYnMoTWF0aC5zaW4oaSAqIDAuMTUpICogMjggKyBNYXRoLnNpbihpICogMC40KSAqIDEyICsgTWF0aC5jb3MoaSAqIDAuMDgpICogOCkpO1xuICAgICAgYmFycy5wdXNoKE1hdGgucm91bmQoaCkpO1xuICAgIH1cbiAgICB0aGlzLndhdmVmb3JtSGVpZ2h0cyA9IGJhcnM7XG4gIH1cblxuICAvLyDilIDilIAgQ29ob3J0IERyb3Bkb3duIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBjb2hvcnREcm9wZG93bk9wZW4gPSBmYWxzZTtcbiAgY29ob3J0RHJvcGRvd25TZWFyY2ggPSAnJztcblxuICB0b2dnbGVDb2hvcnREcm9wZG93bigpOiB2b2lkIHtcbiAgICB0aGlzLmNvaG9ydERyb3Bkb3duT3BlbiA9ICF0aGlzLmNvaG9ydERyb3Bkb3duT3BlbjtcbiAgICBpZiAodGhpcy5jb2hvcnREcm9wZG93bk9wZW4pIHtcbiAgICAgIHRoaXMuY29ob3J0RHJvcGRvd25TZWFyY2ggPSAnJztcbiAgICB9XG4gIH1cblxuICBjbG9zZUNvaG9ydERyb3Bkb3duKCk6IHZvaWQge1xuICAgIHRoaXMuY29ob3J0RHJvcGRvd25PcGVuID0gZmFsc2U7XG4gICAgdGhpcy5jb2hvcnREcm9wZG93blNlYXJjaCA9ICcnO1xuICB9XG5cbiAgc2VsZWN0Q29ob3J0RnJvbURyb3Bkb3duKGNvaG9ydDogYW55KTogdm9pZCB7XG4gICAgY29uc3QgaWQgPSBjb2hvcnQuY29ob3J0SWQgfHwgY29ob3J0LmlkIHx8IGNvaG9ydC5faWQgfHwgJyc7XG4gICAgdGhpcy5jb2hvcnREcm9wZG93bk9wZW4gPSBmYWxzZTtcbiAgICB0aGlzLmNvaG9ydERyb3Bkb3duU2VhcmNoID0gJyc7XG4gICAgdGhpcy5vbkNvaG9ydERyb3Bkb3duQ2hhbmdlKGlkKTtcbiAgfVxuXG4gIGdldCBmaWx0ZXJlZERyb3Bkb3duQ29ob3J0cygpOiBhbnlbXSB7XG4gICAgaWYgKCF0aGlzLmNvaG9ydERyb3Bkb3duU2VhcmNoKSByZXR1cm4gdGhpcy5jb2hvcnRMaXN0O1xuICAgIGNvbnN0IHEgPSB0aGlzLmNvaG9ydERyb3Bkb3duU2VhcmNoLnRvTG93ZXJDYXNlKCk7XG4gICAgcmV0dXJuIHRoaXMuY29ob3J0TGlzdC5maWx0ZXIoKGM6IGFueSkgPT4gKChjLmNvaG9ydE5hbWUgfHwgYy5uYW1lIHx8ICcnKSBhcyBzdHJpbmcpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocSkpO1xuICB9XG5cbiAgLy8g4pSA4pSAIEZpbHRlcnMgRHJhd2VyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBkcmF3ZXJPcGVuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLy8gRGVmYXVsdCBzdG9yZSBsaXN0IChzYW1lIGFzIGV4aXN0aW5nIGF1ZGlvLXBhZ2UvdHJhbnNjcmlwdC1saXN0KVxuICBwcml2YXRlIGRlZmF1bHRTdG9yZXMgPSBbXG4gICAgJzExLTEwNjInLCAnMTEtMTA3OCcsICcxMS0xMDgzJywgJzExLTE1MTUnLCAnMTEtMTU0JywgJzExLTE2MjYnLFxuICAgICcxMS0xODEnLCAnMTEtMTk0NycsICcxMS0xOTk0JywgJzExLTIwMCcsICcxMS0yMDInLCAnMTEtMjE1JyxcbiAgICAnMTEtMjYwJywgJzExLTc4JywgJzExLTgxOSdcbiAgXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGF1ZGlvU2VydmljZTogQXVkaW9TZXJ2aWNlLFxuICAgIHByaXZhdGUgcm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgZ3M6IEdsb2JhbFN0YXRlU2VydmljZVxuICApIHtcbiAgICB0aGlzLmdlbmVyYXRlV2F2ZWZvcm0oKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIDEuIEdldCB1c2VyIGluZm9cbiAgICBpZiAoJ3VzZXItaW5mbycgaW4gbG9jYWxTdG9yYWdlKSB7XG4gICAgICB0aGlzLnVzZXJzID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndXNlci1pbmZvJykgfHwgJ3t9Jyk7XG4gICAgICB0aGlzLmNsaWVudElkID0gdGhpcy51c2Vycz8uY2xpZW50SWQgfHwgJzExJztcbiAgICB9XG5cbiAgICAvLyAyLiBSZXN0b3JlIGZpbHRlcnMgZnJvbSBsb2NhbFN0b3JhZ2VcbiAgICBpZiAoJ2hlYWRlci1maWx0ZXJzJyBpbiBsb2NhbFN0b3JhZ2UpIHtcbiAgICAgIGNvbnN0IGhlYWRlckZpbHRlcnMgPSBKU09OLnBhcnNlKGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdoZWFkZXItZmlsdGVycycpIHx8ICd7fScpO1xuICAgICAgdGhpcy5jbGllbnRJZCA9IGhlYWRlckZpbHRlcnM/LmNsaWVudCB8fCB0aGlzLmNsaWVudElkO1xuICAgICAgaWYgKGhlYWRlckZpbHRlcnM/LmRhdGU/LnN0YXJ0RGF0ZSkge1xuICAgICAgICB0aGlzLnN0YXJ0RGF0ZSA9IGhlYWRlckZpbHRlcnMuZGF0ZS5zdGFydERhdGU7XG4gICAgICAgIHRoaXMuZW5kRGF0ZSA9IGhlYWRlckZpbHRlcnMuZGF0ZS5lbmREYXRlO1xuICAgICAgfVxuICAgICAgaWYgKGhlYWRlckZpbHRlcnM/LnN0b3Jlcz8ubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuc3RvcmVJZHMgPSB0aGlzLmV4dHJhY3RDaGVja2VkU3RvcmVzKGhlYWRlckZpbHRlcnMuc3RvcmVzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAzLiBTdWJzY3JpYmUgdG8gcXVlcnkgcGFyYW1zIGZvciB0YWIgc3dpdGNoaW5nIOKAlCBhbHNvIHJlbG9hZCBkYXRhIG9uIHRhYiBjaGFuZ2VcbiAgICB0aGlzLnJvdXRlLnF1ZXJ5UGFyYW1zLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUocGFyYW1zID0+IHtcbiAgICAgIGNvbnN0IHByZXZQYWdlID0gdGhpcy5jdXJyZW50UGFnZTtcbiAgICAgIGNvbnN0IHRhYiA9IHBhcmFtc1sndGFiJ107XG4gICAgICBpZiAodGFiID09PSAnYW5hbHlzaXMnKSB7XG4gICAgICAgIHRoaXMuY3VycmVudFBhZ2UgPSAnYWdlbnRhbmFseXNpcyc7XG4gICAgICB9IGVsc2UgaWYgKHRhYiA9PT0gJ21hbmFnZScpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9ICdtYW5hZ2UnO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9ICdjb252ZXJzYXRpb25zJztcbiAgICAgIH1cbiAgICAgIC8vIE9ubHkgcmVsb2FkIGlmIHRhYiBhY3R1YWxseSBjaGFuZ2VkIChhdm9pZCBkdXBsaWNhdGUgY2FsbHMgb24gaW5pdClcbiAgICAgIGlmIChwcmV2UGFnZSAhPT0gdGhpcy5jdXJyZW50UGFnZSkge1xuICAgICAgICB0aGlzLmxvYWRDdXJyZW50VGFiKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyA0LiBTdWJzY3JpYmUgdG8gZ2xvYmFsIHRvb2xiYXIgY2hhbmdlcyDigJQgdGhpcyBpcyB0aGUgTUFJTiBkYXRhIHRyaWdnZXJcbiAgICAvLyAgICAoc2FtZSBwYXR0ZXJuIGFzIHRyYW5zY3JpcHQtbGlzdCBhbmQgYXVkaW8tcGFnZSlcbiAgICB0aGlzLmdzLmRhdGFSYW5nZVZhbHVlLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGRhdGE6IGFueSkgPT4ge1xuICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgdGhpcy5oZWFkZXJEYXRhID0gZGF0YTtcbiAgICAgICAgdGhpcy5jbGllbnRJZCA9IGRhdGE/LmNsaWVudCB8fCB0aGlzLmNsaWVudElkO1xuICAgICAgICBpZiAoZGF0YT8uZGF0ZT8uc3RhcnREYXRlKSB7XG4gICAgICAgICAgdGhpcy5zdGFydERhdGUgPSBkYXRhLmRhdGUuc3RhcnREYXRlO1xuICAgICAgICAgIHRoaXMuZW5kRGF0ZSA9IGRhdGEuZGF0ZS5lbmREYXRlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRhPy5zdG9yZXM/Lmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuc3RvcmVJZHMgPSB0aGlzLmV4dHJhY3RDaGVja2VkU3RvcmVzKGRhdGEuc3RvcmVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gRmV0Y2ggZGF0YSBmb3IgY3VycmVudCB0YWIgKGRhdGFSYW5nZVZhbHVlIGZpcmVzIG9uIHBhZ2UgbG9hZCB0b28pXG4gICAgICB0aGlzLmxvYWRDdXJyZW50VGFiKCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBsb2FkQ3VycmVudFRhYigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jdXJyZW50UGFnZSA9PT0gJ2NvbnZlcnNhdGlvbnMnKSB7XG4gICAgICB0aGlzLmNvbnZQYWdlID0gMTtcbiAgICAgIHRoaXMuZmV0Y2hDb252ZXJzYXRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRQYWdlID09PSAnYWdlbnRhbmFseXNpcycpIHtcbiAgICAgIHRoaXMubG9hZENvaG9ydExpc3QoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudFBhZ2UgPT09ICdtYW5hZ2UnKSB7XG4gICAgICB0aGlzLm1hbmFnZVBhZ2UgPSAxO1xuICAgICAgdGhpcy5sb2FkTWFuYWdlQ29ob3J0cygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBNYXBwaW5nIChzYW1lIGFzIHRyYW5zY3JpcHQtbGlzdCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIHByaXZhdGUgbWFwQ29udmVyc2F0aW9uKGl0ZW06IGFueSk6IGFueSB7XG4gICAgY29uc3QgcmF3VGltZSA9IGl0ZW0uVGltZXN0YW1wIHx8IGl0ZW0udGltZSB8fCAnJztcbiAgICBjb25zdCByYXdEdXJhdGlvbiA9IGl0ZW0uRHVyYXRpb24gfHwgaXRlbS5kdXJhdGlvbiB8fCAnJztcbiAgICBjb25zdCByYXdEZXNjID0gaXRlbS5TdW1tYXJ5IHx8IGl0ZW0uYXVkaW9EZXNjcmlwdGlvbiB8fCBpdGVtLnN1bW1hcnkgfHwgaXRlbS5jb252ZXJzYXRpb25EZXRhaWxzPy5hdWRpb1N1bW1hcnkgfHwgJyc7XG4gICAgcmV0dXJuIHtcbiAgICAgIGF1ZGlvSWQ6IGl0ZW0uZG9jX2lkIHx8IGl0ZW0uYXVkaW9JZCB8fCBpdGVtLl9pZCB8fCAnJyxcbiAgICAgIHN0b3JlSWQ6IGl0ZW0uc3RvcmVJZCB8fCAnJyxcbiAgICAgIHN0b3JlTmFtZTogaXRlbS5zdG9yZU5hbWUgfHwgJycsXG4gICAgICB1c2VyTmFtZTogaXRlbS5zdGFmZiB8fCBpdGVtLnN0YWZmSWQgfHwgaXRlbS51c2VyTmFtZSB8fCBpdGVtLnN0YWZmTmFtZSB8fCAnJyxcbiAgICAgIGxvY2F0aW9uOiBpdGVtLmxvY2F0aW9uIHx8IGl0ZW0uc3RhdGUgfHwgJycsXG4gICAgICBkYXRlOiBpdGVtLmRhdGUgfHwgJycsXG4gICAgICB0aW1lOiB0aGlzLmZvcm1hdFRpbWUocmF3VGltZSksXG4gICAgICBkdXJhdGlvbjogdGhpcy5mb3JtYXREdXJhdGlvbihyYXdEdXJhdGlvbiksXG4gICAgICBhdWRpb0Rlc2NyaXB0aW9uOiB0aGlzLmNsZWFuVHJhbnNjcmlwdGlvbihyYXdEZXNjKSxcbiAgICAgIGF1ZGlvVXJsOiBpdGVtLmF1ZGlvVXJsIHx8IGl0ZW0uYXVkaW9fdXJsIHx8ICcnLFxuICAgICAgY29udmVyc2F0aW9uRGV0YWlsczogaXRlbS5jb252ZXJzYXRpb25EZXRhaWxzIHx8IHsgYXVkaW9TdW1tYXJ5OiAnJywgdHJhbnNjcmlwdGlvbjogJycgfSxcbiAgICAgIG1ldHJpY3M6IHRoaXMucGFyc2VNZXRyaWNzKGl0ZW0ubWV0cmljcyksXG4gICAgICBhaUluc2lnaHRzOiBpdGVtLmFpSW5zaWdodHMgfHwgeyB0aXRsZTogJ0FJIEluc2lnaHRzJywgc3VtbWFyeTogW10gfSxcbiAgICAgIF9kZXRhaWxMb2FkZWQ6ICEhKGl0ZW0uYWlJbnNpZ2h0cyB8fCBpdGVtLmNvbnZlcnNhdGlvbkRldGFpbHMpLFxuICAgICAgX2RldGFpbExvYWRpbmc6IGZhbHNlLFxuICAgIH07XG4gIH1cblxuICAvLyBQYXJzZSBtZXRyaWNzIGZyb20gQVBJIHJlc3BvbnNlIChzYW1lIGFzIGF1ZGlvLXBhZ2UpXG4gIHByaXZhdGUgcGFyc2VNZXRyaWNzKHJhdzogYW55KTogYW55W10ge1xuICAgIGlmICghcmF3IHx8IHR5cGVvZiByYXcgIT09ICdvYmplY3QnKSByZXR1cm4gW107XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmF3KSkgcmV0dXJuIHJhdztcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhyYXcpXG4gICAgICAuZmlsdGVyKChzZWN0aW9uOiBhbnkpID0+IHNlY3Rpb24gJiYgdHlwZW9mIHNlY3Rpb24gPT09ICdvYmplY3QnICYmIHNlY3Rpb24udHlwZSlcbiAgICAgIC5tYXAoKHNlY3Rpb246IGFueSkgPT4gKHtcbiAgICAgICAgbmFtZTogc2VjdGlvbi5uYW1lIHx8ICcnLFxuICAgICAgICB0eXBlOiBzZWN0aW9uLnR5cGUgfHwgJycsXG4gICAgICAgIHZhbHVlOiBzZWN0aW9uLnZhbHVlIHx8IFtdXG4gICAgICB9KSk7XG4gIH1cblxuICAvLyBMb2FkIGNvbnZlcnNhdGlvbiBkZXRhaWwgb24gZXhwYW5kIChzYW1lIGFzIGF1ZGlvLXBhZ2UpXG4gIGxvYWRDb252RGV0YWlsKGNvbnY6IGFueSk6IHZvaWQge1xuICAgIGlmICgoY29udi5fZGV0YWlsTG9hZGVkICYmIGNvbnYuYXVkaW9VcmwpIHx8IGNvbnYuX2RldGFpbExvYWRpbmcpIHJldHVybjtcbiAgICBjb252Ll9kZXRhaWxMb2FkaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBwYXlsb2FkID0geyBjb2hvcnRJZDogdGhpcy5zZWxlY3RlZENvaG9ydElkID8gW3RoaXMuc2VsZWN0ZWRDb2hvcnRJZF0gOiBbXSwgY2xpZW50SWQ6IHRoaXMuY2xpZW50SWQgfTtcbiAgICB0aGlzLmF1ZGlvU2VydmljZS5nZXRDb252ZXJzYXRpb25EZXRhaWwoY29udi5hdWRpb0lkLCBwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCByYXcgPSByZXM/LmRhdGE7XG4gICAgICAgIGNvbnN0IGRldGFpbCA9IHJhdz8uYXVkaW9JZCA/IHJhdyA6IChyYXc/LmRhdGE/LmF1ZGlvSWQgPyByYXcuZGF0YSA6IChyYXcgfHwge30pKTtcbiAgICAgICAgaWYgKGRldGFpbC5tZXRyaWNzKSBjb252Lm1ldHJpY3MgPSB0aGlzLnBhcnNlTWV0cmljcyhkZXRhaWwubWV0cmljcyk7XG4gICAgICAgIGlmIChkZXRhaWwuYWlJbnNpZ2h0cz8uc3VtbWFyeT8ubGVuZ3RoKSBjb252LmFpSW5zaWdodHMgPSBkZXRhaWwuYWlJbnNpZ2h0cztcbiAgICAgICAgaWYgKGRldGFpbC5jb252ZXJzYXRpb25EZXRhaWxzPy5hdWRpb1N1bW1hcnkpIGNvbnYuY29udmVyc2F0aW9uRGV0YWlscyA9IGRldGFpbC5jb252ZXJzYXRpb25EZXRhaWxzO1xuICAgICAgICBpZiAoZGV0YWlsLmF1ZGlvVXJsIHx8IGRldGFpbC5hdWRpb191cmwpIGNvbnYuYXVkaW9VcmwgPSBkZXRhaWwuYXVkaW9VcmwgfHwgZGV0YWlsLmF1ZGlvX3VybDtcbiAgICAgICAgY29udi5fZGV0YWlsTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgY29udi5fZGV0YWlsTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7IGNvbnYuX2RldGFpbExvYWRpbmcgPSBmYWxzZTsgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gQ2xlYW4gXCJTdGFmZjpcIiwgXCJDdXN0b21lcjpcIiBwcmVmaXhlcyBmcm9tIHRyYW5zY3JpcHRpb24gdGV4dFxuICBjbGVhblRyYW5zY3JpcHRpb24odGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXRleHQpIHJldHVybiAnJztcbiAgICByZXR1cm4gdGV4dFxuICAgICAgLnJlcGxhY2UoL1xcW1xcZHsyfTpcXGR7Mn1cXHMqLT5cXHMqXFxkezJ9OlxcZHsyfVxcXVxccyovZywgJycpXG4gICAgICAucmVwbGFjZSgvXFxiKFN0YWZmfEN1c3RvbWVyKVxccyo6XFxzKi9naSwgJycpO1xuICB9XG5cbiAgLy8gRm9ybWF0IGR1cmF0aW9uIGZyb20gc2Vjb25kcyAoZS5nLiA1MTQg4oaSIFwiOG0gMTRzXCIpXG4gIHByaXZhdGUgZm9ybWF0RHVyYXRpb24odmFsOiBhbnkpOiBzdHJpbmcge1xuICAgIGlmICghdmFsKSByZXR1cm4gJyc7XG4gICAgY29uc3QgdG90YWxTZWMgPSBwYXJzZUZsb2F0KHZhbCk7XG4gICAgaWYgKGlzTmFOKHRvdGFsU2VjKSkgcmV0dXJuIHZhbDtcbiAgICBjb25zdCBtaW5zID0gTWF0aC5mbG9vcih0b3RhbFNlYyAvIDYwKTtcbiAgICBjb25zdCBzZWNzID0gTWF0aC5mbG9vcih0b3RhbFNlYyAlIDYwKTtcbiAgICByZXR1cm4gc2VjcyA+IDAgPyBgJHttaW5zfW0gJHtzZWNzfXNgIDogYCR7bWluc31tYDtcbiAgfVxuXG4gIC8vIEZvcm1hdCB0aW1lIGZyb20gSVNPIHN0cmluZyAoZS5nLiBcIjIwMjYtMDQtMDhUMjI6MDA6NDIuOTcyNzg5KzA1OjMwXCIg4oaSIFwiMTA6MDAgUE1cIilcbiAgcHJpdmF0ZSBmb3JtYXRUaW1lKHZhbDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoIXZhbCkgcmV0dXJuICcnO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUodmFsKTtcbiAgICAgIGlmIChpc05hTihkYXRlLmdldFRpbWUoKSkpIHJldHVybiB2YWw7XG4gICAgICByZXR1cm4gZGF0ZS50b0xvY2FsZVRpbWVTdHJpbmcoJ2VuLVVTJywgeyBob3VyOiAnMi1kaWdpdCcsIG1pbnV0ZTogJzItZGlnaXQnLCBob3VyMTI6IHRydWUgfSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gdmFsO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBIZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBwcml2YXRlIGV4dHJhY3RDaGVja2VkU3RvcmVzKHN0b3JlczogYW55W10pOiBzdHJpbmdbXSB7XG4gICAgLy8gRmlsdGVyIG9ubHkgY2hlY2tlZCBzdG9yZXMsIHRoZW4gZXh0cmFjdCBzdG9yZUlkXG4gICAgY29uc3QgY2hlY2tlZCA9IHN0b3Jlcy5maWx0ZXIoKHM6IGFueSkgPT4gcy5jaGVja2VkICE9PSBmYWxzZSk7XG4gICAgcmV0dXJuIGNoZWNrZWQubWFwKChzOiBhbnkpID0+IHMuX2lkIHx8IHMuc3RvcmVJZCB8fCBzKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3RvcmVJZHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLnN0b3JlSWRzLmxlbmd0aCA+IDAgPyB0aGlzLnN0b3JlSWRzIDogdGhpcy5kZWZhdWx0U3RvcmVzO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTdGFydERhdGUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zdGFydERhdGUgfHwgJzIwMjYtMDQtMDgnO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRFbmREYXRlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZW5kRGF0ZSB8fCAnMjAyNi0wNC0wOCc7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkQmFzZVBheWxvYWQoKTogYW55IHtcbiAgICByZXR1cm4ge1xuICAgICAgY2xpZW50SWQ6IFt0aGlzLmNsaWVudElkXSxcbiAgICAgIHN0b3JlSWQ6IHRoaXMuZ2V0U3RvcmVJZHMoKSxcbiAgICAgIHN0YXJ0RGF0ZTogdGhpcy5nZXRTdGFydERhdGUoKSxcbiAgICAgIGVuZERhdGU6IHRoaXMuZ2V0RW5kRGF0ZSgpLFxuICAgICAgaXNBSTogdHJ1ZSxcbiAgICAgIGFuYWx5dGljc1R5cGU6ICdhdWRpbycsXG4gICAgICBpc0V4cG9ydDogZmFsc2VcbiAgICB9O1xuICB9XG5cbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIC8vIENPTlZFUlNBVElPTlMgVEFCICh1c2VzIHRyYW5zY3JpcHRzTGlzdCBBUEkpXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICBmZXRjaENvbnZlcnNhdGlvbnMoKTogdm9pZCB7XG4gICAgdGhpcy5jb252TG9hZGluZyA9IHRydWU7XG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIC4uLnRoaXMuYnVpbGRCYXNlUGF5bG9hZCgpLFxuICAgICAgaXNBSTogZmFsc2UsXG4gICAgICBhbmFseXRpY3NUeXBlOiAndHJhbnNjcmlwdCcsXG4gICAgICBzZWFyY2hWYWx1ZTogdGhpcy5jb252U2VhcmNoUXVlcnkgfHwgJycsXG4gICAgICBsaW1pdDogdGhpcy5jb252UGVyUGFnZSxcbiAgICAgIF9pZDogW10sXG4gICAgICBvZmZzZXQ6IHRoaXMuY29udlBhZ2UgLSAxXG4gICAgfTtcblxuICAgIHRoaXMuYXVkaW9TZXJ2aWNlLnRyYW5zY3JpcHRzTGlzdChwYXlsb2FkKS5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xuICAgICAgICBjb25zdCBkYXRhID0gcmVzPy5kYXRhO1xuICAgICAgICBjb25zdCBsaXN0ID0gZGF0YT8uZGF0YSB8fCBkYXRhPy5jb252ZXJzYXRpb25zIHx8IFtdO1xuICAgICAgICB0aGlzLmNvbnZlcnNhdGlvbnMgPSBsaXN0Lm1hcCgoaXRlbTogYW55KSA9PiB0aGlzLm1hcENvbnZlcnNhdGlvbihpdGVtKSk7XG4gICAgICAgIHRoaXMuY29udlRvdGFsID0gZGF0YT8uY291bnQgPz8gZGF0YT8ucGFnaW5hdGlvbj8udG90YWwgPz8gdGhpcy5jb252ZXJzYXRpb25zLmxlbmd0aDtcbiAgICAgICAgdGhpcy5jb252VG90YWxQYWdlcyA9IE1hdGgubWF4KDEsIE1hdGguY2VpbCh0aGlzLmNvbnZUb3RhbCAvIHRoaXMuY29udlBlclBhZ2UpKTtcbiAgICAgICAgdGhpcy5jb252UGFnaW5hdGlvblNpemVzID0gdGhpcy5jb252VG90YWwgPiAxMCA/IFsxMCwgMjAsIDUwLCAxMDBdIDogW3RoaXMuY29udlRvdGFsIHx8IDEwXTtcbiAgICAgICAgdGhpcy5jb252UGVyUGFnZSA9IHRoaXMuY29udlBhZ2luYXRpb25TaXplcy5pbmNsdWRlcyh0aGlzLmNvbnZQZXJQYWdlKSA/IHRoaXMuY29udlBlclBhZ2UgOiB0aGlzLmNvbnZQYWdpbmF0aW9uU2l6ZXNbMF07XG4gICAgICAgIC8vIEF1dG8tZXhwYW5kIGZpcnN0XG4gICAgICAgIGlmICh0aGlzLmNvbnZlcnNhdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMuZXhwYW5kZWRDb252SWRzID0geyBbdGhpcy5jb252ZXJzYXRpb25zWzBdLmF1ZGlvSWRdOiB0cnVlIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jb252TG9hZGluZyA9IGZhbHNlO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgIHRoaXMuY29udmVyc2F0aW9ucyA9IFtdO1xuICAgICAgICB0aGlzLmNvbnZUb3RhbCA9IDA7XG4gICAgICAgIHRoaXMuY29udlRvdGFsUGFnZXMgPSAxO1xuICAgICAgICB0aGlzLmNvbnZMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBvbkNvbnZQYWdlQ2hhbmdlKHBhZ2U6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuY29udlBhZ2UgPSBwYWdlO1xuICAgIHRoaXMuZmV0Y2hDb252ZXJzYXRpb25zKCk7XG4gIH1cblxuICBvbkNvbnZQYWdlU2l6ZUNoYW5nZShzaXplOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnZQZXJQYWdlID0gcGFyc2VJbnQoc2l6ZSk7XG4gICAgdGhpcy5jb252UGFnZSA9IDE7XG4gICAgdGhpcy5mZXRjaENvbnZlcnNhdGlvbnMoKTtcbiAgfVxuXG4gIHRvZ2dsZUNvbnZFeHBhbmQoaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmV4cGFuZGVkQ29udklkc1tpZF0pIHtcbiAgICAgIHRoaXMuZXhwYW5kZWRDb252SWRzID0ge307XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZXhwYW5kZWRDb252SWRzID0geyBbaWRdOiB0cnVlIH07XG4gICAgfVxuICB9XG5cbiAgZ2V0Q29udklkKGNvbnY6IGFueSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbnY/LmRvY19pZCB8fCBjb252Py5hdWRpb0lkIHx8IGNvbnY/Ll9pZCB8fCAnJztcbiAgfVxuXG4gIGdldENvbnZUYWIoY29udklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNvbnZUYWJzW2NvbnZJZF0gfHwgJ3N1bW1hcnknO1xuICB9XG5cbiAgc2V0Q29udlRhYihjb252SWQ6IHN0cmluZywgdGFiOiBzdHJpbmcsIGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuY29udlRhYnNbY29udklkXSA9IHRhYjtcbiAgfVxuXG4gIC8vIEFJIFNlYXJjaFxuICBzZW5kQ29udlF1ZXJ5KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jb252U2VhcmNoUXVlcnkudHJpbSgpKSByZXR1cm47XG4gICAgdGhpcy5jb252QWlMb2FkaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmNvbnZBaVJlcGx5ID0gJyc7XG5cbiAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgdXNlcl9pZDogdGhpcy51c2Vycz8uZW1haWwgfHwgJ3VzZXInLFxuICAgICAgc2Vzc2lvbl9pZDogYEVDSE9fJHtEYXRlLm5vdygpfWAsXG4gICAgICBzZXNzaW9uX2RhdGU6IHRoaXMuc3RhcnREYXRlLFxuICAgICAgc2Vzc2lvbl90aW1lem9uZTogSW50bC5EYXRlVGltZUZvcm1hdCgpLnJlc29sdmVkT3B0aW9ucygpLnRpbWVab25lLFxuICAgICAgbWVzc2FnZTogdGhpcy5jb252U2VhcmNoUXVlcnksXG4gICAgICBhbmFseXRpY3NUeXBlOiAndHJhbnNjcmlwdCcsXG4gICAgICBjb25maWc6IHtcbiAgICAgICAgc2VsZWN0ZWRfc3RvcmVzOiB0aGlzLmdldFN0b3JlSWRzKCksXG4gICAgICAgIGRhdGVfcmFuZ2U6IHsgc3RhcnQ6IHRoaXMuc3RhcnREYXRlLCBlbmQ6IHRoaXMuZW5kRGF0ZSB9LFxuICAgICAgICBzZWxlY3RlZF9wcm9kdWN0czogWydBdWRpbyddXG4gICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMuYXVkaW9TZXJ2aWNlLmNoYXRTdHJlYW0ocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5jb252QWlSZXBseSA9IHR5cGVvZiByZXMgPT09ICdzdHJpbmcnID8gcmVzIDogKHJlcz8uZGF0YT8ubWFwKChkOiBhbnkpID0+IGQudGV4dCkuam9pbignJykgfHwgJ05vIHJlc3BvbnNlJyk7XG4gICAgICAgIHRoaXMuY29udkFpTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7XG4gICAgICAgIHRoaXMuY29udkFpUmVwbHkgPSAnVW5hYmxlIHRvIHByb2Nlc3MgeW91ciBxdWVyeS4gUGxlYXNlIHRyeSBhZ2Fpbi4nO1xuICAgICAgICB0aGlzLmNvbnZBaUxvYWRpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmNvbnZTZWFyY2hRdWVyeSA9ICcnO1xuICB9XG5cbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIC8vIEFHRU5UIEFOQUxZU0lTIFRBQiAodXNlcyBjb2hvcnQgQVBJcylcbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIGxvYWRDb2hvcnRMaXN0KCk6IHZvaWQge1xuICAgIHRoaXMuYXVkaW9TZXJ2aWNlLmxpc3RDb2hvcnRzKHRoaXMuY2xpZW50SWQsIDEwMCwgMCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5jb2hvcnRMaXN0ID0gcmVzPy5kYXRhPy5jb2hvcnRzIHx8IFtdO1xuICAgICAgICAvLyBJZiBhIGNvaG9ydCB3YXMgYWxyZWFkeSBzZWxlY3RlZCAoZS5nLiBmcm9tIGRyb3Bkb3duKSwgbG9hZCBpdHMgZGF0YVxuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZENvaG9ydElkKSB7XG4gICAgICAgICAgdGhpcy5mZXRjaENvaG9ydENhcmRzKCk7XG4gICAgICAgICAgdGhpcy5mZXRjaERldGFpbENvbnZlcnNhdGlvbnMoKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoKSA9PiB7IHRoaXMuY29ob3J0TGlzdCA9IFtdOyB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBTZWxlY3QgY29ob3J0IGZyb20gb3ZlcnZpZXcgY2FyZCBjbGlja1xuICBzZWxlY3RDb2hvcnREZXRhaWwoY29ob3J0OiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkQ29ob3J0SWQgPSBjb2hvcnQuY29ob3J0SWQgfHwgY29ob3J0LmlkIHx8IGNvaG9ydC5faWQgfHwgJyc7XG4gICAgdGhpcy5zZWxlY3RlZENvaG9ydE5hbWUgPSBjb2hvcnQuY29ob3J0TmFtZSB8fCBjb2hvcnQubmFtZSB8fCAnJztcbiAgICB0aGlzLmRldGFpbFZpZXcgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0ZWRDYXJkSWQgPSAnJztcbiAgICB0aGlzLnNlbGVjdGVkQ2FyZE5hbWUgPSAnJztcbiAgICB0aGlzLmRldGFpbFBhZ2UgPSAxO1xuICAgIHRoaXMuZmV0Y2hDb2hvcnRDYXJkcygpO1xuICAgIHRoaXMuZmV0Y2hEZXRhaWxDb252ZXJzYXRpb25zKCk7XG4gIH1cblxuICBiYWNrVG9PdmVydmlldygpOiB2b2lkIHtcbiAgICB0aGlzLmRldGFpbFZpZXcgPSBmYWxzZTtcbiAgICB0aGlzLnNlbGVjdGVkQ29ob3J0SWQgPSAnJztcbiAgICB0aGlzLnNlbGVjdGVkQ29ob3J0TmFtZSA9ICcnO1xuICAgIHRoaXMuY29ob3J0Q2FyZHMgPSBbXTtcbiAgICB0aGlzLmRldGFpbFBhZ2VDb252cyA9IFtdO1xuICAgIHRoaXMuZGV0YWlsQ29udmVyc2F0aW9ucyA9IFtdO1xuICB9XG5cbiAgLy8gQ2hhbmdlIGNvaG9ydCBmcm9tIGRyb3Bkb3duXG4gIG9uQ29ob3J0RHJvcGRvd25DaGFuZ2UoY29ob3J0SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRDb2hvcnRJZCA9IGNvaG9ydElkO1xuICAgIGNvbnN0IGNvaG9ydCA9IHRoaXMuY29ob3J0TGlzdC5maW5kKChjOiBhbnkpID0+IChjLmNvaG9ydElkIHx8IGMuaWQgfHwgYy5faWQpID09PSBjb2hvcnRJZCk7XG4gICAgdGhpcy5zZWxlY3RlZENvaG9ydE5hbWUgPSBjb2hvcnQ/LmNvaG9ydE5hbWUgfHwgY29ob3J0Py5uYW1lIHx8ICcnO1xuICAgIHRoaXMuZGV0YWlsVmlldyA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3RlZENhcmRJZCA9ICcnO1xuICAgIHRoaXMuc2VsZWN0ZWRDYXJkTmFtZSA9ICcnO1xuICAgIHRoaXMuZGV0YWlsUGFnZSA9IDE7XG4gICAgdGhpcy5mZXRjaENvaG9ydENhcmRzKCk7XG4gICAgdGhpcy5mZXRjaERldGFpbENvbnZlcnNhdGlvbnMoKTtcbiAgfVxuXG4gIGZldGNoQ29ob3J0Q2FyZHMoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNlbGVjdGVkQ29ob3J0SWQpIHJldHVybjtcbiAgICB0aGlzLmNhcmRzTG9hZGluZyA9IHRydWU7XG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIC4uLnRoaXMuYnVpbGRCYXNlUGF5bG9hZCgpLFxuICAgICAgY29ob3J0VHlwZTogW3RoaXMuc2VsZWN0ZWRDb2hvcnRJZF1cbiAgICB9O1xuXG4gICAgdGhpcy5hdWRpb1NlcnZpY2UuZ2V0Q29ob3J0QW5hbHlzaXNDYXJkKHBheWxvYWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XG4gICAgICAgIHRoaXMuY29ob3J0Q2FyZHMgPSB0aGlzLnBhcnNlQ29ob3J0QW5hbHlzaXMocmVzPy5kYXRhPy5jb2hvcnRBbmFseXNpcyB8fCB7fSk7XG4gICAgICAgIHRoaXMuY2FyZHNMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgdGhpcy5jb2hvcnRDYXJkcyA9IFtdO1xuICAgICAgICB0aGlzLmNhcmRzTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gUGFyc2UgY29ob3J0IGFuYWx5c2lzIChzYW1lIGFzIGF1ZGlvLXBhZ2UpXG4gIHBhcnNlQ29ob3J0QW5hbHlzaXMoYW5hbHlzaXM6IGFueSk6IGFueVtdIHtcbiAgICBjb25zdCBjYXJkczogYW55W10gPSBbXTtcbiAgICBjb25zdCBudW1lcmljUm93czogYW55W10gPSBbXTtcbiAgICBjb25zdCBza2lwS2V5cyA9IG5ldyBTZXQoWyd0b3RhbEF1ZGlvQXZhaWxhYmxlJywgJ2NvaG9ydFR5cGUnLCAnZGF0ZVJhbmdlJywgJ3VuaXF1ZVBpdGNoZXMnXSk7XG4gICAgdGhpcy50b3RhbEF1ZGlvID0gYW5hbHlzaXMudG90YWxBdWRpb0F2YWlsYWJsZSB8fCAwO1xuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoYW5hbHlzaXMpKSB7XG4gICAgICBpZiAoc2tpcEtleXMuaGFzKGtleSkpIGNvbnRpbnVlO1xuICAgICAgY29uc3Qgc2VjdGlvbiA9IGFuYWx5c2lzW2tleV07XG4gICAgICBpZiAoIXNlY3Rpb24gfHwgdHlwZW9mIHNlY3Rpb24gIT09ICdvYmplY3QnKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgdmFsdWVzOiBhbnlbXSA9IHNlY3Rpb24udmFsdWUgfHwgW107XG4gICAgICBjb25zdCB0eXBlID0gc2VjdGlvbi50eXBlO1xuICAgICAgaWYgKCF2YWx1ZXMubGVuZ3RoKSBjb250aW51ZTtcblxuICAgICAgLy8gQ29tbW9uIGZpZWxkcyBmcm9tIHNlY3Rpb25cbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gc2VjdGlvbi5jb21wdXRhdGlvbl9ub3RlIHx8IHNlY3Rpb24uY29tcHV0YXRpb25Ob3RlIHx8IHNlY3Rpb24uZGVzY3JpcHRpb24gfHwgc2VjdGlvbi5kZXNjIHx8ICcnO1xuICAgICAgY29uc3Qgc2hvcnREZXNjcmlwdGlvbiA9IHNlY3Rpb24uc2hvcnREZXNjcmlwdGlvbiB8fCBzZWN0aW9uLnNob3J0X2Rlc2NyaXB0aW9uIHx8ICcnO1xuICAgICAgY29uc3Qgc3RhdHVzID0gc2VjdGlvbi5zdGF0dXMgfHwgc2VjdGlvbi5zZW50aW1lbnQgfHwgJyc7XG4gICAgICBjb25zdCBhcHBsaWNhYmxlQ291bnQgPSBzZWN0aW9uLmFwcGxpY2FibGVfY291bnQgPz8gc2VjdGlvbi5hcHBsaWNhYmxlQ291bnQgPz8gbnVsbDtcblxuICAgICAgaWYgKHR5cGUgPT09ICdCT09MRUFOX0JBU0tFVCcpIHtcbiAgICAgICAgY29uc3QgY2FyZE5hbWUgPSBzZWN0aW9uLm5hbWUgfHwga2V5O1xuICAgICAgICBjb25zdCBpc0Z1bm5lbCA9IGNhcmROYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2Z1bm5lbCcpO1xuICAgICAgICBjYXJkcy5wdXNoKHtcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgbmFtZTogY2FyZE5hbWUsXG4gICAgICAgICAgdHlwZTogJ0JPT0xFQU5fQkFTS0VUJyxcbiAgICAgICAgICBpc0Z1bm5lbCxcbiAgICAgICAgICBhcHBsaWNhYmxlQ291bnQsXG4gICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgc2hvcnREZXNjcmlwdGlvbixcbiAgICAgICAgICBzdGF0dXMsXG4gICAgICAgICAgYm9vbGVhblJvd3M6IHZhbHVlcy5tYXAoKGl0ZW06IGFueSkgPT4gKHtcbiAgICAgICAgICAgIGlkOiBpdGVtLl9pZCB8fCAnJyxcbiAgICAgICAgICAgIGxhYmVsOiBpdGVtLm5hbWUsXG4gICAgICAgICAgICByZXNwb25zZXM6IGl0ZW0uUmVzcG9uc2VzID8/IGl0ZW0uY291bnQgPz8gMCxcbiAgICAgICAgICAgIHNjb3JlOiBpdGVtLnNjb3JlID8/IDBcbiAgICAgICAgICB9KSkuc29ydCgoYTogYW55LCBiOiBhbnkpID0+IGIucmVzcG9uc2VzIC0gYS5yZXNwb25zZXMpXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnTlVNRVJJQ19TQ0FMQVInIHx8IHR5cGUgPT09ICdOVU1FUklDX0FSUkFZJykge1xuICAgICAgICBjb25zdCBpdGVtID0gdmFsdWVzWzBdIHx8IHt9O1xuICAgICAgICBjb25zdCBzY2FsZSA9IHNlY3Rpb24uc2NhbGUgfHwge307XG4gICAgICAgIG51bWVyaWNSb3dzLnB1c2goe1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICBuYW1lOiBzZWN0aW9uLm5hbWUgfHwga2V5LFxuICAgICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICAgIHN0YXR1cyxcbiAgICAgICAgICBhdmc6IGl0ZW0uQXZnID8/IGl0ZW0uYXZnID8/IDAsXG4gICAgICAgICAgbWluOiBpdGVtLk1pbiA/PyBpdGVtLm1pbiA/PyBzY2FsZS5taW4gPz8gc2VjdGlvbi5taW4gPz8gbnVsbCxcbiAgICAgICAgICBtYXg6IGl0ZW0uTWF4ID8/IGl0ZW0ubWF4ID8/IHNjYWxlLm1heCA/PyBzZWN0aW9uLm1heCA/PyBudWxsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSAnU1VCSkVDVElWRScgfHwgdHlwZSA9PT0gJ1NVQkpFQ1RJVkVfQ09VTlQnKSB7XG4gICAgICAgIGNhcmRzLnB1c2goe1xuICAgICAgICAgIGtleSxcbiAgICAgICAgICBuYW1lOiBzZWN0aW9uLm5hbWUgfHwga2V5LFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgYXBwbGljYWJsZUNvdW50LFxuICAgICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICAgIHNob3J0RGVzY3JpcHRpb24sXG4gICAgICAgICAgc3RhdHVzLFxuICAgICAgICAgIHN1YmplY3RpdmVSb3dzOiB2YWx1ZXMubWFwKChpdGVtOiBhbnkpID0+ICh7XG4gICAgICAgICAgICBfaWQ6IGl0ZW0uX2lkIHx8ICcnLFxuICAgICAgICAgICAgcmVhc29uaW5nOiBpdGVtLnJlYXNvbmluZyB8fCAnJyxcbiAgICAgICAgICAgIHN0b3JlX2lkOiBpdGVtLnN0b3JlX2lkIHx8ICcnLFxuICAgICAgICAgICAgZGF0ZTogaXRlbS5kYXRlIHx8ICcnXG4gICAgICAgICAgfSkpXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEdyb3VwIGFsbCBudW1lcmljIHNjb3JlcyBpbnRvIG9uZSBjYXJkXG4gICAgaWYgKG51bWVyaWNSb3dzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNhcmRzLnB1c2goe1xuICAgICAgICBrZXk6ICdudW1lcmljU2NvcmVzJyxcbiAgICAgICAgbmFtZTogJ0F2ZXJhZ2UgU2NvcmVzJyxcbiAgICAgICAgdHlwZTogJ05VTUVSSUNfR1JPVVAnLFxuICAgICAgICBudW1lcmljUm93c1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gSW5zZXJ0IHVuaXF1ZSBwaXRjaGVzIGNhcmQgaWYgcHJlc2VudCAoc2FtZSBhcyBhdWRpby1wYWdlKVxuICAgIGlmIChhbmFseXNpcy51bmlxdWVQaXRjaGVzICYmIEFycmF5LmlzQXJyYXkoYW5hbHlzaXMudW5pcXVlUGl0Y2hlcykpIHtcbiAgICAgIGNvbnN0IHBpdGNoSW5zZXJ0SWR4ID0gY2FyZHMubGVuZ3RoID49IDIgPyAyIDogY2FyZHMubGVuZ3RoO1xuICAgICAgY2FyZHMuc3BsaWNlKHBpdGNoSW5zZXJ0SWR4LCAwLCB7XG4gICAgICAgIGtleTogJ3VuaXF1ZVBpdGNoZXMnLFxuICAgICAgICBuYW1lOiAnUGl0Y2ggS2V5d29yZHMgVHJhY2tlcicsXG4gICAgICAgIHR5cGU6ICdVTklRVUVfUElUQ0hFUycsXG4gICAgICAgIHBpdGNoUm93czogYW5hbHlzaXMudW5pcXVlUGl0Y2hlcy5tYXAoKHA6IGFueSkgPT4gKHsgaWQ6IHAucGl0Y2hJZCwgZGVzYzogcC5kZXNjcmlwdGlvbiB9KSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBjYXJkcztcbiAgfVxuXG4gIC8vIENhcmQgcm93IGNsaWNrIChzYW1lIGFzIGF1ZGlvLXBhZ2Ugb25DYXJkUm93Q2xpY2spXG4gIHNlbGVjdGVkQ2FyZElkID0gJyc7XG4gIHNlbGVjdGVkQ2FyZE5hbWUgPSAnJztcbiAgdG90YWxBdWRpbyA9IDA7XG5cbiAgb25DYXJkUm93Q2xpY2soaWQ6IGFueSwgbmFtZTogYW55KTogdm9pZCB7XG4gICAgdGhpcy5zZWxlY3RlZENhcmRJZCA9IGlkIHx8ICcnO1xuICAgIHRoaXMuc2VsZWN0ZWRDYXJkTmFtZSA9IGlkID8gJycgOiAobmFtZSB8fCAnJyk7XG4gICAgdGhpcy5kZXRhaWxQYWdlID0gMTtcbiAgICB0aGlzLmZldGNoRGV0YWlsQ29udmVyc2F0aW9ucygpO1xuICB9XG5cbiAgZmV0Y2hEZXRhaWxDb252ZXJzYXRpb25zKCk6IHZvaWQge1xuICAgIHRoaXMuZGV0YWlsTG9hZGluZyA9IHRydWU7XG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgIC4uLnRoaXMuYnVpbGRCYXNlUGF5bG9hZCgpLFxuICAgICAgY29ob3J0VHlwZTogW3RoaXMuc2VsZWN0ZWRDb2hvcnRJZF0sXG4gICAgICBsaW1pdDogdGhpcy5kZXRhaWxQZXJQYWdlLFxuICAgICAgX2lkOiB0aGlzLnNlbGVjdGVkQ2FyZElkID8gW3RoaXMuc2VsZWN0ZWRDYXJkSWRdIDogW10sXG4gICAgICBuYW1lOiB0aGlzLnNlbGVjdGVkQ2FyZE5hbWUsXG4gICAgICBvZmZzZXQ6IHRoaXMuZGV0YWlsUGFnZSAtIDFcbiAgICB9O1xuXG4gICAgdGhpcy5hdWRpb1NlcnZpY2UuZ2V0Q29udmVyc2F0aW9uc0xpc3QocGF5bG9hZCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHJlcz8uZGF0YTtcbiAgICAgICAgY29uc3QgbGlzdCA9IGRhdGE/LmRhdGEgfHwgZGF0YT8uY29udmVyc2F0aW9ucyB8fCBbXTtcbiAgICAgICAgdGhpcy5kZXRhaWxDb252ZXJzYXRpb25zID0gbGlzdC5tYXAoKGl0ZW06IGFueSkgPT4gdGhpcy5tYXBDb252ZXJzYXRpb24oaXRlbSkpO1xuICAgICAgICB0aGlzLmRldGFpbFRvdGFsID0gZGF0YT8uY291bnQgPz8gZGF0YT8ucGFnaW5hdGlvbj8udG90YWwgPz8gdGhpcy5kZXRhaWxDb252ZXJzYXRpb25zLmxlbmd0aDtcbiAgICAgICAgdGhpcy5kZXRhaWxUb3RhbFBhZ2VzID0gTWF0aC5tYXgoMSwgTWF0aC5jZWlsKHRoaXMuZGV0YWlsVG90YWwgLyB0aGlzLmRldGFpbFBlclBhZ2UpKTtcbiAgICAgICAgdGhpcy5kZXRhaWxQYWdpbmF0aW9uU2l6ZXMgPSB0aGlzLmRldGFpbFRvdGFsID4gMTAgPyBbMTAsIDIwLCA1MCwgMTAwXSA6IFt0aGlzLmRldGFpbFRvdGFsIHx8IDEwXTtcbiAgICAgICAgdGhpcy5kZXRhaWxQZXJQYWdlID0gdGhpcy5kZXRhaWxQYWdpbmF0aW9uU2l6ZXMuaW5jbHVkZXModGhpcy5kZXRhaWxQZXJQYWdlKSA/IHRoaXMuZGV0YWlsUGVyUGFnZSA6IHRoaXMuZGV0YWlsUGFnaW5hdGlvblNpemVzWzBdO1xuICAgICAgICB0aGlzLmRldGFpbFBhZ2VDb252cyA9IHRoaXMuZGV0YWlsQ29udmVyc2F0aW9ucztcbiAgICAgICAgaWYgKHRoaXMuZGV0YWlsUGFnZUNvbnZzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aGlzLmRldGFpbE9wZW5JZCA9IHRoaXMuZGV0YWlsUGFnZUNvbnZzWzBdLmF1ZGlvSWQ7XG4gICAgICAgICAgdGhpcy5sb2FkQ29udkRldGFpbCh0aGlzLmRldGFpbFBhZ2VDb252c1swXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kZXRhaWxMb2FkaW5nID0gZmFsc2U7XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgdGhpcy5kZXRhaWxDb252ZXJzYXRpb25zID0gW107XG4gICAgICAgIHRoaXMuZGV0YWlsUGFnZUNvbnZzID0gW107XG4gICAgICAgIHRoaXMuZGV0YWlsVG90YWxQYWdlcyA9IDE7XG4gICAgICAgIHRoaXMuZGV0YWlsTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbG9hZENvbnZlcnNhdGlvbkRldGFpbChjb252OiBhbnkpOiB2b2lkIHtcbiAgICBjb25zdCBhdWRpb0lkID0gY29udj8uZG9jX2lkIHx8IGNvbnY/LmF1ZGlvSWQgfHwgY29udj8uX2lkO1xuICAgIGlmICghYXVkaW9JZCkgcmV0dXJuO1xuXG4gICAgdGhpcy5hdWRpb1NlcnZpY2UuZ2V0Q29udmVyc2F0aW9uRGV0YWlsKGF1ZGlvSWQsIHtcbiAgICAgIGNvaG9ydElkOiBbdGhpcy5zZWxlY3RlZENvaG9ydElkXSxcbiAgICAgIGNsaWVudElkOiB0aGlzLmNsaWVudElkXG4gICAgfSkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5kZXRhaWxDb252RGV0YWlsID0gcmVzPy5kYXRhIHx8IHJlcztcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4geyB0aGlzLmRldGFpbENvbnZEZXRhaWwgPSBudWxsOyB9XG4gICAgfSk7XG4gIH1cblxuICB0b2dnbGVEZXRhaWxDb252KGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmRldGFpbE9wZW5JZCA9IHRoaXMuZGV0YWlsT3BlbklkID09PSBpZCA/IG51bGwgOiBpZDtcbiAgfVxuXG4gIG9uRGV0YWlsUGFnZUNoYW5nZShwYWdlOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmRldGFpbFBhZ2UgPSBwYWdlO1xuICAgIHRoaXMuZmV0Y2hEZXRhaWxDb252ZXJzYXRpb25zKCk7XG4gIH1cblxuICBvbkRldGFpbFBhZ2VTaXplQ2hhbmdlKHNpemU6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuZGV0YWlsUGVyUGFnZSA9IHBhcnNlSW50KHNpemUpO1xuICAgIHRoaXMuZGV0YWlsUGFnZSA9IDE7XG4gICAgdGhpcy5mZXRjaERldGFpbENvbnZlcnNhdGlvbnMoKTtcbiAgfVxuXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICAvLyBNQU5BR0UgVEFCICh1c2VzIGxpc3RDb2hvcnRzL2RlbGV0ZUNvaG9ydCBBUElzKVxuICAvLyDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZBcbiAgbG9hZE1hbmFnZUNvaG9ydHMoKTogdm9pZCB7XG4gICAgdGhpcy5tYW5hZ2VMb2FkaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBvZmZzZXQgPSAodGhpcy5tYW5hZ2VQYWdlIC0gMSkgKiB0aGlzLm1hbmFnZVBlclBhZ2U7XG5cbiAgICB0aGlzLmF1ZGlvU2VydmljZS5saXN0Q29ob3J0cyh0aGlzLmNsaWVudElkLCB0aGlzLm1hbmFnZVBlclBhZ2UsIG9mZnNldCkucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcbiAgICAgICAgdGhpcy5tYW5hZ2VDb2hvcnRzID0gcmVzPy5kYXRhPy5jb2hvcnRzIHx8IFtdO1xuICAgICAgICB0aGlzLm1hbmFnZVRvdGFsID0gcmVzPy5kYXRhPy5wYWdpbmF0aW9uPy50b3RhbCA/PyB0aGlzLm1hbmFnZUNvaG9ydHMubGVuZ3RoO1xuICAgICAgICB0aGlzLm1hbmFnZVRvdGFsUGFnZXMgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodGhpcy5tYW5hZ2VUb3RhbCAvIHRoaXMubWFuYWdlUGVyUGFnZSkpO1xuICAgICAgICB0aGlzLm1hbmFnZUxvYWRpbmcgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKCkgPT4ge1xuICAgICAgICB0aGlzLm1hbmFnZUNvaG9ydHMgPSBbXTtcbiAgICAgICAgdGhpcy5tYW5hZ2VUb3RhbCA9IDA7XG4gICAgICAgIHRoaXMubWFuYWdlVG90YWxQYWdlcyA9IDE7XG4gICAgICAgIHRoaXMubWFuYWdlTG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb25NYW5hZ2VQYWdlQ2hhbmdlKHBhZ2U6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubWFuYWdlUGFnZSA9IHBhZ2U7XG4gICAgdGhpcy5sb2FkTWFuYWdlQ29ob3J0cygpO1xuICB9XG5cbiAgb25NYW5hZ2VQYWdlU2l6ZUNoYW5nZShzaXplOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm1hbmFnZVBlclBhZ2UgPSBwYXJzZUludChzaXplKTtcbiAgICB0aGlzLm1hbmFnZVBhZ2UgPSAxO1xuICAgIHRoaXMubG9hZE1hbmFnZUNvaG9ydHMoKTtcbiAgfVxuXG4gIG9uTWFuYWdlU2VhcmNoKCk6IHZvaWQge1xuICAgIHRoaXMubWFuYWdlUGFnZSA9IDE7XG4gICAgdGhpcy5sb2FkTWFuYWdlQ29ob3J0cygpO1xuICB9XG5cbiAgZGVsZXRlQ29ob3J0KGNvaG9ydElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIWNvbmZpcm0oJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgdGhpcyBjb2hvcnQ/JykpIHJldHVybjtcbiAgICB0aGlzLmF1ZGlvU2VydmljZS5kZWxldGVDb2hvcnQoY29ob3J0SWQpLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKCkgPT4geyB0aGlzLmxvYWRNYW5hZ2VDb2hvcnRzKCk7IH0sXG4gICAgICBlcnJvcjogKCkgPT4geyBhbGVydCgnRmFpbGVkIHRvIGRlbGV0ZSBjb2hvcnQuJyk7IH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICAvLyBBVURJTyBQTEFZRVIgKHNhbWUgcGF0dGVybiBhcyB0cmFuc2NyaXB0LWxpc3QpXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICBwbGF5YmFja1N0YXRlczogeyBbaWQ6IHN0cmluZ106IHsgY3VycmVudFRpbWU6IHN0cmluZzsgdG90YWxUaW1lOiBzdHJpbmc7IHByb2dyZXNzOiBudW1iZXIgfSB9ID0ge307XG4gIGlzTXV0ZWQgPSBmYWxzZTtcblxuICB0b2dnbGVQbGF5KGNvbnZJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgYXVkaW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChgYXVkaW8tJHtjb252SWR9YCkgYXMgSFRNTEF1ZGlvRWxlbWVudDtcbiAgICBpZiAoIWF1ZGlvKSByZXR1cm47XG4gICAgaWYgKHRoaXMucGxheWluZ0NvbnZJZCA9PT0gY29udklkKSB7XG4gICAgICBhdWRpby5wYXVzZSgpO1xuICAgICAgdGhpcy5wbGF5aW5nQ29udklkID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUGF1c2UgYW55IGN1cnJlbnRseSBwbGF5aW5nXG4gICAgICBpZiAodGhpcy5wbGF5aW5nQ29udklkKSB7XG4gICAgICAgIGNvbnN0IG90aGVyID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoYGF1ZGlvLSR7dGhpcy5wbGF5aW5nQ29udklkfWApIGFzIEhUTUxBdWRpb0VsZW1lbnQ7XG4gICAgICAgIGlmIChvdGhlcikgb3RoZXIucGF1c2UoKTtcbiAgICAgICAgdGhpcy5wbGF5aW5nQ29udklkID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBsYXlQcm9taXNlID0gYXVkaW8ucGxheSgpO1xuICAgICAgaWYgKHBsYXlQcm9taXNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcGxheVByb21pc2UudGhlbigoKSA9PiB7IHRoaXMucGxheWluZ0NvbnZJZCA9IGNvbnZJZDsgfSkuY2F0Y2goKCkgPT4geyB0aGlzLnBsYXlpbmdDb252SWQgPSBudWxsOyB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucGxheWluZ0NvbnZJZCA9IGNvbnZJZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvbkxvYWRlZE1ldGFkYXRhKGF1ZGlvOiBIVE1MQXVkaW9FbGVtZW50LCBjb252SWQ6IHN0cmluZywgYXBpRHVyYXRpb24/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucGxheWJhY2tTdGF0ZXNbY29udklkXSkge1xuICAgICAgdGhpcy5wbGF5YmFja1N0YXRlc1tjb252SWRdID0geyBjdXJyZW50VGltZTogJzA6MDAnLCB0b3RhbFRpbWU6ICcwOjAwJywgcHJvZ3Jlc3M6IDAgfTtcbiAgICB9XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLnBsYXliYWNrU3RhdGVzW2NvbnZJZF07XG4gICAgaWYgKGlzRmluaXRlKGF1ZGlvLmR1cmF0aW9uKSAmJiBhdWRpby5kdXJhdGlvbiA+IDApIHtcbiAgICAgIHN0YXRlLnRvdGFsVGltZSA9IHRoaXMuZm9ybWF0QXVkaW9UaW1lKGF1ZGlvLmR1cmF0aW9uKTtcbiAgICB9IGVsc2UgaWYgKGFwaUR1cmF0aW9uKSB7XG4gICAgICBzdGF0ZS50b3RhbFRpbWUgPSBhcGlEdXJhdGlvbjtcbiAgICB9XG4gIH1cblxuICBvblRpbWVVcGRhdGUoYXVkaW86IEhUTUxBdWRpb0VsZW1lbnQsIGNvbnZJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnBsYXliYWNrU3RhdGVzW2NvbnZJZF0pIHtcbiAgICAgIHRoaXMucGxheWJhY2tTdGF0ZXNbY29udklkXSA9IHsgY3VycmVudFRpbWU6ICcwOjAwJywgdG90YWxUaW1lOiAnMDowMCcsIHByb2dyZXNzOiAwIH07XG4gICAgfVxuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5wbGF5YmFja1N0YXRlc1tjb252SWRdO1xuICAgIHN0YXRlLmN1cnJlbnRUaW1lID0gdGhpcy5mb3JtYXRBdWRpb1RpbWUoYXVkaW8uY3VycmVudFRpbWUpO1xuICAgIGlmIChpc0Zpbml0ZShhdWRpby5kdXJhdGlvbikgJiYgYXVkaW8uZHVyYXRpb24gPiAwKSB7XG4gICAgICBzdGF0ZS5wcm9ncmVzcyA9IGF1ZGlvLmN1cnJlbnRUaW1lIC8gYXVkaW8uZHVyYXRpb247XG4gICAgfVxuICB9XG5cbiAgc2Vla0F1ZGlvKGV2ZW50OiBNb3VzZUV2ZW50LCBjb252SWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHRyYWNrID0gZXZlbnQuY3VycmVudFRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCByYXRpbyA9IGV2ZW50Lm9mZnNldFggLyB0cmFjay5vZmZzZXRXaWR0aDtcbiAgICBjb25zdCBhdWRpbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGBhdWRpby0ke2NvbnZJZH1gKSBhcyBIVE1MQXVkaW9FbGVtZW50O1xuICAgIGlmICghYXVkaW8gfHwgIWF1ZGlvLmR1cmF0aW9uKSByZXR1cm47XG4gICAgYXVkaW8uY3VycmVudFRpbWUgPSByYXRpbyAqIGF1ZGlvLmR1cmF0aW9uO1xuICB9XG5cbiAgdG9nZ2xlTXV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLmlzTXV0ZWQgPSAhdGhpcy5pc011dGVkO1xuICAgIGNvbnN0IGF1ZGlvcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ2F1ZGlvJyk7XG4gICAgYXVkaW9zLmZvckVhY2goYSA9PiBhLm11dGVkID0gdGhpcy5pc011dGVkKTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0QXVkaW9UaW1lKHNlY29uZHM6IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKCFzZWNvbmRzKSByZXR1cm4gJzA6MDAnO1xuICAgIGNvbnN0IG1pbnMgPSBNYXRoLmZsb29yKHNlY29uZHMgLyA2MCk7XG4gICAgY29uc3Qgc2VjcyA9IE1hdGguZmxvb3Ioc2Vjb25kcyAlIDYwKTtcbiAgICByZXR1cm4gYCR7bWluc306JHtzZWNzIDwgMTAgPyAnMCcgKyBzZWNzIDogc2Vjc31gO1xuICB9XG5cbiAgLy8g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQXG4gIC8vIEZJTFRFUlMgRFJBV0VSXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICBvcGVuRmlsdGVyRHJhd2VyKCk6IHZvaWQgeyB0aGlzLmRyYXdlck9wZW4gPSB0cnVlOyB9XG4gIGNsb3NlRmlsdGVyRHJhd2VyKCk6IHZvaWQgeyB0aGlzLmRyYXdlck9wZW4gPSBmYWxzZTsgfVxuXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICAvLyBVVElMSVRZXG4gIC8vIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkFxuICB0cmFja0J5SWQoaW5kZXg6IG51bWJlciwgaXRlbTogYW55KTogYW55IHtcbiAgICByZXR1cm4gaXRlbT8uaWQgfHwgaXRlbT8uX2lkIHx8IGl0ZW0/LmRvY19pZCB8fCBpbmRleDtcbiAgfVxuXG4gIGdldFN0YXR1c0JhZGdlKHN0YXR1czogc3RyaW5nKTogeyBiZzogc3RyaW5nOyBjb2xvcjogc3RyaW5nIH0ge1xuICAgIGlmICghc3RhdHVzKSByZXR1cm4geyBiZzogJycsIGNvbG9yOiAnJyB9O1xuICAgIGNvbnN0IHMgPSBzdGF0dXMudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAocy5pbmNsdWRlcygncG9zaXRpdmUnKSB8fCBzLmluY2x1ZGVzKCdzdHJvbmcnKSB8fCBzLmluY2x1ZGVzKCdnb29kJykgfHwgcy5pbmNsdWRlcygnY29uZmlkZW50JykgfHwgcy5pbmNsdWRlcygnZXhjZWxsZW50JykpXG4gICAgICByZXR1cm4geyBiZzogJyNEMUZBRTUnLCBjb2xvcjogJyMwNjVGNDYnIH07XG4gICAgaWYgKHMuaW5jbHVkZXMoJ3dhcm5pbmcnKSB8fCBzLmluY2x1ZGVzKCdtb2RlcmF0ZScpIHx8IHMuaW5jbHVkZXMoJ3Jvb20gdG8gaW1wcm92ZScpIHx8IHMuaW5jbHVkZXMoJ2F2ZXJhZ2UnKSlcbiAgICAgIHJldHVybiB7IGJnOiAnI0ZFRjNDNycsIGNvbG9yOiAnIzkyNDAwRScgfTtcbiAgICBpZiAocy5pbmNsdWRlcygnbmVnYXRpdmUnKSB8fCBzLmluY2x1ZGVzKCd3ZWFrJykgfHwgcy5pbmNsdWRlcygncG9vcicpIHx8IHMuaW5jbHVkZXMoJ2NyaXRpY2FsJykpXG4gICAgICByZXR1cm4geyBiZzogJyNGRUUyRTInLCBjb2xvcjogJyM5OTFCMUInIH07XG4gICAgcmV0dXJuIHsgYmc6ICcjRjBGNEZGJywgY29sb3I6ICcjMUEyQjRCJyB9O1xuICB9XG5cbiAgZm9ybWF0TWV0cmljVmFsdWUodjogYW55KTogc3RyaW5nIHtcbiAgICBpZiAodi5zY29yZSAhPSBudWxsKSB7XG4gICAgICBjb25zdCBzID0gdi5zY29yZTtcbiAgICAgIGlmICh0eXBlb2YgcyA9PT0gJ251bWJlcicpIHJldHVybiBzICsgJyUnO1xuICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKHMpO1xuICAgICAgcmV0dXJuIHN0ci5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHN0ci5zbGljZSgxKS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cbiAgICBjb25zdCB2YWwgPSB2LlRvdGFsID8/IHYudG90YWwgPz8gdi5BdmcgPz8gdi5hdmcgPz8gdi5jb3VudDtcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB2YWwuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB2YWwuc2xpY2UoMSkudG9Mb3dlckNhc2UoKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbCAhPSBudWxsID8gU3RyaW5nKHZhbCkgOiAnJztcbiAgfVxuXG4gIGdldFNjb3JlQ29sb3Ioc2NvcmU6IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKHNjb3JlID49IDM1KSByZXR1cm4gJyMwMDc3RTYnO1xuICAgIGlmIChzY29yZSA+PSAyMCkgcmV0dXJuICcjMDBBM0ZGJztcbiAgICBpZiAoc2NvcmUgPj0gMTApIHJldHVybiAnIzREQzNGRic7XG4gICAgaWYgKHNjb3JlID49IDUpIHJldHVybiAnIzhBRDhGRic7XG4gICAgaWYgKHNjb3JlID49IDIpIHJldHVybiAnI0JERThGRic7XG4gICAgcmV0dXJuICcjRDlGMUZGJztcbiAgfVxuXG4gIGhhc1NlYXJjaE1hdGNoKGxpc3Q6IGFueVtdLCBzZWFyY2g6IHN0cmluZywga2V5MTogc3RyaW5nLCBrZXkyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIXNlYXJjaCkgcmV0dXJuIHRydWU7XG4gICAgY29uc3QgcSA9IHNlYXJjaC50b0xvd2VyQ2FzZSgpO1xuICAgIHJldHVybiBsaXN0LnNvbWUoaXRlbSA9PiAoKGl0ZW1ba2V5MV0gfHwgaXRlbVtrZXkyXSB8fCAnJykgYXMgc3RyaW5nKS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHEpKTtcbiAgfVxuXG4gIE1hdGggPSBNYXRoO1xufVxuIiwiPGRpdiBjbGFzcz1cImVjaG8tcGFnZVwiPlxuICA8ZGl2IGNsYXNzPVwiZWNoby1jb250ZW50XCI+XG5cbiAgICA8IS0tIOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkCBDT05WRVJTQVRJT05TIFRBQiDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImN1cnJlbnRQYWdlID09PSAnY29udmVyc2F0aW9ucydcIj5cblxuICAgICAgPCEtLSBUYW5nbyBBSSBIZWFkZXIgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwidGFuZ28tYWktaGVhZGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YW5nby1haS1sb2dvXCI+XG4gICAgICAgICAgPHN2ZyB3aWR0aD1cIjI2XCIgaGVpZ2h0PVwiMjZcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjZmZmXCIgc3Ryb2tlLXdpZHRoPVwiMS44XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiPjxwYXRoIGQ9XCJNMTIgMmwyLjA5IDYuMjZMMjAgMTBsLTUuOTEgMS43NEwxMiAxOGwtMi4wOS02LjI2TDQgMTBsNS45MS0xLjc0TDEyIDJ6XCIvPjwvc3ZnPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRhbmdvLWFpLWhlYWRlci10ZXh0XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRhbmdvLWFpLXRpdGxlXCI+VGFuZ28gQUk8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFuZ28tYWktc3VidGl0bGVcIj5BbmFseXNlIGNvbnZlcnNhdGlvbnMsIHN0b3JlcyAmIHN0YWZmIHBlcmZvcm1hbmNlPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gU2VhcmNoIENhcmQgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZWNoby1zZWFyY2gtY2FyZFwiPlxuICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImVjaG8tc2VhcmNoLWlucHV0XCIgcGxhY2Vob2xkZXI9XCJBc2sgYW55dGhpbmcuLi4gJ1doaWNoIHN0b3JlcyBhcmUgbm90IHBlcmZvcm1pbmcgd2VsbD8nXCIgWyhuZ01vZGVsKV09XCJjb252U2VhcmNoUXVlcnlcIiAoa2V5dXAuZW50ZXIpPVwic2VuZENvbnZRdWVyeSgpXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJlY2hvLXNlYXJjaC1zZW5kXCIgKGNsaWNrKT1cInNlbmRDb252UXVlcnkoKVwiIFtkaXNhYmxlZF09XCIhY29udlNlYXJjaFF1ZXJ5Py50cmltKClcIj5cbiAgICAgICAgICA8c3ZnIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj5cbiAgICAgICAgICAgIDxsaW5lIHgxPVwiMjJcIiB5MT1cIjJcIiB4Mj1cIjExXCIgeTI9XCIxM1wiPjwvbGluZT5cbiAgICAgICAgICAgIDxwb2x5Z29uIHBvaW50cz1cIjIyIDIgMTUgMjIgMTEgMTMgMiA5IDIyIDJcIj48L3BvbHlnb24+XG4gICAgICAgICAgPC9zdmc+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQUkgUmVzcG9uc2UgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZWNoby1haS1yZXNwb25zZVwiICpuZ0lmPVwiY29udkFpTG9hZGluZyB8fCBjb252QWlSZXBseVwiPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udkFpTG9hZGluZ1wiIGNsYXNzPVwidHlwaW5nXCI+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0eXBpbmctZG90XCI+PC9zcGFuPjxzcGFuIGNsYXNzPVwidHlwaW5nLWRvdFwiPjwvc3Bhbj48c3BhbiBjbGFzcz1cInR5cGluZy1kb3RcIj48L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cCAqbmdJZj1cIiFjb252QWlMb2FkaW5nICYmIGNvbnZBaVJlcGx5XCIgY2xhc3M9XCJlY2hvLWFpLXRleHRcIj57eyBjb252QWlSZXBseSB9fTwvcD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFRvdGFsIGNvdW50IC0tPlxuICAgICAgPGRpdiBjbGFzcz1cImVjaG8tY29udi1jb3VudFwiPnt7IGNvbnZUb3RhbCB9fSBDb252ZXJzYXRpb25zPC9kaXY+XG5cbiAgICAgIDwhLS0gQ29udmVyc2F0aW9ucyBsaXN0IGFyZWEgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29udmVyc2F0aW9ucy1zZWN0aW9uXCI+XG5cbiAgICAgIDwhLS0gTG9hZGluZyAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJjb252TG9hZGluZ1wiIGNsYXNzPVwiZWNoby1lbXB0eS1zdGF0ZVwiPkxvYWRpbmcgY29udmVyc2F0aW9ucy4uLjwvZGl2PlxuXG4gICAgICA8IS0tIENvbnZlcnNhdGlvbiBjYXJkcyAoZHluYW1pYyBmcm9tIEFQSSDigJQgc2FtZSBwYXR0ZXJuIGFzIHRyYW5zY3JpcHQtbGlzdCkgLS0+XG4gICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjb252IG9mIGNvbnZlcnNhdGlvbnM7IHRyYWNrQnk6IHRyYWNrQnlJZFwiIGNsYXNzPVwiY29udi1jYXJkXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb252LWhlYWRlclwiIChjbGljayk9XCJ0b2dnbGVDb252RXhwYW5kKGNvbnYuYXVkaW9JZClcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udi1oZWFkZXItYm9keVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnYtbWV0YS1yb3dcIj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJjb252LWlkXCI+e3sgY29udi5hdWRpb0lkIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldGEtdGFnIGJyYW5kXCIgKm5nSWY9XCJjb252LnN0b3JlTmFtZVwiPnt7IGNvbnYuc3RvcmVOYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldGEtdGFnXCIgKm5nSWY9XCJjb252LmxvY2F0aW9uXCI+e3sgY29udi5sb2NhdGlvbiB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRhLXRhZ1wiICpuZ0lmPVwiY29udi51c2VyTmFtZVwiPnt7IGNvbnYudXNlck5hbWUgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWV0YS10YWdcIiAqbmdJZj1cImNvbnYuZGF0ZVwiPnt7IGNvbnYuZGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRhLXRhZyBtZXRhLXRhZy0tZHVyYXRpb25cIiAqbmdJZj1cImNvbnYuZHVyYXRpb25cIj57eyBjb252LmR1cmF0aW9uIH19PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udi1kZXNjcmlwdGlvblwiPlxuICAgICAgICAgICAgICB7eyBjb252LmF1ZGlvRGVzY3JpcHRpb24gfHwgJ05vIGRlc2NyaXB0aW9uIGF2YWlsYWJsZScgfX1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb252LWNoZXZyb25cIiBbY2xhc3Mub3Blbl09XCJleHBhbmRlZENvbnZJZHNbY29udi5hdWRpb0lkXVwiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiMTJcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjOTRBM0I4XCIgc3Ryb2tlLXdpZHRoPVwiMi41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiPjxwYXRoIGQ9XCJNNiA5bDYgNiA2LTZcIi8+PC9zdmc+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDwhLS0gRXhwYW5kZWQgYm9keSAodW5pZmllZCBsYXlvdXQgbWF0Y2hpbmcgQWdlbnQgQW5hbHlzaXMgZGVzaWduKSAtLT5cbiAgICAgICAgPGRpdiAqbmdJZj1cImV4cGFuZGVkQ29udklkc1tjb252LmF1ZGlvSWRdXCIgY2xhc3M9XCJjb252LWJvZHktZXhwYW5kZWRcIj5cblxuICAgICAgICAgIDwhLS0gV2F2ZWZvcm0gcGxheWVyIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJlY2hvLXBsYXllclwiICpuZ0lmPVwiY29udi5hdWRpb1VybFwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImVjaG8tcGxheS1idG5cIiAoY2xpY2spPVwidG9nZ2xlUGxheShjb252LmF1ZGlvSWQpXCI+XG4gICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJwbGF5aW5nQ29udklkICE9PSBjb252LmF1ZGlvSWRcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIndoaXRlXCI+PHBhdGggZD1cIk04IDV2MTRsMTEtN3pcIi8+PC9zdmc+XG4gICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJwbGF5aW5nQ29udklkID09PSBjb252LmF1ZGlvSWRcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIndoaXRlXCI+PHBhdGggZD1cIk02IDE5aDRWNUg2djE0em04LTE0djE0aDRWNWgtNHpcIi8+PC9zdmc+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlY2hvLXdhdmVmb3JtXCIgKGNsaWNrKT1cInNlZWtBdWRpbygkZXZlbnQsIGNvbnYuYXVkaW9JZClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVjaG8td2YtYmFyXCIgKm5nRm9yPVwibGV0IGggb2Ygd2F2ZWZvcm1IZWlnaHRzOyBsZXQgaSA9IGluZGV4XCIgW3N0eWxlLmhlaWdodC5weF09XCJoXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MucGxheWVkXT1cIihwbGF5YmFja1N0YXRlc1tjb252LmF1ZGlvSWRdPy5wcm9ncmVzcyB8fCAwKSA+IGkgLyB3YXZlZm9ybUhlaWdodHMubGVuZ3RoXCI+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImVjaG8tdGltZVwiPnt7IHBsYXliYWNrU3RhdGVzW2NvbnYuYXVkaW9JZF0/LnRvdGFsVGltZSB8fCBjb252LmR1cmF0aW9uIHx8ICctLScgfX08L3NwYW4+XG4gICAgICAgICAgICA8YXVkaW8gW2lkXT1cIidhdWRpby0nICsgY29udi5hdWRpb0lkXCIgW3NyY109XCJjb252LmF1ZGlvVXJsXCIgcHJlbG9hZD1cIm1ldGFkYXRhXCJcbiAgICAgICAgICAgICAgKHRpbWV1cGRhdGUpPVwib25UaW1lVXBkYXRlKGF1ZGlvRWwsIGNvbnYuYXVkaW9JZClcIlxuICAgICAgICAgICAgICAobG9hZGVkbWV0YWRhdGEpPVwib25Mb2FkZWRNZXRhZGF0YShhdWRpb0VsLCBjb252LmF1ZGlvSWQsIGNvbnYuZHVyYXRpb24pXCJcbiAgICAgICAgICAgICAgKGVuZGVkKT1cInBsYXlpbmdDb252SWQgPSBudWxsXCIgI2F1ZGlvRWw+PC9hdWRpbz5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gU3VtbWFyeSBDb250ZW50IC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb252LWJvZHktcGFkZGluZ1wiPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJzdW1tYXJ5LXRleHRcIj57eyBjb252LmF1ZGlvRGVzY3JpcHRpb24gfHwgY29udi5jb252ZXJzYXRpb25EZXRhaWxzPy5hdWRpb1N1bW1hcnkgfHwgJ05vIHN1bW1hcnkgYXZhaWxhYmxlJyB9fTwvcD5cbiAgICAgICAgICAgIDwhLS0gQUkgSW5zaWdodHMgLS0+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udi5haUluc2lnaHRzPy5zdW1tYXJ5Py5sZW5ndGhcIiBjbGFzcz1cImFpLWluc2lnaHRzLXNlY3Rpb25cIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFpLWluc2lnaHRzLWxhYmVsXCI+QUkgSW5zaWdodHM8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgaW5zaWdodCBvZiBjb252LmFpSW5zaWdodHMuc3VtbWFyeVwiIGNsYXNzPVwiYWktaW5zaWdodC1yb3dcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWktaW5zaWdodC1kb3RcIiBbc3R5bGUuYmFja2dyb3VuZF09XCJpbnNpZ2h0LnR5cGUgPT09ICdwb3NpdGl2ZScgPyAnIzAwQTNGRicgOiBpbnNpZ2h0LnR5cGUgPT09ICduZWdhdGl2ZScgPyAnI0VGNDQ0NCcgOiAnI0Y1OUUwQidcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFpLWluc2lnaHQtdGV4dFwiPnt7IGluc2lnaHQudGV4dCB8fCBpbnNpZ2h0IH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIE5vIGRhdGEgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWNvbnZMb2FkaW5nICYmIGNvbnZlcnNhdGlvbnMubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJlY2hvLWVtcHR5LXN0YXRlLS1zbVwiPk5vIGNvbnZlcnNhdGlvbnMgZm91bmQuPC9kaXY+XG5cbiAgICAgIDwhLS0gUGFnaW5hdGlvbiAtLT5cbiAgICAgIDxsaWItcGFnaW5hdGlvbiAqbmdJZj1cImNvbnZUb3RhbCA+IDBcIiBbaXRlbXNQZXJQYWdlXT1cImNvbnZQZXJQYWdlXCIgW2N1cnJlbnRQYWdlXT1cImNvbnZQYWdlXCIgW3RvdGFsSXRlbXNdPVwiY29udlRvdGFsXCJcbiAgICAgICAgW3BhZ2luYXRpb25TaXplc109XCJjb252UGFnaW5hdGlvblNpemVzXCIgW3BhZ2VTaXplXT1cImNvbnZQZXJQYWdlXCIgKHBhZ2VDaGFuZ2UpPVwib25Db252UGFnZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgKHBhZ2VTaXplQ2hhbmdlKT1cIm9uQ29udlBhZ2VTaXplQ2hhbmdlKCRldmVudClcIj48L2xpYi1wYWdpbmF0aW9uPlxuICAgICAgPC9kaXY+IDwhLS0gZW5kIGNvbnZlcnNhdGlvbnMtc2VjdGlvbiAtLT5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgIDwhLS0g4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQIEFHRU5UIEFOQUxZU0lTIFRBQiDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImN1cnJlbnRQYWdlID09PSAnYWdlbnRhbmFseXNpcydcIj5cblxuICAgICAgPCEtLSDilIDilIAgT1ZFUlZJRVc6IEFnZW50IENhcmRzIEdyaWQg4pSA4pSAIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFkZXRhaWxWaWV3XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJhbmFseXRpY3Mtb3ZlcnZpZXctaGVhZGVyXCI+XG4gICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbmFseXRpY3Mtb3ZlcnZpZXctdGl0bGVcIj5BbmFseXRpY3MgT3ZlcnZpZXc8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbmFseXRpY3Mtb3ZlcnZpZXctc3VidGl0bGVcIj57eyBhY3RpdmVDb2hvcnRzLmxlbmd0aCB9fSBhY3RpdmUgYWdlbnRzPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJmbGV4LXNwYWNlclwiPjwvc3Bhbj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZWNoby1zZWFyY2gtd3JhcFwiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjEzXCIgaGVpZ2h0PVwiMTNcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjOThBMkIzXCIgc3Ryb2tlLXdpZHRoPVwiMS44XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiPjxjaXJjbGUgY3g9XCIxMVwiIGN5PVwiMTFcIiByPVwiNy41XCIvPjxwYXRoIGQ9XCJNMTYuNSAxNi41TDIxIDIxXCIvPjwvc3ZnPlxuICAgICAgICAgICAgPGlucHV0IFsobmdNb2RlbCldPVwiYW5hbHlzaXNTZWFyY2hcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaCBhZ2VudHPigKZcIiBjbGFzcz1cImVjaG8taW5saW5lLWlucHV0XCI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgKm5nSWY9XCJjb2hvcnRMaXN0Lmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwiZWNoby1lbXB0eS1zdGF0ZS0tbXV0ZWRcIj5Mb2FkaW5nIGFnZW50cy4uLjwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJhbmFseXRpY3MtZ3JpZFwiIFtzdHlsZS5ncmlkLXRlbXBsYXRlLWNvbHVtbnNdPVwiJ3JlcGVhdCgnICsgTWF0aC5taW4oY29ob3J0TGlzdC5sZW5ndGgsIDQpICsgJywgMWZyKSdcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2hvcnQgb2YgY29ob3J0TGlzdDsgdHJhY2tCeTogdHJhY2tCeUlkXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW5hbHl0aWNzLWNhcmRcIiAqbmdJZj1cIiFhbmFseXNpc1NlYXJjaCB8fCAoY29ob3J0LmNvaG9ydE5hbWUgfHwgY29ob3J0Lm5hbWUgfHwgJycpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoYW5hbHlzaXNTZWFyY2gudG9Mb3dlckNhc2UoKSlcIiAoY2xpY2spPVwic2VsZWN0Q29ob3J0RGV0YWlsKGNvaG9ydClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFuYWx5dGljcy1jYXJkLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbmFseXRpY3MtY2FyZC10b3Atcm93XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW5hbHl0aWNzLWNhcmQtbmFtZVwiPnt7IGNvaG9ydC5jb2hvcnROYW1lIHx8IGNvaG9ydC5uYW1lIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFuYWx5dGljcy1jYXJkLWJhZGdlLWFjdGl2ZVwiPkFjdGl2ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8IS0tIG1ldHJpY3MgJiBzdG9yZXMgYmFkZ2VzIGhpZGRlbiBmb3Igbm93IC0tPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFuYWx5dGljcy1jYXJkLXNwYWNlclwiPjwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW5hbHl0aWNzLWNhcmQtZm9vdGVyXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhbmFseXRpY3MtaG92ZXItbGlua1wiPlZpZXcgYW5hbHl0aWNzIOKGkjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSDilIDilIAgREVUQUlMOiBTZWxlY3RlZCBDb2hvcnQgTWV0cmljcyArIENvbnZlcnNhdGlvbnMg4pSA4pSAIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImRldGFpbFZpZXdcIj5cblxuICAgICAgICA8IS0tIEhlYWRlcjog4oaQIEJhY2sgKyBUaXRsZSArIENvbnZlcnNhdGlvbnMgKyBEcm9wZG93biAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1oZWFkZXItYmFyXCI+XG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImRldGFpbC1iYWNrLWJ0blwiIChjbGljayk9XCJiYWNrVG9PdmVydmlldygpXCI+XG4gICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjIuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIj48cGF0aCBkPVwiTTE1IDE4bC02LTYgNi02XCIvPjwvc3ZnPlxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWhlYWRlci10aXRsZVwiPnt7IHNlbGVjdGVkQ29ob3J0TmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImZsZXgtc3BhY2VyXCI+PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZGV0YWlsLWhlYWRlci1jb252LWNvdW50XCI+VG90YWwgQ29udmVyc2F0aW9uczoge3sgdG90YWxBdWRpbyB9fTwvc3Bhbj5cblxuICAgICAgICAgIDwhLS0gQ29ob3J0IERyb3Bkb3duIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZ2VudC1kcm9wZG93bi13cmFwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnQtZHJvcGRvd24tdHJpZ2dlclwiIChjbGljayk9XCJ0b2dnbGVDb2hvcnREcm9wZG93bigpXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2hvcnQtZGQtZG90XCI+PC9kaXY+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29ob3J0LWRkLXRyaWdnZXItbmFtZVwiPnt7IHNlbGVjdGVkQ29ob3J0TmFtZSB8fCAnU2VsZWN0IEFnZW50JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjNjY3MDg1XCIgc3Ryb2tlLXdpZHRoPVwiMi41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIFtzdHlsZS50cmFuc2Zvcm1dPVwiY29ob3J0RHJvcGRvd25PcGVuID8gJ3JvdGF0ZSgxODBkZWcpJyA6ICdub25lJ1wiPjxwYXRoIGQ9XCJNNiA5bDYgNiA2LTZcIi8+PC9zdmc+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZ2VudC1kcm9wZG93bi1tZW51XCIgKm5nSWY9XCJjb2hvcnREcm9wZG93bk9wZW5cIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvaG9ydC1kZC1zZWFyY2gtd3JhcFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2hvcnQtZGQtc2VhcmNoLWlubmVyXCI+XG4gICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxM1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiM5OEEyQjNcIiBzdHJva2Utd2lkdGg9XCIxLjhcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCI+PGNpcmNsZSBjeD1cIjExXCIgY3k9XCIxMVwiIHI9XCI3LjVcIi8+PHBhdGggZD1cIk0xNi41IDE2LjVMMjEgMjFcIi8+PC9zdmc+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgWyhuZ01vZGVsKV09XCJjb2hvcnREcm9wZG93blNlYXJjaFwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGFnZW50c+KAplwiIGNsYXNzPVwiZWNoby1pbmxpbmUtaW5wdXQtLXNtYWxsXCI+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29ob3J0LWRkLXNjcm9sbFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGMgb2YgZmlsdGVyZWREcm9wZG93bkNvaG9ydHM7IHRyYWNrQnk6IHRyYWNrQnlJZFwiIGNsYXNzPVwiYWdlbnQtZGQtaXRlbVwiIFtjbGFzcy5zZWxlY3RlZF09XCIoYy5jb2hvcnRJZCB8fCBjLmlkIHx8IGMuX2lkKSA9PT0gc2VsZWN0ZWRDb2hvcnRJZFwiIChjbGljayk9XCJzZWxlY3RDb2hvcnRGcm9tRHJvcGRvd24oYylcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2hvcnQtZGQtaXRlbS1kb3RcIiBbc3R5bGUuYmFja2dyb3VuZF09XCJjLm1ldHJpY3NBZGRlZCA+IDAgPyAnIzEwQjk4MScgOiAnI0QwRDVERCdcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2hvcnQtZGQtaXRlbS1ib2R5XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZ2VudC1kZC1uYW1lXCI+e3sgYy5jb2hvcnROYW1lIHx8IGMubmFtZSB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnQtZGQtbWV0YVwiPnt7IGMubWV0cmljc0FkZGVkIHx8IDAgfX0gbWV0cmljczwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8c3ZnICpuZ0lmPVwiKGMuY29ob3J0SWQgfHwgYy5pZCB8fCBjLl9pZCkgPT09IHNlbGVjdGVkQ29ob3J0SWRcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjMDBBM0ZGXCIgc3Ryb2tlLXdpZHRoPVwiMi41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiPjxwYXRoIGQ9XCJNMjAgNkw5IDE3bC01LTVcIi8+PC9zdmc+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImZpbHRlcmVkRHJvcGRvd25Db2hvcnRzLmxlbmd0aCA9PT0gMFwiIGNsYXNzPVwiY29ob3J0LWRkLW5vLXJlc3VsdHNcIj5ObyBhZ2VudHMgZm91bmQ8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjb2hvcnREcm9wZG93bk9wZW5cIiBjbGFzcz1cImNvaG9ydC1kZC1iYWNrZHJvcFwiIChjbGljayk9XCJjbG9zZUNvaG9ydERyb3Bkb3duKClcIj48L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPCEtLSBMb2FkaW5nIC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiY2FyZHNMb2FkaW5nXCIgY2xhc3M9XCJlY2hvLWVtcHR5LXN0YXRlLS1tdXRlZFwiPkxvYWRpbmcgbWV0cmljcy4uLjwvZGl2PlxuXG4gICAgICAgIDwhLS0gTWV0cmljIENhcmRzIChkeW5hbWljIGNvbHVtbnMgYmFzZWQgb24gY2FyZCBjb3VudCkgLS0+XG4gICAgICAgIDxkaXYgKm5nSWY9XCIhY2FyZHNMb2FkaW5nICYmIGNvaG9ydENhcmRzLmxlbmd0aCA+IDBcIiBjbGFzcz1cIm1ldHJpYy1jYXJkcy1keW5hbWljXCJcbiAgICAgICAgICBbc3R5bGUuZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXT1cIidyZXBlYXQoJyArIE1hdGgubWluKGNvaG9ydENhcmRzLmxlbmd0aCwgNCkgKyAnLCAxZnIpJ1wiPlxuICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGNhcmQgb2YgY29ob3J0Q2FyZHM7IHRyYWNrQnk6IHRyYWNrQnlJZFwiIGNsYXNzPVwibWV0cmljLWNhcmQtZHluYW1pY1wiPlxuICAgICAgICAgICAgPCEtLSBDYXJkIEhlYWRlcjogVGl0bGUgKyBTdGF0dXMgQmFkZ2UgKyBJbmZvIC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldHJpYy1jYXJkLWhlYWRlci1yb3dcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldHJpYy1jYXJkLXRpdGxlXCI+e3sgY2FyZC5uYW1lIH19PC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtY2FyZC1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJjYXJkLnN0YXR1c1wiIGNsYXNzPVwibWV0cmljLXN0YXR1cy1iYWRnZVwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZF09XCJnZXRTdGF0dXNCYWRnZShjYXJkLnN0YXR1cykuYmdcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLmNvbG9yXT1cImdldFN0YXR1c0JhZGdlKGNhcmQuc3RhdHVzKS5jb2xvclwiPnt7IGNhcmQuc3RhdHVzIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtaW5mby1pY29uXCIgKm5nSWY9XCJjYXJkLmRlc2NyaXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCI+PGNpcmNsZSBjeD1cIjEyXCIgY3k9XCIxMlwiIHI9XCIxMFwiLz48bGluZSB4MT1cIjEyXCIgeTE9XCIxNlwiIHgyPVwiMTJcIiB5Mj1cIjEyXCIvPjxsaW5lIHgxPVwiMTJcIiB5MT1cIjhcIiB4Mj1cIjEyLjAxXCIgeTI9XCI4XCIvPjwvc3ZnPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldHJpYy1pbmZvLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdj57eyBjYXJkLmRlc2NyaXB0aW9uIH19PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtY2FyZC1zdWJ0aXRsZVwiICpuZ0lmPVwiY2FyZC50eXBlICE9PSAnTlVNRVJJQ19TQ0FMQVInICYmIGNhcmQudHlwZSAhPT0gJ05VTUVSSUNfQVJSQVknXCI+e3sgY2FyZC5hcHBsaWNhYmxlQ291bnQgPz8gdG90YWxBdWRpbyB9fSBjb252ZXJzYXRpb25zPC9kaXY+XG5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtY2FyZC1jb250ZW50XCI+XG4gICAgICAgICAgICA8IS0tIEJPT0xFQU5fQkFTS0VUIOKAlCBGdW5uZWwgQ2hhcnQgKGxlZnQtYWxpZ25lZCkgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2FyZC50eXBlID09PSAnQk9PTEVBTl9CQVNLRVQnICYmIGNhcmQuaXNGdW5uZWxcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZ1bm5lbC1jaGFydFwiPlxuICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHJvdyBvZiBjYXJkLmJvb2xlYW5Sb3dzOyBsZXQgaSA9IGluZGV4XCIgY2xhc3M9XCJmdW5uZWwtc3RhZ2VcIiAoY2xpY2spPVwib25DYXJkUm93Q2xpY2socm93LmlkLCByb3cubGFiZWwpXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnVubmVsLWJhclwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC4lXT1cImNhcmQuYm9vbGVhblJvd3NbMF0/LnJlc3BvbnNlcyA+IDAgPyAocm93LnJlc3BvbnNlcyAvIGNhcmQuYm9vbGVhblJvd3NbMF0ucmVzcG9uc2VzICogMTAwKSA6IDEwMFwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImdldFNjb3JlQ29sb3Iocm93LnNjb3JlKVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZ1bm5lbC1sYWJlbC13cmFwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmdW5uZWwtbGFiZWxcIj57eyByb3cubGFiZWwgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJmdW5uZWwtdG9vbHRpcFwiPnt7IHJvdy5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImZ1bm5lbC12YWx1ZVwiPiA8c3BhbiBjbGFzcz1cImZ1bm5lbC12YWx1ZS1jb3VudFwiPnt7IHJvdy5yZXNwb25zZXMgfX08L3NwYW4+ICh7eyByb3cuc2NvcmUgfX0pJSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPCEtLSBCT09MRUFOX0JBU0tFVCDigJQgcm93cyB3aXRoIHByb2dyZXNzIGJhcnMgKG5vbi1mdW5uZWwpIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNhcmQudHlwZSA9PT0gJ0JPT0xFQU5fQkFTS0VUJyAmJiAhY2FyZC5pc0Z1bm5lbFwiPlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCByb3cgb2YgY2FyZC5ib29sZWFuUm93czsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwibWV0cmljLWJvb2wtcm93XCIgKGNsaWNrKT1cIm9uQ2FyZFJvd0NsaWNrKHJvdy5pZCwgcm93LmxhYmVsKVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtcm93LWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtcm93LWRvdFwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImdldFNjb3JlQ29sb3Iocm93LnNjb3JlKVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRyaWMtcm93LWxhYmVsXCI+e3sgcm93LmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRyaWMtc2NvcmUgbWV0cmljLXNjb3JlLS10ZWFsXCI+e3sgcm93LnNjb3JlIH19JTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWV0cmljLWNvdW50XCI+e3sgcm93LnJlc3BvbnNlcyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWV0cmljLXByb2dyZXNzLXRyYWNrXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWV0cmljLXByb2dyZXNzLWZpbGxcIiBbc3R5bGUud2lkdGguJV09XCJyb3cuc2NvcmVcIlxuICAgICAgICAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZF09XCJnZXRTY29yZUNvbG9yKHJvdy5zY29yZSlcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPCEtLSBOVU1FUklDX0dST1VQIOKAlCBhbGwgc2NvcmVzIGluIG9uZSBjYXJkIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNhcmQudHlwZSA9PT0gJ05VTUVSSUNfR1JPVVAnXCI+XG4gICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IHJvdyBvZiBjYXJkLm51bWVyaWNSb3dzXCIgY2xhc3M9XCJudW1lcmljLXNjb3JlLXJvd1wiIChjbGljayk9XCJvbkNhcmRSb3dDbGljaygnJywgcm93LmtleSlcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibnVtZXJpYy1yb3ctaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm51bWVyaWMtcm93LW5hbWVcIj57eyByb3cubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibnVtZXJpYy1yb3ctdmFsdWVcIj57eyByb3cuYXZnIH19PHNwYW4gKm5nSWY9XCJyb3cubWF4ICE9PSBudWxsXCIgY2xhc3M9XCJudW1lcmljLXJvdy1tYXhcIj4ve3sgcm93Lm1heCB9fTwvc3Bhbj48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInJvdy5tYXggIT09IG51bGwgJiYgcm93Lm1pbiAhPT0gbnVsbFwiIGNsYXNzPVwibnVtZXJpYy1wcm9ncmVzcy10cmFja1wiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm51bWVyaWMtcHJvZ3Jlc3MtZmlsbFwiXG4gICAgICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC4lXT1cInJvdy5tYXggPiByb3cubWluID8gKChyb3cuYXZnIC0gcm93Lm1pbikgLyAocm93Lm1heCAtIHJvdy5taW4pICogMTAwKSA6IDBcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICAgICAgPCEtLSBVTklRVUVfUElUQ0hFUyDigJQgcGl0Y2gga2V5d29yZHMgdHJhY2tlciAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjYXJkLnR5cGUgPT09ICdVTklRVUVfUElUQ0hFUydcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBpdGNoLWtleXdvcmQtY291bnRcIj57eyBjYXJkLnBpdGNoUm93cz8ubGVuZ3RoIHx8IDAgfX0ga2V5d29yZHM8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBwaXRjaCBvZiBjYXJkLnBpdGNoUm93czsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwibWV0cmljLWJvb2wtcm93XCIgKGNsaWNrKT1cIm9uQ2FyZFJvd0NsaWNrKCcnLCBjYXJkLmtleSlcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtcm93LWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldHJpYy1yb3ctZG90XCJcbiAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZF09XCJbJyMwMEEzRkYnLCcjMTBCOTgxJywnI0Y1OUUwQicsJyNFRjQ0NDQnLCcjOEI1Q0Y2JywnI0VDNDg5OScsJyMwNkI2RDQnLCcjODRDQzE2JywnI0Y5NzMxNicsJyM2MzY2RjEnXVtpICUgMTBdXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGl0Y2gtcm93LWxhYmVsXCI+e3sgcGl0Y2guaWQgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGl0Y2gtcm93LWRlc2NcIj57eyBwaXRjaC5kZXNjID8gcGl0Y2guZGVzYy5zbGljZSgwLCA2MCkgOiAn4oCTJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8IS0tIFNVQkpFQ1RJVkUgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY2FyZC50eXBlID09PSAnU1VCSkVDVElWRScgfHwgY2FyZC50eXBlID09PSAnU1VCSkVDVElWRV9DT1VOVCdcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1YmplY3RpdmUtd3JhcFwiIChjbGljayk9XCJvbkNhcmRSb3dDbGljaygnJywgY2FyZC5rZXkpXCI+XG4gICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgcm93IG9mIGNhcmQuc3ViamVjdGl2ZVJvd3M/LnNsaWNlKDAsIDIpXCIgY2xhc3M9XCJzdWJqZWN0aXZlLXJvd1wiPlxuICAgICAgICAgICAgICAgICAg4oCiIHt7IHJvdy5yZWFzb25pbmcgfHwgcm93LnN0b3JlX2lkIH19XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj48IS0tIGVuZCBtZXRyaWMtY2FyZC1jb250ZW50IC0tPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIE5vIGNhcmRzIC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiIWNhcmRzTG9hZGluZyAmJiBjb2hvcnRDYXJkcy5sZW5ndGggPT09IDBcIiBjbGFzcz1cImVjaG8tZW1wdHktc3RhdGUtLW11dGVkLXNtXCI+Tm8gYW5hbHlzaXMgZGF0YSBhdmFpbGFibGUuPC9kaXY+XG5cbiAgICAgICAgPCEtLSDilIDilIAgQ29udmVyc2F0aW9ucyBTZWN0aW9uIOKUgOKUgCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnZlcnNhdGlvbnMtc2VjdGlvblwiICpuZ0lmPVwiZGV0YWlsUGFnZUNvbnZzLmxlbmd0aCA+IDAgfHwgZGV0YWlsTG9hZGluZ1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtY29udi1zZWN0aW9uLWhlYWRlclwiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCIjMzQ0MDU0XCIgc3Ryb2tlLXdpZHRoPVwiMS44XCI+PHBhdGggZD1cIk0yMCAySDRhMiAyIDAgMCAwLTIgMnYxM2EyIDIgMCAwIDAgMiAyaDExbDUgM1Y0YTIgMiAwIDAgMC0yLTJ6XCIvPjwvc3ZnPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJkZXRhaWwtY29udi1zZWN0aW9uLXRpdGxlXCI+Q29udmVyc2F0aW9uczwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJkZXRhaWxMb2FkaW5nXCIgY2xhc3M9XCJlY2hvLWVtcHR5LXN0YXRlLS1tdXRlZFwiPkxvYWRpbmcuLi48L2Rpdj5cblxuICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGNvbnYgb2YgZGV0YWlsUGFnZUNvbnZzOyB0cmFja0J5OiB0cmFja0J5SWRcIiBjbGFzcz1cImRldGFpbC1jb252LWNhcmRcIj5cbiAgICAgICAgICAgIDwhLS0gQ29udiBoZWFkZXIgLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udi1oZWFkZXJcIiAoY2xpY2spPVwidG9nZ2xlRGV0YWlsQ29udihjb252LmF1ZGlvSWQpOyBsb2FkQ29udkRldGFpbChjb252KVwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbnYtaWRcIj57eyBjb252LmF1ZGlvSWQgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkZXRhaWwtbWV0YS1yb3dcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldGEtdGFnIGJyYW5kXCIgKm5nSWY9XCJjb252LnN0b3JlTmFtZVwiPnt7IGNvbnYuc3RvcmVOYW1lIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWV0YS10YWdcIiAqbmdJZj1cImNvbnYubG9jYXRpb25cIj57eyBjb252LmxvY2F0aW9uIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWV0YS10YWdcIiAqbmdJZj1cImNvbnYuZGF0ZVwiPnt7IGNvbnYuZGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldGEtdGFnXCIgKm5nSWY9XCJjb252LnRpbWVcIj57eyBjb252LnRpbWUgfX08L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udi1jaGV2cm9uXCIgW2NsYXNzLm9wZW5dPVwiZGV0YWlsT3BlbklkID09PSBjb252LmF1ZGlvSWRcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiM5NEEzQjhcIiBzdHJva2Utd2lkdGg9XCIyLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCI+PHBhdGggZD1cIk02IDlsNiA2IDYtNlwiLz48L3N2Zz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPCEtLSBFeHBhbmRlZCBib2R5IC0tPlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cImRldGFpbE9wZW5JZCA9PT0gY29udi5hdWRpb0lkXCIgY2xhc3M9XCJjb252LWJvZHktZXhwYW5kZWRcIj5cbiAgICAgICAgICAgICAgPCEtLSBXYXZlZm9ybSBwbGF5ZXIgLS0+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlY2hvLXBsYXllclwiICpuZ0lmPVwiY29udi5hdWRpb1VybFwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJlY2hvLXBsYXktYnRuXCIgKGNsaWNrKT1cInRvZ2dsZVBsYXkoY29udi5hdWRpb0lkKVwiPlxuICAgICAgICAgICAgICAgICAgPHN2ZyAqbmdJZj1cInBsYXlpbmdDb252SWQgIT09IGNvbnYuYXVkaW9JZFwiIHdpZHRoPVwiMTRcIiBoZWlnaHQ9XCIxNFwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwid2hpdGVcIj48cGF0aCBkPVwiTTggNXYxNGwxMS03elwiLz48L3N2Zz5cbiAgICAgICAgICAgICAgICAgIDxzdmcgKm5nSWY9XCJwbGF5aW5nQ29udklkID09PSBjb252LmF1ZGlvSWRcIiB3aWR0aD1cIjE0XCIgaGVpZ2h0PVwiMTRcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIndoaXRlXCI+PHBhdGggZD1cIk02IDE5aDRWNUg2djE0em04LTE0djE0aDRWNWgtNHpcIi8+PC9zdmc+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVjaG8td2F2ZWZvcm1cIiAoY2xpY2spPVwic2Vla0F1ZGlvKCRldmVudCwgY29udi5hdWRpb0lkKVwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImVjaG8td2YtYmFyXCIgKm5nRm9yPVwibGV0IGggb2Ygd2F2ZWZvcm1IZWlnaHRzOyBsZXQgaSA9IGluZGV4XCIgW3N0eWxlLmhlaWdodC5weF09XCJoXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzLnBsYXllZF09XCIocGxheWJhY2tTdGF0ZXNbY29udi5hdWRpb0lkXT8ucHJvZ3Jlc3MgfHwgMCkgPiBpIC8gd2F2ZWZvcm1IZWlnaHRzLmxlbmd0aFwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZWNoby10aW1lXCI+e3sgcGxheWJhY2tTdGF0ZXNbY29udi5hdWRpb0lkXT8udG90YWxUaW1lIHx8IGNvbnYuZHVyYXRpb24gfHwgJy0tJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8YXVkaW8gW2lkXT1cIidhdWRpby0nICsgY29udi5hdWRpb0lkXCIgW3NyY109XCJjb252LmF1ZGlvVXJsXCIgcHJlbG9hZD1cIm1ldGFkYXRhXCJcbiAgICAgICAgICAgICAgICAgICh0aW1ldXBkYXRlKT1cIm9uVGltZVVwZGF0ZShhdWRpb0VsLCBjb252LmF1ZGlvSWQpXCJcbiAgICAgICAgICAgICAgICAgIChsb2FkZWRtZXRhZGF0YSk9XCJvbkxvYWRlZE1ldGFkYXRhKGF1ZGlvRWwsIGNvbnYuYXVkaW9JZCwgY29udi5kdXJhdGlvbilcIlxuICAgICAgICAgICAgICAgICAgKGVuZGVkKT1cInBsYXlpbmdDb252SWQgPSBudWxsXCIgI2F1ZGlvRWw+PC9hdWRpbz5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgPCEtLSBUYWJzIC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udi10YWJzXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImNvbnYtdGFiLWJ0blwiIFtjbGFzcy5hY3RpdmVdPVwiZ2V0Q29udlRhYihjb252LmF1ZGlvSWQpID09PSAnc3VtbWFyeSdcIiAoY2xpY2spPVwic2V0Q29udlRhYihjb252LmF1ZGlvSWQsICdzdW1tYXJ5JywgJGV2ZW50KVwiPlN1bW1hcnk8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiY29udi10YWItYnRuXCIgW2NsYXNzLmFjdGl2ZV09XCJnZXRDb252VGFiKGNvbnYuYXVkaW9JZCkgPT09ICd0cmFuc2NyaXB0J1wiIChjbGljayk9XCJzZXRDb252VGFiKGNvbnYuYXVkaW9JZCwgJ3RyYW5zY3JpcHQnLCAkZXZlbnQpXCI+VHJhbnNjcmlwdDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICA8IS0tIENvbnRlbnQ6IExlZnQgKFN1bW1hcnkvVHJhbnNjcmlwdCArIEFJIEluc2lnaHRzKSArIFJpZ2h0IChNZXRyaWNzKSAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1jb250ZW50LXNwbGl0XCI+XG4gICAgICAgICAgICAgICAgPCEtLSBMZWZ0IHNpZGUgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1jb250ZW50LWxlZnRcIj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRDb252VGFiKGNvbnYuYXVkaW9JZCkgPT09ICdzdW1tYXJ5J1wiPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInN1bW1hcnktdGV4dFwiPnt7IGNvbnYuYXVkaW9EZXNjcmlwdGlvbiB8fCBjb252LmNvbnZlcnNhdGlvbkRldGFpbHM/LmF1ZGlvU3VtbWFyeSB8fCAnTm8gc3VtbWFyeSBhdmFpbGFibGUnIH19PC9wPlxuICAgICAgICAgICAgICAgICAgICA8IS0tIEFJIEluc2lnaHRzIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udi5haUluc2lnaHRzPy5zdW1tYXJ5Py5sZW5ndGhcIiBjbGFzcz1cImFpLWluc2lnaHRzLXNlY3Rpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWktaW5zaWdodHMtbGFiZWxcIj5BSSBJbnNpZ2h0czwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGluc2lnaHQgb2YgY29udi5haUluc2lnaHRzLnN1bW1hcnlcIiBjbGFzcz1cImFpLWluc2lnaHQtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWktaW5zaWdodC1kb3RcIiBbc3R5bGUuYmFja2dyb3VuZF09XCJpbnNpZ2h0LnR5cGUgPT09ICdwb3NpdGl2ZScgPyAnIzAwQTNGRicgOiBpbnNpZ2h0LnR5cGUgPT09ICduZWdhdGl2ZScgPyAnI0VGNDQ0NCcgOiAnI0Y1OUUwQidcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWktaW5zaWdodC10ZXh0XCI+e3sgaW5zaWdodC50ZXh0IHx8IGluc2lnaHQgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZ2V0Q29udlRhYihjb252LmF1ZGlvSWQpID09PSAndHJhbnNjcmlwdCdcIj5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJzdW1tYXJ5LXRleHQgc3VtbWFyeS10ZXh0LS1wcmV3cmFwXCI+e3sgY2xlYW5UcmFuc2NyaXB0aW9uKGNvbnYuY29udmVyc2F0aW9uRGV0YWlscz8udHJhbnNjcmlwdGlvbikgfHwgJ05vIHRyYW5zY3JpcHQgYXZhaWxhYmxlJyB9fTwvcD5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwhLS0gUmlnaHQgc2lkZTogTWV0cmljcyAob25seSBzaG93IHZhbHVlcyB0aGF0IGhhdmUgZGF0YSkgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRldGFpbC1jb250ZW50LXJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWV0cmljcy1wYW5lbC1sYWJlbFwiPk1ldHJpY3M8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb252Lm1ldHJpY3M/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBtIG9mIGNvbnYubWV0cmljc1wiIGNsYXNzPVwibWV0cmljLWl0ZW0td3JhcFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gU2luZ2xlIHZhbHVlOiBuYW1lICsgdmFsdWUgb24gc2FtZSByb3cgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm0udmFsdWU/Lmxlbmd0aCA9PT0gMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1ldHJpYy1zaW5nbGUtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibWV0cmljLXNpbmdsZS1uYW1lXCIgW3RpdGxlXT1cIm0ubmFtZVwiPnt7IG0ubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtZXRyaWMtc2luZ2xlLXZhbHVlXCIgW3N0eWxlLmNvbG9yXT1cIm0udmFsdWVbMF0uc2NvcmUgIT09IG51bGwgJiYgbS52YWx1ZVswXS5zY29yZSAhPT0gdW5kZWZpbmVkID8gJyMwMEEzRkYnIDogJyMzNDQwNTQnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZm9ybWF0TWV0cmljVmFsdWUobS52YWx1ZVswXSkgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgPCEtLSBNdWx0aXBsZSB2YWx1ZXM6IGhlYWRlciArIHJvd3MgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm0udmFsdWU/Lmxlbmd0aCA+IDFcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtZXRyaWMtbXVsdGktaGVhZGVyXCIgW3RpdGxlXT1cIm0ubmFtZVwiPnt7IG0ubmFtZSB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgdiBvZiBtLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIodi5zY29yZSAhPT0gbnVsbCAmJiB2LnNjb3JlICE9PSB1bmRlZmluZWQpIHx8ICh2LlRvdGFsICE9PSBudWxsICYmIHYuVG90YWwgIT09IHVuZGVmaW5lZCkgfHwgKHYuQXZnICE9PSBudWxsICYmIHYuQXZnICE9PSB1bmRlZmluZWQpIHx8ICh2LnRvdGFsICE9PSBudWxsICYmIHYudG90YWwgIT09IHVuZGVmaW5lZCkgfHwgKHYuYXZnICE9PSBudWxsICYmIHYuYXZnICE9PSB1bmRlZmluZWQpIHx8ICh2LmNvdW50ICE9PSBudWxsICYmIHYuY291bnQgIT09IHVuZGVmaW5lZClcIiBjbGFzcz1cIm1ldHJpYy1tdWx0aS1yb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldHJpYy1tdWx0aS1uYW1lXCIgW3RpdGxlXT1cInYubmFtZVwiPnt7IHYubmFtZSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1ldHJpYy1tdWx0aS12YWx1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUuY29sb3JdPVwidi5zY29yZSAhPT0gbnVsbCAmJiB2LnNjb3JlICE9PSB1bmRlZmluZWQgPyAnIzAwQTNGRicgOiAnIzM0NDA1NCdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGZvcm1hdE1ldHJpY1ZhbHVlKHYpIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFjb252Lm1ldHJpY3M/Lmxlbmd0aFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiY29udi5zdG9yZU5hbWVcIiBjbGFzcz1cIm1ldHJpYy1mYWxsYmFjay1yb3dcIj48c3BhbiBjbGFzcz1cIm1ldHJpYy1mYWxsYmFjay1sYWJlbFwiPlN0b3JlPC9zcGFuPjxzcGFuIGNsYXNzPVwibWV0cmljLWZhbGxiYWNrLXZhbHVlXCI+e3sgY29udi5zdG9yZU5hbWUgfX08L3NwYW4+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjb252LmR1cmF0aW9uXCIgY2xhc3M9XCJtZXRyaWMtZmFsbGJhY2stcm93XCI+PHNwYW4gY2xhc3M9XCJtZXRyaWMtZmFsbGJhY2stbGFiZWxcIj5EdXJhdGlvbjwvc3Bhbj48c3BhbiBjbGFzcz1cIm1ldHJpYy1mYWxsYmFjay12YWx1ZVwiPnt7IGNvbnYuZHVyYXRpb24gfX08L3NwYW4+PC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJjb252Ll9kZXRhaWxMb2FkaW5nXCIgY2xhc3M9XCJtZXRyaWMtZGV0YWlsLWxvYWRpbmdcIj5Mb2FkaW5nLi4uPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgKm5nSWY9XCIhZGV0YWlsTG9hZGluZyAmJiBkZXRhaWxQYWdlQ29udnMubGVuZ3RoID09PSAwICYmIChzZWxlY3RlZENhcmRJZCB8fCBzZWxlY3RlZENhcmROYW1lKVwiIGNsYXNzPVwiZWNoby1lbXB0eS1zdGF0ZS0tY29tcGFjdFwiPk5vIGNvbnZlcnNhdGlvbnMgZm91bmQuPC9kaXY+XG5cbiAgICAgICAgPCEtLSBQYWdpbmF0aW9uIC0tPlxuICAgICAgICA8bGliLXBhZ2luYXRpb24gKm5nSWY9XCJkZXRhaWxUb3RhbCA+IDBcIiBbaXRlbXNQZXJQYWdlXT1cImRldGFpbFBlclBhZ2VcIiBbY3VycmVudFBhZ2VdPVwiZGV0YWlsUGFnZVwiIFt0b3RhbEl0ZW1zXT1cImRldGFpbFRvdGFsXCJcbiAgICAgICAgICBbcGFnaW5hdGlvblNpemVzXT1cImRldGFpbFBhZ2luYXRpb25TaXplc1wiIFtwYWdlU2l6ZV09XCJkZXRhaWxQZXJQYWdlXCIgKHBhZ2VDaGFuZ2UpPVwib25EZXRhaWxQYWdlQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgIChwYWdlU2l6ZUNoYW5nZSk9XCJvbkRldGFpbFBhZ2VTaXplQ2hhbmdlKCRldmVudClcIj48L2xpYi1wYWdpbmF0aW9uPlxuICAgICAgPC9uZy1jb250YWluZXI+PCEtLSBlbmQgZGV0YWlsVmlldyAtLT5cbiAgICA8L25nLWNvbnRhaW5lcj48IS0tIGVuZCBhZ2VudGFuYWx5c2lzIC0tPlxuXG4gICAgPCEtLSDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgTUFOQUdFIFRBQiDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZAgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImN1cnJlbnRQYWdlID09PSAnbWFuYWdlJ1wiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1hbmFnZS1oZWFkZXJcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibWFuYWdlLXRpdGxlXCI+QWdlbnRzPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm1hbmFnZS1zdWJ0aXRsZVwiPnt7IG1hbmFnZVRvdGFsIH19IGFnZW50czwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJmbGV4LXNwYWNlclwiPjwvc3Bhbj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImVjaG8tc2VhcmNoLXdyYXAtLXdpZGVcIj5cbiAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxM1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cIiM5NEEzQjhcIiBzdHJva2Utd2lkdGg9XCIxLjhcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCI+PGNpcmNsZSBjeD1cIjExXCIgY3k9XCIxMVwiIHI9XCI3LjVcIi8+PHBhdGggZD1cIk0xNi41IDE2LjVMMjEgMjFcIi8+PC9zdmc+XG4gICAgICAgICAgPGlucHV0IFsobmdNb2RlbCldPVwibWFuYWdlU2VhcmNoXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25NYW5hZ2VTZWFyY2goKVwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGFnZW50cy4uLlwiIGNsYXNzPVwibWFuYWdlLXNlYXJjaC1pbnB1dFwiPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2ICpuZ0lmPVwibWFuYWdlTG9hZGluZ1wiIGNsYXNzPVwiZWNoby1lbXB0eS1zdGF0ZVwiPkxvYWRpbmcgYWdlbnRzLi4uPC9kaXY+XG5cbiAgICAgIDwhLS0gQWdlbnRzIHRhYmxlIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cIiFtYW5hZ2VMb2FkaW5nXCIgY2xhc3M9XCJlY2hvLWNhcmRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFnZW50cy10YWJsZS1oZWFkZXIgYWdlbnRzLXRhYmxlLTRjb2xcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnRzLXRhYmxlLWNlbGxcIj5BZ2VudCBOYW1lPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFnZW50cy10YWJsZS1jZWxsIGFnZW50cy10YWJsZS1jZWxsLS1jZW50ZXJcIj5NZXRyaWNzPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFnZW50cy10YWJsZS1jZWxsIGFnZW50cy10YWJsZS1jZWxsLS1jZW50ZXJcIj5Tb3VyY2U8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnRzLXRhYmxlLWNlbGwgYWdlbnRzLXRhYmxlLWNlbGwtLWNlbnRlclwiPkFjdGlvbjwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY29ob3J0IG9mIG1hbmFnZUNvaG9ydHM7IHRyYWNrQnk6IHRyYWNrQnlJZFwiIGNsYXNzPVwiYWdlbnRzLXRhYmxlLXJvdyBhZ2VudHMtdGFibGUtNGNvbFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZ2VudC1jZWxsLW5hbWUtd3JhcFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFnZW50LWNlbGwtbmFtZVwiPnt7IGNvaG9ydC5jb2hvcnROYW1lIHx8IGNvaG9ydC5uYW1lIH19PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnQtY2VsbC1kZXNjXCI+e3sgY29ob3J0LmNvaG9ydERlc2NyaXB0aW9uIHx8IGNvaG9ydC5kZXNjcmlwdGlvbiB8fCAnJyB9fTwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZ2VudC1jZWxsLW1ldHJpY3NcIj57eyBjb2hvcnQubWV0cmljc0FkZGVkIHx8IGNvaG9ydC5tZXRyaWNBZGRlZCB8fCBjb2hvcnQubWV0cmljcz8ubGVuZ3RoIHx8IDAgfX08L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWdlbnQtY2VsbC1zb3VyY2VcIj57eyBjb2hvcnQuc291cmNlPy5qb2luKCcsICcpIHx8ICfigJMnIH19PC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImFnZW50LWNlbGwtYWN0aW9uXCI+XG4gICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJkZWxldGVDb2hvcnQoY29ob3J0LmNvaG9ydElkIHx8IGNvaG9ydC5pZCB8fCBjb2hvcnQuX2lkKVwiIGNsYXNzPVwiYWdlbnQtZGVsZXRlLWJ0blwiPkRlbGV0ZTwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAqbmdJZj1cIm1hbmFnZUNvaG9ydHMubGVuZ3RoID09PSAwXCIgY2xhc3M9XCJtYW5hZ2Utbm8tcmVzdWx0c1wiPk5vIGNvaG9ydHMgZm91bmQuPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBNYW5hZ2UgcGFnaW5hdGlvbiAtLT5cbiAgICAgIDxsaWItcGFnaW5hdGlvbiAqbmdJZj1cIm1hbmFnZVRvdGFsID4gMFwiIFtpdGVtc1BlclBhZ2VdPVwibWFuYWdlUGVyUGFnZVwiIFtjdXJyZW50UGFnZV09XCJtYW5hZ2VQYWdlXCIgW3RvdGFsSXRlbXNdPVwibWFuYWdlVG90YWxcIlxuICAgICAgICBbcGFnaW5hdGlvblNpemVzXT1cIm1hbmFnZVBhZ2luYXRpb25TaXplc1wiIFtwYWdlU2l6ZV09XCJtYW5hZ2VQZXJQYWdlXCIgKHBhZ2VDaGFuZ2UpPVwib25NYW5hZ2VQYWdlQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAocGFnZVNpemVDaGFuZ2UpPVwib25NYW5hZ2VQYWdlU2l6ZUNoYW5nZSgkZXZlbnQpXCI+PC9saWItcGFnaW5hdGlvbj5cbiAgICA8L25nLWNvbnRhaW5lcj5cblxuICA8L2Rpdj5cbjwvZGl2PlxuXG48IS0tIOKVkOKVkOKVkCBGSUxURVJTIERSQVdFUiDilZDilZDilZAgLS0+XG48ZGl2IGNsYXNzPVwiZHJhd2VyLW92ZXJsYXlcIiAqbmdJZj1cImRyYXdlck9wZW5cIiAoY2xpY2spPVwiY2xvc2VGaWx0ZXJEcmF3ZXIoKVwiPjwvZGl2PlxuPGRpdiBjbGFzcz1cImFmLWRyYXdlclwiICpuZ0lmPVwiZHJhd2VyT3BlblwiPlxuICA8ZGl2IGNsYXNzPVwiZHJhd2VyLWhlYWRlclwiPlxuICAgIDxzcGFuIGNsYXNzPVwiZHJhd2VyLWhlYWRlci10aXRsZVwiPkZpbHRlcnM8L3NwYW4+XG4gICAgPGJ1dHRvbiAoY2xpY2spPVwiY2xvc2VGaWx0ZXJEcmF3ZXIoKVwiIGNsYXNzPVwiZHJhd2VyLWNsb3NlLWJ0blwiPsOXPC9idXR0b24+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZHJhd2VyLWJvZHlcIj5cbiAgICA8cCBjbGFzcz1cImRyYXdlci1wbGFjZWhvbGRlci10ZXh0XCI+RmlsdGVyIGNvbmZpZ3VyYXRpb24gY29taW5nIHNvb24uIFVzZXMgdGhlIHNhbWUgZmlsdGVyIEFQSXMgYXMgdGhlIGV4aXN0aW5nIGF1ZGlvIHBhZ2VzLjwvcD5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJhZi1mb290ZXJcIj5cbiAgICA8YnV0dG9uIGNsYXNzPVwiYWYtY2FuY2VsXCIgKGNsaWNrKT1cImNsb3NlRmlsdGVyRHJhd2VyKClcIj5DbG9zZTwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19
|