UNPKG

go-captcha-angular

Version:

GoCaptcha for Angular, which implements click mode, slider mode, drag-drop mode and rotation mode.

220 lines 39.8 kB
import { Component, Input, ViewChild, ViewEncapsulation } from '@angular/core'; import { checkTargetFather, mergeTo } from "../../helper/helper"; import { defaultSlideConfig, defaultSlideData } from "./slide-instance"; import * as i0 from "@angular/core"; import * as i1 from "../../icons/arrows-icon.component"; import * as i2 from "../../icons/close-icon.component"; import * as i3 from "../../icons/refresh-icon.component"; import * as i4 from "../../icons/loading-icon.component"; export class SlideComponent { constructor() { this.localConfig = { ...defaultSlideConfig() }; this.localData = { ...defaultSlideData() }; this.localEvents = {}; this.state = { dragLeft: 0, thumbLeft: this.localData.thumbX || 0 }; this.isFreeze = false; this.dsFn = (event) => event.preventDefault(); } set config(config) { mergeTo(this.localConfig, config); this.localConfig = config; } set data(data) { mergeTo(this.localData, data); this.localData = data; this.updateState(); } set events(events) { mergeTo(this.localEvents, events); this.localEvents = events; } get hasDisplayWrapperState() { return (this.localConfig.width || 0) > 0 || (this.localConfig.height || 0) > 0; } get hasDisplayImageState() { return (this.localData.image && this.localData.image.length > 0) || (this.localData.thumb && this.localData.thumb.length > 0); } ngAfterViewInit() { this.dragBlockRef.nativeElement && this.dragBlockRef.nativeElement.addEventListener('dragstart', this.dsFn); } ngOnDestroy() { this.dragBlockRef.nativeElement && this.dragBlockRef.nativeElement.removeEventListener('dragstart', this.dsFn); } updateState() { if (!this.isFreeze) { this.state.thumbLeft = (this.localData.thumbX || 0); } } dragEvent(e) { if (!checkTargetFather(this.dragBarRef.nativeElement, e)) { return; } const touch = e.touches && e.touches[0]; const offsetLeft = this.dragBlockRef.nativeElement.offsetLeft; const width = this.containerRef.nativeElement.offsetWidth; const blockWidth = this.dragBlockRef.nativeElement.offsetWidth; const maxWidth = width - blockWidth; const tileWith = this.tileRef.nativeElement.offsetWidth; const tileOffsetLeft = this.tileRef.nativeElement.offsetLeft; const containerMaxWidth = width - tileWith; const tileMaxWith = width - (tileWith + tileOffsetLeft); const ratio = tileMaxWith / maxWidth; let isMoving = false; let tmpLeaveDragEvent = null; let startX = 0; let currentThumbX = 0; if (touch) { startX = touch.pageX - offsetLeft; } else { startX = e.clientX - offsetLeft; } const moveEvent = (e) => { isMoving = true; const mTouche = e.touches && e.touches[0]; let left = 0; if (mTouche) { left = mTouche.pageX - startX; } else { left = e.clientX - startX; } const ctX = tileOffsetLeft + (left * ratio); if (left >= maxWidth) { this.state.dragLeft = maxWidth; currentThumbX = containerMaxWidth; this.state.thumbLeft = currentThumbX; return; } if (left <= 0) { this.state.dragLeft = 0; currentThumbX = tileOffsetLeft; this.state.thumbLeft = currentThumbX; return; } this.state.dragLeft = left; currentThumbX = currentThumbX = ctX; this.state.thumbLeft = currentThumbX; this.localEvents.move && this.localEvents.move(currentThumbX, this.localData.thumbY || 0); e.cancelBubble = true; e.preventDefault(); }; const upEvent = (e) => { if (!checkTargetFather(this.dragBarRef.nativeElement, e)) { return; } clearEvent(); if (!isMoving) { return; } isMoving = false; if (currentThumbX < 0) { return; } this.localEvents.confirm && this.localEvents.confirm({ x: parseInt(currentThumbX.toString()), y: this.localData.thumbY || 0 }, () => { this.reset(); }); e.cancelBubble = true; e.preventDefault(); }; const leaveDragBlockEvent = (e) => { tmpLeaveDragEvent = e; }; const enterDragBlockEvent = () => { tmpLeaveDragEvent = null; }; const leaveUpEvent = (_) => { if (!tmpLeaveDragEvent) { return; } upEvent(tmpLeaveDragEvent); clearEvent(); }; const scope = this.localConfig.scope; const dragDom = scope ? this.rootRef.nativeElement : this.dragBarRef.nativeElement; const scopeDom = scope ? this.rootRef.nativeElement : document.body; const clearEvent = () => { scopeDom.removeEventListener("mousemove", moveEvent, false); scopeDom.removeEventListener("touchmove", moveEvent, { passive: false }); dragDom.removeEventListener("mouseup", upEvent, false); dragDom.removeEventListener("mouseenter", enterDragBlockEvent, false); dragDom.removeEventListener("mouseleave", leaveDragBlockEvent, false); dragDom.removeEventListener("touchend", upEvent, false); scopeDom.removeEventListener("mouseleave", upEvent, false); scopeDom.removeEventListener("mouseup", leaveUpEvent, false); this.isFreeze = false; }; this.isFreeze = true; scopeDom.addEventListener("mousemove", moveEvent, false); scopeDom.addEventListener("touchmove", moveEvent, { passive: false }); dragDom.addEventListener("mouseup", upEvent, false); dragDom.addEventListener("mouseenter", enterDragBlockEvent, false); dragDom.addEventListener("mouseleave", leaveDragBlockEvent, false); dragDom.addEventListener("touchend", upEvent, false); scopeDom.addEventListener("mouseleave", upEvent, false); scopeDom.addEventListener("mouseup", leaveUpEvent, false); } closeEvent(e) { this.close(); e.cancelBubble = true; e.preventDefault(); return false; } refreshEvent(e) { this.refresh(); e.cancelBubble = true; e.preventDefault(); return false; } reset() { this.state.dragLeft = 0; this.state.thumbLeft = this.localData.thumbX || 0; } clear() { this.reset(); setTimeout(() => { this.localData.image = ''; this.localData.thumb = ''; this.localData.thumbX = 0; this.localData.thumbY = 0; this.localData.thumbHeight = 0; this.localData.thumbWidth = 0; }, 0); } close() { this.localEvents.close && this.localEvents.close(); this.reset(); } refresh() { this.localEvents.refresh && this.localEvents.refresh(); this.reset(); } } SlideComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SlideComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); SlideComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: SlideComponent, selector: "go-captcha-slide", inputs: { config: "config", data: "data", events: "events" }, viewQueries: [{ propertyName: "rootRef", first: true, predicate: ["rootRef"], descendants: true }, { propertyName: "containerRef", first: true, predicate: ["containerRef"], descendants: true }, { propertyName: "dragBlockRef", first: true, predicate: ["dragBlockRef"], descendants: true }, { propertyName: "dragBarRef", first: true, predicate: ["dragBarRef"], descendants: true }, { propertyName: "tileRef", first: true, predicate: ["tileRef"], descendants: true }], ngImport: i0, template: "<div\n class=\"go-captcha gc-wrapper\"\n [class]=\"{'gc-theme': localConfig.showTheme}\"\n [style]=\"{\n width: (localConfig.width || 0) + ( localConfig.horizontalPadding * 2) + (localConfig.showTheme ? 2 : 0) + 'px',\n paddingLeft: localConfig.horizontalPadding + 'px',\n paddingRight: localConfig.horizontalPadding + 'px',\n paddingTop: localConfig.verticalPadding + 'px',\n paddingBottom: localConfig.verticalPadding + 'px',\n display: hasDisplayWrapperState ? 'block' : 'none'\n }\"\n #rootRef\n>\n <div class=\"gc-header\">\n <span>{{ localConfig.title }}</span>\n <div class=\"gc-icon-block\">\n <close-icon\n [width]=\"localConfig.iconSize\"\n [height]=\"localConfig.iconSize\"\n (click)=\"closeEvent($event)\"\n ></close-icon>\n <refresh-icon\n [width]=\"localConfig.iconSize\"\n [height]=\"localConfig.iconSize\"\n (click)=\"refreshEvent($event)\"\n ></refresh-icon>\n </div>\n </div>\n <div\n class=\"gc-body\"\n #containerRef\n [style]=\"{\n width: localConfig.width + 'px',\n height: localConfig.height + 'px'\n }\"\n >\n <div class=\"gc-loading\">\n <loading-icon></loading-icon>\n </div>\n <img\n class=\"gc-picture\"\n [class]=\"{'gc-hide': localData.image == ''}\"\n [style]=\"{display: hasDisplayImageState ? 'block' : 'none'}\"\n [attr.src]=\"localData.image\"\n alt=\"\"\n />\n <div\n class=\"gc-tile\"\n #tileRef\n [style]=\"{\n width: localData.thumbWidth + 'px',\n height: localData.thumbHeight + 'px',\n top: localData.thumbY + 'px',\n left: state.thumbLeft + 'px'\n }\"\n >\n <img\n [class]=\"{'gc-hide': localData.thumb == ''}\"\n [attr.src]=\"localData.thumb\"\n [style]=\"{display: hasDisplayImageState ? 'block' : 'none'}\"\n alt=\"\"\n />\n </div>\n </div>\n <div class=\"gc-footer\">\n <div class=\"gc-drag-slide-bar\" #dragBarRef>\n <div class=\"gc-drag-line\"></div>\n <div\n class=\"gc-drag-block\"\n #dragBlockRef\n (mousedown)=\"dragEvent($event)\"\n [style]=\"{left: state.dragLeft + 'px'}\"\n [class]=\"{'disabled': !hasDisplayImageState}\"\n >\n <div class=\"drag-block-inline\" (touchstart)=\"dragEvent($event)\">\n <arrows-icon></arrows-icon>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".go-captcha .gc-tile{position:absolute;z-index:2;cursor:pointer}.go-captcha .gc-tile img{display:block;cursor:pointer;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: i1.ArrowsIconComponent, selector: "arrows-icon", inputs: ["width", "height"] }, { kind: "component", type: i2.CloseIconComponent, selector: "close-icon", inputs: ["width", "height"] }, { kind: "component", type: i3.RefreshIconComponent, selector: "refresh-icon", inputs: ["width", "height"] }, { kind: "component", type: i4.LoadingIconComponent, selector: "loading-icon", inputs: ["width", "height"] }], encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SlideComponent, decorators: [{ type: Component, args: [{ selector: 'go-captcha-slide', encapsulation: ViewEncapsulation.None, template: "<div\n class=\"go-captcha gc-wrapper\"\n [class]=\"{'gc-theme': localConfig.showTheme}\"\n [style]=\"{\n width: (localConfig.width || 0) + ( localConfig.horizontalPadding * 2) + (localConfig.showTheme ? 2 : 0) + 'px',\n paddingLeft: localConfig.horizontalPadding + 'px',\n paddingRight: localConfig.horizontalPadding + 'px',\n paddingTop: localConfig.verticalPadding + 'px',\n paddingBottom: localConfig.verticalPadding + 'px',\n display: hasDisplayWrapperState ? 'block' : 'none'\n }\"\n #rootRef\n>\n <div class=\"gc-header\">\n <span>{{ localConfig.title }}</span>\n <div class=\"gc-icon-block\">\n <close-icon\n [width]=\"localConfig.iconSize\"\n [height]=\"localConfig.iconSize\"\n (click)=\"closeEvent($event)\"\n ></close-icon>\n <refresh-icon\n [width]=\"localConfig.iconSize\"\n [height]=\"localConfig.iconSize\"\n (click)=\"refreshEvent($event)\"\n ></refresh-icon>\n </div>\n </div>\n <div\n class=\"gc-body\"\n #containerRef\n [style]=\"{\n width: localConfig.width + 'px',\n height: localConfig.height + 'px'\n }\"\n >\n <div class=\"gc-loading\">\n <loading-icon></loading-icon>\n </div>\n <img\n class=\"gc-picture\"\n [class]=\"{'gc-hide': localData.image == ''}\"\n [style]=\"{display: hasDisplayImageState ? 'block' : 'none'}\"\n [attr.src]=\"localData.image\"\n alt=\"\"\n />\n <div\n class=\"gc-tile\"\n #tileRef\n [style]=\"{\n width: localData.thumbWidth + 'px',\n height: localData.thumbHeight + 'px',\n top: localData.thumbY + 'px',\n left: state.thumbLeft + 'px'\n }\"\n >\n <img\n [class]=\"{'gc-hide': localData.thumb == ''}\"\n [attr.src]=\"localData.thumb\"\n [style]=\"{display: hasDisplayImageState ? 'block' : 'none'}\"\n alt=\"\"\n />\n </div>\n </div>\n <div class=\"gc-footer\">\n <div class=\"gc-drag-slide-bar\" #dragBarRef>\n <div class=\"gc-drag-line\"></div>\n <div\n class=\"gc-drag-block\"\n #dragBlockRef\n (mousedown)=\"dragEvent($event)\"\n [style]=\"{left: state.dragLeft + 'px'}\"\n [class]=\"{'disabled': !hasDisplayImageState}\"\n >\n <div class=\"drag-block-inline\" (touchstart)=\"dragEvent($event)\">\n <arrows-icon></arrows-icon>\n </div>\n </div>\n </div>\n </div>\n</div>", styles: [".go-captcha .gc-tile{position:absolute;z-index:2;cursor:pointer}.go-captcha .gc-tile img{display:block;cursor:pointer;width:100%;height:100%}\n"] }] }], propDecorators: { rootRef: [{ type: ViewChild, args: ['rootRef', { static: false }] }], containerRef: [{ type: ViewChild, args: ['containerRef', { static: false }] }], dragBlockRef: [{ type: ViewChild, args: ['dragBlockRef', { static: false }] }], dragBarRef: [{ type: ViewChild, args: ['dragBarRef', { static: false }] }], tileRef: [{ type: ViewChild, args: ['tileRef', { static: false }] }], config: [{ type: Input }], data: [{ type: Input }], events: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZ28tY2FwdGNoYS1hbmd1bGFyL3NyYy9saWIvbW9kdWxlcy9zbGlkZS9zbGlkZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nby1jYXB0Y2hhLWFuZ3VsYXIvc3JjL2xpYi9tb2R1bGVzL3NsaWRlL3NsaWRlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQWMsS0FBSyxFQUFpQixTQUFTLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxlQUFlLENBQUE7QUFDdkcsT0FBTyxFQUFDLGlCQUFpQixFQUFFLE9BQU8sRUFBYyxNQUFNLHFCQUFxQixDQUFDO0FBQzVFLE9BQU8sRUFBQyxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBcUMsTUFBTSxrQkFBa0IsQ0FBQzs7Ozs7O0FBUTFHLE1BQU0sT0FBTyxjQUFjO0lBTjNCO1FBT0ksZ0JBQVcsR0FBaUIsRUFBQyxHQUFHLGtCQUFrQixFQUFFLEVBQUMsQ0FBQTtRQUNyRCxjQUFTLEdBQWMsRUFBQyxHQUFHLGdCQUFnQixFQUFFLEVBQUMsQ0FBQTtRQUM5QyxnQkFBVyxHQUFnQixFQUFFLENBQUE7UUFpQjdCLFVBQUssR0FBMEMsRUFBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUMsQ0FBQTtRQUNuRyxhQUFRLEdBQVksS0FBSyxDQUFBO1FBNkJqQixTQUFJLEdBQUcsQ0FBQyxLQUFVLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQTtLQThMeEQ7SUF6TkcsSUFDSSxNQUFNLENBQUMsTUFBbUI7UUFDMUIsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDakMsSUFB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QUFLLEVBQUUsQ0FBQTtRQUNsRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUE7SUFDaEIsQ0FBQztJQUVELE9BQU87UUFDSCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ3RELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUNoQixDQUFDOzs0R0EvT1EsY0FBYztnR0FBZCxjQUFjLHdrQkNWM0IseTZFQWdGTTs0RkR0RU8sY0FBYztrQkFOMUIsU0FBUzsrQkFDSSxrQkFBa0IsaUJBR2IsaUJBQWlCLENBQUMsSUFBSTs4QkFRckMsT0FBTztzQkFETixTQUFTO3VCQUFDLFNBQVMsRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUM7Z0JBSXJDLFlBQVk7c0JBRFgsU0FBUzt1QkFBQyxjQUFjLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDO2dCQUkxQyxZQUFZO3NCQURYLFNBQVM7dUJBQUMsY0FBYyxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQztnQkFJMUMsVUFBVTtzQkFEVCxTQUFTO3VCQUFDLFlBQVksRUFBRSxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUM7Z0JBSXhDLE9BQU87c0JBRE4sU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFDO2dCQU9qQyxNQUFNO3NCQURULEtBQUs7Z0JBT0YsSUFBSTtzQkFEUCxLQUFLO2dCQVFGLE1BQU07c0JBRFQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tcG9uZW50LCBFbGVtZW50UmVmLCBJbnB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkLCBWaWV3RW5jYXBzdWxhdGlvbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcbmltcG9ydCB7Y2hlY2tUYXJnZXRGYXRoZXIsIG1lcmdlVG8sIG1lcmdlVG9PdmVyfSBmcm9tIFwiLi4vLi4vaGVscGVyL2hlbHBlclwiO1xuaW1wb3J0IHtkZWZhdWx0U2xpZGVDb25maWcsIGRlZmF1bHRTbGlkZURhdGEsIFNsaWRlQ29uZmlnLCBTbGlkZURhdGEsIFNsaWRlRXZlbnR9IGZyb20gXCIuL3NsaWRlLWluc3RhbmNlXCI7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnZ28tY2FwdGNoYS1zbGlkZScsXG4gICAgdGVtcGxhdGVVcmw6ICdzbGlkZS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJ3NsaWRlLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgU2xpZGVDb21wb25lbnQge1xuICAgIGxvY2FsQ29uZmlnPzogU2xpZGVDb25maWcgPSB7Li4uZGVmYXVsdFNsaWRlQ29uZmlnKCl9XG4gICAgbG9jYWxEYXRhOiBTbGlkZURhdGEgPSB7Li4uZGVmYXVsdFNsaWRlRGF0YSgpfVxuICAgIGxvY2FsRXZlbnRzPzogU2xpZGVFdmVudCA9IHt9XG5cbiAgICBAVmlld0NoaWxkKCdyb290UmVmJywge3N0YXRpYzogZmFsc2V9KVxuICAgIHJvb3RSZWY6IEVsZW1lbnRSZWZcblxuICAgIEBWaWV3Q2hpbGQoJ2NvbnRhaW5lclJlZicsIHtzdGF0aWM6IGZhbHNlfSlcbiAgICBjb250YWluZXJSZWY6IEVsZW1lbnRSZWZcblxuICAgIEBWaWV3Q2hpbGQoJ2RyYWdCbG9ja1JlZicsIHtzdGF0aWM6IGZhbHNlfSlcbiAgICBkcmFnQmxvY2tSZWY6IEVsZW1lbnRSZWZcblxuICAgIEBWaWV3Q2hpbGQoJ2RyYWdCYXJSZWYnLCB7c3RhdGljOiBmYWxzZX0pXG4gICAgZHJhZ0JhclJlZjogRWxlbWVudFJlZlxuXG4gICAgQFZpZXdDaGlsZCgndGlsZVJlZicsIHtzdGF0aWM6IGZhbHNlfSlcbiAgICB0aWxlUmVmOiBFbGVtZW50UmVmXG5cbiAgICBzdGF0ZToge2RyYWdMZWZ0OiBudW1iZXIsIHRodW1iTGVmdDogbnVtYmVyfSA9IHtkcmFnTGVmdDogMCwgdGh1bWJMZWZ0OiB0aGlzLmxvY2FsRGF0YS50aHVtYlggfHwgMH1cbiAgICBpc0ZyZWV6ZTogYm9vbGVhbiA9IGZhbHNlXG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBjb25maWcoY29uZmlnOiBTbGlkZUNvbmZpZykge1xuICAgICAgICBtZXJnZVRvKHRoaXMubG9jYWxDb25maWcsIGNvbmZpZylcbiAgICAgICAgdGhpcy5sb2NhbENvbmZpZyA9IGNvbmZpZ1xuICAgIH1cblxuICAgIEBJbnB1dCgpXG4gICAgc2V0IGRhdGEoZGF0YTogU2xpZGVEYXRhKSB7XG4gICAgICAgIG1lcmdlVG8odGhpcy5sb2NhbERhdGEsIGRhdGEpXG4gICAgICAgIHRoaXMubG9jYWxEYXRhID0gZGF0YVxuICAgICAgICB0aGlzLnVwZGF0ZVN0YXRlKClcbiAgICB9XG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBldmVudHMoZXZlbnRzOiBTbGlkZUV2ZW50KSB7XG4gICAgICAgIG1lcmdlVG8odGhpcy5sb2NhbEV2ZW50cywgZXZlbnRzKVxuICAgICAgICB0aGlzLmxvY2FsRXZlbnRzID0gZXZlbnRzXG4gICAgfVxuXG4gICAgZ2V0IGhhc0Rpc3BsYXlXcmFwcGVyU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy5sb2NhbENvbmZpZy53aWR0aCB8fCAwKSA+IDAgfHwgKHRoaXMubG9jYWxDb25maWcuaGVpZ2h0IHx8IDApID4gMFxuICAgIH1cblxuICAgIGdldCBoYXNEaXNwbGF5SW1hZ2VTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLmxvY2FsRGF0YS5pbWFnZSAmJiB0aGlzLmxvY2FsRGF0YS5pbWFnZS5sZW5ndGggPiAwKSB8fCAodGhpcy5sb2NhbERhdGEudGh1bWIgJiYgdGhpcy5sb2NhbERhdGEudGh1bWIubGVuZ3RoID4gMClcbiAgICB9XG5cbiAgICBwcml2YXRlIGRzRm4gPSAoZXZlbnQ6IGFueSkgPT4gZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAgICAgdGhpcy5kcmFnQmxvY2tSZWYubmF0aXZlRWxlbWVudCAmJiB0aGlzLmRyYWdCbG9ja1JlZi5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdzdGFydCcsIHRoaXMuZHNGbik7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuZHJhZ0Jsb2NrUmVmLm5hdGl2ZUVsZW1lbnQgJiYgdGhpcy5kcmFnQmxvY2tSZWYubmF0aXZlRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCB0aGlzLmRzRm4pO1xuICAgIH1cblxuICAgIHVwZGF0ZVN0YXRlKCkge1xuICAgICAgICBpZiAoIXRoaXMuaXNGcmVlemUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUudGh1bWJMZWZ0ID0gKHRoaXMubG9jYWxEYXRhLnRodW1iWCB8fCAwKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZHJhZ0V2ZW50IChlOiBFdmVudHxhbnkpIHtcbiAgICAgICAgaWYgKCFjaGVja1RhcmdldEZhdGhlcih0aGlzLmRyYWdCYXJSZWYubmF0aXZlRWxlbWVudCwgZSkpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdG91Y2ggPSBlLnRvdWNoZXMgJiYgZS50b3VjaGVzWzBdO1xuICAgICAgICBjb25zdCBvZmZzZXRMZWZ0ID0gdGhpcy5kcmFnQmxvY2tSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRMZWZ0XG4gICAgICAgIGNvbnN0IHdpZHRoID0gdGhpcy5jb250YWluZXJSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aFxuICAgICAgICBjb25zdCBibG9ja1dpZHRoID0gdGhpcy5kcmFnQmxvY2tSZWYubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aFxuICAgICAgICBjb25zdCBtYXhXaWR0aCA9IHdpZHRoIC0gYmxvY2tXaWR0aFxuXG4gICAgICAgIGNvbnN0IHRpbGVXaXRoICA9IHRoaXMudGlsZVJlZi5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoXG4gICAgICAgIGNvbnN0IHRpbGVPZmZzZXRMZWZ0ID0gdGhpcy50aWxlUmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0TGVmdFxuICAgICAgICBjb25zdCBjb250YWluZXJNYXhXaWR0aCA9IHdpZHRoIC0gdGlsZVdpdGhcbiAgICAgICAgY29uc3QgdGlsZU1heFdpdGggPSB3aWR0aCAtICh0aWxlV2l0aCArIHRpbGVPZmZzZXRMZWZ0KVxuICAgICAgICBjb25zdCByYXRpbyA9IHRpbGVNYXhXaXRoIC8gbWF4V2lkdGhcblxuICAgICAgICBsZXQgaXNNb3ZpbmcgPSBmYWxzZVxuICAgICAgICBsZXQgdG1wTGVhdmVEcmFnRXZlbnQ6IEV2ZW50fGFueSA9IG51bGxcbiAgICAgICAgbGV0IHN0YXJ0WCA9IDBcbiAgICAgICAgbGV0IGN1cnJlbnRUaHVtYlggPSAwXG4gICAgICAgIGlmICh0b3VjaCkge1xuICAgICAgICAgICAgc3RhcnRYID0gdG91Y2gucGFnZVggLSBvZmZzZXRMZWZ0XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdGFydFggPSBlLmNsaWVudFggLSBvZmZzZXRMZWZ0XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtb3ZlRXZlbnQgPSAoZTogRXZlbnR8YW55KSA9PiB7XG4gICAgICAgICAgICBpc01vdmluZyA9IHRydWVcbiAgICAgICAgICAgIGNvbnN0IG1Ub3VjaGUgPSBlLnRvdWNoZXMgJiYgZS50b3VjaGVzWzBdO1xuXG4gICAgICAgICAgICBsZXQgbGVmdCA9IDA7XG4gICAgICAgICAgICBpZiAobVRvdWNoZSkge1xuICAgICAgICAgICAgICAgIGxlZnQgPSBtVG91Y2hlLnBhZ2VYIC0gc3RhcnRYXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxlZnQgPSBlLmNsaWVudFggLSBzdGFydFhcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY3RYID0gdGlsZU9mZnNldExlZnQgKyAobGVmdCAqIHJhdGlvKVxuICAgICAgICAgICAgaWYgKGxlZnQgPj0gbWF4V2lkdGgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLmRyYWdMZWZ0ID0gbWF4V2lkdGhcbiAgICAgICAgICAgICAgICBjdXJyZW50VGh1bWJYID0gY29udGFpbmVyTWF4V2lkdGhcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlLnRodW1iTGVmdCA9IGN1cnJlbnRUaHVtYlhcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGxlZnQgPD0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUuZHJhZ0xlZnQgPSAwXG4gICAgICAgICAgICAgICAgY3VycmVudFRodW1iWCA9IHRpbGVPZmZzZXRMZWZ0XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS50aHVtYkxlZnQgPSBjdXJyZW50VGh1bWJYXG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZHJhZ0xlZnQgPSBsZWZ0XG4gICAgICAgICAgICBjdXJyZW50VGh1bWJYID0gY3VycmVudFRodW1iWCA9IGN0WFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS50aHVtYkxlZnQgPSBjdXJyZW50VGh1bWJYXG5cbiAgICAgICAgICAgIHRoaXMubG9jYWxFdmVudHMubW92ZSAmJiB0aGlzLmxvY2FsRXZlbnRzLm1vdmUoY3VycmVudFRodW1iWCwgdGhpcy5sb2NhbERhdGEudGh1bWJZIHx8IDApXG5cbiAgICAgICAgICAgIGUuY2FuY2VsQnViYmxlID0gdHJ1ZVxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1cEV2ZW50ID0gKGU6IEV2ZW50fGFueSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFjaGVja1RhcmdldEZhdGhlcih0aGlzLmRyYWdCYXJSZWYubmF0aXZlRWxlbWVudCwgZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2xlYXJFdmVudCgpXG4gICAgICAgICAgICBpZiAoIWlzTW92aW5nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlzTW92aW5nID0gZmFsc2VcblxuICAgICAgICAgICAgaWYgKGN1cnJlbnRUaHVtYlggPCAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMubG9jYWxFdmVudHMuY29uZmlybSAmJiB0aGlzLmxvY2FsRXZlbnRzLmNvbmZpcm0oe3g6IHBhcnNlSW50KGN1cnJlbnRUaHVtYlgudG9TdHJpbmcoKSksIHk6IHRoaXMubG9jYWxEYXRhLnRodW1iWSB8fCAwfSwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzZXQoKVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZS5jYW5jZWxCdWJibGUgPSB0cnVlXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxlYXZlRHJhZ0Jsb2NrRXZlbnQgPSAoZTogRXZlbnR8YW55KSA9PiB7XG4gICAgICAgICAgICB0bXBMZWF2ZURyYWdFdmVudCA9IGVcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVudGVyRHJhZ0Jsb2NrRXZlbnQgPSAoKSA9PiB7XG4gICAgICAgICAgICB0bXBMZWF2ZURyYWdFdmVudCA9IG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxlYXZlVXBFdmVudCA9IChfOiBFdmVudHxhbnkpID0+IHtcbiAgICAgICAgICAgIGlmKCF0bXBMZWF2ZURyYWdFdmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1cEV2ZW50KHRtcExlYXZlRHJhZ0V2ZW50KVxuICAgICAgICAgICAgY2xlYXJFdmVudCgpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzY29wZSA9IHRoaXMubG9jYWxDb25maWcuc2NvcGVcbiAgICAgICAgY29uc3QgZHJhZ0RvbSA9IHNjb3BlID8gdGhpcy5yb290UmVmLm5hdGl2ZUVsZW1lbnQgOiB0aGlzLmRyYWdCYXJSZWYubmF0aXZlRWxlbWVudFxuICAgICAgICBjb25zdCBzY29wZURvbSA9IHNjb3BlID8gdGhpcy5yb290UmVmLm5hdGl2ZUVsZW1lbnQgOiBkb2N1bWVudC5ib2R5XG5cbiAgICAgICAgY29uc3QgY2xlYXJFdmVudCA9ICgpID0+IHtcbiAgICAgICAgICAgIHNjb3BlRG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgbW92ZUV2ZW50LCBmYWxzZSlcbiAgICAgICAgICAgIHNjb3BlRG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0b3VjaG1vdmVcIiwgbW92ZUV2ZW50LCB7IHBhc3NpdmU6IGZhbHNlIH0pXG5cbiAgICAgICAgICAgIGRyYWdEb20ucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJtb3VzZXVwXCIsIHVwRXZlbnQsIGZhbHNlKVxuICAgICAgICAgICAgZHJhZ0RvbS5yZW1vdmVFdmVudExpc3RlbmVyKCBcIm1vdXNlZW50ZXJcIiwgZW50ZXJEcmFnQmxvY2tFdmVudCwgZmFsc2UpXG4gICAgICAgICAgICBkcmFnRG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwibW91c2VsZWF2ZVwiLCBsZWF2ZURyYWdCbG9ja0V2ZW50LCBmYWxzZSlcbiAgICAgICAgICAgIGRyYWdEb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRvdWNoZW5kXCIsIHVwRXZlbnQsIGZhbHNlKVxuXG4gICAgICAgICAgICBzY29wZURvbS5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2VsZWF2ZVwiLCB1cEV2ZW50LCBmYWxzZSlcbiAgICAgICAgICAgIHNjb3BlRG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIGxlYXZlVXBFdmVudCwgZmFsc2UpXG4gICAgICAgICAgICB0aGlzLmlzRnJlZXplID0gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzRnJlZXplID0gdHJ1ZVxuXG4gICAgICAgIHNjb3BlRG9tLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgbW92ZUV2ZW50LCBmYWxzZSlcbiAgICAgICAgc2NvcGVEb20uYWRkRXZlbnRMaXN0ZW5lcihcInRvdWNobW92ZVwiLCBtb3ZlRXZlbnQsIHsgcGFzc2l2ZTogZmFsc2UgfSlcblxuICAgICAgICBkcmFnRG9tLmFkZEV2ZW50TGlzdGVuZXIoIFwibW91c2V1cFwiLCB1cEV2ZW50LCBmYWxzZSlcbiAgICAgICAgZHJhZ0RvbS5hZGRFdmVudExpc3RlbmVyKCBcIm1vdXNlZW50ZXJcIiwgZW50ZXJEcmFnQmxvY2tFdmVudCwgZmFsc2UpXG4gICAgICAgIGRyYWdEb20uYWRkRXZlbnRMaXN0ZW5lciggXCJtb3VzZWxlYXZlXCIsIGxlYXZlRHJhZ0Jsb2NrRXZlbnQsIGZhbHNlKVxuICAgICAgICBkcmFnRG9tLmFkZEV2ZW50TGlzdGVuZXIoXCJ0b3VjaGVuZFwiLCB1cEV2ZW50LCBmYWxzZSlcblxuICAgICAgICBzY29wZURvbS5hZGRFdmVudExpc3RlbmVyKFwibW91c2VsZWF2ZVwiLCB1cEV2ZW50LCBmYWxzZSlcbiAgICAgICAgc2NvcGVEb20uYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgbGVhdmVVcEV2ZW50LCBmYWxzZSlcbiAgICB9XG5cbiAgICBjbG9zZUV2ZW50KGU6IEV2ZW50fGFueSl7XG4gICAgICAgIHRoaXMuY2xvc2UoKVxuICAgICAgICBlLmNhbmNlbEJ1YmJsZSA9IHRydWVcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJlZnJlc2hFdmVudChlOiBFdmVudHxhbnkpIHtcbiAgICAgICAgdGhpcy5yZWZyZXNoKClcbiAgICAgICAgZS5jYW5jZWxCdWJibGUgPSB0cnVlXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICByZXNldCgpe1xuICAgICAgICB0aGlzLnN0YXRlLmRyYWdMZWZ0ID0gMFxuICAgICAgICB0aGlzLnN0YXRlLnRodW1iTGVmdCA9IHRoaXMubG9jYWxEYXRhLnRodW1iWCB8fCAwXG4gICAgfVxuXG4gICAgY2xlYXIoKXtcbiAgICAgICAgdGhpcy5yZXNldCgpXG4gICAgICAgIHNldFRpbWVvdXQoKCk9PiB7XG4gICAgICAgICAgICB0aGlzLmxvY2FsRGF0YS5pbWFnZSA9ICcnXG4gICAgICAgICAgICB0aGlzLmxvY2FsRGF0YS50aHVtYiA9ICcnXG4gICAgICAgICAgICB0aGlzLmxvY2FsRGF0YS50aHVtYlggPSAwXG4gICAgICAgICAgICB0aGlzLmxvY2FsRGF0YS50aHVtYlkgPSAwXG4gICAgICAgICAgICB0aGlzLmxvY2FsRGF0YS50aHVtYkhlaWdodCA9IDBcbiAgICAgICAgICAgIHRoaXMubG9jYWxEYXRhLnRodW1iV2lkdGggPSAwXG4gICAgICAgIH0sIDApXG4gICAgfVxuXG4gICAgY2xvc2UoKSB7XG4gICAgICAgIHRoaXMubG9jYWxFdmVudHMuY2xvc2UgJiYgdGhpcy5sb2NhbEV2ZW50cy5jbG9zZSgpXG4gICAgICAgIHRoaXMucmVzZXQoKVxuICAgIH1cblxuICAgIHJlZnJlc2goKSB7XG4gICAgICAgIHRoaXMubG9jYWxFdmVudHMucmVmcmVzaCAmJiB0aGlzLmxvY2FsRXZlbnRzLnJlZnJlc2goKVxuICAgICAgICB0aGlzLnJlc2V0KClcbiAgICB9XG59XG4iLCI8ZGl2XG4gIGNsYXNzPVwiZ28tY2FwdGNoYSBnYy13cmFwcGVyXCJcbiAgW2NsYXNzXT1cInsnZ2MtdGhlbWUnOiBsb2NhbENvbmZpZy5zaG93VGhlbWV9XCJcbiAgW3N0eWxlXT1cIntcbiAgICB3aWR0aDogIChsb2NhbENvbmZpZy53aWR0aCB8fCAwKSArICggbG9jYWxDb25maWcuaG9yaXpvbnRhbFBhZGRpbmcgKiAyKSArIChsb2NhbENvbmZpZy5zaG93VGhlbWUgPyAyIDogMCkgKyAncHgnLFxuICAgIHBhZGRpbmdMZWZ0OiBsb2NhbENvbmZpZy5ob3Jpem9udGFsUGFkZGluZyArICdweCcsXG4gICAgcGFkZGluZ1JpZ2h0OiBsb2NhbENvbmZpZy5ob3Jpem9udGFsUGFkZGluZyArICdweCcsXG4gICAgcGFkZGluZ1RvcDogbG9jYWxDb25maWcudmVydGljYWxQYWRkaW5nICsgJ3B4JyxcbiAgICBwYWRkaW5nQm90dG9tOiBsb2NhbENvbmZpZy52ZXJ0aWNhbFBhZGRpbmcgKyAncHgnLFxuICAgIGRpc3BsYXk6IGhhc0Rpc3BsYXlXcmFwcGVyU3RhdGUgPyAnYmxvY2snIDogJ25vbmUnXG4gIH1cIlxuICAjcm9vdFJlZlxuPlxuICA8ZGl2IGNsYXNzPVwiZ2MtaGVhZGVyXCI+XG4gICAgPHNwYW4+e3sgbG9jYWxDb25maWcudGl0bGUgfX08L3NwYW4+XG4gICAgPGRpdiBjbGFzcz1cImdjLWljb24tYmxvY2tcIj5cbiAgICAgIDxjbG9zZS1pY29uXG4gICAgICAgIFt3aWR0aF09XCJsb2NhbENvbmZpZy5pY29uU2l6ZVwiXG4gICAgICAgIFtoZWlnaHRdPVwibG9jYWxDb25maWcuaWNvblNpemVcIlxuICAgICAgICAoY2xpY2spPVwiY2xvc2VFdmVudCgkZXZlbnQpXCJcbiAgICAgID48L2Nsb3NlLWljb24+XG4gICAgICA8cmVmcmVzaC1pY29uXG4gICAgICAgIFt3aWR0aF09XCJsb2NhbENvbmZpZy5pY29uU2l6ZVwiXG4gICAgICAgIFtoZWlnaHRdPVwibG9jYWxDb25maWcuaWNvblNpemVcIlxuICAgICAgICAoY2xpY2spPVwicmVmcmVzaEV2ZW50KCRldmVudClcIlxuICAgICAgPjwvcmVmcmVzaC1pY29uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdlxuICAgIGNsYXNzPVwiZ2MtYm9keVwiXG4gICAgI2NvbnRhaW5lclJlZlxuICAgIFtzdHlsZV09XCJ7XG4gICAgICB3aWR0aDogbG9jYWxDb25maWcud2lkdGggKyAncHgnLFxuICAgICAgaGVpZ2h0OiBsb2NhbENvbmZpZy5oZWlnaHQgKyAncHgnXG4gICAgfVwiXG4gID5cbiAgICA8ZGl2IGNsYXNzPVwiZ2MtbG9hZGluZ1wiPlxuICAgICAgPGxvYWRpbmctaWNvbj48L2xvYWRpbmctaWNvbj5cbiAgICA8L2Rpdj5cbiAgICA8aW1nXG4gICAgICBjbGFzcz1cImdjLXBpY3R1cmVcIlxuICAgICAgW2NsYXNzXT1cInsnZ2MtaGlkZSc6IGxvY2FsRGF0YS5pbWFnZSA9PSAnJ31cIlxuICAgICAgW3N0eWxlXT1cIntkaXNwbGF5OiBoYXNEaXNwbGF5SW1hZ2VTdGF0ZSA/ICdibG9jaycgOiAnbm9uZSd9XCJcbiAgICAgIFthdHRyLnNyY109XCJsb2NhbERhdGEuaW1hZ2VcIlxuICAgICAgYWx0PVwiXCJcbiAgICAvPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwiZ2MtdGlsZVwiXG4gICAgICAjdGlsZVJlZlxuICAgICAgW3N0eWxlXT1cIntcbiAgICAgICAgd2lkdGg6IGxvY2FsRGF0YS50aHVtYldpZHRoICsgJ3B4JyxcbiAgICAgICAgaGVpZ2h0OiBsb2NhbERhdGEudGh1bWJIZWlnaHQgKyAncHgnLFxuICAgICAgICB0b3A6IGxvY2FsRGF0YS50aHVtYlkgKyAncHgnLFxuICAgICAgICBsZWZ0OiBzdGF0ZS50aHVtYkxlZnQgKyAncHgnXG4gICAgICB9XCJcbiAgICA+XG4gICAgICA8aW1nXG4gICAgICAgIFtjbGFzc109XCJ7J2djLWhpZGUnOiBsb2NhbERhdGEudGh1bWIgPT0gJyd9XCJcbiAgICAgICAgW2F0dHIuc3JjXT1cImxvY2FsRGF0YS50aHVtYlwiXG4gICAgICAgIFtzdHlsZV09XCJ7ZGlzcGxheTogaGFzRGlzcGxheUltYWdlU3RhdGUgPyAnYmxvY2snIDogJ25vbmUnfVwiXG4gICAgICAgIGFsdD1cIlwiXG4gICAgICAvPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImdjLWZvb3RlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJnYy1kcmFnLXNsaWRlLWJhclwiICNkcmFnQmFyUmVmPlxuICAgICAgPGRpdiBjbGFzcz1cImdjLWRyYWctbGluZVwiPjwvZGl2PlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImdjLWRyYWctYmxvY2tcIlxuICAgICAgICAjZHJhZ0Jsb2NrUmVmXG4gICAgICAgIChtb3VzZWRvd24pPVwiZHJhZ0V2ZW50KCRldmVudClcIlxuICAgICAgICBbc3R5bGVdPVwie2xlZnQ6IHN0YXRlLmRyYWdMZWZ0ICsgJ3B4J31cIlxuICAgICAgICBbY2xhc3NdPVwieydkaXNhYmxlZCc6ICFoYXNEaXNwbGF5SW1hZ2VTdGF0ZX1cIlxuICAgICAgPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZHJhZy1ibG9jay1pbmxpbmVcIiAodG91Y2hzdGFydCk9XCJkcmFnRXZlbnQoJGV2ZW50KVwiPlxuICAgICAgICAgIDxhcnJvd3MtaWNvbj48L2Fycm93cy1pY29uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==