UNPKG

angular-responsive-carousel-ng16

Version:

Carousel for Angular. A simple solution for horizontal scrolling images with lazy loading.

422 lines 58.1 kB
import { Component, EventEmitter, HostBinding, HostListener, Input, Output } from '@angular/core'; import { Touches } from './touches'; import { Carousel } from './carousel'; import { Container } from './container'; import { Cells } from './cells'; import { Slide } from './slide'; import { Utils } from './utils'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; export class CarouselComponent { get isContainerLocked() { if (this.carousel) { return this.carousel.isContainerLocked; } } get slideCounter() { if (this.carousel) { return this.carousel.slideCounter; } } get lapCounter() { if (this.carousel) { return this.carousel.lapCounter; } } get isLandscape() { return window.innerWidth > window.innerHeight; } get isSafari() { const ua = navigator.userAgent.toLowerCase(); if (ua.indexOf('safari') !== -1) { return !(ua.indexOf('chrome') > -1); } } get counter() { let counter; if (this.loop) { counter = this.slideCounter % this.cellLength; } else { counter = this.slideCounter; } return counter + 1 + this.counterSeparator + this.cellLength; } get cellsElement() { return this.elementRef.nativeElement.querySelector('.carousel-cells'); } get isArrows() { return this.arrows && !this.freeScroll; } get isCounter() { return this._isCounter && this.cellLength > 1; } get activeDotIndex() { return this.slideCounter % this.cellLength; } get cellLimit() { if (this.carousel) { return this.carousel.cellLimit; } } get carouselWidth() { return this.elementRef.nativeElement.clientWidth; } set images(images) { this._images = images; } get images() { return this._images; } set cellWidth(value) { if (value) { this._cellWidth = value; } } set isCounter(value) { if (value) { this._isCounter = value; } } set loop(value) { if (value) { this._loop = value; } } get loop() { if (this.images) { return this._loop; } else { return false; } } set lightDOM(value) { if (value) { this._lightDOM = value; } } get lightDOM() { if (this.images) { return this._lightDOM; } else { return false; } } onWindowResize(event) { if (this.utils.visibleWidth !== this.savedCarouselWidth) { this.resize(); } } onMousemove(event) { if (this.autoplay && this.pauseOnHover) { this.carousel.stopAutoplay(); } } onMouseleave(event) { if (this.autoplay && this.pauseOnHover) { this.carousel.autoplay(); } } constructor(elementRef, ref) { this.elementRef = elementRef; this.ref = ref; this.minTimeout = 30; this.isVideoPlaying = false; this._isCounter = false; this._cellWidth = 200; this._loop = false; this._lightDOM = false; this.isMoving = false; this.isNgContent = false; this.events = new EventEmitter(); this.height = 200; this.autoplay = false; this.autoplayInterval = 5000; this.pauseOnHover = true; this.dots = false; this.margin = 10; this.objectFit = 'cover'; this.minSwipeDistance = 10; this.transitionDuration = 200; this.transitionTimingFunction = 'ease-out'; this.counterSeparator = " / "; this.overflowCellsLimit = 3; this.listeners = 'mouse and touch'; this.cellsToScroll = 1; this.freeScroll = false; this.arrows = true; this.arrowsOutside = false; this.arrowsTheme = 'light'; this.hostClassCarousel = true; this.handleTouchstart = (event) => { this.touches.addEventListeners("mousemove", "handleMousemove"); this.carousel.handleTouchstart(event); this.isMoving = true; }; this.handleHorizontalSwipe = (event) => { event.preventDefault(); this.carousel.handleHorizontalSwipe(event); }; this.handleTouchend = (event) => { const touches = event.touches; this.carousel.handleTouchend(event); this.touches.removeEventListeners("mousemove", "handleMousemove"); this.isMoving = false; }; this.handleTap = (event) => { let outboundEvent = { name: 'click' }; let nodes = Array.prototype.slice.call(this.cellsElement.children); let cellElement = event.srcElement.closest(".carousel-cell"); const i = nodes.indexOf(cellElement); const cellIndex = nodes.indexOf(cellElement); if (this.images) { //outboundEvent.fileIndex = this.carousel.getFileIndex(i); //outboundEvent.file = this.carousel.getFile(cellIndex); } else { outboundEvent.cellIndex = cellIndex; } }; } ngOnInit() { this.isNgContent = this.cellsElement.children.length > 0; this.touches = new Touches({ element: this.cellsElement, listeners: this.listeners, mouseListeners: { "mousedown": "handleMousedown", "mouseup": "handleMouseup" } }); this.touches.on('touchstart', this.handleTouchstart); this.touches.on('horizontal-swipe', this.handleHorizontalSwipe); this.touches.on('touchend', this.handleTouchend); this.touches.on('mousedown', this.handleTouchstart); this.touches.on('mouseup', this.handleTouchend); this.touches.on('tap', this.handleTap); this.setDimensions(); } ngAfterViewInit() { this.initCarousel(); this.cellLength = this.getCellLength(); this.dotsArr = Array(this.cellLength).fill(1); this.ref.detectChanges(); this.carousel.lineUpCells(); this.savedCarouselWidth = this.carouselWidth; /* Start detecting changes in the DOM tree */ this.detectDomChanges(); } ngOnChanges(changes) { if (changes.width || changes.height || changes.images) { this.setDimensions(); this.initCarousel(); this.carousel.lineUpCells(); this.ref.detectChanges(); } } ngOnDestroy() { this.touches.destroy(); //this.carousel.destroy(); } initCarousel() { this.carouselProperties = { id: this.id, cellsElement: this.elementRef.nativeElement.querySelector('.carousel-cells'), hostElement: this.elementRef.nativeElement, images: this.images, cellWidth: this.getCellWidth(), loop: this.loop, autoplayInterval: this.autoplayInterval, overflowCellsLimit: this.overflowCellsLimit, visibleWidth: this.width, margin: this.margin, minSwipeDistance: this.minSwipeDistance, transitionDuration: this.transitionDuration, transitionTimingFunction: this.transitionTimingFunction, videoProperties: this.videoProperties, eventHandler: this.events, freeScroll: this.freeScroll, lightDOM: this.lightDOM }; this.utils = new Utils(this.carouselProperties); this.cells = new Cells(this.carouselProperties, this.utils); this.container = new Container(this.carouselProperties, this.utils, this.cells); this.slide = new Slide(this.carouselProperties, this.utils, this.cells, this.container); this.carousel = new Carousel(this.carouselProperties, this.utils, this.cells, this.container, this.slide); if (this.autoplay) { this.carousel.autoplay(); } } resize() { this.landscapeMode = this.isLandscape; this.savedCarouselWidth = this.carouselWidth; this.carouselProperties.cellWidth = this.getCellWidth(); this.cells.updateProperties(this.carouselProperties); this.carousel.updateProperties(this.carouselProperties); this.container.updateProperties(this.carouselProperties); this.slide.updateProperties(this.carouselProperties); this.utils.updateProperties(this.carouselProperties); this.carousel.lineUpCells(); this.slide.select(0); this.ref.detectChanges(); } detectDomChanges() { const observer = new MutationObserver((mutations) => { this.onDomChanges(); }); var config = { attributes: true, childList: true, characterData: true }; observer.observe(this.cellsElement, config); } onDomChanges() { this.cellLength = this.getCellLength(); this.carousel.lineUpCells(); this.ref.detectChanges(); } setDimensions() { this.hostStyleHeight = this.height + 'px'; this.hostStyleWidth = this.width + 'px'; } getImage(index) { return this.carousel.getImage(index); } handleTransitionendCellContainer(event) { if (event.target['className'] === 'carousel-cells') { this.carousel.handleTransitionend(); } } getCellWidth() { let elementWidth = this.carouselWidth; if (this.cellsToShow) { let margin = this.cellsToShow > 1 ? this.margin : 0; let totalMargin = margin * (this.cellsToShow - 1); return (elementWidth - totalMargin) / this.cellsToShow; } if (this._cellWidth === '100%') { return elementWidth; } else { return this._cellWidth; } } next() { this.carousel.next(this.cellsToScroll); this.carousel.stopAutoplay(); } prev() { this.carousel.prev(this.cellsToScroll); this.carousel.stopAutoplay(); } isNextArrowDisabled() { if (this.carousel) { return this.carousel.isNextArrowDisabled(); } } isPrevArrowDisabled() { if (this.carousel) { return this.carousel.isPrevArrowDisabled(); } } getCellLength() { if (this.images) { return this.images.length; } else { return this.cellsElement.children.length; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.0", ngImport: i0, type: CarouselComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.0", type: CarouselComponent, selector: "carousel, [carousel]", inputs: { id: "id", height: "height", width: "width", autoplay: "autoplay", autoplayInterval: "autoplayInterval", pauseOnHover: "pauseOnHover", dots: "dots", borderRadius: "borderRadius", margin: "margin", objectFit: "objectFit", minSwipeDistance: "minSwipeDistance", transitionDuration: "transitionDuration", transitionTimingFunction: "transitionTimingFunction", videoProperties: "videoProperties", counterSeparator: "counterSeparator", overflowCellsLimit: "overflowCellsLimit", listeners: "listeners", cellsToShow: "cellsToShow", cellsToScroll: "cellsToScroll", freeScroll: "freeScroll", arrows: "arrows", arrowsOutside: "arrowsOutside", arrowsTheme: "arrowsTheme", images: "images", cellWidth: "cellWidth", isCounter: ["counter", "isCounter"], loop: "loop", lightDOM: "lightDOM" }, outputs: { events: "events" }, host: { listeners: { "window:resize": "onWindowResize($event)", "mousemove": "onMousemove($event)", "mouseleave": "onMouseleave($event)" }, properties: { "class.carousel": "this.hostClassCarousel", "style.height": "this.hostStyleHeight", "style.width": "this.hostStyleWidth" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"carousel-counter\" *ngIf=\"isCounter\">{{counter}}</div>\n\n<div class=\"carousel-container\" [class.carousel-moving]=\"isMoving\">\n\t<div class=\"carousel-cells\" #cells (transitionend)=\"handleTransitionendCellContainer($event)\">\n\t\t<ng-content></ng-content>\n\n\t\t<ng-template ngFor let-image [ngForOf]=\"images\" let-i=\"index\">\n\t\t\t<div class=\"carousel-cell\" \n\t\t\t\t[style.width]=\"getCellWidth()+'px'\"\n\t\t\t\t[style.border-radius]=\"borderRadius+'px'\"\n\t\t\t\t*ngIf=\"i < cellLimit\">\n\t\t\t\t<!-- Image -->\n\t\t\t\t<img \n\t\t\t\t\t*ngIf=\"getImage(i) && getImage(i)['image']\" \n\t\t\t\t\t[src]=\"getImage(i)['image']['path']\"\n\t\t\t\t\t[style.object-fit]=\"objectFit\"\n\t\t\t\t\tdraggable=\"false\" />\n\n\t\t\t</div>\n\t\t</ng-template>\n\t</div>\n\n\t<div class=\"carousel-dots\" *ngIf=\"dots\">\n\t\t<div class=\"carousel-dot\" [class.carousel-dot-active]=\"i === activeDotIndex\" *ngFor=\"let dot of dotsArr; index as i\"></div>\n\t</div>\n</div>\n\n<div class=\"carousel-arrows\" \n\t[class.carousel-arrows-outside]=\"arrowsOutside\" \n\t[class.carousel-dark-arrows]=\"arrowsTheme === 'dark'\"\n\t*ngIf=\"isArrows\">\n\t\n\t<div class=\"carousel-arrow carousel-arrow-prev\" [class.carousel-arrow-disabled]=\"isPrevArrowDisabled()\" (click)=\"prev()\"></div>\n\t<div class=\"carousel-arrow carousel-arrow-next\" [class.carousel-arrow-disabled]=\"isNextArrowDisabled()\" (click)=\"next()\"></div>\n</div>", styles: [":host{position:relative;display:block;top:0;left:0;width:100%;height:100%;-webkit-user-select:none;user-select:none;z-index:10000;transform-origin:top left;box-sizing:border-box}:host .carousel-container{overflow:hidden;width:100%;height:100%;cursor:grab}:host .carousel-container.carousel-moving{cursor:grabbing}:host .carousel-counter{text-align:right;position:absolute;z-index:30;transition:opacity .2s;top:8px;right:24px;border-radius:13px;background-color:#1725444d;font-size:11px;color:#fff;padding:5px 7px;line-height:initial}:host ::ng-deep .carousel-cells{transition:transform .2s;width:100%;height:100%;display:block;will-change:transform}:host ::ng-deep .carousel-cells .carousel-cell.swiper-prev-image{transform:translate3d(-100%,0,0)}:host ::ng-deep .carousel-cells .carousel-cell.swiper-next-image{transform:translate3d(100%,0,0)}:host ::ng-deep .carousel-cells .carousel-cell{width:100%;height:100%;position:absolute;overflow:hidden}:host ::ng-deep .carousel-cells .carousel-cell img,:host ::ng-deep .carousel-cells .carousel-cell video{width:100%;height:100%;position:relative;object-fit:contain}:host ::ng-deep .carousel-cells .carousel-cell img.swiper-hide{display:none}:host ::ng-deep .carousel-cells .carousel-cell .carousel-play{position:absolute;inset:0;z-index:1}:host .carousel-arrow{width:40px;height:40px;background-color:#fff;background-repeat:no-repeat;background-size:31px;background-position:center;border-radius:100px;position:absolute;top:50%;margin-top:-20px;z-index:10;cursor:pointer;box-shadow:0 0 5px #00000026}:host .carousel-arrow-prev{left:10px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMTUuNDEgMTYuNTlMMTAuODMgMTJsNC41OC00LjU5TDE0IDZsLTYgNiA2IDYgMS40MS0xLjQxeiIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMFYweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==)}:host .carousel-arrow-next{right:10px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNOC41OSAxNi41OUwxMy4xNyAxMiA4LjU5IDcuNDEgMTAgNmw2IDYtNiA2LTEuNDEtMS40MXoiLz48cGF0aCBkPSJNMCAwaDI0djI0SDBWMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=)}:host .carousel-arrows-outside .carousel-arrow-prev{left:-60px}:host .carousel-arrows-outside .carousel-arrow-next{right:-60px}:host .carousel-dark-arrows .carousel-arrow{filter:invert(1)}:host .carousel-arrow-disabled{cursor:default;opacity:.5}:host .carousel-dots{position:absolute;left:0;right:0;bottom:0;z-index:10;text-align:center}:host .carousel-dots .carousel-dot{display:inline-block;border:2px solid #fff;border-radius:100px;margin:4px;width:8px;height:8px}:host .carousel-dots .carousel-dot-active{background-color:#fff}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.0", ngImport: i0, type: CarouselComponent, decorators: [{ type: Component, args: [{ selector: 'carousel, [carousel]', template: "<div class=\"carousel-counter\" *ngIf=\"isCounter\">{{counter}}</div>\n\n<div class=\"carousel-container\" [class.carousel-moving]=\"isMoving\">\n\t<div class=\"carousel-cells\" #cells (transitionend)=\"handleTransitionendCellContainer($event)\">\n\t\t<ng-content></ng-content>\n\n\t\t<ng-template ngFor let-image [ngForOf]=\"images\" let-i=\"index\">\n\t\t\t<div class=\"carousel-cell\" \n\t\t\t\t[style.width]=\"getCellWidth()+'px'\"\n\t\t\t\t[style.border-radius]=\"borderRadius+'px'\"\n\t\t\t\t*ngIf=\"i < cellLimit\">\n\t\t\t\t<!-- Image -->\n\t\t\t\t<img \n\t\t\t\t\t*ngIf=\"getImage(i) && getImage(i)['image']\" \n\t\t\t\t\t[src]=\"getImage(i)['image']['path']\"\n\t\t\t\t\t[style.object-fit]=\"objectFit\"\n\t\t\t\t\tdraggable=\"false\" />\n\n\t\t\t</div>\n\t\t</ng-template>\n\t</div>\n\n\t<div class=\"carousel-dots\" *ngIf=\"dots\">\n\t\t<div class=\"carousel-dot\" [class.carousel-dot-active]=\"i === activeDotIndex\" *ngFor=\"let dot of dotsArr; index as i\"></div>\n\t</div>\n</div>\n\n<div class=\"carousel-arrows\" \n\t[class.carousel-arrows-outside]=\"arrowsOutside\" \n\t[class.carousel-dark-arrows]=\"arrowsTheme === 'dark'\"\n\t*ngIf=\"isArrows\">\n\t\n\t<div class=\"carousel-arrow carousel-arrow-prev\" [class.carousel-arrow-disabled]=\"isPrevArrowDisabled()\" (click)=\"prev()\"></div>\n\t<div class=\"carousel-arrow carousel-arrow-next\" [class.carousel-arrow-disabled]=\"isNextArrowDisabled()\" (click)=\"next()\"></div>\n</div>", styles: [":host{position:relative;display:block;top:0;left:0;width:100%;height:100%;-webkit-user-select:none;user-select:none;z-index:10000;transform-origin:top left;box-sizing:border-box}:host .carousel-container{overflow:hidden;width:100%;height:100%;cursor:grab}:host .carousel-container.carousel-moving{cursor:grabbing}:host .carousel-counter{text-align:right;position:absolute;z-index:30;transition:opacity .2s;top:8px;right:24px;border-radius:13px;background-color:#1725444d;font-size:11px;color:#fff;padding:5px 7px;line-height:initial}:host ::ng-deep .carousel-cells{transition:transform .2s;width:100%;height:100%;display:block;will-change:transform}:host ::ng-deep .carousel-cells .carousel-cell.swiper-prev-image{transform:translate3d(-100%,0,0)}:host ::ng-deep .carousel-cells .carousel-cell.swiper-next-image{transform:translate3d(100%,0,0)}:host ::ng-deep .carousel-cells .carousel-cell{width:100%;height:100%;position:absolute;overflow:hidden}:host ::ng-deep .carousel-cells .carousel-cell img,:host ::ng-deep .carousel-cells .carousel-cell video{width:100%;height:100%;position:relative;object-fit:contain}:host ::ng-deep .carousel-cells .carousel-cell img.swiper-hide{display:none}:host ::ng-deep .carousel-cells .carousel-cell .carousel-play{position:absolute;inset:0;z-index:1}:host .carousel-arrow{width:40px;height:40px;background-color:#fff;background-repeat:no-repeat;background-size:31px;background-position:center;border-radius:100px;position:absolute;top:50%;margin-top:-20px;z-index:10;cursor:pointer;box-shadow:0 0 5px #00000026}:host .carousel-arrow-prev{left:10px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMTUuNDEgMTYuNTlMMTAuODMgMTJsNC41OC00LjU5TDE0IDZsLTYgNiA2IDYgMS40MS0xLjQxeiIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMFYweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==)}:host .carousel-arrow-next{right:10px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNOC41OSAxNi41OUwxMy4xNyAxMiA4LjU5IDcuNDEgMTAgNmw2IDYtNiA2LTEuNDEtMS40MXoiLz48cGF0aCBkPSJNMCAwaDI0djI0SDBWMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=)}:host .carousel-arrows-outside .carousel-arrow-prev{left:-60px}:host .carousel-arrows-outside .carousel-arrow-next{right:-60px}:host .carousel-dark-arrows .carousel-arrow{filter:invert(1)}:host .carousel-arrow-disabled{cursor:default;opacity:.5}:host .carousel-dots{position:absolute;left:0;right:0;bottom:0;z-index:10;text-align:center}:host .carousel-dots .carousel-dot{display:inline-block;border:2px solid #fff;border-radius:100px;margin:4px;width:8px;height:8px}:host .carousel-dots .carousel-dot-active{background-color:#fff}\n"] }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { events: [{ type: Output }], id: [{ type: Input }], height: [{ type: Input }], width: [{ type: Input }], autoplay: [{ type: Input }], autoplayInterval: [{ type: Input }], pauseOnHover: [{ type: Input }], dots: [{ type: Input }], borderRadius: [{ type: Input }], margin: [{ type: Input }], objectFit: [{ type: Input }], minSwipeDistance: [{ type: Input }], transitionDuration: [{ type: Input }], transitionTimingFunction: [{ type: Input }], videoProperties: [{ type: Input }], counterSeparator: [{ type: Input }], overflowCellsLimit: [{ type: Input }], listeners: [{ type: Input }], cellsToShow: [{ type: Input }], cellsToScroll: [{ type: Input }], freeScroll: [{ type: Input }], arrows: [{ type: Input }], arrowsOutside: [{ type: Input }], arrowsTheme: [{ type: Input }], images: [{ type: Input }], cellWidth: [{ type: Input, args: ['cellWidth'] }], isCounter: [{ type: Input, args: ['counter'] }], loop: [{ type: Input, args: ['loop'] }], lightDOM: [{ type: Input, args: ['lightDOM'] }], hostClassCarousel: [{ type: HostBinding, args: ['class.carousel'] }], hostStyleHeight: [{ type: HostBinding, args: ['style.height'] }], hostStyleWidth: [{ type: HostBinding, args: ['style.width'] }], onWindowResize: [{ type: HostListener, args: ['window:resize', ['$event']] }], onMousemove: [{ type: HostListener, args: ['mousemove', ['$event']] }], onMouseleave: [{ type: HostListener, args: ['mouseleave', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1yZXNwb25zaXZlLWNhcm91c2VsLW5nMTYvc3JjL2xpYi9jYXJvdXNlbC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXJlc3BvbnNpdmUtY2Fyb3VzZWwtbmcxNi9zcmMvbGliL2Nhcm91c2VsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBb0IsU0FBUyxFQUF5QixZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUEyQixNQUFNLGVBQWUsQ0FBQztBQUdwSyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFDcEMsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLFNBQVMsQ0FBQzs7O0FBVTlCLE1BQU0sT0FBTyxpQkFBaUI7SUF3QjFCLElBQUksaUJBQWlCO1FBQ2pCLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQztTQUMxQztJQUNMLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDWixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDZixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDO1NBQ3JDO0lBQ0wsQ0FBQztJQUVELElBQUksVUFBVTtRQUNWLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLE9BQU8sSUFB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O2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBR0YsTUFBTTtzQkFEVCxLQUFLO2dCQVFrQixTQUFTO3NCQUFoQyxLQUFLO3VCQUFDLFdBQVc7Z0JBTUksU0FBUztzQkFBOUIsS0FBSzt1QkFBQyxTQUFTO2dCQU1HLElBQUk7c0JBQXRCLEtBQUs7dUJBQUMsTUFBTTtnQkFjVSxRQUFRO3NCQUE5QixLQUFLO3VCQUFDLFVBQVU7Z0JBY2MsaUJBQWlCO3NCQUEvQyxXQUFXO3VCQUFDLGdCQUFnQjtnQkFDQSxlQUFlO3NCQUEzQyxXQUFXO3VCQUFDLGNBQWM7Z0JBQ0MsY0FBYztzQkFBekMsV0FBVzt1QkFBQyxhQUFhO2dCQUcxQixjQUFjO3NCQURiLFlBQVk7dUJBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVF6QyxXQUFXO3NCQURWLFlBQVk7dUJBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVFyQyxZQUFZO3NCQURYLFlBQVk7dUJBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBWaWV3Q2hpbGQsIEV2ZW50RW1pdHRlciwgSG9zdEJpbmRpbmcsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIE91dHB1dCwgT25EZXN0cm95LCBTaW1wbGVDaGFuZ2VzfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtJbWFnZXN9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5pbXBvcnQge1RvdWNoZXN9IGZyb20gJy4vdG91Y2hlcyc7XG5pbXBvcnQge0Nhcm91c2VsfSBmcm9tICcuL2Nhcm91c2VsJztcbmltcG9ydCB7Q29udGFpbmVyfSBmcm9tICcuL2NvbnRhaW5lcic7XG5pbXBvcnQge0NlbGxzfSBmcm9tICcuL2NlbGxzJztcbmltcG9ydCB7U2xpZGV9IGZyb20gJy4vc2xpZGUnO1xuaW1wb3J0IHtVdGlsc30gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge1Byb3BlcnRpZXMgYXMgQ2Fyb3VzZWxQcm9wZXJ0aWVzfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuXG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnY2Fyb3VzZWwsIFtjYXJvdXNlbF0nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9jYXJvdXNlbC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vY2Fyb3VzZWwuY29tcG9uZW50LnNhc3MnXVxufSlcblxuZXhwb3J0IGNsYXNzIENhcm91c2VsQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgICBjYXJvdXNlbDphbnk7XG4gICAgY29udGFpbmVyOmFueTtcbiAgICB1dGlsczphbnk7XG4gICAgY2VsbHM6YW55O1xuICAgIHNsaWRlOmFueTtcbiAgICBfaWQhOiBzdHJpbmc7XG4gICAgX2ltYWdlcyE6IEltYWdlcztcbiAgICB0b3VjaGVzOiBhbnk7XG4gICAgbGFuZHNjYXBlTW9kZTogYW55O1xuICAgIG1pblRpbWVvdXQgPSAzMDtcbiAgICBpc1ZpZGVvUGxheWluZzogYm9vbGVhbiA9IGZhbHNlO1xuICAgIF9pc0NvdW50ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBfd2lkdGghOiBudW1iZXI7XG4gICAgX2NlbGxXaWR0aDogbnVtYmVyIHwgJzEwMCUnID0gMjAwO1xuICAgIF9sb29wOiBib29sZWFuID0gZmFsc2U7XG4gICAgX2xpZ2h0RE9NOiBib29sZWFuID0gZmFsc2U7XG4gICAgaXNNb3Zpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBpc05nQ29udGVudDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIGNlbGxMZW5ndGghOiBudW1iZXI7XG4gICAgZG90c0FycjogYW55O1xuICAgIGNhcm91c2VsUHJvcGVydGllcyE6IENhcm91c2VsUHJvcGVydGllcztcbiAgICBzYXZlZENhcm91c2VsV2lkdGghOiBudW1iZXI7XG5cbiAgICBnZXQgaXNDb250YWluZXJMb2NrZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmNhcm91c2VsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5pc0NvbnRhaW5lckxvY2tlZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBzbGlkZUNvdW50ZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLmNhcm91c2VsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5zbGlkZUNvdW50ZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgbGFwQ291bnRlcigpIHtcbiAgICAgICAgaWYgKHRoaXMuY2Fyb3VzZWwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNhcm91c2VsLmxhcENvdW50ZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgaXNMYW5kc2NhcGUoKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuaW5uZXJXaWR0aCA+IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICB9XG5cbiAgICBnZXQgaXNTYWZhcmkoKTogYW55IHtcbiAgICAgICAgY29uc3QgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmICh1YS5pbmRleE9mKCdzYWZhcmknKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiAhKHVhLmluZGV4T2YoJ2Nocm9tZScpID4gLTEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IGNvdW50ZXIoKSB7XG4gICAgICAgIGxldCBjb3VudGVyO1xuXG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIGNvdW50ZXIgPSB0aGlzLnNsaWRlQ291bnRlciAlIHRoaXMuY2VsbExlbmd0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvdW50ZXIgPSB0aGlzLnNsaWRlQ291bnRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb3VudGVyICsgMSArIHRoaXMuY291bnRlclNlcGFyYXRvciArIHRoaXMuY2VsbExlbmd0aDtcbiAgICB9XG5cbiAgICBnZXQgY2VsbHNFbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNhcm91c2VsLWNlbGxzJyk7XG4gICAgfVxuXG4gICAgZ2V0IGlzQXJyb3dzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcnJvd3MgJiYgIXRoaXMuZnJlZVNjcm9sbDtcbiAgICB9XG5cbiAgICBnZXQgaXNDb3VudGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNDb3VudGVyICYmIHRoaXMuY2VsbExlbmd0aCA+IDE7XG4gICAgfVxuXG4gICAgZ2V0IGFjdGl2ZURvdEluZGV4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zbGlkZUNvdW50ZXIgJSB0aGlzLmNlbGxMZW5ndGg7XG4gICAgfVxuXG4gICAgZ2V0IGNlbGxMaW1pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMuY2Fyb3VzZWwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNhcm91c2VsLmNlbGxMaW1pdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBjYXJvdXNlbFdpZHRoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY2xpZW50V2lkdGg7XG4gICAgfVxuXG4gICAgQE91dHB1dCgpIGV2ZW50czogRXZlbnRFbWl0dGVyIDwgYW55ID4gPSBuZXcgRXZlbnRFbWl0dGVyIDwgYW55ID4gKCk7XG5cbiAgICBASW5wdXQoKSBpZCE6IG51bWJlcjtcbiAgICBASW5wdXQoKSBoZWlnaHQ6IG51bWJlciA9IDIwMDtcbiAgICBASW5wdXQoKSB3aWR0aCE6IG51bWJlcjtcbiAgICBASW5wdXQoKSBhdXRvcGxheTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGF1dG9wbGF5SW50ZXJ2YWw6IG51bWJlciA9IDUwMDA7XG4gICAgQElucHV0KCkgcGF1c2VPbkhvdmVyOiBib29sZWFuID0gdHJ1ZTtcbiAgICBASW5wdXQoKSBkb3RzOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgYm9yZGVyUmFkaXVzITogbnVtYmVyO1xuICAgIEBJbnB1dCgpIG1hcmdpbjogbnVtYmVyID0gMTA7XG4gICAgQElucHV0KCkgb2JqZWN0Rml0OiAnY29udGFpbicgfCAnY292ZXInIHwgJ25vbmUnID0gJ2NvdmVyJztcbiAgICBASW5wdXQoKSBtaW5Td2lwZURpc3RhbmNlOiBudW1iZXIgPSAxMDtcbiAgICBASW5wdXQoKSB0cmFuc2l0aW9uRHVyYXRpb246IG51bWJlciA9IDIwMDtcbiAgICBASW5wdXQoKSB0cmFuc2l0aW9uVGltaW5nRnVuY3Rpb246ICdlYXNlJyB8ICdlYXNlLWluJyB8ICdlYXNlLW91dCcgfCAnZWFzZS1pbi1vdXQnIHwgJ2xpbmVhcicgPSAnZWFzZS1vdXQnO1xuICAgIEBJbnB1dCgpIHZpZGVvUHJvcGVydGllczogYW55O1xuICAgIEBJbnB1dCgpIGNvdW50ZXJTZXBhcmF0b3I6IHN0cmluZyA9IFwiIC8gXCI7XG4gICAgQElucHV0KCkgb3ZlcmZsb3dDZWxsc0xpbWl0OiBudW1iZXIgPSAzO1xuICAgIEBJbnB1dCgpIGxpc3RlbmVyczogJ2F1dG8nIHwgJ21vdXNlIGFuZCB0b3VjaCcgPSAnbW91c2UgYW5kIHRvdWNoJztcbiAgICBASW5wdXQoKSBjZWxsc1RvU2hvdyE6IG51bWJlcjtcbiAgICBASW5wdXQoKSBjZWxsc1RvU2Nyb2xsOiBudW1iZXIgPSAxO1xuICAgIEBJbnB1dCgpIGZyZWVTY3JvbGw6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBhcnJvd3M6IGJvb2xlYW4gPSB0cnVlO1xuICAgIEBJbnB1dCgpIGFycm93c091dHNpZGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBhcnJvd3NUaGVtZTogJ2xpZ2h0JyB8ICdkYXJrJyA9ICdsaWdodCc7XG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBpbWFnZXMoaW1hZ2VzOiBJbWFnZXMgJiBhbnkpIHtcbiAgICAgICAgdGhpcy5faW1hZ2VzID0gaW1hZ2VzO1xuICAgIH1cbiAgICBnZXQgaW1hZ2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faW1hZ2VzO1xuICAgIH1cblxuICAgIEBJbnB1dCgnY2VsbFdpZHRoJykgc2V0IGNlbGxXaWR0aCh2YWx1ZTogbnVtYmVyIHwgJzEwMCUnKSB7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fY2VsbFdpZHRoID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASW5wdXQoJ2NvdW50ZXInKSBzZXQgaXNDb3VudGVyKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5faXNDb3VudGVyID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASW5wdXQoJ2xvb3AnKSBzZXQgbG9vcCh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX2xvb3AgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBsb29wKCkge1xuICAgICAgICBpZiAodGhpcy5pbWFnZXMpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQElucHV0KCdsaWdodERPTScpIHNldCBsaWdodERPTSh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX2xpZ2h0RE9NID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgbGlnaHRET00oKSB7XG4gICAgICAgIGlmICh0aGlzLmltYWdlcykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xpZ2h0RE9NO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5jYXJvdXNlbCcpIGhvc3RDbGFzc0Nhcm91c2VsOiBib29sZWFuID0gdHJ1ZTtcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLmhlaWdodCcpIGhvc3RTdHlsZUhlaWdodCE6IHN0cmluZztcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLndpZHRoJykgaG9zdFN0eWxlV2lkdGghOiBzdHJpbmc7XG5cbiAgICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcbiAgICBvbldpbmRvd1Jlc2l6ZShldmVudDogYW55KSB7XG4gICAgICAgIGlmICh0aGlzLnV0aWxzLnZpc2libGVXaWR0aCAhPT0gdGhpcy5zYXZlZENhcm91c2VsV2lkdGgpIHtcbiAgICAgICAgICAgIHRoaXMucmVzaXplKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZW1vdmUnLCBbJyRldmVudCddKVxuICAgIG9uTW91c2Vtb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmF1dG9wbGF5ICYmIHRoaXMucGF1c2VPbkhvdmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNhcm91c2VsLnN0b3BBdXRvcGxheSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScsIFsnJGV2ZW50J10pXG4gICAgb25Nb3VzZWxlYXZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmF1dG9wbGF5ICYmIHRoaXMucGF1c2VPbkhvdmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNhcm91c2VsLmF1dG9wbGF5KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIHJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcblxuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmlzTmdDb250ZW50ID0gdGhpcy5jZWxsc0VsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoID4gMDtcblxuICAgICAgICB0aGlzLnRvdWNoZXMgPSBuZXcgVG91Y2hlcyh7XG4gICAgICAgICAgICBlbGVtZW50OiB0aGlzLmNlbGxzRWxlbWVudCxcbiAgICAgICAgICAgIGxpc3RlbmVyczogdGhpcy5saXN0ZW5lcnMsXG4gICAgICAgICAgICBtb3VzZUxpc3RlbmVyczoge1xuICAgICAgICAgICAgICAgIFwibW91c2Vkb3duXCI6IFwiaGFuZGxlTW91c2Vkb3duXCIsXG4gICAgICAgICAgICAgICAgXCJtb3VzZXVwXCI6IFwiaGFuZGxlTW91c2V1cFwiXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMudG91Y2hlcy5vbigndG91Y2hzdGFydCcsIHRoaXMuaGFuZGxlVG91Y2hzdGFydCk7XG4gICAgICAgIHRoaXMudG91Y2hlcy5vbignaG9yaXpvbnRhbC1zd2lwZScsIHRoaXMuaGFuZGxlSG9yaXpvbnRhbFN3aXBlKTtcbiAgICAgICAgdGhpcy50b3VjaGVzLm9uKCd0b3VjaGVuZCcsIHRoaXMuaGFuZGxlVG91Y2hlbmQpO1xuICAgICAgICB0aGlzLnRvdWNoZXMub24oJ21vdXNlZG93bicsIHRoaXMuaGFuZGxlVG91Y2hzdGFydCk7XG4gICAgICAgIHRoaXMudG91Y2hlcy5vbignbW91c2V1cCcsIHRoaXMuaGFuZGxlVG91Y2hlbmQpO1xuICAgICAgICB0aGlzLnRvdWNoZXMub24oJ3RhcCcsIHRoaXMuaGFuZGxlVGFwKTtcblxuICAgICAgICB0aGlzLnNldERpbWVuc2lvbnMoKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIHRoaXMuaW5pdENhcm91c2VsKCk7XG4gICAgICAgIHRoaXMuY2VsbExlbmd0aCA9IHRoaXMuZ2V0Q2VsbExlbmd0aCgpO1xuICAgICAgICB0aGlzLmRvdHNBcnIgPSBBcnJheSh0aGlzLmNlbGxMZW5ndGgpLmZpbGwoMSk7XG4gICAgICAgIHRoaXMucmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgdGhpcy5jYXJvdXNlbC5saW5lVXBDZWxscygpO1xuICAgICAgICB0aGlzLnNhdmVkQ2Fyb3VzZWxXaWR0aCA9IHRoaXMuY2Fyb3VzZWxXaWR0aDtcblxuICAgICAgICAvKiBTdGFydCBkZXRlY3RpbmcgY2hhbmdlcyBpbiB0aGUgRE9NIHRyZWUgKi9cbiAgICAgICAgdGhpcy5kZXRlY3REb21DaGFuZ2VzKCk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgICAgICBpZiAoY2hhbmdlcy53aWR0aCB8fCBjaGFuZ2VzLmhlaWdodCB8fCBjaGFuZ2VzLmltYWdlcykge1xuICAgICAgICAgICAgdGhpcy5zZXREaW1lbnNpb25zKCk7XG4gICAgICAgICAgICB0aGlzLmluaXRDYXJvdXNlbCgpO1xuICAgICAgICAgICAgdGhpcy5jYXJvdXNlbC5saW5lVXBDZWxscygpO1xuICAgICAgICAgICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMudG91Y2hlcy5kZXN0cm95KCk7XG4gICAgICAgIC8vdGhpcy5jYXJvdXNlbC5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgaW5pdENhcm91c2VsKCkge1xuICAgICAgICB0aGlzLmNhcm91c2VsUHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICAgICAgY2VsbHNFbGVtZW50OiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuY2Fyb3VzZWwtY2VsbHMnKSxcbiAgICAgICAgICAgIGhvc3RFbGVtZW50OiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgIGltYWdlczogdGhpcy5pbWFnZXMsXG4gICAgICAgICAgICBjZWxsV2lkdGg6IHRoaXMuZ2V0Q2VsbFdpZHRoKCksXG4gICAgICAgICAgICBsb29wOiB0aGlzLmxvb3AsXG4gICAgICAgICAgICBhdXRvcGxheUludGVydmFsOiB0aGlzLmF1dG9wbGF5SW50ZXJ2YWwsXG4gICAgICAgICAgICBvdmVyZmxvd0NlbGxzTGltaXQ6IHRoaXMub3ZlcmZsb3dDZWxsc0xpbWl0LFxuICAgICAgICAgICAgdmlzaWJsZVdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgICAgICAgbWFyZ2luOiB0aGlzLm1hcmdpbixcbiAgICAgICAgICAgIG1pblN3aXBlRGlzdGFuY2U6IHRoaXMubWluU3dpcGVEaXN0YW5jZSxcbiAgICAgICAgICAgIHRyYW5zaXRpb25EdXJhdGlvbjogdGhpcy50cmFuc2l0aW9uRHVyYXRpb24sXG4gICAgICAgICAgICB0cmFuc2l0aW9uVGltaW5nRnVuY3Rpb246IHRoaXMudH