@rybos/ngx-gallery
Version:
A simple responsive native gallery component for Angular 15.
276 lines • 47.3 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { NgxGalleryOrder } from '../ngx-gallery-order';
import * as i0 from "@angular/core";
import * as i1 from "@angular/platform-browser";
import * as i2 from "../ngx-gallery.service";
import * as i3 from "@angular/common";
import * as i4 from "../ngx-gallery-arrows/ngx-gallery-arrows.component";
import * as i5 from "../ngx-gallery-action/ngx-gallery-action.component";
export class NgxGalleryThumbnailsComponent {
constructor(sanitization, elementRef, helperService) {
this.sanitization = sanitization;
this.elementRef = elementRef;
this.helperService = helperService;
this.minStopIndex = 0;
this.activeChange = new EventEmitter();
this.index = 0;
}
ngOnChanges(changes) {
if (changes['selectedIndex']) {
this.validateIndex();
}
if (changes['swipe']) {
this.helperService.manageSwipe(this.swipe, this.elementRef, 'thumbnails', () => this.moveRight(), () => this.moveLeft());
}
if (this.images) {
this.remainingCountValue = this.images.length - (this.rows * this.columns);
}
}
onMouseEnter() {
this.mouseenter = true;
}
onMouseLeave() {
this.mouseenter = false;
}
reset(index) {
this.selectedIndex = index;
this.setDefaultPosition();
this.index = 0;
this.validateIndex();
}
getImages() {
if (!this.images) {
return [];
}
if (this.remainingCount) {
return this.images.slice(0, this.rows * this.columns);
}
else if (this.lazyLoading && this.order !== NgxGalleryOrder.Row) {
let stopIndex = 0;
if (this.order === NgxGalleryOrder.Column) {
stopIndex = (this.index + this.columns + this.moveSize) * this.rows;
}
else if (this.order === NgxGalleryOrder.Page) {
stopIndex = this.index + ((this.columns * this.rows) * 2);
}
if (stopIndex <= this.minStopIndex) {
stopIndex = this.minStopIndex;
}
else {
this.minStopIndex = stopIndex;
}
return this.images.slice(0, stopIndex);
}
else {
return this.images;
}
}
handleClick(event, index) {
if (!this.hasLink(index) && !this.isAnimating) {
this.selectedIndex = index;
this.activeChange.emit(index);
}
event.stopPropagation();
event.preventDefault();
}
hasLink(index) {
return !!(this.links && this.links.length && this.links[index]);
}
moveRight() {
if (this.canMoveRight()) {
this.index += this.moveSize;
const maxIndex = this.getMaxIndex() - this.columns;
if (this.index > maxIndex) {
this.index = maxIndex;
}
this.setThumbnailsPosition();
}
}
moveLeft() {
if (this.canMoveLeft()) {
this.index -= this.moveSize;
if (this.index < 0) {
this.index = 0;
}
this.setThumbnailsPosition();
}
}
canMoveRight() {
return this.index + this.columns < this.getMaxIndex();
}
canMoveLeft() {
return this.index !== 0;
}
getThumbnailLeft(index) {
let calculatedIndex;
if (this.order === NgxGalleryOrder.Column) {
calculatedIndex = Math.floor(index / this.rows);
}
else if (this.order === NgxGalleryOrder.Page) {
calculatedIndex = (index % this.columns) + (Math.floor(index / (this.rows * this.columns)) * this.columns);
}
else if (this.order === NgxGalleryOrder.Row && this.remainingCount) {
calculatedIndex = index % this.columns;
}
else {
calculatedIndex = index % Math.ceil(this.images.length / this.rows);
}
return this.getThumbnailPosition(calculatedIndex, this.columns);
}
getThumbnailTop(index) {
let calculatedIndex;
if (this.order === NgxGalleryOrder.Column) {
calculatedIndex = index % this.rows;
}
else if (this.order === NgxGalleryOrder.Page) {
calculatedIndex = Math.floor(index / this.columns) - (Math.floor(index / (this.rows * this.columns)) * this.rows);
}
else if (this.order === NgxGalleryOrder.Row && this.remainingCount) {
calculatedIndex = Math.floor(index / this.columns);
}
else {
calculatedIndex = Math.floor(index / Math.ceil(this.images.length / this.rows));
}
return this.getThumbnailPosition(calculatedIndex, this.rows);
}
getThumbnailWidth() {
return this.getThumbnailDimension(this.columns);
}
getThumbnailHeight() {
return this.getThumbnailDimension(this.rows);
}
setThumbnailsPosition() {
this.thumbnailsLeft = -((100 / this.columns) * this.index) + '%';
this.thumbnailsMarginLeft = -((this.margin - (((this.columns - 1)
* this.margin) / this.columns)) * this.index) + 'px';
}
setDefaultPosition() {
this.thumbnailsLeft = '0px';
this.thumbnailsMarginLeft = '0px';
}
canShowArrows() {
if (this.remainingCount) {
return false;
}
else {
return this.arrows && this.images && this.images.length > this.getVisibleCount()
&& (!this.arrowsAutoHide || this.mouseenter);
}
}
validateIndex() {
if (this.images) {
let newIndex;
if (this.order === NgxGalleryOrder.Column) {
newIndex = Math.floor(this.selectedIndex / this.rows);
}
else {
newIndex = this.selectedIndex % Math.ceil(this.images.length / this.rows);
}
if (this.remainingCount) {
newIndex = 0;
}
if (newIndex < this.index || newIndex >= this.index + this.columns) {
const maxIndex = this.getMaxIndex() - this.columns;
this.index = newIndex > maxIndex ? maxIndex : newIndex;
this.setThumbnailsPosition();
}
}
}
getSafeUrl(image) {
return this.sanitization.bypassSecurityTrustStyle(this.helperService.getBackgroundUrl(image.toString()));
}
getFileType(fileSource) {
return this.helperService.getFileType(fileSource.toString());
}
getThumbnailPosition(index, count) {
return this.getSafeStyle('calc(' + ((100 / count) * index) + '% + '
+ ((this.margin - (((count - 1) * this.margin) / count)) * index) + 'px)');
}
getThumbnailDimension(count) {
if (this.margin !== 0) {
return this.getSafeStyle('calc(' + (100 / count) + '% - '
+ (((count - 1) * this.margin) / count) + 'px)');
}
else {
return this.getSafeStyle('calc(' + (100 / count) + '% + 1px)');
}
}
getMaxIndex() {
if (this.order === NgxGalleryOrder.Page) {
let maxIndex = (Math.floor(this.images.length / this.getVisibleCount()) * this.columns);
if (this.images.length % this.getVisibleCount() > this.columns) {
maxIndex += this.columns;
}
else {
maxIndex += this.images.length % this.getVisibleCount();
}
return maxIndex;
}
else {
return Math.ceil(this.images.length / this.rows);
}
}
getVisibleCount() {
return this.columns * this.rows;
}
getSafeStyle(value) {
return this.sanitization.bypassSecurityTrustStyle(value);
}
}
NgxGalleryThumbnailsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: NgxGalleryThumbnailsComponent, deps: [{ token: i1.DomSanitizer }, { token: i0.ElementRef }, { token: i2.NgxGalleryService }], target: i0.ɵɵFactoryTarget.Component });
NgxGalleryThumbnailsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.0", type: NgxGalleryThumbnailsComponent, selector: "ngx-gallery-thumbnails", inputs: { images: "images", isAnimating: "isAnimating", links: "links", labels: "labels", linkTarget: "linkTarget", columns: "columns", rows: "rows", arrows: "arrows", arrowsAutoHide: "arrowsAutoHide", margin: "margin", selectedIndex: "selectedIndex", clickable: "clickable", swipe: "swipe", size: "size", arrowPrevIcon: "arrowPrevIcon", arrowNextIcon: "arrowNextIcon", moveSize: "moveSize", order: "order", remainingCount: "remainingCount", lazyLoading: "lazyLoading", actions: "actions" }, outputs: { activeChange: "activeChange" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ngx-gallery-thumbnails-wrapper ngx-gallery-thumbnail-size-{{size}}\">\r\n <div class=\"ngx-gallery-thumbnails\" [style.transform]=\"'translateX(' + thumbnailsLeft + ')'\"\r\n [style.marginLeft]=\"thumbnailsMarginLeft\">\r\n <a [href]=\"hasLink(i) ? links[i] : '#'\" [target]=\"linkTarget\" class=\"ngx-gallery-thumbnail\"\r\n *ngFor=\"let image of getImages(); let i = index;\"\r\n (click)=\"handleClick($event, i)\" [style.width]=\"getThumbnailWidth()\" [style.height]=\"getThumbnailHeight()\"\r\n [style.left]=\"getThumbnailLeft(i)\" [style.top]=\"getThumbnailTop(i)\"\r\n [ngClass]=\"{ 'ngx-gallery-active': i === selectedIndex, 'ngx-gallery-clickable': clickable }\"\r\n [attr.aria-label]=\"labels[i]\">\r\n <div *ngIf=\"getFileType(image) === 'image'\" [style.background-image]=\"getSafeUrl(image)\" class=\"ngx-gallery-thumbnail\"\r\n [ngClass]=\"{ 'ngx-gallery-active': i === selectedIndex, 'ngx-gallery-clickable': clickable }\"\r\n style=\"width: 100%; height: 100%; position:absolute;\"></div>\r\n <div *ngIf=\"getFileType(image) === 'video'\" class=\"ngx-gallery-thumbnail-video\">\r\n <video class=\"ngx-gallery-thumbnail\" [ngClass]=\"{ 'ngx-gallery-active': i === selectedIndex, 'ngx-gallery-clickable': clickable }\"\r\n style=\"width: 100%; height: 100%; position:absolute; left:0; background:#000;\">\r\n <source [src]=\"image\">\r\n Your browser does not support the video tag.\r\n </video>\r\n </div>\r\n <div class=\"ngx-gallery-icons-wrapper\">\r\n <ngx-gallery-action *ngFor=\"let action of actions\" [icon]=\"action.icon\" [disabled]=\"action.disabled\"\r\n [titleText]=\"action.titleText\" (closeClick)=\"action.onClick($event, i)\"></ngx-gallery-action>\r\n </div>\r\n <div class=\"ngx-gallery-remaining-count-overlay\"\r\n *ngIf=\"remainingCount && remainingCountValue && (i === (rows * columns) - 1)\">\r\n <span class=\"ngx-gallery-remaining-count\">+{{remainingCountValue}}</span>\r\n </div>\r\n </a>\r\n </div>\r\n</div>\r\n<ngx-gallery-arrows *ngIf=\"canShowArrows()\" (prevClick)=\"moveLeft()\" (nextClick)=\"moveRight()\"\r\n [prevDisabled]=\"!canMoveLeft()\" [nextDisabled]=\"!canMoveRight()\" [arrowPrevIcon]=\"arrowPrevIcon\"\r\n [arrowNextIcon]=\"arrowNextIcon\"></ngx-gallery-arrows>\r\n", styles: ["@charset \"UTF-8\";:host{width:100%;display:inline-block;position:relative;font-size:25px}.ngx-gallery-thumbnails-wrapper{width:100%;height:100%;position:absolute;overflow:hidden}.ngx-gallery-thumbnails{height:100%;width:100%;position:absolute;left:0;transform:translate(0);transition:transform .5s ease-in-out;will-change:transform}.ngx-gallery-thumbnails .ngx-gallery-thumbnail{position:absolute;height:100%;background-position:center;background-repeat:no-repeat;text-decoration:none;border:1px double black}.ngx-gallery-thumbnails .ngx-gallery-thumbnail .ngx-gallery-thumbnail-video:after{content:\"\\f144\";display:block;position:absolute;background:rgba(0,0,0,0);height:100%;width:100%;left:0;top:calc(50% - 20px);font-size:40px;color:#fff;margin:0;padding:0;font-family:fontawesome;text-shadow:0px 4px 3px rgba(0,0,0,.4),0px 8px 13px rgba(0,0,0,.1),0px 18px 23px rgba(0,0,0,.1)}.ngx-gallery-thumbnails .ngx-gallery-thumbnail .img{background-size:cover;height:100%}.ngx-gallery-thumbnails .ngx-gallery-thumbnail.ngx-gallery-active{border:1px double #cc4548}.ngx-gallery-thumbnail-size-cover .ngx-gallery-thumbnails .ngx-gallery-thumbnail{background-size:cover}.ngx-gallery-thumbnail-size-contain .ngx-gallery-thumbnails .ngx-gallery-thumbnail{background-size:contain}.ngx-gallery-remaining-count-overlay{width:100%;height:100%;position:absolute;left:0;top:0;background-color:#0006}.ngx-gallery-remaining-count{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;font-size:30px}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.NgxGalleryArrowsComponent, selector: "ngx-gallery-arrows", inputs: ["prevDisabled", "nextDisabled", "arrowPrevIcon", "arrowNextIcon"], outputs: ["prevClick", "nextClick"] }, { kind: "component", type: i5.NgxGalleryActionComponent, selector: "ngx-gallery-action", inputs: ["icon", "disabled", "titleText"], outputs: ["closeClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.0", ngImport: i0, type: NgxGalleryThumbnailsComponent, decorators: [{
type: Component,
args: [{ selector: 'ngx-gallery-thumbnails', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ngx-gallery-thumbnails-wrapper ngx-gallery-thumbnail-size-{{size}}\">\r\n <div class=\"ngx-gallery-thumbnails\" [style.transform]=\"'translateX(' + thumbnailsLeft + ')'\"\r\n [style.marginLeft]=\"thumbnailsMarginLeft\">\r\n <a [href]=\"hasLink(i) ? links[i] : '#'\" [target]=\"linkTarget\" class=\"ngx-gallery-thumbnail\"\r\n *ngFor=\"let image of getImages(); let i = index;\"\r\n (click)=\"handleClick($event, i)\" [style.width]=\"getThumbnailWidth()\" [style.height]=\"getThumbnailHeight()\"\r\n [style.left]=\"getThumbnailLeft(i)\" [style.top]=\"getThumbnailTop(i)\"\r\n [ngClass]=\"{ 'ngx-gallery-active': i === selectedIndex, 'ngx-gallery-clickable': clickable }\"\r\n [attr.aria-label]=\"labels[i]\">\r\n <div *ngIf=\"getFileType(image) === 'image'\" [style.background-image]=\"getSafeUrl(image)\" class=\"ngx-gallery-thumbnail\"\r\n [ngClass]=\"{ 'ngx-gallery-active': i === selectedIndex, 'ngx-gallery-clickable': clickable }\"\r\n style=\"width: 100%; height: 100%; position:absolute;\"></div>\r\n <div *ngIf=\"getFileType(image) === 'video'\" class=\"ngx-gallery-thumbnail-video\">\r\n <video class=\"ngx-gallery-thumbnail\" [ngClass]=\"{ 'ngx-gallery-active': i === selectedIndex, 'ngx-gallery-clickable': clickable }\"\r\n style=\"width: 100%; height: 100%; position:absolute; left:0; background:#000;\">\r\n <source [src]=\"image\">\r\n Your browser does not support the video tag.\r\n </video>\r\n </div>\r\n <div class=\"ngx-gallery-icons-wrapper\">\r\n <ngx-gallery-action *ngFor=\"let action of actions\" [icon]=\"action.icon\" [disabled]=\"action.disabled\"\r\n [titleText]=\"action.titleText\" (closeClick)=\"action.onClick($event, i)\"></ngx-gallery-action>\r\n </div>\r\n <div class=\"ngx-gallery-remaining-count-overlay\"\r\n *ngIf=\"remainingCount && remainingCountValue && (i === (rows * columns) - 1)\">\r\n <span class=\"ngx-gallery-remaining-count\">+{{remainingCountValue}}</span>\r\n </div>\r\n </a>\r\n </div>\r\n</div>\r\n<ngx-gallery-arrows *ngIf=\"canShowArrows()\" (prevClick)=\"moveLeft()\" (nextClick)=\"moveRight()\"\r\n [prevDisabled]=\"!canMoveLeft()\" [nextDisabled]=\"!canMoveRight()\" [arrowPrevIcon]=\"arrowPrevIcon\"\r\n [arrowNextIcon]=\"arrowNextIcon\"></ngx-gallery-arrows>\r\n", styles: ["@charset \"UTF-8\";:host{width:100%;display:inline-block;position:relative;font-size:25px}.ngx-gallery-thumbnails-wrapper{width:100%;height:100%;position:absolute;overflow:hidden}.ngx-gallery-thumbnails{height:100%;width:100%;position:absolute;left:0;transform:translate(0);transition:transform .5s ease-in-out;will-change:transform}.ngx-gallery-thumbnails .ngx-gallery-thumbnail{position:absolute;height:100%;background-position:center;background-repeat:no-repeat;text-decoration:none;border:1px double black}.ngx-gallery-thumbnails .ngx-gallery-thumbnail .ngx-gallery-thumbnail-video:after{content:\"\\f144\";display:block;position:absolute;background:rgba(0,0,0,0);height:100%;width:100%;left:0;top:calc(50% - 20px);font-size:40px;color:#fff;margin:0;padding:0;font-family:fontawesome;text-shadow:0px 4px 3px rgba(0,0,0,.4),0px 8px 13px rgba(0,0,0,.1),0px 18px 23px rgba(0,0,0,.1)}.ngx-gallery-thumbnails .ngx-gallery-thumbnail .img{background-size:cover;height:100%}.ngx-gallery-thumbnails .ngx-gallery-thumbnail.ngx-gallery-active{border:1px double #cc4548}.ngx-gallery-thumbnail-size-cover .ngx-gallery-thumbnails .ngx-gallery-thumbnail{background-size:cover}.ngx-gallery-thumbnail-size-contain .ngx-gallery-thumbnails .ngx-gallery-thumbnail{background-size:contain}.ngx-gallery-remaining-count-overlay{width:100%;height:100%;position:absolute;left:0;top:0;background-color:#0006}.ngx-gallery-remaining-count{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;font-size:30px}\n"] }]
}], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: i0.ElementRef }, { type: i2.NgxGalleryService }]; }, propDecorators: { images: [{
type: Input
}], isAnimating: [{
type: Input
}], links: [{
type: Input
}], labels: [{
type: Input
}], linkTarget: [{
type: Input
}], columns: [{
type: Input
}], rows: [{
type: Input
}], arrows: [{
type: Input
}], arrowsAutoHide: [{
type: Input
}], margin: [{
type: Input
}], selectedIndex: [{
type: Input
}], clickable: [{
type: Input
}], swipe: [{
type: Input
}], size: [{
type: Input
}], arrowPrevIcon: [{
type: Input
}], arrowNextIcon: [{
type: Input
}], moveSize: [{
type: Input
}], order: [{
type: Input
}], remainingCount: [{
type: Input
}], lazyLoading: [{
type: Input
}], actions: [{
type: Input
}], activeChange: [{
type: Output
}], onMouseEnter: [{
type: HostListener,
args: ['mouseenter']
}], onMouseLeave: [{
type: HostListener,
args: ['mouseleave']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWdhbGxlcnktdGh1bWJuYWlscy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9nYWxsZXJ5L3NyYy9saWIvbmd4LWdhbGxlcnktdGh1bWJuYWlscy9uZ3gtZ2FsbGVyeS10aHVtYm5haWxzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2dhbGxlcnkvc3JjL2xpYi9uZ3gtZ2FsbGVyeS10aHVtYm5haWxzL25neC1nYWxsZXJ5LXRodW1ibmFpbHMuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBRVQsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUVQLE1BQU0sZUFBZSxDQUFDO0FBSXZCLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQzs7Ozs7OztBQVFyRCxNQUFNLE9BQU8sNkJBQTZCO0lBa0N4QyxZQUFvQixZQUEwQixFQUFVLFVBQXNCLEVBQzFELGFBQWdDO1FBRGhDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQVUsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUMxRCxrQkFBYSxHQUFiLGFBQWEsQ0FBbUI7UUE3QnBELGlCQUFZLEdBQUcsQ0FBQyxDQUFDO1FBd0JQLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUVwQyxVQUFLLEdBQUcsQ0FBQyxDQUFDO0lBSWxCLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLEVBQUU7WUFDNUIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1NBQ3RCO1FBRUQsSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDcEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsVUFB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QUFNO3NCQUFkLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBRUksWUFBWTtzQkFBckIsTUFBTTtnQkF1QnFCLFlBQVk7c0JBQXZDLFlBQVk7dUJBQUMsWUFBWTtnQkFJRSxZQUFZO3NCQUF2QyxZQUFZO3VCQUFDLFlBQVkiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBIb3N0TGlzdGVuZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIE9uSW5pdCxcclxuICBPdXRwdXQsXHJcbiAgU2ltcGxlQ2hhbmdlc1xyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0RvbVNhbml0aXplciwgU2FmZVJlc291cmNlVXJsLCBTYWZlU3R5bGV9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5pbXBvcnQge05neEdhbGxlcnlTZXJ2aWNlfSBmcm9tICcuLi9uZ3gtZ2FsbGVyeS5zZXJ2aWNlJztcclxuaW1wb3J0IHtOZ3hHYWxsZXJ5QWN0aW9ufSBmcm9tICcuLi9uZ3gtZ2FsbGVyeS1hY3Rpb24nO1xyXG5pbXBvcnQge05neEdhbGxlcnlPcmRlcn0gZnJvbSAnLi4vbmd4LWdhbGxlcnktb3JkZXInO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduZ3gtZ2FsbGVyeS10aHVtYm5haWxzJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vbmd4LWdhbGxlcnktdGh1bWJuYWlscy5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vbmd4LWdhbGxlcnktdGh1bWJuYWlscy5jb21wb25lbnQuc2NzcyddLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOZ3hHYWxsZXJ5VGh1bWJuYWlsc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XHJcbiAgdGh1bWJuYWlsc0xlZnQ6IHN0cmluZztcclxuICB0aHVtYm5haWxzTWFyZ2luTGVmdDogc3RyaW5nO1xyXG4gIG1vdXNlZW50ZXI6IGJvb2xlYW47XHJcbiAgcmVtYWluaW5nQ291bnRWYWx1ZTogbnVtYmVyO1xyXG5cclxuICBtaW5TdG9wSW5kZXggPSAwO1xyXG5cclxuICBASW5wdXQoKSBpbWFnZXM6IHN0cmluZ1tdIHwgU2FmZVJlc291cmNlVXJsW107XHJcbiAgQElucHV0KCkgaXNBbmltYXRpbmc6IGJvb2xlYW47XHJcbiAgQElucHV0KCkgbGlua3M6IHN0cmluZ1tdO1xyXG4gIEBJbnB1dCgpIGxhYmVsczogc3RyaW5nW107XHJcbiAgQElucHV0KCkgbGlua1RhcmdldDogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGNvbHVtbnM6IG51bWJlcjtcclxuICBASW5wdXQoKSByb3dzOiBudW1iZXI7XHJcbiAgQElucHV0KCkgYXJyb3dzOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGFycm93c0F1dG9IaWRlOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIG1hcmdpbjogbnVtYmVyO1xyXG4gIEBJbnB1dCgpIHNlbGVjdGVkSW5kZXg6IG51bWJlcjtcclxuICBASW5wdXQoKSBjbGlja2FibGU6IGJvb2xlYW47XHJcbiAgQElucHV0KCkgc3dpcGU6IGJvb2xlYW47XHJcbiAgQElucHV0KCkgc2l6ZTogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGFycm93UHJldkljb246IHN0cmluZztcclxuICBASW5wdXQoKSBhcnJvd05leHRJY29uOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgbW92ZVNpemU6IG51bWJlcjtcclxuICBASW5wdXQoKSBvcmRlcjogbnVtYmVyO1xyXG4gIEBJbnB1dCgpIHJlbWFpbmluZ0NvdW50OiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGxhenlMb2FkaW5nOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGFjdGlvbnM6IE5neEdhbGxlcnlBY3Rpb25bXTtcclxuXHJcbiAgQE91dHB1dCgpIGFjdGl2ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgcHJpdmF0ZSBpbmRleCA9IDA7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2FuaXRpemF0aW9uOiBEb21TYW5pdGl6ZXIsIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcclxuICAgICAgICAgICAgICBwcml2YXRlIGhlbHBlclNlcnZpY2U6IE5neEdhbGxlcnlTZXJ2aWNlKSB7XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICBpZiAoY2hhbmdlc1snc2VsZWN0ZWRJbmRleCddKSB7XHJcbiAgICAgIHRoaXMudmFsaWRhdGVJbmRleCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChjaGFuZ2VzWydzd2lwZSddKSB7XHJcbiAgICAgIHRoaXMuaGVscGVyU2VydmljZS5tYW5hZ2VTd2lwZSh0aGlzLnN3aXBlLCB0aGlzLmVsZW1lbnRSZWYsXHJcbiAgICAgICAgJ3RodW1ibmFpbHMnLCAoKSA9PiB0aGlzLm1vdmVSaWdodCgpLCAoKSA9PiB0aGlzLm1vdmVMZWZ0KCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmltYWdlcykge1xyXG4gICAgICB0aGlzLnJlbWFpbmluZ0NvdW50VmFsdWUgPSB0aGlzLmltYWdlcy5sZW5ndGggLSAodGhpcy5yb3dzICogdGhpcy5jb2x1bW5zKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlZW50ZXInKSBvbk1vdXNlRW50ZXIoKSB7XHJcbiAgICB0aGlzLm1vdXNlZW50ZXIgPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScpIG9uTW91c2VMZWF2ZSgpIHtcclxuICAgIHRoaXMubW91c2VlbnRlciA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcmVzZXQoaW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gaW5kZXg7XHJcbiAgICB0aGlzLnNldERlZmF1bHRQb3NpdGlvbigpO1xyXG5cclxuICAgIHRoaXMuaW5kZXggPSAwO1xyXG4gICAgdGhpcy52YWxpZGF0ZUluZGV4KCk7XHJcbiAgfVxyXG5cclxuICBnZXRJbWFnZXMoKTogc3RyaW5nW10gfCBTYWZlUmVzb3VyY2VVcmxbXSB7XHJcbiAgICBpZiAoIXRoaXMuaW1hZ2VzKSB7XHJcbiAgICAgIHJldHVybiBbXTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5yZW1haW5pbmdDb3VudCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5pbWFnZXMuc2xpY2UoMCwgdGhpcy5yb3dzICogdGhpcy5jb2x1bW5zKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5sYXp5TG9hZGluZyAmJiB0aGlzLm9yZGVyICE9PSBOZ3hHYWxsZXJ5T3JkZXIuUm93KSB7XHJcbiAgICAgIGxldCBzdG9wSW5kZXggPSAwO1xyXG5cclxuICAgICAgaWYgKHRoaXMub3JkZXIgPT09IE5neEdhbGxlcnlPcmRlci5Db2x1bW4pIHtcclxuICAgICAgICBzdG9wSW5kZXggPSAodGhpcy5pbmRleCArIHRoaXMuY29sdW1ucyArIHRoaXMubW92ZVNpemUpICogdGhpcy5yb3dzO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMub3JkZXIgPT09IE5neEdhbGxlcnlPcmRlci5QYWdlKSB7XHJcbiAgICAgICAgc3RvcEluZGV4ID0gdGhpcy5pbmRleCArICgodGhpcy5jb2x1bW5zICogdGhpcy5yb3dzKSAqIDIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoc3RvcEluZGV4IDw9IHRoaXMubWluU3RvcEluZGV4KSB7XHJcbiAgICAgICAgc3RvcEluZGV4ID0gdGhpcy5taW5TdG9wSW5kZXg7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5taW5TdG9wSW5kZXggPSBzdG9wSW5kZXg7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0aGlzLmltYWdlcy5zbGljZSgwLCBzdG9wSW5kZXgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMuaW1hZ2VzO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaGFuZGxlQ2xpY2soZXZlbnQ6IEV2ZW50LCBpbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaGFzTGluayhpbmRleCkgJiYgIXRoaXMuaXNBbmltYXRpbmcpIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZEluZGV4ID0gaW5kZXg7XHJcbiAgICAgIHRoaXMuYWN0aXZlQ2hhbmdlLmVtaXQoaW5kZXgpO1xyXG4gICAgfVxyXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gIH1cclxuXHJcbiAgaGFzTGluayhpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gISEodGhpcy5saW5rcyAmJiB0aGlzLmxpbmtzLmxlbmd0aCAmJiB0aGlzLmxpbmtzW2luZGV4XSk7XHJcbiAgfVxyXG5cclxuICBtb3ZlUmlnaHQoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5jYW5Nb3ZlUmlnaHQoKSkge1xyXG4gICAgICB0aGlzLmluZGV4ICs9IHRoaXMubW92ZVNpemU7XHJcbiAgICAgIGNvbnN0IG1heEluZGV4ID0gdGhpcy5nZXRNYXhJbmRleCgpIC0gdGhpcy5jb2x1bW5zO1xyXG5cclxuICAgICAgaWYgKHRoaXMuaW5kZXggPiBtYXhJbmRleCkge1xyXG4gICAgICAgIHRoaXMuaW5kZXggPSBtYXhJbmRleDtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5zZXRUaHVtYm5haWxzUG9zaXRpb24oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG1vdmVMZWZ0KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuY2FuTW92ZUxlZnQoKSkge1xyXG4gICAgICB0aGlzLmluZGV4IC09IHRoaXMubW92ZVNpemU7XHJcblxyXG4gICAgICBpZiAodGhpcy5pbmRleCA8IDApIHtcclxuICAgICAgICB0aGlzLmluZGV4ID0gMDtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5zZXRUaHVtYm5haWxzUG9zaXRpb24oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNhbk1vdmVSaWdodCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmluZGV4ICsgdGhpcy5jb2x1bW5zIDwgdGhpcy5nZXRNYXhJbmRleCgpO1xyXG4gIH1cclxuXHJcbiAgY2FuTW92ZUxlZnQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5pbmRleCAhPT0gMDtcclxuICB9XHJcblxyXG4gIGdldFRodW1ibmFpbExlZnQoaW5kZXg6IG51bWJlcik6IFNhZmVTdHlsZSB7XHJcbiAgICBsZXQgY2FsY3VsYXRlZEluZGV4O1xyXG5cclxuICAgIGlmICh0aGlzLm9yZGVyID09PSBOZ3hHYWxsZXJ5T3JkZXIuQ29sdW1uKSB7XHJcbiAgICAgIGNhbGN1bGF0ZWRJbmRleCA9IE1hdGguZmxvb3IoaW5kZXggLyB0aGlzLnJvd3MpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLm9yZGVyID09PSBOZ3hHYWxsZXJ5T3JkZXIuUGFnZSkge1xyXG4gICAgICBjYWxjdWxhdGVkSW5kZXggPSAoaW5kZXggJSB0aGlzLmNvbHVtbnMpICsgKE1hdGguZmxvb3IoaW5kZXggLyAodGhpcy5yb3dzICogdGhpcy5jb2x1bW5zKSkgKiB0aGlzLmNvbHVtbnMpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLm9yZGVyID09PSBOZ3hHYWxsZXJ5T3JkZXIuUm93ICYmIHRoaXMucmVtYWluaW5nQ291bnQpIHtcclxuICAgICAgY2FsY3VsYXRlZEluZGV4ID0gaW5kZXggJSB0aGlzLmNvbHVtbnM7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjYWxjdWxhdGVkSW5kZXggPSBpbmRleCAlIE1hdGguY2VpbCh0aGlzLmltYWdlcy5sZW5ndGggLyB0aGlzLnJvd3MpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmdldFRodW1ibmFpbFBvc2l0aW9uKGNhbGN1bGF0ZWRJbmRleCwgdGhpcy5jb2x1bW5zKTtcclxuICB9XHJcblxyXG4gIGdldFRodW1ibmFpbFRvcChpbmRleDogbnVtYmVyKTogU2FmZVN0eWxlIHtcclxuICAgIGxldCBjYWxjdWxhdGVkSW5kZXg7XHJcblxyXG4gICAgaWYgKHRoaXMub3JkZXIgPT09IE5neEdhbGxlcnlPcmRlci5Db2x1bW4pIHtcclxuICAgICAgY2FsY3VsYXRlZEluZGV4ID0gaW5kZXggJSB0aGlzLnJvd3M7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMub3JkZXIgPT09IE5neEdhbGxlcnlPcmRlci5QYWdlKSB7XHJcbiAgICAgIGNhbGN1bGF0ZWRJbmRleCA9IE1hdGguZmxvb3IoaW5kZXggLyB0aGlzLmNvbHVtbnMpIC0gKE1hdGguZmxvb3IoaW5kZXggLyAodGhpcy5yb3dzICogdGhpcy5jb2x1bW5zKSkgKiB0aGlzLnJvd3MpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLm9yZGVyID09PSBOZ3hHYWxsZXJ5T3JkZXIuUm93ICYmIHRoaXMucmVtYWluaW5nQ291bnQpIHtcclxuICAgICAgY2FsY3VsYXRlZEluZGV4ID0gTWF0aC5mbG9vcihpbmRleCAvIHRoaXMuY29sdW1ucyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjYWxjdWxhdGVkSW5kZXggPSBNYXRoLmZsb29yKGluZGV4IC8gTWF0aC5jZWlsKHRoaXMuaW1hZ2VzLmxlbmd0aCAvIHRoaXMucm93cykpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmdldFRodW1ibmFpbFBvc2l0aW9uKGNhbGN1bGF0ZWRJbmRleCwgdGhpcy5yb3dzKTtcclxuICB9XHJcblxyXG4gIGdldFRodW1ibmFpbFdpZHRoKCk6IFNhZmVTdHlsZSB7XHJcbiAgICByZXR1cm4gdGhpcy5nZXRUaHVtYm5haWxEaW1lbnNpb24odGhpcy5jb2x1bW5zKTtcclxuICB9XHJcblxyXG4gIGdldFRodW1ibmFpbEhlaWdodCgpOiBTYWZlU3R5bGUge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0VGh1bWJuYWlsRGltZW5zaW9uKHRoaXMucm93cyk7XHJcbiAgfVxyXG5cclxuICBzZXRUaHVtYm5haWxzUG9zaXRpb24oKTogdm9pZCB7XHJcbiAgICB0aGlzLnRodW1ibmFpbHNMZWZ0ID0gLSgoMTAwIC8gdGhpcy5jb2x1bW5zKSAqIHRoaXMuaW5kZXgpICsgJyUnO1xyXG5cclxuICAgIHRoaXMudGh1bWJuYWlsc01hcmdpbkxlZnQgPSAtKCh0aGlzLm1hcmdpbiAtICgoKHRoaXMuY29sdW1ucyAtIDEpXHJcbiAgICAgICogdGhpcy5tYXJnaW4pIC8gdGhpcy5jb2x1bW5zKSkgKiB0aGlzLmluZGV4KSArICdweCc7XHJcbiAgfVxyXG5cclxuICBzZXREZWZhdWx0UG9zaXRpb24oKTogdm9pZCB7XHJcbiAgICB0aGlzLnRodW1ibmFpbHNMZWZ0ID0gJzBweCc7XHJcbiAgICB0aGlzLnRodW1ibmFpbHNNYXJnaW5MZWZ0ID0gJzBweCc7XHJcbiAgfVxyXG5cclxuICBjYW5TaG93QXJyb3dzKCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHRoaXMucmVtYWluaW5nQ291bnQpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMuYXJyb3dzICYmIHRoaXMuaW1hZ2VzICYmIHRoaXMuaW1hZ2VzLmxlbmd0aCA+IHRoaXMuZ2V0VmlzaWJsZUNvdW50KClcclxuICAgICAgICAmJiAoIXRoaXMuYXJyb3dzQXV0b0hpZGUgfHwgdGhpcy5tb3VzZWVudGVyKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHZhbGlkYXRlSW5kZXgoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5pbWFnZXMpIHtcclxuICAgICAgbGV0IG5ld0luZGV4O1xyXG5cclxuICAgICAgaWYgKHRoaXMub3JkZXIgPT09IE5neEdhbGxlcnlPcmRlci5Db2x1bW4pIHtcclxuICAgICAgICBuZXdJbmRleCA9IE1hdGguZmxvb3IodGhpcy5zZWxlY3RlZEluZGV4IC8gdGhpcy5yb3dzKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBuZXdJbmRleCA9IHRoaXMuc2VsZWN0ZWRJbmRleCAlIE1hdGguY2VpbCh0aGlzLmltYWdlcy5sZW5ndGggLyB0aGlzLnJvd3MpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5yZW1haW5pbmdDb3VudCkge1xyXG4gICAgICAgIG5ld0luZGV4ID0gMDtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG5ld0luZGV4IDwgdGhpcy5pbmRleCB8fCBuZXdJbmRleCA+PSB0aGlzLmluZGV4ICsgdGhpcy5jb2x1bW5zKSB7XHJcbiAgICAgICAgY29uc3QgbWF4SW5kZXggPSB0aGlzLmdldE1heEluZGV4KCkgLSB0aGlzLmNvbHVtbnM7XHJcbiAgICAgICAgdGhpcy5pbmRleCA9IG5ld0luZGV4ID4gbWF4SW5kZXggPyBtYXhJbmRleCA6IG5ld0luZGV4O1xyXG5cclxuICAgICAgICB0aGlzLnNldFRodW1ibmFpbHNQb3NpdGlvbigpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXRTYWZlVXJsKGltYWdlOiBzdHJpbmcgfCBTYWZlUmVzb3VyY2VVcmwpOiBTYWZlU3R5bGUge1xyXG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemF0aW9uLmJ5cGFzc1NlY3VyaXR5VHJ1c3RTdHlsZSh0aGlzLmhlbHBlclNlcnZpY2UuZ2V0QmFja2dyb3VuZFVybChpbWFnZS50b1N0cmluZygpKSk7XHJcbiAgfVxyXG5cclxuICBnZXRGaWxlVHlwZShmaWxlU291cmNlOiBzdHJpbmcgfCBTYWZlUmVzb3VyY2VVcmwpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuaGVscGVyU2VydmljZS5nZXRGaWxlVHlwZShmaWxlU291cmNlLnRvU3RyaW5nKCkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRUaHVtYm5haWxQb3NpdGlvbihpbmRleDogbnVtYmVyLCBjb3VudDogbnVtYmVyKTogU2FmZVN0eWxlIHtcclxuICAgIHJldHVybiB0aGlzLmdldFNhZmVTdHlsZSgnY2FsYygnICsgKCgxMDAgLyBjb3VudCkgKiBpbmRleCkgKyAnJSArICdcclxuICAgICAgKyAoKHRoaXMubWFyZ2luIC0gKCgoY291bnQgLSAxKSAqIHRoaXMubWFyZ2luKSAvIGNvdW50KSkgKiBpbmRleCkgKyAncHgpJyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFRodW1ibmFpbERpbWVuc2lvbihjb3VudDogbnVtYmVyKTogU2FmZVN0eWxlIHtcclxuICAgIGlmICh0aGlzLm1hcmdpbiAhPT0gMCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5nZXRTYWZlU3R5bGUoJ2NhbGMoJyArICgxMDAgLyBjb3VudCkgKyAnJSAtICdcclxuICAgICAgICArICgoKGNvdW50IC0gMSkgKiB0aGlzLm1hcmdpbikgLyBjb3VudCkgKyAncHgpJyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5nZXRTYWZlU3R5bGUoJ2NhbGMoJyArICgxMDAgLyBjb3VudCkgKyAnJSArIDFweCknKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0TWF4SW5kZXgoKTogbnVtYmVyIHtcclxuICAgIGlmICh0aGlzLm9yZGVyID09PSBOZ3hHYWxsZXJ5T3JkZXIuUGFnZSkge1xyXG4gICAgICBsZXQgbWF4SW5kZXggPSAoTWF0aC5mbG9vcih0aGlzLmltYWdlcy5sZW5ndGggLyB0aGlzLmdldFZpc2libGVDb3VudCgpKSAqIHRoaXMuY29sdW1ucyk7XHJcblxyXG4gICAgICBpZiAodGhpcy5pbWFnZXMubGVuZ3RoICUgdGhpcy5nZXRWaXNpYmxlQ291bnQoKSA+IHRoaXMuY29sdW1ucykge1xyXG4gICAgICAgIG1heEluZGV4ICs9IHRoaXMuY29sdW1ucztcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBtYXhJbmRleCArPSB0aGlzLmltYWdlcy5sZW5ndGggJSB0aGlzLmdldFZpc2libGVDb3VudCgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gbWF4SW5kZXg7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gTWF0aC5jZWlsKHRoaXMuaW1hZ2VzLmxlbmd0aCAvIHRoaXMucm93cyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFZpc2libGVDb3VudCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuY29sdW1ucyAqIHRoaXMucm93cztcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0U2FmZVN0eWxlKHZhbHVlOiBzdHJpbmcpOiBTYWZlU3R5bGUge1xyXG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemF0aW9uLmJ5cGFzc1NlY3VyaXR5VHJ1c3RTdHlsZSh2YWx1ZSk7XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJuZ3gtZ2FsbGVyeS10aHVtYm5haWxzLXdyYXBwZXIgbmd4LWdhbGxlcnktdGh1bWJuYWlsLXNpemUte3tzaXplfX1cIj5cclxuICA8ZGl2IGNsYXNzPVwibmd4LWdhbGxlcnktdGh1bWJuYWlsc1wiIFtzdHlsZS50cmFuc2Zvcm1dPVwiJ3RyYW5zbGF0ZVgoJyArIHRodW1ibmFpbHNMZWZ0ICsgJyknXCJcclxuICAgICAgIFtzdHlsZS5tYXJnaW5MZWZ0XT1cInRodW1ibmFpbHNNYXJnaW5MZWZ0XCI+XHJcbiAgICA8YSBbaHJlZl09XCJoYXNMaW5rKGkpID8gbGlua3NbaV0gOiAnIydcIiBbdGFyZ2V0XT1cImxpbmtUYXJnZXRcIiBjbGFzcz1cIm5neC1nYWxsZXJ5LXRodW1ibmFpbFwiXHJcbiAgICAgICAqbmdGb3I9XCJsZXQgaW1hZ2Ugb2YgZ2V0SW1hZ2VzKCk7IGxldCBpID0gaW5kZXg7XCJcclxuICAgICAgIChjbGljayk9XCJoYW5kbGVDbGljaygkZXZlbnQsIGkpXCIgW3N0eWxlLndpZHRoXT1cImdldFRodW1ibmFpbFdpZHRoKClcIiBbc3R5bGUuaGVpZ2h0XT1cImdldFRodW1ibmFpbEhlaWdodCgpXCJcclxuICAgICAgIFtzdHlsZS5sZWZ0XT1cImdldFRodW1ibmFpbExlZnQoaSlcIiBbc3R5bGUudG9wXT1cImdldFRodW1ibmFpbFRvcChpKVwiXHJcbiAgICAgICBbbmdDbGFzc109XCJ7ICduZ3gtZ2FsbGVyeS1hY3RpdmUnOiBpID09PSBzZWxlY3RlZEluZGV4LCAnbmd4LWdhbGxlcnktY2xpY2thYmxlJzogY2xpY2thYmxlIH1cIlxyXG4gICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJsYWJlbHNbaV1cIj5cclxuICAgICAgIDxkaXYgKm5nSWY9XCJnZXRGaWxlVHlwZShpbWFnZSkgPT09ICdpbWFnZSdcIiBbc3R5bGUuYmFja2dyb3VuZC1pbWFnZV09XCJnZXRTYWZlVXJsKGltYWdlKVwiIGNsYXNzPVwibmd4LWdhbGxlcnktdGh1bWJuYWlsXCJcclxuICAgICAgIFtuZ0NsYXNzXT1cInsgJ25neC1nYWxsZXJ5LWFjdGl2ZSc6IGkgPT09IHNlbGVjdGVkSW5kZXgsICduZ3gtZ2FsbGVyeS1jbGlja2FibGUnOiBjbGlja2FibGUgfVwiXHJcbiAgICAgICBzdHlsZT1cIndpZHRoOiAxMDAlOyBoZWlnaHQ6IDEwMCU7IHBvc2l0aW9uOmFic29sdXRlO1wiPjwvZGl2PlxyXG4gICAgICAgPGRpdiAqbmdJZj1cImdldEZpbGVUeXBlKGltYWdlKSA9PT0gJ3ZpZGVvJ1wiIGNsYXNzPVwibmd4LWdhbGxlcnktdGh1bWJuYWlsLXZpZGVvXCI+XHJcbiAgICAgICAgPHZpZGVvICBjbGFzcz1cIm5neC1nYWxsZXJ5LXRodW1ibmFpbFwiIFtuZ0NsYXNzXT1cInsgJ25neC1nYWxsZXJ5LWFjdGl2ZSc6IGkgPT09IHNlbGVjdGVkSW5kZXgsICduZ3gtZ2FsbGVyeS1jbGlja2FibGUnOiBjbGlja2FibGUgfVwiXHJcbiAgICAgICAgc3R5bGU9XCJ3aWR0aDogMTAwJTsgaGVpZ2h0OiAxMDAlOyBwb3NpdGlvbjphYnNvbHV0ZTsgbGVmdDowOyBiYWNrZ3JvdW5kOiMwMDA7XCI+XHJcbiAgICAgICAgPHNvdXJjZSBbc3JjXT1cImltYWdlXCI+XHJcbiAgICAgICAgICBZb3VyIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCB0aGUgdmlkZW8gdGFnLlxyXG4gICAgICAgPC92aWRlbz5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgICA8ZGl2IGNsYXNzPVwibmd4LWdhbGxlcnktaWNvbnMtd3JhcHBlclwiPlxyXG4gICAgICAgIDxuZ3gtZ2FsbGVyeS1hY3Rpb24gKm5nRm9yPVwibGV0IGFjdGlvbiBvZiBhY3Rpb25zXCIgW2ljb25dPVwiYWN0aW9uLmljb25cIiBbZGlzYWJsZWRdPVwiYWN0aW9uLmRpc2FibGVkXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZVRleHRdPVwiYWN0aW9uLnRpdGxlVGV4dFwiIChjbG9zZUNsaWNrKT1cImFjdGlvbi5vbkNsaWNrKCRldmVudCwgaSlcIj48L25neC1nYWxsZXJ5LWFjdGlvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJuZ3gtZ2FsbGVyeS1yZW1haW5pbmctY291bnQtb3ZlcmxheVwiXHJcbiAgICAgICAgICAgKm5nSWY9XCJyZW1haW5pbmdDb3VudCAmJiByZW1haW5pbmdDb3VudFZhbHVlICYmIChpID09PSAocm93cyAqIGNvbHVtbnMpIC0gMSlcIj5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cIm5neC1nYWxsZXJ5LXJlbWFpbmluZy1jb3VudFwiPit7e3JlbWFpbmluZ0NvdW50VmFsdWV9fTwvc3Bhbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2E+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG48bmd4LWdhbGxlcnktYXJyb3dzICpuZ0lmPVwiY2FuU2hvd0Fycm93cygpXCIgKHByZXZDbGljayk9XCJtb3ZlTGVmdCgpXCIgKG5leHRDbGljayk9XCJtb3ZlUmlnaHQoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgW3ByZXZEaXNhYmxlZF09XCIhY2FuTW92ZUxlZnQoKVwiIFtuZXh0RGlzYWJsZWRdPVwiIWNhbk1vdmVSaWdodCgpXCIgW2Fycm93UHJldkljb25dPVwiYXJyb3dQcmV2SWNvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgW2Fycm93TmV4dEljb25dPVwiYXJyb3dOZXh0SWNvblwiPjwvbmd4LWdhbGxlcnktYXJyb3dzPlxyXG4iXX0=