angular-responsive-carousel-ng16
Version:
Carousel for Angular. A simple solution for horizontal scrolling images with lazy loading.
422 lines • 58.1 kB
JavaScript
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1yZXNwb25zaXZlLWNhcm91c2VsLW5nMTYvc3JjL2xpYi9jYXJvdXNlbC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLXJlc3BvbnNpdmUtY2Fyb3VzZWwtbmcxNi9zcmMvbGliL2Nhcm91c2VsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBb0IsU0FBUyxFQUF5QixZQUFZLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUEyQixNQUFNLGVBQWUsQ0FBQztBQUdwSyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFDcEMsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGFBQWEsQ0FBQztBQUN0QyxPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFDOUIsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLFNBQVMsQ0FBQzs7O0FBVTlCLE1BQU0sT0FBTyxpQkFBaUI7SUF3QjFCLElBQUksaUJBQWlCO1FBQ2pCLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQztTQUMxQztJQUNMLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDWixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDZixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDO1NBQ3JDO0lBQ0wsQ0FBQztJQUVELElBQUksVUFBVTtRQUNWLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUM7U0FDbkM7SUFDTCxDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ1gsT0FBTyxNQUFNLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUM7SUFDbEQsQ0FBQztJQUVELElBQUksUUFBUTtRQUNSLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDN0MsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFO1lBQzdCLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN2QztJQUNMLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDUCxJQUFJLE9BQU8sQ0FBQztRQUVaLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtZQUNYLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7U0FDakQ7YUFBTTtZQUNILE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1NBQy9CO1FBRUQsT0FBTyxPQUFPLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ2pFLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDWixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDUixPQUFPLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQzNDLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDVCxPQUFPLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVELElBQUksY0FBYztRQUNkLE9BQU8sSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQy9DLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDVCxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDZixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1NBQ2xDO0lBQ0wsQ0FBQztJQUVELElBQUksYUFBYTtRQUNiLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO0lBQ3JELENBQUM7SUE0QkQsSUFDSSxNQUFNLENBQUMsTUFBb0I7UUFDM0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7SUFDMUIsQ0FBQztJQUNELElBQUksTUFBTTtRQUNOLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN4QixDQUFDO0lBRUQsSUFBd0IsU0FBUyxDQUFDLEtBQXNCO1FBQ3BELElBQUksS0FBSyxFQUFFO1lBQ1AsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7U0FDM0I7SUFDTCxDQUFDO0lBRUQsSUFBc0IsU0FBUyxDQUFDLEtBQWM7UUFDMUMsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztTQUMzQjtJQUNMLENBQUM7SUFFRCxJQUFtQixJQUFJLENBQUMsS0FBYztRQUNsQyxJQUFJLEtBQUssRUFBRTtZQUNQLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1NBQ3RCO0lBQ0wsQ0FBQztJQUVELElBQUksSUFBSTtRQUNKLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNiLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztTQUNyQjthQUFNO1lBQ0gsT0FBTyxLQUFLLENBQUM7U0FDaEI7SUFDTCxDQUFDO0lBRUQsSUFBdUIsUUFBUSxDQUFDLEtBQWM7UUFDMUMsSUFBSSxLQUFLLEVBQUU7WUFDUCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztTQUMxQjtJQUNMLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDUixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDYixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7U0FDekI7YUFBTTtZQUNILE9BQU8sS0FBSyxDQUFDO1NBQ2hCO0lBQ0wsQ0FBQztJQU9ELGNBQWMsQ0FBQyxLQUFVO1FBQ3JCLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQ3JELElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztTQUNqQjtJQUNMLENBQUM7SUFHRCxXQUFXLENBQUMsS0FBaUI7UUFDekIsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDcEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztTQUNoQztJQUNMLENBQUM7SUFHRCxZQUFZLENBQUMsS0FBaUI7UUFDMUIsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDcEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztTQUM1QjtJQUNMLENBQUM7SUFFRCxZQUNZLFVBQXNCLEVBQ3RCLEdBQXNCO1FBRHRCLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUF0TGxDLGVBQVUsR0FBRyxFQUFFLENBQUM7UUFDaEIsbUJBQWMsR0FBWSxLQUFLLENBQUM7UUFDaEMsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUU1QixlQUFVLEdBQW9CLEdBQUcsQ0FBQztRQUNsQyxVQUFLLEdBQVksS0FBSyxDQUFDO1FBQ3ZCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFDM0IsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUMxQixnQkFBVyxHQUFZLEtBQUssQ0FBQztRQXlFbkIsV0FBTSxHQUF5QixJQUFJLFlBQVksRUFBVyxDQUFDO1FBRzVELFdBQU0sR0FBVyxHQUFHLENBQUM7UUFFckIsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUMxQixxQkFBZ0IsR0FBVyxJQUFJLENBQUM7UUFDaEMsaUJBQVksR0FBWSxJQUFJLENBQUM7UUFDN0IsU0FBSSxHQUFZLEtBQUssQ0FBQztRQUV0QixXQUFNLEdBQVcsRUFBRSxDQUFDO1FBQ3BCLGNBQVMsR0FBaUMsT0FBTyxDQUFDO1FBQ2xELHFCQUFnQixHQUFXLEVBQUUsQ0FBQztRQUM5Qix1QkFBa0IsR0FBVyxHQUFHLENBQUM7UUFDakMsNkJBQXdCLEdBQStELFVBQVUsQ0FBQztRQUVsRyxxQkFBZ0IsR0FBVyxLQUFLLENBQUM7UUFDakMsdUJBQWtCLEdBQVcsQ0FBQyxDQUFDO1FBQy9CLGNBQVMsR0FBK0IsaUJBQWlCLENBQUM7UUFFMUQsa0JBQWEsR0FBVyxDQUFDLENBQUM7UUFDMUIsZUFBVSxHQUFZLEtBQUssQ0FBQztRQUM1QixXQUFNLEdBQVksSUFBSSxDQUFDO1FBQ3ZCLGtCQUFhLEdBQVksS0FBSyxDQUFDO1FBQy9CLGdCQUFXLEdBQXFCLE9BQU8sQ0FBQztRQWtEbEIsc0JBQWlCLEdBQVksSUFBSSxDQUFDO1FBMEpqRSxxQkFBZ0IsR0FBRyxDQUFDLEtBQVUsRUFBRSxFQUFFO1lBQzlCLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFDL0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN0QyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUN6QixDQUFDLENBQUE7UUFFRCwwQkFBcUIsR0FBRyxDQUFDLEtBQVUsRUFBRSxFQUFFO1lBQ25DLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FBQTtRQUVELG1CQUFjLEdBQUcsQ0FBQyxLQUFVLEVBQUUsRUFBRTtZQUM1QixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1lBQzlCLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3BDLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFDbEUsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDMUIsQ0FBQyxDQUFBO1FBRUQsY0FBUyxHQUFHLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDdkIsSUFBSSxhQUFhLEdBQVE7Z0JBQ3JCLElBQUksRUFBRSxPQUFPO2FBQ2hCLENBQUE7WUFDRCxJQUFJLEtBQUssR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNuRSxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzdELE1BQU0sQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDckMsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUU3QyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ2IsMERBQTBEO2dCQUMxRCx3REFBd0Q7YUFDM0Q7aUJBQU07Z0JBQ0gsYUFBYSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7YUFDdkM7UUFDTCxDQUFDLENBQUE7SUE5SkQsQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQztZQUN2QixPQUFPLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDMUIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3pCLGNBQWMsRUFBRTtnQkFDWixXQUFXLEVBQUUsaUJBQWlCO2dCQUM5QixTQUFTLEVBQUUsZUFBZTthQUM3QjtTQUNKLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNoRSxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNwRCxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFdkMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxlQUFlO1FBQ1gsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBRTdDLDZDQUE2QztRQUM3QyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQzlCLElBQUksT0FBTyxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEVBQUU7WUFDbkQsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDNUI7SUFDTCxDQUFDO0lBRUQsV0FBVztRQUNQLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDdkIsMEJBQTBCO0lBQzlCLENBQUM7SUFFRCxZQUFZO1FBQ1IsSUFBSSxDQUFDLGtCQUFrQixHQUFHO1lBQ3RCLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtZQUNYLFlBQVksRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUM7WUFDNUUsV0FBVyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYTtZQUMxQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsU0FBUyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDOUIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ2YsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtZQUN2QyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsa0JBQWtCO1lBQzNDLFlBQVksRUFBRSxJQUFJLENBQUMsS0FBSztZQUN4QixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtZQUN2QyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsa0JBQWtCO1lBQzNDLHdCQUF3QixFQUFFLElBQUksQ0FBQyx3QkFBd0I7WUFDdkQsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO1lBQ3JDLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTTtZQUN6QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7WUFDM0IsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1NBQzFCLENBQUM7UUFFRixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoRixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3hGLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUxRyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDZixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQzVCO0lBQ0wsQ0FBQztJQUVELE1BQU07UUFDRixJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDdEMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFFN0MsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEQsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDNUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsZ0JBQWdCO1FBQ1osTUFBTSxRQUFRLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1lBQ2hELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksTUFBTSxHQUFHO1lBQ1QsVUFBVSxFQUFFLElBQUk7WUFDaEIsU0FBUyxFQUFFLElBQUk7WUFDZixhQUFhLEVBQUUsSUFBSTtTQUN0QixDQUFDO1FBQ0YsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxZQUFZO1FBQ1IsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzdCLENBQUM7SUFFRCxhQUFhO1FBQ1QsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUMxQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0lBQzVDLENBQUM7SUFFRCxRQUFRLENBQUMsS0FBWTtRQUNqQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFxQ0QsZ0NBQWdDLENBQUMsS0FBUztRQUN0QyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQUssZ0JBQWdCLEVBQUU7WUFDaEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1NBQ3ZDO0lBQ0wsQ0FBQztJQUVELFlBQVk7UUFDUixJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBRXRDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNsQixJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BELElBQUksV0FBVyxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDbEQsT0FBTyxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1NBQzFEO1FBRUQsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLE1BQU0sRUFBRTtZQUM1QixPQUFPLFlBQVksQ0FBQztTQUN2QjthQUFNO1lBQ0gsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO1NBQzFCO0lBQ0wsQ0FBQztJQUVELElBQUk7UUFDQSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsSUFBSTtRQUNBLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFRCxtQkFBbUI7UUFDZixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDZixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztTQUM5QztJQUNMLENBQUM7SUFFRCxtQkFBbUI7UUFDZixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDZixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztTQUM5QztJQUNMLENBQUM7SUFFRCxhQUFhO1FBQ1QsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2IsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztTQUM3QjthQUFNO1lBQ0gsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7U0FDNUM7SUFDTCxDQUFDOzhHQXBaUSxpQkFBaUI7a0dBQWpCLGlCQUFpQix5cENDbEI5QiwrNkNBa0NNOzsyRkRoQk8saUJBQWlCO2tCQU43QixTQUFTOytCQUNJLHNCQUFzQjtpSUFnR3RCLE1BQU07c0JBQWYsTUFBTTtnQkFFRSxFQUFFO3NCQUFWLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLGdCQUFnQjtzQkFBeEIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csd0JBQXdCO3NCQUFoQyxLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBR0YsTUFBTTtzQkFEVCxLQUFLO2dCQVFrQixTQUFTO3NCQUFoQyxLQUFLO3VCQUFDLFdBQVc7Z0JBTUksU0FBUztzQkFBOUIsS0FBSzt1QkFBQyxTQUFTO2dCQU1HLElBQUk7c0JBQXRCLEtBQUs7dUJBQUMsTUFBTTtnQkFjVSxRQUFRO3NCQUE5QixLQUFLO3VCQUFDLFVBQVU7Z0JBY2MsaUJBQWlCO3NCQUEvQyxXQUFXO3VCQUFDLGdCQUFnQjtnQkFDQSxlQUFlO3NCQUEzQyxXQUFXO3VCQUFDLGNBQWM7Z0JBQ0MsY0FBYztzQkFBekMsV0FBVzt1QkFBQyxhQUFhO2dCQUcxQixjQUFjO3NCQURiLFlBQVk7dUJBQUMsZUFBZSxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVF6QyxXQUFXO3NCQURWLFlBQVk7dUJBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVFyQyxZQUFZO3NCQURYLFlBQVk7dUJBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBWaWV3Q2hpbGQsIEV2ZW50RW1pdHRlciwgSG9zdEJpbmRpbmcsIEhvc3RMaXN0ZW5lciwgSW5wdXQsIE91dHB1dCwgT25EZXN0cm95LCBTaW1wbGVDaGFuZ2VzfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtJbWFnZXN9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5pbXBvcnQge1RvdWNoZXN9IGZyb20gJy4vdG91Y2hlcyc7XG5pbXBvcnQge0Nhcm91c2VsfSBmcm9tICcuL2Nhcm91c2VsJztcbmltcG9ydCB7Q29udGFpbmVyfSBmcm9tICcuL2NvbnRhaW5lcic7XG5pbXBvcnQge0NlbGxzfSBmcm9tICcuL2NlbGxzJztcbmltcG9ydCB7U2xpZGV9IGZyb20gJy4vc2xpZGUnO1xuaW1wb3J0IHtVdGlsc30gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQge1Byb3BlcnRpZXMgYXMgQ2Fyb3VzZWxQcm9wZXJ0aWVzfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuXG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnY2Fyb3VzZWwsIFtjYXJvdXNlbF0nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9jYXJvdXNlbC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vY2Fyb3VzZWwuY29tcG9uZW50LnNhc3MnXVxufSlcblxuZXhwb3J0IGNsYXNzIENhcm91c2VsQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgICBjYXJvdXNlbDphbnk7XG4gICAgY29udGFpbmVyOmFueTtcbiAgICB1dGlsczphbnk7XG4gICAgY2VsbHM6YW55O1xuICAgIHNsaWRlOmFueTtcbiAgICBfaWQhOiBzdHJpbmc7XG4gICAgX2ltYWdlcyE6IEltYWdlcztcbiAgICB0b3VjaGVzOiBhbnk7XG4gICAgbGFuZHNjYXBlTW9kZTogYW55O1xuICAgIG1pblRpbWVvdXQgPSAzMDtcbiAgICBpc1ZpZGVvUGxheWluZzogYm9vbGVhbiA9IGZhbHNlO1xuICAgIF9pc0NvdW50ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBfd2lkdGghOiBudW1iZXI7XG4gICAgX2NlbGxXaWR0aDogbnVtYmVyIHwgJzEwMCUnID0gMjAwO1xuICAgIF9sb29wOiBib29sZWFuID0gZmFsc2U7XG4gICAgX2xpZ2h0RE9NOiBib29sZWFuID0gZmFsc2U7XG4gICAgaXNNb3Zpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBpc05nQ29udGVudDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIGNlbGxMZW5ndGghOiBudW1iZXI7XG4gICAgZG90c0FycjogYW55O1xuICAgIGNhcm91c2VsUHJvcGVydGllcyE6IENhcm91c2VsUHJvcGVydGllcztcbiAgICBzYXZlZENhcm91c2VsV2lkdGghOiBudW1iZXI7XG5cbiAgICBnZXQgaXNDb250YWluZXJMb2NrZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmNhcm91c2VsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5pc0NvbnRhaW5lckxvY2tlZDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBzbGlkZUNvdW50ZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLmNhcm91c2VsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYXJvdXNlbC5zbGlkZUNvdW50ZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgbGFwQ291bnRlcigpIHtcbiAgICAgICAgaWYgKHRoaXMuY2Fyb3VzZWwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNhcm91c2VsLmxhcENvdW50ZXI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgaXNMYW5kc2NhcGUoKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cuaW5uZXJXaWR0aCA+IHdpbmRvdy5pbm5lckhlaWdodDtcbiAgICB9XG5cbiAgICBnZXQgaXNTYWZhcmkoKTogYW55IHtcbiAgICAgICAgY29uc3QgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmICh1YS5pbmRleE9mKCdzYWZhcmknKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiAhKHVhLmluZGV4T2YoJ2Nocm9tZScpID4gLTEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0IGNvdW50ZXIoKSB7XG4gICAgICAgIGxldCBjb3VudGVyO1xuXG4gICAgICAgIGlmICh0aGlzLmxvb3ApIHtcbiAgICAgICAgICAgIGNvdW50ZXIgPSB0aGlzLnNsaWRlQ291bnRlciAlIHRoaXMuY2VsbExlbmd0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvdW50ZXIgPSB0aGlzLnNsaWRlQ291bnRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb3VudGVyICsgMSArIHRoaXMuY291bnRlclNlcGFyYXRvciArIHRoaXMuY2VsbExlbmd0aDtcbiAgICB9XG5cbiAgICBnZXQgY2VsbHNFbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmNhcm91c2VsLWNlbGxzJyk7XG4gICAgfVxuXG4gICAgZ2V0IGlzQXJyb3dzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcnJvd3MgJiYgIXRoaXMuZnJlZVNjcm9sbDtcbiAgICB9XG5cbiAgICBnZXQgaXNDb3VudGVyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNDb3VudGVyICYmIHRoaXMuY2VsbExlbmd0aCA+IDE7XG4gICAgfVxuXG4gICAgZ2V0IGFjdGl2ZURvdEluZGV4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zbGlkZUNvdW50ZXIgJSB0aGlzLmNlbGxMZW5ndGg7XG4gICAgfVxuXG4gICAgZ2V0IGNlbGxMaW1pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMuY2Fyb3VzZWwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNhcm91c2VsLmNlbGxMaW1pdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBjYXJvdXNlbFdpZHRoKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY2xpZW50V2lkdGg7XG4gICAgfVxuXG4gICAgQE91dHB1dCgpIGV2ZW50czogRXZlbnRFbWl0dGVyIDwgYW55ID4gPSBuZXcgRXZlbnRFbWl0dGVyIDwgYW55ID4gKCk7XG5cbiAgICBASW5wdXQoKSBpZCE6IG51bWJlcjtcbiAgICBASW5wdXQoKSBoZWlnaHQ6IG51bWJlciA9IDIwMDtcbiAgICBASW5wdXQoKSB3aWR0aCE6IG51bWJlcjtcbiAgICBASW5wdXQoKSBhdXRvcGxheTogYm9vbGVhbiA9IGZhbHNlO1xuICAgIEBJbnB1dCgpIGF1dG9wbGF5SW50ZXJ2YWw6IG51bWJlciA9IDUwMDA7XG4gICAgQElucHV0KCkgcGF1c2VPbkhvdmVyOiBib29sZWFuID0gdHJ1ZTtcbiAgICBASW5wdXQoKSBkb3RzOiBib29sZWFuID0gZmFsc2U7XG4gICAgQElucHV0KCkgYm9yZGVyUmFkaXVzITogbnVtYmVyO1xuICAgIEBJbnB1dCgpIG1hcmdpbjogbnVtYmVyID0gMTA7XG4gICAgQElucHV0KCkgb2JqZWN0Rml0OiAnY29udGFpbicgfCAnY292ZXInIHwgJ25vbmUnID0gJ2NvdmVyJztcbiAgICBASW5wdXQoKSBtaW5Td2lwZURpc3RhbmNlOiBudW1iZXIgPSAxMDtcbiAgICBASW5wdXQoKSB0cmFuc2l0aW9uRHVyYXRpb246IG51bWJlciA9IDIwMDtcbiAgICBASW5wdXQoKSB0cmFuc2l0aW9uVGltaW5nRnVuY3Rpb246ICdlYXNlJyB8ICdlYXNlLWluJyB8ICdlYXNlLW91dCcgfCAnZWFzZS1pbi1vdXQnIHwgJ2xpbmVhcicgPSAnZWFzZS1vdXQnO1xuICAgIEBJbnB1dCgpIHZpZGVvUHJvcGVydGllczogYW55O1xuICAgIEBJbnB1dCgpIGNvdW50ZXJTZXBhcmF0b3I6IHN0cmluZyA9IFwiIC8gXCI7XG4gICAgQElucHV0KCkgb3ZlcmZsb3dDZWxsc0xpbWl0OiBudW1iZXIgPSAzO1xuICAgIEBJbnB1dCgpIGxpc3RlbmVyczogJ2F1dG8nIHwgJ21vdXNlIGFuZCB0b3VjaCcgPSAnbW91c2UgYW5kIHRvdWNoJztcbiAgICBASW5wdXQoKSBjZWxsc1RvU2hvdyE6IG51bWJlcjtcbiAgICBASW5wdXQoKSBjZWxsc1RvU2Nyb2xsOiBudW1iZXIgPSAxO1xuICAgIEBJbnB1dCgpIGZyZWVTY3JvbGw6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBhcnJvd3M6IGJvb2xlYW4gPSB0cnVlO1xuICAgIEBJbnB1dCgpIGFycm93c091dHNpZGU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICBASW5wdXQoKSBhcnJvd3NUaGVtZTogJ2xpZ2h0JyB8ICdkYXJrJyA9ICdsaWdodCc7XG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBpbWFnZXMoaW1hZ2VzOiBJbWFnZXMgJiBhbnkpIHtcbiAgICAgICAgdGhpcy5faW1hZ2VzID0gaW1hZ2VzO1xuICAgIH1cbiAgICBnZXQgaW1hZ2VzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faW1hZ2VzO1xuICAgIH1cblxuICAgIEBJbnB1dCgnY2VsbFdpZHRoJykgc2V0IGNlbGxXaWR0aCh2YWx1ZTogbnVtYmVyIHwgJzEwMCUnKSB7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fY2VsbFdpZHRoID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASW5wdXQoJ2NvdW50ZXInKSBzZXQgaXNDb3VudGVyKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5faXNDb3VudGVyID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASW5wdXQoJ2xvb3AnKSBzZXQgbG9vcCh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX2xvb3AgPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBsb29wKCkge1xuICAgICAgICBpZiAodGhpcy5pbWFnZXMpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb29wO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQElucHV0KCdsaWdodERPTScpIHNldCBsaWdodERPTSh2YWx1ZTogYm9vbGVhbikge1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuX2xpZ2h0RE9NID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXQgbGlnaHRET00oKSB7XG4gICAgICAgIGlmICh0aGlzLmltYWdlcykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2xpZ2h0RE9NO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5jYXJvdXNlbCcpIGhvc3RDbGFzc0Nhcm91c2VsOiBib29sZWFuID0gdHJ1ZTtcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLmhlaWdodCcpIGhvc3RTdHlsZUhlaWdodCE6IHN0cmluZztcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLndpZHRoJykgaG9zdFN0eWxlV2lkdGghOiBzdHJpbmc7XG5cbiAgICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcbiAgICBvbldpbmRvd1Jlc2l6ZShldmVudDogYW55KSB7XG4gICAgICAgIGlmICh0aGlzLnV0aWxzLnZpc2libGVXaWR0aCAhPT0gdGhpcy5zYXZlZENhcm91c2VsV2lkdGgpIHtcbiAgICAgICAgICAgIHRoaXMucmVzaXplKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZW1vdmUnLCBbJyRldmVudCddKVxuICAgIG9uTW91c2Vtb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmF1dG9wbGF5ICYmIHRoaXMucGF1c2VPbkhvdmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNhcm91c2VsLnN0b3BBdXRvcGxheSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScsIFsnJGV2ZW50J10pXG4gICAgb25Nb3VzZWxlYXZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmF1dG9wbGF5ICYmIHRoaXMucGF1c2VPbkhvdmVyKSB7XG4gICAgICAgICAgICB0aGlzLmNhcm91c2VsLmF1dG9wbGF5KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIHJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcblxuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmlzTmdDb250ZW50ID0gdGhpcy5jZWxsc0VsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoID4gMDtcblxuICAgICAgICB0aGlzLnRvdWNoZXMgPSBuZXcgVG91Y2hlcyh7XG4gICAgICAgICAgICBlbGVtZW50OiB0aGlzLmNlbGxzRWxlbWVudCxcbiAgICAgICAgICAgIGxpc3RlbmVyczogdGhpcy5saXN0ZW5lcnMsXG4gICAgICAgICAgICBtb3VzZUxpc3RlbmVyczoge1xuICAgICAgICAgICAgICAgIFwibW91c2Vkb3duXCI6IFwiaGFuZGxlTW91c2Vkb3duXCIsXG4gICAgICAgICAgICAgICAgXCJtb3VzZXVwXCI6IFwiaGFuZGxlTW91c2V1cFwiXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMudG91Y2hlcy5vbigndG91Y2hzdGFydCcsIHRoaXMuaGFuZGxlVG91Y2hzdGFydCk7XG4gICAgICAgIHRoaXMudG91Y2hlcy5vbignaG9yaXpvbnRhbC1zd2lwZScsIHRoaXMuaGFuZGxlSG9yaXpvbnRhbFN3aXBlKTtcbiAgICAgICAgdGhpcy50b3VjaGVzLm9uKCd0b3VjaGVuZCcsIHRoaXMuaGFuZGxlVG91Y2hlbmQpO1xuICAgICAgICB0aGlzLnRvdWNoZXMub24oJ21vdXNlZG93bicsIHRoaXMuaGFuZGxlVG91Y2hzdGFydCk7XG4gICAgICAgIHRoaXMudG91Y2hlcy5vbignbW91c2V1cCcsIHRoaXMuaGFuZGxlVG91Y2hlbmQpO1xuICAgICAgICB0aGlzLnRvdWNoZXMub24oJ3RhcCcsIHRoaXMuaGFuZGxlVGFwKTtcblxuICAgICAgICB0aGlzLnNldERpbWVuc2lvbnMoKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgICAgIHRoaXMuaW5pdENhcm91c2VsKCk7XG4gICAgICAgIHRoaXMuY2VsbExlbmd0aCA9IHRoaXMuZ2V0Q2VsbExlbmd0aCgpO1xuICAgICAgICB0aGlzLmRvdHNBcnIgPSBBcnJheSh0aGlzLmNlbGxMZW5ndGgpLmZpbGwoMSk7XG4gICAgICAgIHRoaXMucmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgdGhpcy5jYXJvdXNlbC5saW5lVXBDZWxscygpO1xuICAgICAgICB0aGlzLnNhdmVkQ2Fyb3VzZWxXaWR0aCA9IHRoaXMuY2Fyb3VzZWxXaWR0aDtcblxuICAgICAgICAvKiBTdGFydCBkZXRlY3RpbmcgY2hhbmdlcyBpbiB0aGUgRE9NIHRyZWUgKi9cbiAgICAgICAgdGhpcy5kZXRlY3REb21DaGFuZ2VzKCk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgICAgICBpZiAoY2hhbmdlcy53aWR0aCB8fCBjaGFuZ2VzLmhlaWdodCB8fCBjaGFuZ2VzLmltYWdlcykge1xuICAgICAgICAgICAgdGhpcy5zZXREaW1lbnNpb25zKCk7XG4gICAgICAgICAgICB0aGlzLmluaXRDYXJvdXNlbCgpO1xuICAgICAgICAgICAgdGhpcy5jYXJvdXNlbC5saW5lVXBDZWxscygpO1xuICAgICAgICAgICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMudG91Y2hlcy5kZXN0cm95KCk7XG4gICAgICAgIC8vdGhpcy5jYXJvdXNlbC5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgaW5pdENhcm91c2VsKCkge1xuICAgICAgICB0aGlzLmNhcm91c2VsUHJvcGVydGllcyA9IHtcbiAgICAgICAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgICAgICAgY2VsbHNFbGVtZW50OiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcuY2Fyb3VzZWwtY2VsbHMnKSxcbiAgICAgICAgICAgIGhvc3RFbGVtZW50OiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCxcbiAgICAgICAgICAgIGltYWdlczogdGhpcy5pbWFnZXMsXG4gICAgICAgICAgICBjZWxsV2lkdGg6IHRoaXMuZ2V0Q2VsbFdpZHRoKCksXG4gICAgICAgICAgICBsb29wOiB0aGlzLmxvb3AsXG4gICAgICAgICAgICBhdXRvcGxheUludGVydmFsOiB0aGlzLmF1dG9wbGF5SW50ZXJ2YWwsXG4gICAgICAgICAgICBvdmVyZmxvd0NlbGxzTGltaXQ6IHRoaXMub3ZlcmZsb3dDZWxsc0xpbWl0LFxuICAgICAgICAgICAgdmlzaWJsZVdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgICAgICAgbWFyZ2luOiB0aGlzLm1hcmdpbixcbiAgICAgICAgICAgIG1pblN3aXBlRGlzdGFuY2U6IHRoaXMubWluU3dpcGVEaXN0YW5jZSxcbiAgICAgICAgICAgIHRyYW5zaXRpb25EdXJhdGlvbjogdGhpcy50cmFuc2l0aW9uRHVyYXRpb24sXG4gICAgICAgICAgICB0cmFuc2l0aW9uVGltaW5nRnVuY3Rpb246IHRoaXMudH