@cqa-lib/cqa-ui 1.1.220 → 1.1.221
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/execution-screen/breakpoints-modal/breakpoints-modal.component.mjs +88 -0
- package/esm2020/lib/execution-screen/jump-to-step-modal/jump-to-step-modal.component.mjs +129 -0
- package/esm2020/lib/ui-kit.module.mjs +11 -1
- package/esm2020/public-api.mjs +3 -1
- package/fesm2015/cqa-lib-cqa-ui.mjs +216 -1
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +216 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/execution-screen/breakpoints-modal/breakpoints-modal.component.d.ts +40 -0
- package/lib/execution-screen/jump-to-step-modal/jump-to-step-modal.component.d.ts +48 -0
- package/lib/ui-kit.module.d.ts +92 -90
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
- package/styles.css +1 -1
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "@angular/material/icon";
|
|
4
|
+
import * as i2 from "../../button/button.component";
|
|
5
|
+
import * as i3 from "@angular/common";
|
|
6
|
+
export class BreakpointsModalComponent {
|
|
7
|
+
constructor() {
|
|
8
|
+
/** Whether the modal is open */
|
|
9
|
+
this.isOpen = false;
|
|
10
|
+
/** Modal title */
|
|
11
|
+
this.title = 'Breakpoints';
|
|
12
|
+
/** List of breakpoint items to display */
|
|
13
|
+
this.items = [];
|
|
14
|
+
/** Label for the remove-all button */
|
|
15
|
+
this.buttonLabel = 'Remove all breakpoints';
|
|
16
|
+
/** Label for the empty state */
|
|
17
|
+
this.emptyStateLabel = 'No breakpoints set.';
|
|
18
|
+
/** Internal copy so items can be removed locally when parent doesn't re-bind */
|
|
19
|
+
this.displayItems = [];
|
|
20
|
+
/** Emitted when modal should be closed */
|
|
21
|
+
this.onClose = new EventEmitter();
|
|
22
|
+
/** Emitted when a single breakpoint should be removed */
|
|
23
|
+
this.onRemove = new EventEmitter();
|
|
24
|
+
/** Emitted when all breakpoints should be removed */
|
|
25
|
+
this.onRemoveAll = new EventEmitter();
|
|
26
|
+
}
|
|
27
|
+
ngOnChanges(changes) {
|
|
28
|
+
if (changes['items']) {
|
|
29
|
+
this.displayItems = [...(this.items || [])];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
get summaryText() {
|
|
33
|
+
const count = this.displayItems.length;
|
|
34
|
+
if (count === 0)
|
|
35
|
+
return '';
|
|
36
|
+
return count === 1 ? '1 breakpoint set' : `${count} breakpoints set`;
|
|
37
|
+
}
|
|
38
|
+
get hasItems() {
|
|
39
|
+
return this.displayItems && this.displayItems.length > 0;
|
|
40
|
+
}
|
|
41
|
+
removeItem(item) {
|
|
42
|
+
this.onRemove.emit(item);
|
|
43
|
+
this.displayItems = this.displayItems.filter(b => b.stepId !== item.stepId);
|
|
44
|
+
if (this.displayItems.length === 0) {
|
|
45
|
+
this.handleClose();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
removeAll() {
|
|
49
|
+
this.onRemoveAll.emit();
|
|
50
|
+
this.displayItems = [];
|
|
51
|
+
}
|
|
52
|
+
onBackdropClick(event) {
|
|
53
|
+
const target = event.target;
|
|
54
|
+
const currentTarget = event.currentTarget;
|
|
55
|
+
if (target === currentTarget || target.classList.contains('modal-backdrop')) {
|
|
56
|
+
this.handleClose();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
handleClose() {
|
|
60
|
+
this.onClose.emit();
|
|
61
|
+
}
|
|
62
|
+
trackByItemId(index, item) {
|
|
63
|
+
return item.id;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
BreakpointsModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BreakpointsModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
67
|
+
BreakpointsModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: BreakpointsModalComponent, selector: "cqa-breakpoints-modal", inputs: { isOpen: "isOpen", title: "title", items: "items", buttonLabel: "buttonLabel", emptyStateLabel: "emptyStateLabel" }, outputs: { onClose: "onClose", onRemove: "onRemove", onRemoveAll: "onRemoveAll" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"isOpen\"\n class=\"modal-backdrop cqa-fixed cqa-inset-0 cqa-bg-black cqa-bg-opacity-50 cqa-z-50 cqa-flex cqa-items-center cqa-justify-center cqa-p-4\"\n (click)=\"onBackdropClick($event)\">\n <div\n class=\"cqa-rounded-xl cqa-bg-white cqa-shadow-lg cqa-w-full cqa-max-w-[420px] cqa-overflow-hidden cqa-flex cqa-flex-col\"\n style=\"box-shadow: 0px 8px 8px -4px #10182808; max-height: 90vh;\"\n (click)=\"$event.stopPropagation()\">\n\n <!-- Header -->\n <div class=\"cqa-px-6 cqa-pt-6 cqa-pb-2\">\n <div class=\"cqa-flex cqa-items-start cqa-justify-between cqa-gap-3\">\n <h2 class=\"cqa-text-lg cqa-font-semibold cqa-text-[#0B0B0C] cqa-text-base cqa-font-inter\">\n {{ title }}\n </h2>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-6 cqa-h-6 cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-text-gray-500 hover:cqa-text-gray-700 cqa-transition-colors cqa-rounded cqa--mt-[2px] cqa--mr-[2px]\"\n (click)=\"handleClose()\"\n aria-label=\"Close modal\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px] !cqa-block !cqa-leading-none\">close</mat-icon>\n </button>\n </div>\n <!-- Summary text -->\n <p *ngIf=\"hasItems\" class=\"cqa-text-sm cqa-font-normal cqa-text-[#666666] cqa-text-sm cqa-leading-[1.4] cqa-font-inter cqa-m-0 cqa-mt-1\">\n {{ summaryText }}\n </p>\n </div>\n\n <!-- Divider -->\n <div class=\"cqa--mx-2 cqa-w-[calc(100%+1rem)] cqa-flex-shrink-0\">\n <div class=\"cqa-h-px cqa-w-full cqa-bg-[#E5E7EB]\" role=\"presentation\"></div>\n </div>\n\n <!-- Content -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-overflow-x-hidden cqa-px-6 cqa-pt-4 cqa-pb-2\" style=\"scrollbar-width: thin; max-height: 50vh;\">\n <!-- Empty State -->\n <div *ngIf=\"!hasItems\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8 cqa-text-center\">\n <p class=\"cqa-text-sm cqa-text-[#666666] cqa-font-inter cqa-m-0\">\n {{ emptyStateLabel || 'No Data Found.' }}\n </p>\n </div>\n\n <!-- Breakpoints List -->\n <div *ngIf=\"hasItems\" class=\"cqa-flex cqa-flex-col cqa-gap-4\">\n <div\n *ngFor=\"let item of displayItems; trackBy: trackByItemId\"\n class=\"cqa-flex cqa-items-start cqa-gap-3 cqa-px-4 cqa-py-3 cqa-bg-[#e5e7eb2e] cqa-rounded-lg cqa-min-w-0 cqa-border cqa-border-solid cqa-border-[#E5E7EB]\">\n\n <!-- Red Breakpoint Dot -->\n <span class=\"cqa-flex-shrink-0 cqa-w-[10px] cqa-h-[10px] cqa-mt-[5px] cqa-rounded-full cqa-bg-[#DC2626]\" aria-hidden=\"true\"></span>\n\n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-[2px] cqa-min-w-0 cqa-flex-1\">\n <span class=\"cqa-text-sm cqa-font-normal cqa-text-[#6B7280] cqa-leading-[1.3] cqa-font-inter\">\n {{ item.primaryLabel }}\n </span>\n <span class=\"cqa-text-sm cqa-font-normal cqa-text-[#111827] cqa-leading-[1.4] cqa-font-inter cqa-break-words\">\n {{ item.secondaryLabel }}\n </span>\n </div>\n <div (click)=\"$event.stopPropagation()\">\n <cqa-button\n type=\"button\"\n variant=\"text\"\n [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove breakpoint'\"\n (clicked)=\"removeItem(item)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\" fill=\"#99999E\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Footer: Remove All Button -->\n <div *ngIf=\"hasItems\" class=\"cqa-px-6 cqa-pb-6 cqa-pt-4\">\n \n <cqa-button\n [fullWidth]=\"true\"\n (click)=\"removeAll()\"\n [label]=\"buttonLabel\"\n variant=\"outlined\"\n color=\"black\"\n [text]=\"buttonLabel\"\n >\n </cqa-button>\n <!-- <button\n type=\"button\"\n class=\"cqa-w-full cqa-py-[10px] cqa-px-5 cqa-text-sm cqa-font-medium cqa-text-[#212121] cqa-bg-white cqa-border cqa-border-solid cqa-border-[#D9D9D9] cqa-rounded-lg cqa-cursor-pointer cqa-transition-colors hover:cqa-bg-[#F9FAFB] hover:cqa-border-[#9CA3AF] cqa-font-inter\"\n (click)=\"removeAll()\">\n {{ buttonLabel }}\n </button> -->\n </div>\n </div>\n</div>\n\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2.ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
68
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BreakpointsModalComponent, decorators: [{
|
|
69
|
+
type: Component,
|
|
70
|
+
args: [{ selector: 'cqa-breakpoints-modal', host: { class: 'cqa-ui-root' }, template: "<div *ngIf=\"isOpen\"\n class=\"modal-backdrop cqa-fixed cqa-inset-0 cqa-bg-black cqa-bg-opacity-50 cqa-z-50 cqa-flex cqa-items-center cqa-justify-center cqa-p-4\"\n (click)=\"onBackdropClick($event)\">\n <div\n class=\"cqa-rounded-xl cqa-bg-white cqa-shadow-lg cqa-w-full cqa-max-w-[420px] cqa-overflow-hidden cqa-flex cqa-flex-col\"\n style=\"box-shadow: 0px 8px 8px -4px #10182808; max-height: 90vh;\"\n (click)=\"$event.stopPropagation()\">\n\n <!-- Header -->\n <div class=\"cqa-px-6 cqa-pt-6 cqa-pb-2\">\n <div class=\"cqa-flex cqa-items-start cqa-justify-between cqa-gap-3\">\n <h2 class=\"cqa-text-lg cqa-font-semibold cqa-text-[#0B0B0C] cqa-text-base cqa-font-inter\">\n {{ title }}\n </h2>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-6 cqa-h-6 cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-text-gray-500 hover:cqa-text-gray-700 cqa-transition-colors cqa-rounded cqa--mt-[2px] cqa--mr-[2px]\"\n (click)=\"handleClose()\"\n aria-label=\"Close modal\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px] !cqa-block !cqa-leading-none\">close</mat-icon>\n </button>\n </div>\n <!-- Summary text -->\n <p *ngIf=\"hasItems\" class=\"cqa-text-sm cqa-font-normal cqa-text-[#666666] cqa-text-sm cqa-leading-[1.4] cqa-font-inter cqa-m-0 cqa-mt-1\">\n {{ summaryText }}\n </p>\n </div>\n\n <!-- Divider -->\n <div class=\"cqa--mx-2 cqa-w-[calc(100%+1rem)] cqa-flex-shrink-0\">\n <div class=\"cqa-h-px cqa-w-full cqa-bg-[#E5E7EB]\" role=\"presentation\"></div>\n </div>\n\n <!-- Content -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-overflow-x-hidden cqa-px-6 cqa-pt-4 cqa-pb-2\" style=\"scrollbar-width: thin; max-height: 50vh;\">\n <!-- Empty State -->\n <div *ngIf=\"!hasItems\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-8 cqa-text-center\">\n <p class=\"cqa-text-sm cqa-text-[#666666] cqa-font-inter cqa-m-0\">\n {{ emptyStateLabel || 'No Data Found.' }}\n </p>\n </div>\n\n <!-- Breakpoints List -->\n <div *ngIf=\"hasItems\" class=\"cqa-flex cqa-flex-col cqa-gap-4\">\n <div\n *ngFor=\"let item of displayItems; trackBy: trackByItemId\"\n class=\"cqa-flex cqa-items-start cqa-gap-3 cqa-px-4 cqa-py-3 cqa-bg-[#e5e7eb2e] cqa-rounded-lg cqa-min-w-0 cqa-border cqa-border-solid cqa-border-[#E5E7EB]\">\n\n <!-- Red Breakpoint Dot -->\n <span class=\"cqa-flex-shrink-0 cqa-w-[10px] cqa-h-[10px] cqa-mt-[5px] cqa-rounded-full cqa-bg-[#DC2626]\" aria-hidden=\"true\"></span>\n\n <!-- Text Content -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-[2px] cqa-min-w-0 cqa-flex-1\">\n <span class=\"cqa-text-sm cqa-font-normal cqa-text-[#6B7280] cqa-leading-[1.3] cqa-font-inter\">\n {{ item.primaryLabel }}\n </span>\n <span class=\"cqa-text-sm cqa-font-normal cqa-text-[#111827] cqa-leading-[1.4] cqa-font-inter cqa-break-words\">\n {{ item.secondaryLabel }}\n </span>\n </div>\n <div (click)=\"$event.stopPropagation()\">\n <cqa-button\n type=\"button\"\n variant=\"text\"\n [customClass]=\"'cqa-api-edit-step-verification-delete'\"\n [tooltip]=\"'Remove breakpoint'\"\n (clicked)=\"removeItem(item)\">\n <svg class=\"cqa-api-edit-step-verification-delete-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M10.6663 6V12.6667H5.33301V6H10.6663ZM9.66634 2H6.33301L5.66634 2.66667H3.33301V4H12.6663V2.66667H10.333L9.66634 2ZM11.9997 4.66667H3.99967V12.6667C3.99967 13.4 4.59967 14 5.33301 14H10.6663C11.3997 14 11.9997 13.4 11.9997 12.6667V4.66667Z\" fill=\"#99999E\" />\n </svg>\n </cqa-button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Footer: Remove All Button -->\n <div *ngIf=\"hasItems\" class=\"cqa-px-6 cqa-pb-6 cqa-pt-4\">\n \n <cqa-button\n [fullWidth]=\"true\"\n (click)=\"removeAll()\"\n [label]=\"buttonLabel\"\n variant=\"outlined\"\n color=\"black\"\n [text]=\"buttonLabel\"\n >\n </cqa-button>\n <!-- <button\n type=\"button\"\n class=\"cqa-w-full cqa-py-[10px] cqa-px-5 cqa-text-sm cqa-font-medium cqa-text-[#212121] cqa-bg-white cqa-border cqa-border-solid cqa-border-[#D9D9D9] cqa-rounded-lg cqa-cursor-pointer cqa-transition-colors hover:cqa-bg-[#F9FAFB] hover:cqa-border-[#9CA3AF] cqa-font-inter\"\n (click)=\"removeAll()\">\n {{ buttonLabel }}\n </button> -->\n </div>\n </div>\n</div>\n\n", styles: [] }]
|
|
71
|
+
}], propDecorators: { isOpen: [{
|
|
72
|
+
type: Input
|
|
73
|
+
}], title: [{
|
|
74
|
+
type: Input
|
|
75
|
+
}], items: [{
|
|
76
|
+
type: Input
|
|
77
|
+
}], buttonLabel: [{
|
|
78
|
+
type: Input
|
|
79
|
+
}], emptyStateLabel: [{
|
|
80
|
+
type: Input
|
|
81
|
+
}], onClose: [{
|
|
82
|
+
type: Output
|
|
83
|
+
}], onRemove: [{
|
|
84
|
+
type: Output
|
|
85
|
+
}], onRemoveAll: [{
|
|
86
|
+
type: Output
|
|
87
|
+
}] } });
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJlYWtwb2ludHMtbW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9leGVjdXRpb24tc2NyZWVuL2JyZWFrcG9pbnRzLW1vZGFsL2JyZWFrcG9pbnRzLW1vZGFsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvZXhlY3V0aW9uLXNjcmVlbi9icmVha3BvaW50cy1tb2RhbC9icmVha3BvaW50cy1tb2RhbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUE0QixNQUFNLGVBQWUsQ0FBQzs7Ozs7QUFpQmpHLE1BQU0sT0FBTyx5QkFBeUI7SUFOdEM7UUFPRSxnQ0FBZ0M7UUFDdkIsV0FBTSxHQUFZLEtBQUssQ0FBQztRQUVqQyxrQkFBa0I7UUFDVCxVQUFLLEdBQVcsYUFBYSxDQUFDO1FBRXZDLDBDQUEwQztRQUNqQyxVQUFLLEdBQXFCLEVBQUUsQ0FBQztRQUV0QyxzQ0FBc0M7UUFDN0IsZ0JBQVcsR0FBVyx3QkFBd0IsQ0FBQztRQUV4RCxnQ0FBZ0M7UUFDdkIsb0JBQWUsR0FBVyxxQkFBcUIsQ0FBQztRQUV6RCxnRkFBZ0Y7UUFDaEYsaUJBQVksR0FBcUIsRUFBRSxDQUFDO1FBRXBDLDBDQUEwQztRQUNoQyxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUU3Qyx5REFBeUQ7UUFDL0MsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFrQixDQUFDO1FBRXhELHFEQUFxRDtRQUMzQyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFRLENBQUM7S0ErQ2xEO0lBN0NDLFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNwQixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztTQUM3QztJQUNILENBQUM7SUFFRCxJQUFJLFdBQVc7UUFDYixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQztRQUN2QyxJQUFJLEtBQUssS0FBSyxDQUFDO1lBQUUsT0FBTyxFQUFFLENBQUM7UUFDM0IsT0FBTyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLGtCQUFrQixDQUFDO0lBQ3ZFLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRCxVQUFVLENBQUMsSUFBb0I7UUFDN0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVFLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO1lBQ2xDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUNwQjtJQUNILENBQUM7SUFFRCxTQUFTO1FBQ1AsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRUQsZUFBZSxDQUFDLEtBQWlCO1FBQy9CLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFxQixDQUFDO1FBQzNDLE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQyxhQUE0QixDQUFDO1FBRXpELElBQUksTUFBTSxLQUFLLGFBQWEsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQzNFLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUNwQjtJQUNILENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQWEsRUFBRSxJQUFvQjtRQUMvQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDakIsQ0FBQzs7c0hBeEVVLHlCQUF5QjswR0FBekIseUJBQXlCLDRVQ2pCdEMsd3pKQWtHQTsyRkRqRmEseUJBQXlCO2tCQU5yQyxTQUFTOytCQUNFLHVCQUF1QixRQUczQixFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7OEJBSXJCLE1BQU07c0JBQWQsS0FBSztnQkFHRyxLQUFLO3NCQUFiLEtBQUs7Z0JBR0csS0FBSztzQkFBYixLQUFLO2dCQUdHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBR0csZUFBZTtzQkFBdkIsS0FBSztnQkFNSSxPQUFPO3NCQUFoQixNQUFNO2dCQUdHLFFBQVE7c0JBQWpCLE1BQU07Z0JBR0csV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkNoYW5nZXMsIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBCcmVha3BvaW50SXRlbSB7XG4gIGlkOiBzdHJpbmc7XG4gIHN0ZXBJZDogbnVtYmVyO1xuICBzdGVwTnVtYmVyOiBzdHJpbmcgfCBudW1iZXI7XG4gIHByaW1hcnlMYWJlbDogc3RyaW5nO1xuICBzZWNvbmRhcnlMYWJlbDogc3RyaW5nO1xuICBba2V5OiBzdHJpbmddOiBhbnk7IC8vIEFsbG93IGFkZGl0aW9uYWwgcHJvcGVydGllc1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjcWEtYnJlYWtwb2ludHMtbW9kYWwnLFxuICB0ZW1wbGF0ZVVybDogJy4vYnJlYWtwb2ludHMtbW9kYWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFtdLFxuICBob3N0OiB7IGNsYXNzOiAnY3FhLXVpLXJvb3QnIH1cbn0pXG5leHBvcnQgY2xhc3MgQnJlYWtwb2ludHNNb2RhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qKiBXaGV0aGVyIHRoZSBtb2RhbCBpcyBvcGVuICovXG4gIEBJbnB1dCgpIGlzT3BlbjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBNb2RhbCB0aXRsZSAqL1xuICBASW5wdXQoKSB0aXRsZTogc3RyaW5nID0gJ0JyZWFrcG9pbnRzJztcblxuICAvKiogTGlzdCBvZiBicmVha3BvaW50IGl0ZW1zIHRvIGRpc3BsYXkgKi9cbiAgQElucHV0KCkgaXRlbXM6IEJyZWFrcG9pbnRJdGVtW10gPSBbXTtcblxuICAvKiogTGFiZWwgZm9yIHRoZSByZW1vdmUtYWxsIGJ1dHRvbiAqL1xuICBASW5wdXQoKSBidXR0b25MYWJlbDogc3RyaW5nID0gJ1JlbW92ZSBhbGwgYnJlYWtwb2ludHMnO1xuXG4gIC8qKiBMYWJlbCBmb3IgdGhlIGVtcHR5IHN0YXRlICovXG4gIEBJbnB1dCgpIGVtcHR5U3RhdGVMYWJlbDogc3RyaW5nID0gJ05vIGJyZWFrcG9pbnRzIHNldC4nO1xuXG4gIC8qKiBJbnRlcm5hbCBjb3B5IHNvIGl0ZW1zIGNhbiBiZSByZW1vdmVkIGxvY2FsbHkgd2hlbiBwYXJlbnQgZG9lc24ndCByZS1iaW5kICovXG4gIGRpc3BsYXlJdGVtczogQnJlYWtwb2ludEl0ZW1bXSA9IFtdO1xuXG4gIC8qKiBFbWl0dGVkIHdoZW4gbW9kYWwgc2hvdWxkIGJlIGNsb3NlZCAqL1xuICBAT3V0cHV0KCkgb25DbG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAvKiogRW1pdHRlZCB3aGVuIGEgc2luZ2xlIGJyZWFrcG9pbnQgc2hvdWxkIGJlIHJlbW92ZWQgKi9cbiAgQE91dHB1dCgpIG9uUmVtb3ZlID0gbmV3IEV2ZW50RW1pdHRlcjxCcmVha3BvaW50SXRlbT4oKTtcblxuICAvKiogRW1pdHRlZCB3aGVuIGFsbCBicmVha3BvaW50cyBzaG91bGQgYmUgcmVtb3ZlZCAqL1xuICBAT3V0cHV0KCkgb25SZW1vdmVBbGwgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydpdGVtcyddKSB7XG4gICAgICB0aGlzLmRpc3BsYXlJdGVtcyA9IFsuLi4odGhpcy5pdGVtcyB8fCBbXSldO1xuICAgIH1cbiAgfVxuXG4gIGdldCBzdW1tYXJ5VGV4dCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvdW50ID0gdGhpcy5kaXNwbGF5SXRlbXMubGVuZ3RoO1xuICAgIGlmIChjb3VudCA9PT0gMCkgcmV0dXJuICcnO1xuICAgIHJldHVybiBjb3VudCA9PT0gMSA/ICcxIGJyZWFrcG9pbnQgc2V0JyA6IGAke2NvdW50fSBicmVha3BvaW50cyBzZXRgO1xuICB9XG5cbiAgZ2V0IGhhc0l0ZW1zKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRpc3BsYXlJdGVtcyAmJiB0aGlzLmRpc3BsYXlJdGVtcy5sZW5ndGggPiAwO1xuICB9XG5cbiAgcmVtb3ZlSXRlbShpdGVtOiBCcmVha3BvaW50SXRlbSk6IHZvaWQge1xuICAgIHRoaXMub25SZW1vdmUuZW1pdChpdGVtKTtcbiAgICB0aGlzLmRpc3BsYXlJdGVtcyA9IHRoaXMuZGlzcGxheUl0ZW1zLmZpbHRlcihiID0+IGIuc3RlcElkICE9PSBpdGVtLnN0ZXBJZCk7XG4gICAgaWYgKHRoaXMuZGlzcGxheUl0ZW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5oYW5kbGVDbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIHJlbW92ZUFsbCgpOiB2b2lkIHtcbiAgICB0aGlzLm9uUmVtb3ZlQWxsLmVtaXQoKTtcbiAgICB0aGlzLmRpc3BsYXlJdGVtcyA9IFtdO1xuICB9XG5cbiAgb25CYWNrZHJvcENsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGNvbnN0IGN1cnJlbnRUYXJnZXQgPSBldmVudC5jdXJyZW50VGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuXG4gICAgaWYgKHRhcmdldCA9PT0gY3VycmVudFRhcmdldCB8fCB0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKCdtb2RhbC1iYWNrZHJvcCcpKSB7XG4gICAgICB0aGlzLmhhbmRsZUNsb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlQ2xvc2UoKTogdm9pZCB7XG4gICAgdGhpcy5vbkNsb3NlLmVtaXQoKTtcbiAgfVxuXG4gIHRyYWNrQnlJdGVtSWQoaW5kZXg6IG51bWJlciwgaXRlbTogQnJlYWtwb2ludEl0ZW0pOiBzdHJpbmcge1xuICAgIHJldHVybiBpdGVtLmlkO1xuICB9XG59XG5cbiIsIjxkaXYgKm5nSWY9XCJpc09wZW5cIlxuICBjbGFzcz1cIm1vZGFsLWJhY2tkcm9wIGNxYS1maXhlZCBjcWEtaW5zZXQtMCBjcWEtYmctYmxhY2sgY3FhLWJnLW9wYWNpdHktNTAgY3FhLXotNTAgY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXAtNFwiXG4gIChjbGljayk9XCJvbkJhY2tkcm9wQ2xpY2soJGV2ZW50KVwiPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJjcWEtcm91bmRlZC14bCBjcWEtYmctd2hpdGUgY3FhLXNoYWRvdy1sZyBjcWEtdy1mdWxsIGNxYS1tYXgtdy1bNDIwcHhdIGNxYS1vdmVyZmxvdy1oaWRkZW4gY3FhLWZsZXggY3FhLWZsZXgtY29sXCJcbiAgICBzdHlsZT1cImJveC1zaGFkb3c6IDBweCA4cHggOHB4IC00cHggIzEwMTgyODA4OyBtYXgtaGVpZ2h0OiA5MHZoO1wiXG4gICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuXG4gICAgPCEtLSBIZWFkZXIgLS0+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1weC02IGNxYS1wdC02IGNxYS1wYi0yXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLXN0YXJ0IGNxYS1qdXN0aWZ5LWJldHdlZW4gY3FhLWdhcC0zXCI+XG4gICAgICAgIDxoMiBjbGFzcz1cImNxYS10ZXh0LWxnIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LVsjMEIwQjBDXSBjcWEtdGV4dC1iYXNlIGNxYS1mb250LWludGVyXCI+XG4gICAgICAgICAge3sgdGl0bGUgfX1cbiAgICAgICAgPC9oMj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXctNiBjcWEtaC02IGNxYS1wLTAgY3FhLWJvcmRlci0wIGNxYS1iZy10cmFuc3BhcmVudCBjcWEtY3Vyc29yLXBvaW50ZXIgY3FhLXRleHQtZ3JheS01MDAgaG92ZXI6Y3FhLXRleHQtZ3JheS03MDAgY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1yb3VuZGVkIGNxYS0tbXQtWzJweF0gY3FhLS1tci1bMnB4XVwiXG4gICAgICAgICAgKGNsaWNrKT1cImhhbmRsZUNsb3NlKClcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCJDbG9zZSBtb2RhbFwiPlxuICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIiFjcWEtdy01ICFjcWEtaC01ICFjcWEtdGV4dC1bMjBweF0gIWNxYS1ibG9jayAhY3FhLWxlYWRpbmctbm9uZVwiPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICAgIDwhLS0gU3VtbWFyeSB0ZXh0IC0tPlxuICAgICAgPHAgKm5nSWY9XCJoYXNJdGVtc1wiIGNsYXNzPVwiY3FhLXRleHQtc20gY3FhLWZvbnQtbm9ybWFsICBjcWEtdGV4dC1bIzY2NjY2Nl0gY3FhLXRleHQtc20gY3FhLWxlYWRpbmctWzEuNF0gY3FhLWZvbnQtaW50ZXIgY3FhLW0tMCBjcWEtbXQtMVwiPlxuICAgICAgICB7eyBzdW1tYXJ5VGV4dCB9fVxuICAgICAgPC9wPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBEaXZpZGVyIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtLW14LTIgY3FhLXctW2NhbGMoMTAwJSsxcmVtKV0gY3FhLWZsZXgtc2hyaW5rLTBcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjcWEtaC1weCBjcWEtdy1mdWxsIGNxYS1iZy1bI0U1RTdFQl1cIiByb2xlPVwicHJlc2VudGF0aW9uXCI+PC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIENvbnRlbnQgLS0+XG4gICAgPGRpdiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLW92ZXJmbG93LXktYXV0byBjcWEtb3ZlcmZsb3cteC1oaWRkZW4gY3FhLXB4LTYgY3FhLXB0LTQgY3FhLXBiLTJcIiBzdHlsZT1cInNjcm9sbGJhci13aWR0aDogdGhpbjsgbWF4LWhlaWdodDogNTB2aDtcIj5cbiAgICAgIDwhLS0gRW1wdHkgU3RhdGUgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWhhc0l0ZW1zXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXB5LTggY3FhLXRleHQtY2VudGVyXCI+XG4gICAgICAgIDxwIGNsYXNzPVwiY3FhLXRleHQtc20gY3FhLXRleHQtWyM2NjY2NjZdIGNxYS1mb250LWludGVyIGNxYS1tLTBcIj5cbiAgICAgICAgICB7eyBlbXB0eVN0YXRlTGFiZWwgfHwgJ05vIERhdGEgRm91bmQuJyB9fVxuICAgICAgICA8L3A+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPCEtLSBCcmVha3BvaW50cyBMaXN0IC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImhhc0l0ZW1zXCIgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC00XCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBkaXNwbGF5SXRlbXM7IHRyYWNrQnk6IHRyYWNrQnlJdGVtSWRcIlxuICAgICAgICAgIGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLXN0YXJ0IGNxYS1nYXAtMyBjcWEtcHgtNCBjcWEtcHktMyBjcWEtYmctWyNlNWU3ZWIyZV0gY3FhLXJvdW5kZWQtbGcgY3FhLW1pbi13LTAgY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyNFNUU3RUJdXCI+XG5cbiAgICAgICAgICA8IS0tIFJlZCBCcmVha3BvaW50IERvdCAtLT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS1mbGV4LXNocmluay0wIGNxYS13LVsxMHB4XSBjcWEtaC1bMTBweF0gY3FhLW10LVs1cHhdIGNxYS1yb3VuZGVkLWZ1bGwgY3FhLWJnLVsjREMyNjI2XVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvc3Bhbj5cblxuICAgICAgICAgIDwhLS0gVGV4dCBDb250ZW50IC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleCBjcWEtZmxleC1jb2wgY3FhLWdhcC1bMnB4XSBjcWEtbWluLXctMCBjcWEtZmxleC0xXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS10ZXh0LXNtIGNxYS1mb250LW5vcm1hbCBjcWEtdGV4dC1bIzZCNzI4MF0gY3FhLWxlYWRpbmctWzEuM10gY3FhLWZvbnQtaW50ZXJcIj5cbiAgICAgICAgICAgICAge3sgaXRlbS5wcmltYXJ5TGFiZWwgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY3FhLXRleHQtc20gY3FhLWZvbnQtbm9ybWFsIGNxYS10ZXh0LVsjMTExODI3XSBjcWEtbGVhZGluZy1bMS40XSBjcWEtZm9udC1pbnRlciBjcWEtYnJlYWstd29yZHNcIj5cbiAgICAgICAgICAgICAge3sgaXRlbS5zZWNvbmRhcnlMYWJlbCB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiPlxuICAgICAgICAgICAgPGNxYS1idXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIHZhcmlhbnQ9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgW2N1c3RvbUNsYXNzXT1cIidjcWEtYXBpLWVkaXQtc3RlcC12ZXJpZmljYXRpb24tZGVsZXRlJ1wiXG4gICAgICAgICAgICAgIFt0b29sdGlwXT1cIidSZW1vdmUgYnJlYWtwb2ludCdcIlxuICAgICAgICAgICAgICAoY2xpY2tlZCk9XCJyZW1vdmVJdGVtKGl0ZW0pXCI+XG4gICAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJjcWEtYXBpLWVkaXQtc3RlcC12ZXJpZmljYXRpb24tZGVsZXRlLWljb25cIiB3aWR0aD1cIjE2XCIgaGVpZ2h0PVwiMTZcIiB2aWV3Qm94PVwiMCAwIDE2IDE2XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgPHBhdGggZD1cIk0xMC42NjYzIDZWMTIuNjY2N0g1LjMzMzAxVjZIMTAuNjY2M1pNOS42NjYzNCAySDYuMzMzMDFMNS42NjYzNCAyLjY2NjY3SDMuMzMzMDFWNEgxMi42NjYzVjIuNjY2NjdIMTAuMzMzTDkuNjY2MzQgMlpNMTEuOTk5NyA0LjY2NjY3SDMuOTk5NjdWMTIuNjY2N0MzLjk5OTY3IDEzLjQgNC41OTk2NyAxNCA1LjMzMzAxIDE0SDEwLjY2NjNDMTEuMzk5NyAxNCAxMS45OTk3IDEzLjQgMTEuOTk5NyAxMi42NjY3VjQuNjY2NjdaXCIgZmlsbD1cIiM5OTk5OUVcIiAvPlxuICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDwvY3FhLWJ1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDwhLS0gRm9vdGVyOiBSZW1vdmUgQWxsIEJ1dHRvbiAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwiaGFzSXRlbXNcIiBjbGFzcz1cImNxYS1weC02IGNxYS1wYi02IGNxYS1wdC00XCI+XG4gICAgICBcbiAgICAgIDxjcWEtYnV0dG9uXG4gICAgICAgIFtmdWxsV2lkdGhdPVwidHJ1ZVwiXG4gICAgICAgIChjbGljayk9XCJyZW1vdmVBbGwoKVwiXG4gICAgICAgIFtsYWJlbF09XCJidXR0b25MYWJlbFwiXG4gICAgICAgIHZhcmlhbnQ9XCJvdXRsaW5lZFwiXG4gICAgICAgIGNvbG9yPVwiYmxhY2tcIlxuICAgICAgICBbdGV4dF09XCJidXR0b25MYWJlbFwiXG4gICAgICAgID5cbiAgICAgIDwvY3FhLWJ1dHRvbj5cbiAgICAgIDwhLS0gPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJjcWEtdy1mdWxsIGNxYS1weS1bMTBweF0gY3FhLXB4LTUgY3FhLXRleHQtc20gY3FhLWZvbnQtbWVkaXVtIGNxYS10ZXh0LVsjMjEyMTIxXSBjcWEtYmctd2hpdGUgY3FhLWJvcmRlciBjcWEtYm9yZGVyLXNvbGlkIGNxYS1ib3JkZXItWyNEOUQ5RDldIGNxYS1yb3VuZGVkLWxnIGNxYS1jdXJzb3ItcG9pbnRlciBjcWEtdHJhbnNpdGlvbi1jb2xvcnMgaG92ZXI6Y3FhLWJnLVsjRjlGQUZCXSBob3ZlcjpjcWEtYm9yZGVyLVsjOUNBM0FGXSBjcWEtZm9udC1pbnRlclwiXG4gICAgICAgIChjbGljayk9XCJyZW1vdmVBbGwoKVwiPlxuICAgICAgICB7eyBidXR0b25MYWJlbCB9fVxuICAgICAgPC9idXR0b24+IC0tPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG4iXX0=
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "@angular/material/icon";
|
|
4
|
+
import * as i2 from "../../search-bar/search-bar.component";
|
|
5
|
+
import * as i3 from "@angular/common";
|
|
6
|
+
export class JumpToStepModalComponent {
|
|
7
|
+
constructor() {
|
|
8
|
+
/** Whether the modal is open */
|
|
9
|
+
this.isOpen = false;
|
|
10
|
+
/** Modal title */
|
|
11
|
+
this.title = 'Jump to Step';
|
|
12
|
+
/** List of step items to display */
|
|
13
|
+
this.items = [];
|
|
14
|
+
/** Search placeholder text */
|
|
15
|
+
this.searchPlaceholder = 'Search steps by name or number...';
|
|
16
|
+
/** Search Empty State text */
|
|
17
|
+
this.searchEmptyStateLabel = 'No steps found';
|
|
18
|
+
/** Current search value */
|
|
19
|
+
this.searchValue = '';
|
|
20
|
+
/** Whether search is enabled */
|
|
21
|
+
this.enableSearch = true;
|
|
22
|
+
/** Filtered items based on search */
|
|
23
|
+
this.filteredItems = [];
|
|
24
|
+
/** Emitted when modal should be closed */
|
|
25
|
+
this.onClose = new EventEmitter();
|
|
26
|
+
/** Emitted when search value changes */
|
|
27
|
+
this.onSearch = new EventEmitter();
|
|
28
|
+
/** Emitted when a step item is selected */
|
|
29
|
+
this.onSelect = new EventEmitter();
|
|
30
|
+
}
|
|
31
|
+
ngOnChanges(changes) {
|
|
32
|
+
if (changes['items'] || changes['searchValue']) {
|
|
33
|
+
this.updateFilteredItems();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
updateFilteredItems() {
|
|
37
|
+
if (!this.items || this.items.length === 0) {
|
|
38
|
+
this.filteredItems = [];
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!this.searchValue || this.searchValue.trim() === '') {
|
|
42
|
+
this.filteredItems = [...this.items];
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const searchTerm = this.searchValue.toLowerCase().trim();
|
|
46
|
+
this.filteredItems = this.items.filter(item => {
|
|
47
|
+
const stepNumberMatch = String(item.stepNumber).toLowerCase().includes(searchTerm);
|
|
48
|
+
const descriptionMatch = item.description.toLowerCase().includes(searchTerm);
|
|
49
|
+
return stepNumberMatch || descriptionMatch;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
onSearchValueChange(value) {
|
|
53
|
+
this.searchValue = value;
|
|
54
|
+
this.updateFilteredItems();
|
|
55
|
+
this.onSearch.emit(value);
|
|
56
|
+
}
|
|
57
|
+
onItemClick(item) {
|
|
58
|
+
this.onSelect.emit(item);
|
|
59
|
+
}
|
|
60
|
+
onBackdropClick(event) {
|
|
61
|
+
const target = event.target;
|
|
62
|
+
const currentTarget = event.currentTarget;
|
|
63
|
+
if (target === currentTarget || target.classList.contains('modal-backdrop')) {
|
|
64
|
+
this.handleClose();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
handleClose() {
|
|
68
|
+
this.onClose.emit();
|
|
69
|
+
}
|
|
70
|
+
getStatusBadgeClasses(status) {
|
|
71
|
+
const baseClasses = 'cqa-inline-flex cqa-items-center cqa-justify-center cqa-rounded-[6px] cqa-text-xs cqa-font-medium cqa-py-[4px] cqa-px-3';
|
|
72
|
+
switch (status) {
|
|
73
|
+
case 'passed':
|
|
74
|
+
return `${baseClasses} cqa-bg-green-100 cqa-text-green-800`;
|
|
75
|
+
case 'current':
|
|
76
|
+
return `${baseClasses} cqa-bg-blue-100 cqa-text-blue-800`;
|
|
77
|
+
case 'pending':
|
|
78
|
+
return `${baseClasses} cqa-bg-gray-100 cqa-text-gray-800`;
|
|
79
|
+
case 'failed':
|
|
80
|
+
return `${baseClasses} cqa-bg-red-100 cqa-text-red-800`;
|
|
81
|
+
case 'running':
|
|
82
|
+
return `${baseClasses} cqa-bg-blue-100 cqa-text-blue-800`;
|
|
83
|
+
case 'skipped':
|
|
84
|
+
return `${baseClasses} cqa-bg-gray-100 cqa-text-gray-800`;
|
|
85
|
+
default:
|
|
86
|
+
return `${baseClasses} cqa-bg-gray-100 cqa-text-gray-800`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
get hasItems() {
|
|
90
|
+
return this.filteredItems && this.filteredItems.length > 0;
|
|
91
|
+
}
|
|
92
|
+
get itemsCount() {
|
|
93
|
+
return this.filteredItems ? this.filteredItems.length : 0;
|
|
94
|
+
}
|
|
95
|
+
/** Convert stepNumber to string for the badge label (String() is not available in templates) */
|
|
96
|
+
toLabel(value) {
|
|
97
|
+
return '' + value;
|
|
98
|
+
}
|
|
99
|
+
trackByItemId(index, item) {
|
|
100
|
+
return item.id;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
JumpToStepModalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: JumpToStepModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
104
|
+
JumpToStepModalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: JumpToStepModalComponent, selector: "cqa-jump-to-step-modal", inputs: { isOpen: "isOpen", title: "title", items: "items", searchPlaceholder: "searchPlaceholder", searchEmptyStateLabel: "searchEmptyStateLabel", searchValue: "searchValue", enableSearch: "enableSearch" }, outputs: { onClose: "onClose", onSearch: "onSearch", onSelect: "onSelect" }, host: { classAttribute: "cqa-ui-root" }, usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"isOpen\"\n class=\"modal-backdrop cqa-fixed cqa-inset-0 cqa-bg-black cqa-bg-opacity-50 cqa-z-50 cqa-flex cqa-items-center cqa-justify-center cqa-p-4\"\n (click)=\"onBackdropClick($event)\">\n <div\n class=\"cqa-rounded-lg cqa-bg-white cqa-shadow-lg cqa-w-full cqa-max-w-[500px] cqa-overflow-hidden cqa-flex cqa-flex-col\"\n style=\"box-shadow: 0px 8px 8px -4px #10182808; max-height: 90vh;\"\n (click)=\"$event.stopPropagation()\">\n\n <!-- Header -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-6 cqa-pt-6 cqa-pb-4\">\n <h2 class=\"cqa-text-base cqa-font-semibold cqa-text-[#0A0A0A] cqa-leading-[24px] cqa-font-inter\">\n {{ title }}\n </h2>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-6 cqa-h-6 cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-text-gray-500 hover:cqa-text-gray-700 cqa-transition-colors\"\n (click)=\"handleClose()\"\n aria-label=\"Close modal\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px] !cqa-block !cqa-leading-none\">close</mat-icon>\n </button>\n </div>\n\n\n <!-- Search Bar -->\n <div *ngIf=\"enableSearch\" class=\"cqa-px-6 cqa-pb-4\">\n <cqa-search-bar\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [fullWidth]=\"true\"\n (valueChange)=\"onSearchValueChange($event)\">\n </cqa-search-bar>\n </div>\n\n <!-- Divider below search -->\n <div class=\"cqa--mx-2 cqa-w-[calc(100%+1rem)] cqa-flex-shrink-0\">\n <div class=\"cqa-h-px cqa-w-full cqa-bg-[#E5E7EB]\" role=\"presentation\"></div>\n </div>\n\n <!-- Steps List -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-overflow-x-hidden cqa-px-6 cqa-pt-2\" style=\"scrollbar-width: thin;\">\n <!-- Empty State -->\n <div *ngIf=\"!hasItems\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-12 cqa-text-center\">\n <p class=\"cqa-text-sm cqa-text-gray-500 cqa-font-inter\">\n {{searchEmptyStateLabel || 'No Data found.'}}\n </p>\n </div>\n\n <!-- Steps List -->\n <div *ngIf=\"hasItems\" class=\"cqa-flex cqa-flex-col\">\n <button\n *ngFor=\"let item of filteredItems; trackBy: trackByItemId\"\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-px-3 cqa-py-3 cqa-w-full cqa-text-left cqa-border-0 cqa-bg-transparent hover:cqa-bg-gray-50 cqa-cursor-pointer cqa-transition-colors cqa-rounded-md cqa-min-w-0\"\n (click)=\"onItemClick(item)\">\n\n <!-- Step Number Badge -->\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-rounded-[6px] cqa-text-xs cqa-font-medium cqa-py-[4px] cqa-px-[10px] cqa-flex-shrink-0 cqa-border cqa-border-solid cqa-border-[#E2E8F0] cqa-text-[#3F43EE] cqa-bg-[#F8F9FF]\"\n style=\"min-width: 32px;\">\n {{ item.stepNumber }}\n </span>\n\n <!-- Step Description -->\n <span class=\"cqa-flex-1 cqa-text-sm cqa-text-[#0A0A0A] cqa-font-inter cqa-font-normal cqa-leading-[20px] cqa-min-w-0 cqa-truncate\">\n {{ item.description }}\n </span>\n\n <!-- Status Badge -->\n <span class=\"cqa-flex-shrink-0\" [ngClass]=\"getStatusBadgeClasses(item.status)\">\n {{ item.status }}\n </span>\n\n <!-- Right Arrow Icon-->\n <!-- <span class=\"cqa-flex cqa-items-center cqa-justify-center cqa-flex-shrink-0\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4L10 8L6 12\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span> -->\n </button>\n </div>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"hasItems\" class=\"cqa-px-6 cqa-pb-5 cqa-pt-3\">\n <p class=\"cqa-text-xs cqa-text-[#6B7280] cqa-font-inter cqa-font-normal\">\n {{ itemsCount }} {{ itemsCount === 1 ? 'step' : 'steps' }} found\n </p>\n </div>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2.SearchBarComponent, selector: "cqa-search-bar", inputs: ["placeholder", "value", "disabled", "showClear", "ariaLabel", "autoFocus", "size", "fullWidth"], outputs: ["valueChange", "search", "cleared"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
105
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: JumpToStepModalComponent, decorators: [{
|
|
106
|
+
type: Component,
|
|
107
|
+
args: [{ selector: 'cqa-jump-to-step-modal', host: { class: 'cqa-ui-root' }, template: "<div *ngIf=\"isOpen\"\n class=\"modal-backdrop cqa-fixed cqa-inset-0 cqa-bg-black cqa-bg-opacity-50 cqa-z-50 cqa-flex cqa-items-center cqa-justify-center cqa-p-4\"\n (click)=\"onBackdropClick($event)\">\n <div\n class=\"cqa-rounded-lg cqa-bg-white cqa-shadow-lg cqa-w-full cqa-max-w-[500px] cqa-overflow-hidden cqa-flex cqa-flex-col\"\n style=\"box-shadow: 0px 8px 8px -4px #10182808; max-height: 90vh;\"\n (click)=\"$event.stopPropagation()\">\n\n <!-- Header -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-px-6 cqa-pt-6 cqa-pb-4\">\n <h2 class=\"cqa-text-base cqa-font-semibold cqa-text-[#0A0A0A] cqa-leading-[24px] cqa-font-inter\">\n {{ title }}\n </h2>\n <button\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-6 cqa-h-6 cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-text-gray-500 hover:cqa-text-gray-700 cqa-transition-colors\"\n (click)=\"handleClose()\"\n aria-label=\"Close modal\">\n <mat-icon class=\"!cqa-w-5 !cqa-h-5 !cqa-text-[20px] !cqa-block !cqa-leading-none\">close</mat-icon>\n </button>\n </div>\n\n\n <!-- Search Bar -->\n <div *ngIf=\"enableSearch\" class=\"cqa-px-6 cqa-pb-4\">\n <cqa-search-bar\n [placeholder]=\"searchPlaceholder\"\n [value]=\"searchValue\"\n [fullWidth]=\"true\"\n (valueChange)=\"onSearchValueChange($event)\">\n </cqa-search-bar>\n </div>\n\n <!-- Divider below search -->\n <div class=\"cqa--mx-2 cqa-w-[calc(100%+1rem)] cqa-flex-shrink-0\">\n <div class=\"cqa-h-px cqa-w-full cqa-bg-[#E5E7EB]\" role=\"presentation\"></div>\n </div>\n\n <!-- Steps List -->\n <div class=\"cqa-flex-1 cqa-overflow-y-auto cqa-overflow-x-hidden cqa-px-6 cqa-pt-2\" style=\"scrollbar-width: thin;\">\n <!-- Empty State -->\n <div *ngIf=\"!hasItems\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-justify-center cqa-py-12 cqa-text-center\">\n <p class=\"cqa-text-sm cqa-text-gray-500 cqa-font-inter\">\n {{searchEmptyStateLabel || 'No Data found.'}}\n </p>\n </div>\n\n <!-- Steps List -->\n <div *ngIf=\"hasItems\" class=\"cqa-flex cqa-flex-col\">\n <button\n *ngFor=\"let item of filteredItems; trackBy: trackByItemId\"\n type=\"button\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-px-3 cqa-py-3 cqa-w-full cqa-text-left cqa-border-0 cqa-bg-transparent hover:cqa-bg-gray-50 cqa-cursor-pointer cqa-transition-colors cqa-rounded-md cqa-min-w-0\"\n (click)=\"onItemClick(item)\">\n\n <!-- Step Number Badge -->\n <span class=\"cqa-inline-flex cqa-items-center cqa-justify-center cqa-rounded-[6px] cqa-text-xs cqa-font-medium cqa-py-[4px] cqa-px-[10px] cqa-flex-shrink-0 cqa-border cqa-border-solid cqa-border-[#E2E8F0] cqa-text-[#3F43EE] cqa-bg-[#F8F9FF]\"\n style=\"min-width: 32px;\">\n {{ item.stepNumber }}\n </span>\n\n <!-- Step Description -->\n <span class=\"cqa-flex-1 cqa-text-sm cqa-text-[#0A0A0A] cqa-font-inter cqa-font-normal cqa-leading-[20px] cqa-min-w-0 cqa-truncate\">\n {{ item.description }}\n </span>\n\n <!-- Status Badge -->\n <span class=\"cqa-flex-shrink-0\" [ngClass]=\"getStatusBadgeClasses(item.status)\">\n {{ item.status }}\n </span>\n\n <!-- Right Arrow Icon-->\n <!-- <span class=\"cqa-flex cqa-items-center cqa-justify-center cqa-flex-shrink-0\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 4L10 8L6 12\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span> -->\n </button>\n </div>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"hasItems\" class=\"cqa-px-6 cqa-pb-5 cqa-pt-3\">\n <p class=\"cqa-text-xs cqa-text-[#6B7280] cqa-font-inter cqa-font-normal\">\n {{ itemsCount }} {{ itemsCount === 1 ? 'step' : 'steps' }} found\n </p>\n </div>\n </div>\n</div>\n", styles: [] }]
|
|
108
|
+
}], propDecorators: { isOpen: [{
|
|
109
|
+
type: Input
|
|
110
|
+
}], title: [{
|
|
111
|
+
type: Input
|
|
112
|
+
}], items: [{
|
|
113
|
+
type: Input
|
|
114
|
+
}], searchPlaceholder: [{
|
|
115
|
+
type: Input
|
|
116
|
+
}], searchEmptyStateLabel: [{
|
|
117
|
+
type: Input
|
|
118
|
+
}], searchValue: [{
|
|
119
|
+
type: Input
|
|
120
|
+
}], enableSearch: [{
|
|
121
|
+
type: Input
|
|
122
|
+
}], onClose: [{
|
|
123
|
+
type: Output
|
|
124
|
+
}], onSearch: [{
|
|
125
|
+
type: Output
|
|
126
|
+
}], onSelect: [{
|
|
127
|
+
type: Output
|
|
128
|
+
}] } });
|
|
129
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianVtcC10by1zdGVwLW1vZGFsLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvZXhlY3V0aW9uLXNjcmVlbi9qdW1wLXRvLXN0ZXAtbW9kYWwvanVtcC10by1zdGVwLW1vZGFsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvZXhlY3V0aW9uLXNjcmVlbi9qdW1wLXRvLXN0ZXAtbW9kYWwvanVtcC10by1zdGVwLW1vZGFsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQTRCLE1BQU0sZUFBZSxDQUFDOzs7OztBQWtCakcsTUFBTSxPQUFPLHdCQUF3QjtJQU5yQztRQU9FLGdDQUFnQztRQUN2QixXQUFNLEdBQVksS0FBSyxDQUFDO1FBRWpDLGtCQUFrQjtRQUNULFVBQUssR0FBVyxjQUFjLENBQUM7UUFFeEMsb0NBQW9DO1FBQzNCLFVBQUssR0FBcUIsRUFBRSxDQUFDO1FBRXRDLDhCQUE4QjtRQUNyQixzQkFBaUIsR0FBVyxtQ0FBbUMsQ0FBQztRQUV6RSw4QkFBOEI7UUFDckIsMEJBQXFCLEdBQVcsZ0JBQWdCLENBQUM7UUFFMUQsMkJBQTJCO1FBQ2xCLGdCQUFXLEdBQVcsRUFBRSxDQUFDO1FBRWxDLGdDQUFnQztRQUN2QixpQkFBWSxHQUFZLElBQUksQ0FBQztRQUV0QyxxQ0FBcUM7UUFDckMsa0JBQWEsR0FBcUIsRUFBRSxDQUFDO1FBRXJDLDBDQUEwQztRQUNoQyxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUU3Qyx3Q0FBd0M7UUFDOUIsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFVLENBQUM7UUFFaEQsMkNBQTJDO1FBQ2pDLGFBQVEsR0FBRyxJQUFJLFlBQVksRUFBa0IsQ0FBQztLQXVGekQ7SUFyRkMsV0FBVyxDQUFDLE9B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QyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUM3RCxDQUFDO0lBRUQsSUFBSSxVQUFVO1FBQ1osT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxnR0FBZ0c7SUFDaEcsT0FBTyxDQUFDLEtBQXNCO1FBQzVCLE9BQU8sRUFBRSxHQUFHLEtBQUssQ0FBQztJQUNwQixDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQWEsRUFBRSxJQUFvQjtRQUMvQyxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDakIsQ0FBQzs7cUhBdEhVLHdCQUF3Qjt5R0FBeEIsd0JBQXdCLHlaQ2xCckMsMm1JQXlGQTsyRkR2RWEsd0JBQXdCO2tCQU5wQyxTQUFTOytCQUNFLHdCQUF3QixRQUc1QixFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7OEJBSXJCLE1BQU07c0JBQWQsS0FBSztnQkFHRyxLQUFLO3NCQUFiLEtBQUs7Z0JBR0csS0FBSztzQkFBYixLQUFLO2dCQUdHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFHRyxxQkFBcUI7c0JBQTdCLEtBQUs7Z0JBR0csV0FBVztzQkFBbkIsS0FBSztnQkFHRyxZQUFZO3NCQUFwQixLQUFLO2dCQU1JLE9BQU87c0JBQWhCLE1BQU07Z0JBR0csUUFBUTtzQkFBakIsTUFBTTtnQkFHRyxRQUFRO3NCQUFqQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5leHBvcnQgdHlwZSBTdGVwSXRlbVN0YXR1cyA9ICdwYXNzZWQnIHwgJ2N1cnJlbnQnIHwgJ3BlbmRpbmcnIHwgJ2ZhaWxlZCcgfCAncnVubmluZycgfCAnc2tpcHBlZCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSnVtcFRvU3RlcEl0ZW0ge1xuICBpZDogc3RyaW5nO1xuICBzdGVwTnVtYmVyOiBzdHJpbmcgfCBudW1iZXI7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHN0YXR1czogU3RlcEl0ZW1TdGF0dXM7XG4gIFtrZXk6IHN0cmluZ106IGFueTsgLy8gQWxsb3cgYWRkaXRpb25hbCBwcm9wZXJ0aWVzXG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2NxYS1qdW1wLXRvLXN0ZXAtbW9kYWwnLFxuICB0ZW1wbGF0ZVVybDogJy4vanVtcC10by1zdGVwLW1vZGFsLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbXSxcbiAgaG9zdDogeyBjbGFzczogJ2NxYS11aS1yb290JyB9XG59KVxuZXhwb3J0IGNsYXNzIEp1bXBUb1N0ZXBNb2RhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qKiBXaGV0aGVyIHRoZSBtb2RhbCBpcyBvcGVuICovXG4gIEBJbnB1dCgpIGlzT3BlbjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBNb2RhbCB0aXRsZSAqL1xuICBASW5wdXQoKSB0aXRsZTogc3RyaW5nID0gJ0p1bXAgdG8gU3RlcCc7XG5cbiAgLyoqIExpc3Qgb2Ygc3RlcCBpdGVtcyB0byBkaXNwbGF5ICovXG4gIEBJbnB1dCgpIGl0ZW1zOiBKdW1wVG9TdGVwSXRlbVtdID0gW107XG5cbiAgLyoqIFNlYXJjaCBwbGFjZWhvbGRlciB0ZXh0ICovXG4gIEBJbnB1dCgpIHNlYXJjaFBsYWNlaG9sZGVyOiBzdHJpbmcgPSAnU2VhcmNoIHN0ZXBzIGJ5IG5hbWUgb3IgbnVtYmVyLi4uJztcblxuICAvKiogU2VhcmNoIEVtcHR5IFN0YXRlIHRleHQgKi9cbiAgQElucHV0KCkgc2VhcmNoRW1wdHlTdGF0ZUxhYmVsOiBzdHJpbmcgPSAnTm8gc3RlcHMgZm91bmQnO1xuXG4gIC8qKiBDdXJyZW50IHNlYXJjaCB2YWx1ZSAqL1xuICBASW5wdXQoKSBzZWFyY2hWYWx1ZTogc3RyaW5nID0gJyc7XG5cbiAgLyoqIFdoZXRoZXIgc2VhcmNoIGlzIGVuYWJsZWQgKi9cbiAgQElucHV0KCkgZW5hYmxlU2VhcmNoOiBib29sZWFuID0gdHJ1ZTtcblxuICAvKiogRmlsdGVyZWQgaXRlbXMgYmFzZWQgb24gc2VhcmNoICovXG4gIGZpbHRlcmVkSXRlbXM6IEp1bXBUb1N0ZXBJdGVtW10gPSBbXTtcblxuICAvKiogRW1pdHRlZCB3aGVuIG1vZGFsIHNob3VsZCBiZSBjbG9zZWQgKi9cbiAgQE91dHB1dCgpIG9uQ2xvc2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgLyoqIEVtaXR0ZWQgd2hlbiBzZWFyY2ggdmFsdWUgY2hhbmdlcyAqL1xuICBAT3V0cHV0KCkgb25TZWFyY2ggPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcblxuICAvKiogRW1pdHRlZCB3aGVuIGEgc3RlcCBpdGVtIGlzIHNlbGVjdGVkICovXG4gIEBPdXRwdXQoKSBvblNlbGVjdCA9IG5ldyBFdmVudEVtaXR0ZXI8SnVtcFRvU3RlcEl0ZW0+KCk7XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydpdGVtcyddIHx8IGNoYW5nZXNbJ3NlYXJjaFZhbHVlJ10pIHtcbiAgICAgIHRoaXMudXBkYXRlRmlsdGVyZWRJdGVtcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlRmlsdGVyZWRJdGVtcygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXRlbXMgfHwgdGhpcy5pdGVtcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuZmlsdGVyZWRJdGVtcyA9IFtdO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5zZWFyY2hWYWx1ZSB8fCB0aGlzLnNlYXJjaFZhbHVlLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgIHRoaXMuZmlsdGVyZWRJdGVtcyA9IFsuLi50aGlzLml0ZW1zXTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzZWFyY2hUZXJtID0gdGhpcy5zZWFyY2hWYWx1ZS50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcbiAgICB0aGlzLmZpbHRlcmVkSXRlbXMgPSB0aGlzLml0ZW1zLmZpbHRlcihpdGVtID0+IHtcbiAgICAgIGNvbnN0IHN0ZXBOdW1iZXJNYXRjaCA9IFN0cmluZyhpdGVtLnN0ZXBOdW1iZXIpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoc2VhcmNoVGVybSk7XG4gICAgICBjb25zdCBkZXNjcmlwdGlvbk1hdGNoID0gaXRlbS5kZXNjcmlwdGlvbi50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaFRlcm0pO1xuICAgICAgcmV0dXJuIHN0ZXBOdW1iZXJNYXRjaCB8fCBkZXNjcmlwdGlvbk1hdGNoO1xuICAgIH0pO1xuICB9XG5cbiAgb25TZWFyY2hWYWx1ZUNoYW5nZSh2YWx1ZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5zZWFyY2hWYWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMudXBkYXRlRmlsdGVyZWRJdGVtcygpO1xuICAgIHRoaXMub25TZWFyY2guZW1pdCh2YWx1ZSk7XG4gIH1cblxuICBvbkl0ZW1DbGljayhpdGVtOiBKdW1wVG9TdGVwSXRlbSk6IHZvaWQge1xuICAgIHRoaXMub25TZWxlY3QuZW1pdChpdGVtKTtcbiAgfVxuXG4gIG9uQmFja2Ryb3BDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBjdXJyZW50VGFyZ2V0ID0gZXZlbnQuY3VycmVudFRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBcbiAgICBpZiAodGFyZ2V0ID09PSBjdXJyZW50VGFyZ2V0IHx8IHRhcmdldC5jbGFzc0xpc3QuY29udGFpbnMoJ21vZGFsLWJhY2tkcm9wJykpIHtcbiAgICAgIHRoaXMuaGFuZGxlQ2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICBoYW5kbGVDbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2xvc2UuZW1pdCgpO1xuICB9XG5cbiAgZ2V0U3RhdHVzQmFkZ2VDbGFzc2VzKHN0YXR1czogU3RlcEl0ZW1TdGF0dXMpOiBzdHJpbmcge1xuICAgIGNvbnN0IGJhc2VDbGFzc2VzID0gJ2NxYS1pbmxpbmUtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1qdXN0aWZ5LWNlbnRlciBjcWEtcm91bmRlZC1bNnB4XSBjcWEtdGV4dC14cyBjcWEtZm9udC1tZWRpdW0gY3FhLXB5LVs0cHhdIGNxYS1weC0zJztcbiAgICBcbiAgICBzd2l0Y2ggKHN0YXR1cykge1xuICAgICAgY2FzZSAncGFzc2VkJzpcbiAgICAgICAgcmV0dXJuIGAke2Jhc2VDbGFzc2VzfSBjcWEtYmctZ3JlZW4tMTAwIGNxYS10ZXh0LWdyZWVuLTgwMGA7XG4gICAgICBjYXNlICdjdXJyZW50JzpcbiAgICAgICAgcmV0dXJuIGAke2Jhc2VDbGFzc2VzfSBjcWEtYmctYmx1ZS0xMDAgY3FhLXRleHQtYmx1ZS04MDBgO1xuICAgICAgY2FzZSAncGVuZGluZyc6XG4gICAgICAgIHJldHVybiBgJHtiYXNlQ2xhc3Nlc30gY3FhLWJnLWdyYXktMTAwIGNxYS10ZXh0LWdyYXktODAwYDtcbiAgICAgIGNhc2UgJ2ZhaWxlZCc6XG4gICAgICAgIHJldHVybiBgJHtiYXNlQ2xhc3Nlc30gY3FhLWJnLXJlZC0xMDAgY3FhLXRleHQtcmVkLTgwMGA7XG4gICAgICBjYXNlICdydW5uaW5nJzpcbiAgICAgICAgcmV0dXJuIGAke2Jhc2VDbGFzc2VzfSBjcWEtYmctYmx1ZS0xMDAgY3FhLXRleHQtYmx1ZS04MDBgO1xuICAgICAgY2FzZSAnc2tpcHBlZCc6XG4gICAgICAgIHJldHVybiBgJHtiYXNlQ2xhc3Nlc30gY3FhLWJnLWdyYXktMTAwIGNxYS10ZXh0LWdyYXktODAwYDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBgJHtiYXNlQ2xhc3Nlc30gY3FhLWJnLWdyYXktMTAwIGNxYS10ZXh0LWdyYXktODAwYDtcbiAgICB9XG4gIH1cblxuICBnZXQgaGFzSXRlbXMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyZWRJdGVtcyAmJiB0aGlzLmZpbHRlcmVkSXRlbXMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIGdldCBpdGVtc0NvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyZWRJdGVtcyA/IHRoaXMuZmlsdGVyZWRJdGVtcy5sZW5ndGggOiAwO1xuICB9XG5cbiAgLyoqIENvbnZlcnQgc3RlcE51bWJlciB0byBzdHJpbmcgZm9yIHRoZSBiYWRnZSBsYWJlbCAoU3RyaW5nKCkgaXMgbm90IGF2YWlsYWJsZSBpbiB0ZW1wbGF0ZXMpICovXG4gIHRvTGFiZWwodmFsdWU6IHN0cmluZyB8IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuICcnICsgdmFsdWU7XG4gIH1cblxuICB0cmFja0J5SXRlbUlkKGluZGV4OiBudW1iZXIsIGl0ZW06IEp1bXBUb1N0ZXBJdGVtKTogc3RyaW5nIHtcbiAgICByZXR1cm4gaXRlbS5pZDtcbiAgfVxufVxuXG4iLCI8ZGl2ICpuZ0lmPVwiaXNPcGVuXCJcbiAgY2xhc3M9XCJtb2RhbC1iYWNrZHJvcCBjcWEtZml4ZWQgY3FhLWluc2V0LTAgY3FhLWJnLWJsYWNrIGNxYS1iZy1vcGFjaXR5LTUwIGNxYS16LTUwIGNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1wLTRcIlxuICAoY2xpY2spPVwib25CYWNrZHJvcENsaWNrKCRldmVudClcIj5cbiAgPGRpdlxuICAgIGNsYXNzPVwiY3FhLXJvdW5kZWQtbGcgY3FhLWJnLXdoaXRlIGNxYS1zaGFkb3ctbGcgIGNxYS13LWZ1bGwgY3FhLW1heC13LVs1MDBweF0gY3FhLW92ZXJmbG93LWhpZGRlbiBjcWEtZmxleCBjcWEtZmxleC1jb2xcIlxuICAgIHN0eWxlPVwiYm94LXNoYWRvdzogMHB4IDhweCA4cHggLTRweCAjMTAxODI4MDg7IG1heC1oZWlnaHQ6IDkwdmg7XCJcbiAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG5cbiAgICA8IS0tIEhlYWRlciAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1iZXR3ZWVuIGNxYS1weC02IGNxYS1wdC02IGNxYS1wYi00XCI+XG4gICAgICA8aDIgY2xhc3M9XCJjcWEtdGV4dC1iYXNlIGNxYS1mb250LXNlbWlib2xkIGNxYS10ZXh0LVsjMEEwQTBBXSBjcWEtbGVhZGluZy1bMjRweF0gY3FhLWZvbnQtaW50ZXJcIj5cbiAgICAgICAge3sgdGl0bGUgfX1cbiAgICAgIDwvaDI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS13LTYgY3FhLWgtNiBjcWEtcC0wIGNxYS1ib3JkZXItMCBjcWEtYmctdHJhbnNwYXJlbnQgY3FhLWN1cnNvci1wb2ludGVyIGNxYS10ZXh0LWdyYXktNTAwIGhvdmVyOmNxYS10ZXh0LWdyYXktNzAwIGNxYS10cmFuc2l0aW9uLWNvbG9yc1wiXG4gICAgICAgIChjbGljayk9XCJoYW5kbGVDbG9zZSgpXCJcbiAgICAgICAgYXJpYS1sYWJlbD1cIkNsb3NlIG1vZGFsXCI+XG4gICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cIiFjcWEtdy01ICFjcWEtaC01ICFjcWEtdGV4dC1bMjBweF0gIWNxYS1ibG9jayAhY3FhLWxlYWRpbmctbm9uZVwiPmNsb3NlPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG5cbiAgICA8IS0tIFNlYXJjaCBCYXIgLS0+XG4gICAgPGRpdiAqbmdJZj1cImVuYWJsZVNlYXJjaFwiIGNsYXNzPVwiY3FhLXB4LTYgY3FhLXBiLTRcIj5cbiAgICAgIDxjcWEtc2VhcmNoLWJhclxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwic2VhcmNoUGxhY2Vob2xkZXJcIlxuICAgICAgICBbdmFsdWVdPVwic2VhcmNoVmFsdWVcIlxuICAgICAgICBbZnVsbFdpZHRoXT1cInRydWVcIlxuICAgICAgICAodmFsdWVDaGFuZ2UpPVwib25TZWFyY2hWYWx1ZUNoYW5nZSgkZXZlbnQpXCI+XG4gICAgICA8L2NxYS1zZWFyY2gtYmFyPlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBEaXZpZGVyIGJlbG93IHNlYXJjaCAtLT5cbiAgICA8ZGl2IGNsYXNzPVwiY3FhLS1teC0yIGNxYS13LVtjYWxjKDEwMCUrMXJlbSldIGNxYS1mbGV4LXNocmluay0wXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY3FhLWgtcHggY3FhLXctZnVsbCBjcWEtYmctWyNFNUU3RUJdXCIgcm9sZT1cInByZXNlbnRhdGlvblwiPjwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBTdGVwcyBMaXN0IC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjcWEtZmxleC0xIGNxYS1vdmVyZmxvdy15LWF1dG8gY3FhLW92ZXJmbG93LXgtaGlkZGVuIGNxYS1weC02IGNxYS1wdC0yXCIgc3R5bGU9XCJzY3JvbGxiYXItd2lkdGg6IHRoaW47XCI+XG4gICAgICA8IS0tIEVtcHR5IFN0YXRlIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cIiFoYXNJdGVtc1wiIGNsYXNzPVwiY3FhLWZsZXggY3FhLWZsZXgtY29sIGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1weS0xMiBjcWEtdGV4dC1jZW50ZXJcIj5cbiAgICAgICAgPHAgY2xhc3M9XCJjcWEtdGV4dC1zbSBjcWEtdGV4dC1ncmF5LTUwMCBjcWEtZm9udC1pbnRlclwiPlxuICAgICAgICAge3tzZWFyY2hFbXB0eVN0YXRlTGFiZWwgfHwgJ05vIERhdGEgZm91bmQuJ319XG4gICAgICAgIDwvcD5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIFN0ZXBzIExpc3QgLS0+XG4gICAgICA8ZGl2ICpuZ0lmPVwiaGFzSXRlbXNcIiBjbGFzcz1cImNxYS1mbGV4IGNxYS1mbGV4LWNvbFwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZmlsdGVyZWRJdGVtczsgdHJhY2tCeTogdHJhY2tCeUl0ZW1JZFwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJjcWEtZmxleCBjcWEtaXRlbXMtY2VudGVyIGNxYS1nYXAtMyBjcWEtcHgtMyBjcWEtcHktMyBjcWEtdy1mdWxsIGNxYS10ZXh0LWxlZnQgY3FhLWJvcmRlci0wIGNxYS1iZy10cmFuc3BhcmVudCBob3ZlcjpjcWEtYmctZ3JheS01MCBjcWEtY3Vyc29yLXBvaW50ZXIgY3FhLXRyYW5zaXRpb24tY29sb3JzIGNxYS1yb3VuZGVkLW1kIGNxYS1taW4tdy0wXCJcbiAgICAgICAgICAoY2xpY2spPVwib25JdGVtQ2xpY2soaXRlbSlcIj5cblxuICAgICAgICAgIDwhLS0gU3RlcCBOdW1iZXIgQmFkZ2UgLS0+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtaW5saW5lLWZsZXggY3FhLWl0ZW1zLWNlbnRlciBjcWEtanVzdGlmeS1jZW50ZXIgY3FhLXJvdW5kZWQtWzZweF0gY3FhLXRleHQteHMgY3FhLWZvbnQtbWVkaXVtIGNxYS1weS1bNHB4XSBjcWEtcHgtWzEwcHhdIGNxYS1mbGV4LXNocmluay0wIGNxYS1ib3JkZXIgY3FhLWJvcmRlci1zb2xpZCBjcWEtYm9yZGVyLVsjRTJFOEYwXSBjcWEtdGV4dC1bIzNGNDNFRV0gY3FhLWJnLVsjRjhGOUZGXVwiXG4gICAgICAgICAgICBzdHlsZT1cIm1pbi13aWR0aDogMzJweDtcIj5cbiAgICAgICAgICAgIHt7IGl0ZW0uc3RlcE51bWJlciB9fVxuICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgIDwhLS0gU3RlcCBEZXNjcmlwdGlvbiAtLT5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImNxYS1mbGV4LTEgY3FhLXRleHQtc20gY3FhLXRleHQtWyMwQTBBMEFdIGNxYS1mb250LWludGVyIGNxYS1mb250LW5vcm1hbCBjcWEtbGVhZGluZy1bMjBweF0gY3FhLW1pbi13LTAgY3FhLXRydW5jYXRlXCI+XG4gICAgICAgICAgICB7eyBpdGVtLmRlc2NyaXB0aW9uIH19XG4gICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgPCEtLSBTdGF0dXMgQmFkZ2UgLS0+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJjcWEtZmxleC1zaHJpbmstMFwiIFtuZ0NsYXNzXT1cImdldFN0YXR1c0JhZGdlQ2xhc3NlcyhpdGVtLnN0YXR1cylcIj5cbiAgICAgICAgICAgIHt7IGl0ZW0uc3RhdHVzIH19XG4gICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgPCEtLSBSaWdodCBBcnJvdyBJY29uLS0+XG4gICAgICAgICAgPCEtLSA8c3BhbiBjbGFzcz1cImNxYS1mbGV4IGNxYS1pdGVtcy1jZW50ZXIgY3FhLWp1c3RpZnktY2VudGVyIGNxYS1mbGV4LXNocmluay0wXCI+XG4gICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTZcIiBoZWlnaHQ9XCIxNlwiIHZpZXdCb3g9XCIwIDAgMTYgMTZcIiBmaWxsPVwibm9uZVwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIj5cbiAgICAgICAgICAgICAgPHBhdGggZD1cIk02IDRMMTAgOEw2IDEyXCIgc3Ryb2tlPVwiIzlDQTNBRlwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvc3Bhbj4gLS0+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIEZvb3RlciAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwiaGFzSXRlbXNcIiBjbGFzcz1cImNxYS1weC02IGNxYS1wYi01IGNxYS1wdC0zXCI+XG4gICAgICA8cCBjbGFzcz1cImNxYS10ZXh0LXhzIGNxYS10ZXh0LVsjNkI3MjgwXSBjcWEtZm9udC1pbnRlciBjcWEtZm9udC1ub3JtYWxcIj5cbiAgICAgICAge3sgaXRlbXNDb3VudCB9fSB7eyBpdGVtc0NvdW50ID09PSAxID8gJ3N0ZXAnIDogJ3N0ZXBzJyB9fSBmb3VuZFxuICAgICAgPC9wPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19
|