968 lines
120 KiB
JavaScript
968 lines
120 KiB
JavaScript
import { CommonModule, DOCUMENT, isPlatformBrowser } from '@angular/common';
|
|
import { ChangeDetectionStrategy, Component, ContentChild, ContentChildren, EventEmitter, Inject, Input, NgModule, Output, PLATFORM_ID, ViewChild, ViewEncapsulation, booleanAttribute, numberAttribute } from '@angular/core';
|
|
import { Footer, Header, PrimeTemplate, SharedModule } from 'primeng/api';
|
|
import { ChevronDownIcon } from 'primeng/icons/chevrondown';
|
|
import { ChevronLeftIcon } from 'primeng/icons/chevronleft';
|
|
import { ChevronRightIcon } from 'primeng/icons/chevronright';
|
|
import { ChevronUpIcon } from 'primeng/icons/chevronup';
|
|
import { RippleModule } from 'primeng/ripple';
|
|
import { UniqueComponentId } from 'primeng/utils';
|
|
import { DomHandler } from 'primeng/dom';
|
|
import * as i0 from "@angular/core";
|
|
import * as i1 from "primeng/api";
|
|
import * as i2 from "@angular/common";
|
|
import * as i3 from "primeng/ripple";
|
|
/**
|
|
* Carousel is a content slider featuring various customization options.
|
|
* @group Components
|
|
*/
|
|
export class Carousel {
|
|
el;
|
|
zone;
|
|
cd;
|
|
renderer;
|
|
document;
|
|
platformId;
|
|
config;
|
|
/**
|
|
* Index of the first item.
|
|
* @defaultValue 0
|
|
* @group Props
|
|
*/
|
|
get page() {
|
|
return this._page;
|
|
}
|
|
set page(val) {
|
|
if (this.isCreated && val !== this._page) {
|
|
if (this.autoplayInterval) {
|
|
this.stopAutoplay();
|
|
}
|
|
if (val > this._page && val <= this.totalDots() - 1) {
|
|
this.step(-1, val);
|
|
}
|
|
else if (val < this._page) {
|
|
this.step(1, val);
|
|
}
|
|
}
|
|
this._page = val;
|
|
}
|
|
/**
|
|
* Number of items per page.
|
|
* @defaultValue 1
|
|
* @group Props
|
|
*/
|
|
get numVisible() {
|
|
return this._numVisible;
|
|
}
|
|
set numVisible(val) {
|
|
this._numVisible = val;
|
|
}
|
|
/**
|
|
* Number of items to scroll.
|
|
* @defaultValue 1
|
|
* @group Props
|
|
*/
|
|
get numScroll() {
|
|
return this._numVisible;
|
|
}
|
|
set numScroll(val) {
|
|
this._numScroll = val;
|
|
}
|
|
/**
|
|
* An array of options for responsive design.
|
|
* @see {CarouselResponsiveOptions}
|
|
* @group Props
|
|
*/
|
|
responsiveOptions;
|
|
/**
|
|
* Specifies the layout of the component.
|
|
* @group Props
|
|
*/
|
|
orientation = 'horizontal';
|
|
/**
|
|
* Height of the viewport in vertical layout.
|
|
* @group Props
|
|
*/
|
|
verticalViewPortHeight = '300px';
|
|
/**
|
|
* Style class of main content.
|
|
* @group Props
|
|
*/
|
|
contentClass = '';
|
|
/**
|
|
* Style class of the indicator items.
|
|
* @group Props
|
|
*/
|
|
indicatorsContentClass = '';
|
|
/**
|
|
* Inline style of the indicator items.
|
|
* @group Props
|
|
*/
|
|
indicatorsContentStyle;
|
|
/**
|
|
* Style class of the indicators.
|
|
* @group Props
|
|
*/
|
|
indicatorStyleClass = '';
|
|
/**
|
|
* Style of the indicators.
|
|
* @group Props
|
|
*/
|
|
indicatorStyle;
|
|
/**
|
|
* An array of objects to display.
|
|
* @defaultValue null
|
|
* @group Props
|
|
*/
|
|
get value() {
|
|
return this._value;
|
|
}
|
|
set value(val) {
|
|
this._value = val;
|
|
}
|
|
/**
|
|
* Defines if scrolling would be infinite.
|
|
* @group Props
|
|
*/
|
|
circular = false;
|
|
/**
|
|
* Whether to display indicator container.
|
|
* @group Props
|
|
*/
|
|
showIndicators = true;
|
|
/**
|
|
* Whether to display navigation buttons in container.
|
|
* @group Props
|
|
*/
|
|
showNavigators = true;
|
|
/**
|
|
* Time in milliseconds to scroll items automatically.
|
|
* @group Props
|
|
*/
|
|
autoplayInterval = 0;
|
|
/**
|
|
* Inline style of the component.
|
|
* @group Props
|
|
*/
|
|
style;
|
|
/**
|
|
* Style class of the viewport container.
|
|
* @group Props
|
|
*/
|
|
styleClass;
|
|
/**
|
|
* Callback to invoke after scroll.
|
|
* @param {CarouselPageEvent} event - Custom page event.
|
|
* @group Emits
|
|
*/
|
|
onPage = new EventEmitter();
|
|
itemsContainer;
|
|
indicatorContent;
|
|
headerFacet;
|
|
footerFacet;
|
|
templates;
|
|
_numVisible = 1;
|
|
_numScroll = 1;
|
|
_oldNumScroll = 0;
|
|
prevState = {
|
|
numScroll: 0,
|
|
numVisible: 0,
|
|
value: []
|
|
};
|
|
defaultNumScroll = 1;
|
|
defaultNumVisible = 1;
|
|
_page = 0;
|
|
_value;
|
|
carouselStyle;
|
|
id;
|
|
totalShiftedItems;
|
|
isRemainingItemsAdded = false;
|
|
animationTimeout;
|
|
translateTimeout;
|
|
remainingItems = 0;
|
|
_items;
|
|
startPos;
|
|
documentResizeListener;
|
|
clonedItemsForStarting;
|
|
clonedItemsForFinishing;
|
|
allowAutoplay;
|
|
interval;
|
|
isCreated;
|
|
swipeThreshold = 20;
|
|
itemTemplate;
|
|
headerTemplate;
|
|
footerTemplate;
|
|
previousIconTemplate;
|
|
nextIconTemplate;
|
|
window;
|
|
constructor(el, zone, cd, renderer, document, platformId, config) {
|
|
this.el = el;
|
|
this.zone = zone;
|
|
this.cd = cd;
|
|
this.renderer = renderer;
|
|
this.document = document;
|
|
this.platformId = platformId;
|
|
this.config = config;
|
|
this.totalShiftedItems = this.page * this.numScroll * -1;
|
|
this.window = this.document.defaultView;
|
|
}
|
|
ngOnChanges(simpleChange) {
|
|
if (isPlatformBrowser(this.platformId)) {
|
|
if (simpleChange.value) {
|
|
if (this.circular && this._value) {
|
|
this.setCloneItems();
|
|
}
|
|
}
|
|
if (this.isCreated) {
|
|
if (simpleChange.numVisible) {
|
|
if (this.responsiveOptions) {
|
|
this.defaultNumVisible = this.numVisible;
|
|
}
|
|
if (this.isCircular()) {
|
|
this.setCloneItems();
|
|
}
|
|
this.createStyle();
|
|
this.calculatePosition();
|
|
}
|
|
if (simpleChange.numScroll) {
|
|
if (this.responsiveOptions) {
|
|
this.defaultNumScroll = this.numScroll;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this.cd.markForCheck();
|
|
}
|
|
ngAfterContentInit() {
|
|
this.id = UniqueComponentId();
|
|
if (isPlatformBrowser(this.platformId)) {
|
|
this.allowAutoplay = !!this.autoplayInterval;
|
|
if (this.circular) {
|
|
this.setCloneItems();
|
|
}
|
|
if (this.responsiveOptions) {
|
|
this.defaultNumScroll = this._numScroll;
|
|
this.defaultNumVisible = this._numVisible;
|
|
}
|
|
this.createStyle();
|
|
this.calculatePosition();
|
|
if (this.responsiveOptions) {
|
|
this.bindDocumentListeners();
|
|
}
|
|
}
|
|
this.templates?.forEach((item) => {
|
|
switch (item.getType()) {
|
|
case 'item':
|
|
this.itemTemplate = item.template;
|
|
break;
|
|
case 'header':
|
|
this.headerTemplate = item.template;
|
|
break;
|
|
case 'footer':
|
|
this.footerTemplate = item.template;
|
|
break;
|
|
case 'previousicon':
|
|
this.previousIconTemplate = item.template;
|
|
break;
|
|
case 'nexticon':
|
|
this.nextIconTemplate = item.template;
|
|
break;
|
|
default:
|
|
this.itemTemplate = item.template;
|
|
break;
|
|
}
|
|
});
|
|
this.cd.detectChanges();
|
|
}
|
|
ngAfterContentChecked() {
|
|
if (isPlatformBrowser(this.platformId)) {
|
|
const isCircular = this.isCircular();
|
|
let totalShiftedItems = this.totalShiftedItems;
|
|
if (this.value && this.itemsContainer && (this.prevState.numScroll !== this._numScroll || this.prevState.numVisible !== this._numVisible || this.prevState.value.length !== this.value.length)) {
|
|
if (this.autoplayInterval) {
|
|
this.stopAutoplay(false);
|
|
}
|
|
this.remainingItems = (this.value.length - this._numVisible) % this._numScroll;
|
|
let page = this._page;
|
|
if (this.totalDots() !== 0 && page >= this.totalDots()) {
|
|
page = this.totalDots() - 1;
|
|
this._page = page;
|
|
this.onPage.emit({
|
|
page: this.page
|
|
});
|
|
}
|
|
totalShiftedItems = page * this._numScroll * -1;
|
|
if (isCircular) {
|
|
totalShiftedItems -= this._numVisible;
|
|
}
|
|
if (page === this.totalDots() - 1 && this.remainingItems > 0) {
|
|
totalShiftedItems += -1 * this.remainingItems + this._numScroll;
|
|
this.isRemainingItemsAdded = true;
|
|
}
|
|
else {
|
|
this.isRemainingItemsAdded = false;
|
|
}
|
|
if (totalShiftedItems !== this.totalShiftedItems) {
|
|
this.totalShiftedItems = totalShiftedItems;
|
|
}
|
|
this._oldNumScroll = this._numScroll;
|
|
this.prevState.numScroll = this._numScroll;
|
|
this.prevState.numVisible = this._numVisible;
|
|
this.prevState.value = [...this._value];
|
|
if (this.totalDots() > 0 && this.itemsContainer.nativeElement) {
|
|
this.itemsContainer.nativeElement.style.transform = this.isVertical() ? `translate3d(0, ${totalShiftedItems * (100 / this._numVisible)}%, 0)` : `translate3d(${totalShiftedItems * (100 / this._numVisible)}%, 0, 0)`;
|
|
}
|
|
this.isCreated = true;
|
|
if (this.autoplayInterval && this.isAutoplay()) {
|
|
this.startAutoplay();
|
|
}
|
|
}
|
|
if (isCircular) {
|
|
if (this.page === 0) {
|
|
totalShiftedItems = -1 * this._numVisible;
|
|
}
|
|
else if (totalShiftedItems === 0) {
|
|
totalShiftedItems = -1 * this.value.length;
|
|
if (this.remainingItems > 0) {
|
|
this.isRemainingItemsAdded = true;
|
|
}
|
|
}
|
|
if (totalShiftedItems !== this.totalShiftedItems) {
|
|
this.totalShiftedItems = totalShiftedItems;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
createStyle() {
|
|
if (!this.carouselStyle) {
|
|
this.carouselStyle = this.renderer.createElement('style');
|
|
this.carouselStyle.type = 'text/css';
|
|
this.renderer.appendChild(this.document.head, this.carouselStyle);
|
|
}
|
|
let innerHTML = `
|
|
#${this.id} .p-carousel-item {
|
|
flex: 1 0 ${100 / this.numVisible}%
|
|
}
|
|
`;
|
|
if (this.responsiveOptions) {
|
|
this.responsiveOptions.sort((data1, data2) => {
|
|
const value1 = data1.breakpoint;
|
|
const value2 = data2.breakpoint;
|
|
let result = null;
|
|
if (value1 == null && value2 != null)
|
|
result = -1;
|
|
else if (value1 != null && value2 == null)
|
|
result = 1;
|
|
else if (value1 == null && value2 == null)
|
|
result = 0;
|
|
else if (typeof value1 === 'string' && typeof value2 === 'string')
|
|
result = value1.localeCompare(value2, undefined, { numeric: true });
|
|
else
|
|
result = value1 < value2 ? -1 : value1 > value2 ? 1 : 0;
|
|
return -1 * result;
|
|
});
|
|
for (let i = 0; i < this.responsiveOptions.length; i++) {
|
|
let res = this.responsiveOptions[i];
|
|
innerHTML += `
|
|
@media screen and (max-width: ${res.breakpoint}) {
|
|
#${this.id} .p-carousel-item {
|
|
flex: 1 0 ${100 / res.numVisible}%
|
|
}
|
|
}
|
|
`;
|
|
}
|
|
}
|
|
this.carouselStyle.innerHTML = innerHTML;
|
|
}
|
|
calculatePosition() {
|
|
if (this.responsiveOptions) {
|
|
let matchedResponsiveData = {
|
|
numVisible: this.defaultNumVisible,
|
|
numScroll: this.defaultNumScroll
|
|
};
|
|
if (typeof window !== 'undefined') {
|
|
let windowWidth = window.innerWidth;
|
|
for (let i = 0; i < this.responsiveOptions.length; i++) {
|
|
let res = this.responsiveOptions[i];
|
|
if (parseInt(res.breakpoint, 10) >= windowWidth) {
|
|
matchedResponsiveData = res;
|
|
}
|
|
}
|
|
}
|
|
if (this._numScroll !== matchedResponsiveData.numScroll) {
|
|
let page = this._page;
|
|
page = Math.floor((page * this._numScroll) / matchedResponsiveData.numScroll);
|
|
let totalShiftedItems = matchedResponsiveData.numScroll * this.page * -1;
|
|
if (this.isCircular()) {
|
|
totalShiftedItems -= matchedResponsiveData.numVisible;
|
|
}
|
|
this.totalShiftedItems = totalShiftedItems;
|
|
this._numScroll = matchedResponsiveData.numScroll;
|
|
this._page = page;
|
|
this.onPage.emit({
|
|
page: this.page
|
|
});
|
|
}
|
|
if (this._numVisible !== matchedResponsiveData.numVisible) {
|
|
this._numVisible = matchedResponsiveData.numVisible;
|
|
this.setCloneItems();
|
|
}
|
|
this.cd.markForCheck();
|
|
}
|
|
}
|
|
setCloneItems() {
|
|
this.clonedItemsForStarting = [];
|
|
this.clonedItemsForFinishing = [];
|
|
if (this.isCircular()) {
|
|
this.clonedItemsForStarting.push(...this.value.slice(-1 * this._numVisible));
|
|
this.clonedItemsForFinishing.push(...this.value.slice(0, this._numVisible));
|
|
}
|
|
}
|
|
firstIndex() {
|
|
return this.isCircular() ? -1 * (this.totalShiftedItems + this.numVisible) : this.totalShiftedItems * -1;
|
|
}
|
|
lastIndex() {
|
|
return this.firstIndex() + this.numVisible - 1;
|
|
}
|
|
totalDots() {
|
|
return this.value?.length ? Math.ceil((this.value.length - this._numVisible) / this._numScroll) + 1 : 0;
|
|
}
|
|
totalDotsArray() {
|
|
const totalDots = this.totalDots();
|
|
return totalDots <= 0 ? [] : Array(totalDots).fill(0);
|
|
}
|
|
isVertical() {
|
|
return this.orientation === 'vertical';
|
|
}
|
|
isCircular() {
|
|
return this.circular && this.value && this.value.length >= this.numVisible;
|
|
}
|
|
isAutoplay() {
|
|
return this.autoplayInterval && this.allowAutoplay;
|
|
}
|
|
isForwardNavDisabled() {
|
|
return this.isEmpty() || (this._page >= this.totalDots() - 1 && !this.isCircular());
|
|
}
|
|
isBackwardNavDisabled() {
|
|
return this.isEmpty() || (this._page <= 0 && !this.isCircular());
|
|
}
|
|
isEmpty() {
|
|
return !this.value || this.value.length === 0;
|
|
}
|
|
navForward(e, index) {
|
|
if (this.isCircular() || this._page < this.totalDots() - 1) {
|
|
this.step(-1, index);
|
|
}
|
|
if (this.autoplayInterval) {
|
|
this.stopAutoplay();
|
|
}
|
|
if (e && e.cancelable) {
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
navBackward(e, index) {
|
|
if (this.isCircular() || this._page !== 0) {
|
|
this.step(1, index);
|
|
}
|
|
if (this.autoplayInterval) {
|
|
this.stopAutoplay();
|
|
}
|
|
if (e && e.cancelable) {
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
onDotClick(e, index) {
|
|
let page = this._page;
|
|
if (this.autoplayInterval) {
|
|
this.stopAutoplay();
|
|
}
|
|
if (index > page) {
|
|
this.navForward(e, index);
|
|
}
|
|
else if (index < page) {
|
|
this.navBackward(e, index);
|
|
}
|
|
}
|
|
onIndicatorKeydown(event) {
|
|
switch (event.code) {
|
|
case 'ArrowRight':
|
|
this.onRightKey();
|
|
break;
|
|
case 'ArrowLeft':
|
|
this.onLeftKey();
|
|
break;
|
|
}
|
|
}
|
|
onRightKey() {
|
|
const indicators = [...DomHandler.find(this.indicatorContent.nativeElement, '[data-pc-section="indicator"]')];
|
|
const activeIndex = this.findFocusedIndicatorIndex();
|
|
this.changedFocusedIndicator(activeIndex, activeIndex + 1 === indicators.length ? indicators.length - 1 : activeIndex + 1);
|
|
}
|
|
onLeftKey() {
|
|
const activeIndex = this.findFocusedIndicatorIndex();
|
|
this.changedFocusedIndicator(activeIndex, activeIndex - 1 <= 0 ? 0 : activeIndex - 1);
|
|
}
|
|
onHomeKey() {
|
|
const activeIndex = this.findFocusedIndicatorIndex();
|
|
this.changedFocusedIndicator(activeIndex, 0);
|
|
}
|
|
onEndKey() {
|
|
const indicators = [...DomHandler.find(this.indicatorContent.nativeElement, '[data-pc-section="indicator"]r')];
|
|
const activeIndex = this.findFocusedIndicatorIndex();
|
|
this.changedFocusedIndicator(activeIndex, indicators.length - 1);
|
|
}
|
|
onTabKey() {
|
|
const indicators = [...DomHandler.find(this.indicatorContent.nativeElement, '[data-pc-section="indicator"]')];
|
|
const highlightedIndex = indicators.findIndex((ind) => DomHandler.getAttribute(ind, 'data-p-highlight') === true);
|
|
const activeIndicator = DomHandler.findSingle(this.indicatorContent.nativeElement, '[data-pc-section="indicator"] > button[tabindex="0"]');
|
|
const activeIndex = indicators.findIndex((ind) => ind === activeIndicator.parentElement);
|
|
indicators[activeIndex].children[0].tabIndex = '-1';
|
|
indicators[highlightedIndex].children[0].tabIndex = '0';
|
|
}
|
|
findFocusedIndicatorIndex() {
|
|
const indicators = [...DomHandler.find(this.indicatorContent.nativeElement, '[data-pc-section="indicator"]')];
|
|
const activeIndicator = DomHandler.findSingle(this.indicatorContent.nativeElement, '[data-pc-section="indicator"] > button[tabindex="0"]');
|
|
return indicators.findIndex((ind) => ind === activeIndicator.parentElement);
|
|
}
|
|
changedFocusedIndicator(prevInd, nextInd) {
|
|
const indicators = [...DomHandler.find(this.indicatorContent.nativeElement, '[data-pc-section="indicator"]')];
|
|
indicators[prevInd].children[0].tabIndex = '-1';
|
|
indicators[nextInd].children[0].tabIndex = '0';
|
|
indicators[nextInd].children[0].focus();
|
|
}
|
|
step(dir, page) {
|
|
let totalShiftedItems = this.totalShiftedItems;
|
|
const isCircular = this.isCircular();
|
|
if (page != null) {
|
|
totalShiftedItems = this._numScroll * page * -1;
|
|
if (isCircular) {
|
|
totalShiftedItems -= this._numVisible;
|
|
}
|
|
this.isRemainingItemsAdded = false;
|
|
}
|
|
else {
|
|
totalShiftedItems += this._numScroll * dir;
|
|
if (this.isRemainingItemsAdded) {
|
|
totalShiftedItems += this.remainingItems - this._numScroll * dir;
|
|
this.isRemainingItemsAdded = false;
|
|
}
|
|
let originalShiftedItems = isCircular ? totalShiftedItems + this._numVisible : totalShiftedItems;
|
|
page = Math.abs(Math.floor(originalShiftedItems / this._numScroll));
|
|
}
|
|
if (isCircular && this.page === this.totalDots() - 1 && dir === -1) {
|
|
totalShiftedItems = -1 * (this.value.length + this._numVisible);
|
|
page = 0;
|
|
}
|
|
else if (isCircular && this.page === 0 && dir === 1) {
|
|
totalShiftedItems = 0;
|
|
page = this.totalDots() - 1;
|
|
}
|
|
else if (page === this.totalDots() - 1 && this.remainingItems > 0) {
|
|
totalShiftedItems += this.remainingItems * -1 - this._numScroll * dir;
|
|
this.isRemainingItemsAdded = true;
|
|
}
|
|
if (this.itemsContainer) {
|
|
this.itemsContainer.nativeElement.style.transform = this.isVertical() ? `translate3d(0, ${totalShiftedItems * (100 / this._numVisible)}%, 0)` : `translate3d(${totalShiftedItems * (100 / this._numVisible)}%, 0, 0)`;
|
|
this.itemsContainer.nativeElement.style.transition = 'transform 500ms ease 0s';
|
|
}
|
|
this.totalShiftedItems = totalShiftedItems;
|
|
this._page = page;
|
|
this.onPage.emit({
|
|
page: this.page
|
|
});
|
|
this.cd.markForCheck();
|
|
}
|
|
startAutoplay() {
|
|
this.interval = setInterval(() => {
|
|
if (this.totalDots() > 0) {
|
|
if (this.page === this.totalDots() - 1) {
|
|
this.step(-1, 0);
|
|
}
|
|
else {
|
|
this.step(-1, this.page + 1);
|
|
}
|
|
}
|
|
}, this.autoplayInterval);
|
|
this.allowAutoplay = true;
|
|
this.cd.markForCheck();
|
|
}
|
|
stopAutoplay(changeAllow = true) {
|
|
if (this.interval) {
|
|
clearInterval(this.interval);
|
|
this.interval = undefined;
|
|
if (changeAllow) {
|
|
this.allowAutoplay = false;
|
|
}
|
|
}
|
|
this.cd.markForCheck();
|
|
}
|
|
isPlaying() {
|
|
return !!this.interval;
|
|
}
|
|
onTransitionEnd() {
|
|
if (this.itemsContainer) {
|
|
this.itemsContainer.nativeElement.style.transition = '';
|
|
if ((this.page === 0 || this.page === this.totalDots() - 1) && this.isCircular()) {
|
|
this.itemsContainer.nativeElement.style.transform = this.isVertical() ? `translate3d(0, ${this.totalShiftedItems * (100 / this._numVisible)}%, 0)` : `translate3d(${this.totalShiftedItems * (100 / this._numVisible)}%, 0, 0)`;
|
|
}
|
|
}
|
|
}
|
|
onTouchStart(e) {
|
|
let touchobj = e.changedTouches[0];
|
|
this.startPos = {
|
|
x: touchobj.pageX,
|
|
y: touchobj.pageY
|
|
};
|
|
}
|
|
onTouchMove(e) {
|
|
if (e.cancelable) {
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
onTouchEnd(e) {
|
|
let touchobj = e.changedTouches[0];
|
|
if (this.isVertical()) {
|
|
this.changePageOnTouch(e, touchobj.pageY - this.startPos.y);
|
|
}
|
|
else {
|
|
this.changePageOnTouch(e, touchobj.pageX - this.startPos.x);
|
|
}
|
|
}
|
|
changePageOnTouch(e, diff) {
|
|
if (Math.abs(diff) > this.swipeThreshold) {
|
|
if (diff < 0) {
|
|
this.navForward(e);
|
|
}
|
|
else {
|
|
this.navBackward(e);
|
|
}
|
|
}
|
|
}
|
|
ariaPrevButtonLabel() {
|
|
return this.config.translation.aria ? this.config.translation.aria.prevPageLabel : undefined;
|
|
}
|
|
ariaSlideLabel() {
|
|
return this.config.translation.aria ? this.config.translation.aria.slide : undefined;
|
|
}
|
|
ariaNextButtonLabel() {
|
|
return this.config.translation.aria ? this.config.translation.aria.nextPageLabel : undefined;
|
|
}
|
|
ariaSlideNumber(value) {
|
|
return this.config.translation.aria ? this.config.translation.aria.slideNumber.replace(/{slideNumber}/g, value) : undefined;
|
|
}
|
|
ariaPageLabel(value) {
|
|
return this.config.translation.aria ? this.config.translation.aria.pageLabel.replace(/{page}/g, value) : undefined;
|
|
}
|
|
bindDocumentListeners() {
|
|
if (isPlatformBrowser(this.platformId)) {
|
|
if (!this.documentResizeListener) {
|
|
this.documentResizeListener = this.renderer.listen(this.window, 'resize', (event) => {
|
|
this.calculatePosition();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
unbindDocumentListeners() {
|
|
if (isPlatformBrowser(this.platformId)) {
|
|
if (this.documentResizeListener) {
|
|
this.documentResizeListener();
|
|
this.documentResizeListener = null;
|
|
}
|
|
}
|
|
}
|
|
ngOnDestroy() {
|
|
if (this.responsiveOptions) {
|
|
this.unbindDocumentListeners();
|
|
}
|
|
if (this.autoplayInterval) {
|
|
this.stopAutoplay();
|
|
}
|
|
}
|
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: Carousel, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i0.Renderer2 }, { token: DOCUMENT }, { token: PLATFORM_ID }, { token: i1.PrimeNGConfig }], target: i0.ɵɵFactoryTarget.Component });
|
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "17.3.7", type: Carousel, selector: "p-carousel", inputs: { page: "page", numVisible: "numVisible", numScroll: "numScroll", responsiveOptions: "responsiveOptions", orientation: "orientation", verticalViewPortHeight: "verticalViewPortHeight", contentClass: "contentClass", indicatorsContentClass: "indicatorsContentClass", indicatorsContentStyle: "indicatorsContentStyle", indicatorStyleClass: "indicatorStyleClass", indicatorStyle: "indicatorStyle", value: "value", circular: ["circular", "circular", booleanAttribute], showIndicators: ["showIndicators", "showIndicators", booleanAttribute], showNavigators: ["showNavigators", "showNavigators", booleanAttribute], autoplayInterval: ["autoplayInterval", "autoplayInterval", numberAttribute], style: "style", styleClass: "styleClass" }, outputs: { onPage: "onPage" }, host: { classAttribute: "p-element" }, queries: [{ propertyName: "headerFacet", first: true, predicate: Header, descendants: true }, { propertyName: "footerFacet", first: true, predicate: Footer, descendants: true }, { propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "itemsContainer", first: true, predicate: ["itemsContainer"], descendants: true }, { propertyName: "indicatorContent", first: true, predicate: ["indicatorContent"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
|
|
<div [attr.id]="id" [ngClass]="{ 'p-carousel p-component': true, 'p-carousel-vertical': isVertical(), 'p-carousel-horizontal': !isVertical() }" [ngStyle]="style" [class]="styleClass" role="region">
|
|
<div class="p-carousel-header" *ngIf="headerFacet || headerTemplate">
|
|
<ng-content select="p-header"></ng-content>
|
|
<ng-container *ngTemplateOutlet="headerTemplate"></ng-container>
|
|
</div>
|
|
<div [class]="contentClass" [ngClass]="'p-carousel-content'">
|
|
<div class="p-carousel-container" [attr.aria-live]="allowAutoplay ? 'polite' : 'off'">
|
|
<button
|
|
type="button"
|
|
*ngIf="showNavigators"
|
|
[ngClass]="{ 'p-carousel-prev p-link': true, 'p-disabled': isBackwardNavDisabled() }"
|
|
[disabled]="isBackwardNavDisabled()"
|
|
[attr.aria-label]="ariaPrevButtonLabel()"
|
|
(click)="navBackward($event)"
|
|
pRipple
|
|
>
|
|
<ng-container *ngIf="!previousIconTemplate">
|
|
<ChevronLeftIcon *ngIf="!isVertical()" [styleClass]="'carousel-prev-icon'" />
|
|
<ChevronUpIcon *ngIf="isVertical()" [styleClass]="'carousel-prev-icon'" />
|
|
</ng-container>
|
|
<span *ngIf="previousIconTemplate" class="p-carousel-prev-icon">
|
|
<ng-template *ngTemplateOutlet="previousIconTemplate"></ng-template>
|
|
</span>
|
|
</button>
|
|
<div class="p-carousel-items-content" [ngStyle]="{ height: isVertical() ? verticalViewPortHeight : 'auto' }" (touchend)="onTouchEnd($event)" (touchstart)="onTouchStart($event)" (touchmove)="onTouchMove($event)">
|
|
<div #itemsContainer class="p-carousel-items-container" (transitionend)="onTransitionEnd()">
|
|
<div
|
|
*ngFor="let item of clonedItemsForStarting; let index = index"
|
|
[ngClass]="{
|
|
'p-carousel-item p-carousel-item-cloned': true,
|
|
'p-carousel-item-active': totalShiftedItems * -1 === value.length,
|
|
'p-carousel-item-start': 0 === index,
|
|
'p-carousel-item-end': clonedItemsForStarting.length - 1 === index
|
|
}"
|
|
[attr.aria-hidden]="!(totalShiftedItems * -1 === value.length)"
|
|
[attr.aria-label]="ariaSlideNumber(index)"
|
|
[attr.aria-roledescription]="ariaSlideLabel()"
|
|
>
|
|
<ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item }"></ng-container>
|
|
</div>
|
|
<div
|
|
*ngFor="let item of value; let index = index"
|
|
[ngClass]="{ 'p-carousel-item': true, 'p-carousel-item-active': firstIndex() <= index && lastIndex() >= index, 'p-carousel-item-start': firstIndex() === index, 'p-carousel-item-end': lastIndex() === index }"
|
|
[attr.aria-hidden]="!(totalShiftedItems * -1 === value.length)"
|
|
[attr.aria-label]="ariaSlideNumber(index)"
|
|
[attr.aria-roledescription]="ariaSlideLabel()"
|
|
>
|
|
<ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item }"></ng-container>
|
|
</div>
|
|
<div
|
|
*ngFor="let item of clonedItemsForFinishing; let index = index"
|
|
[ngClass]="{
|
|
'p-carousel-item p-carousel-item-cloned': true,
|
|
'p-carousel-item-active': totalShiftedItems * -1 === numVisible,
|
|
'p-carousel-item-start': 0 === index,
|
|
'p-carousel-item-end': clonedItemsForFinishing.length - 1 === index
|
|
}"
|
|
>
|
|
<ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item }"></ng-container>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
*ngIf="showNavigators"
|
|
[ngClass]="{ 'p-carousel-next p-link': true, 'p-disabled': isForwardNavDisabled() }"
|
|
[disabled]="isForwardNavDisabled()"
|
|
(click)="navForward($event)"
|
|
pRipple
|
|
[attr.aria-label]="ariaNextButtonLabel()"
|
|
>
|
|
<ng-container *ngIf="!nextIconTemplate">
|
|
<ChevronRightIcon *ngIf="!isVertical()" [styleClass]="'carousel-prev-icon'" />
|
|
<ChevronDownIcon *ngIf="isVertical()" [styleClass]="'carousel-prev-icon'" />
|
|
</ng-container>
|
|
<span *ngIf="nextIconTemplate" class="p-carousel-prev-icon">
|
|
<ng-template *ngTemplateOutlet="nextIconTemplate"></ng-template>
|
|
</span>
|
|
</button>
|
|
</div>
|
|
<ul #indicatorContent [ngClass]="'p-carousel-indicators p-reset'" [class]="indicatorsContentClass" [ngStyle]="indicatorsContentStyle" *ngIf="showIndicators" (keydown)="onIndicatorKeydown($event)">
|
|
<li *ngFor="let totalDot of totalDotsArray(); let i = index" [ngClass]="{ 'p-carousel-indicator': true, 'p-highlight': _page === i }" [attr.data-pc-section]="'indicator'">
|
|
<button
|
|
type="button"
|
|
[ngClass]="'p-link'"
|
|
(click)="onDotClick($event, i)"
|
|
[class]="indicatorStyleClass"
|
|
[ngStyle]="indicatorStyle"
|
|
[attr.aria-label]="ariaPageLabel(i + 1)"
|
|
[attr.aria-current]="_page === i ? 'page' : undefined"
|
|
[tabindex]="_page === i ? 0 : -1"
|
|
></button>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="p-carousel-footer" *ngIf="footerFacet || footerTemplate">
|
|
<ng-content select="p-footer"></ng-content>
|
|
<ng-container *ngTemplateOutlet="footerTemplate"></ng-container>
|
|
</div>
|
|
</div>
|
|
`, isInline: true, styles: ["@layer primeng{.p-carousel{display:flex;flex-direction:column}.p-carousel-content{display:flex;flex-direction:column;overflow:auto}.p-carousel-prev,.p-carousel-next{align-self:center;flex-grow:0;flex-shrink:0;display:flex;justify-content:center;align-items:center;overflow:hidden;position:relative}.p-carousel-container{display:flex;flex-direction:row}.p-carousel-items-content{overflow:hidden;width:100%}.p-carousel-items-container{display:flex;flex-direction:row}.p-carousel-indicators{display:flex;flex-direction:row;justify-content:center;flex-wrap:wrap}.p-carousel-indicator>button{display:flex;align-items:center;justify-content:center}.p-carousel-vertical .p-carousel-container{flex-direction:column}.p-carousel-vertical .p-carousel-items-container{flex-direction:column;height:100%}.p-items-hidden .p-carousel-item{visibility:hidden}.p-items-hidden .p-carousel-item.p-carousel-item-active{visibility:visible}}\n"], dependencies: [{ kind: "directive", type: i0.forwardRef(() => i2.NgClass), selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i0.forwardRef(() => i2.NgForOf), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i0.forwardRef(() => i2.NgIf), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i0.forwardRef(() => i2.NgTemplateOutlet), selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i0.forwardRef(() => i2.NgStyle), selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i0.forwardRef(() => i3.Ripple), selector: "[pRipple]" }, { kind: "component", type: i0.forwardRef(() => ChevronRightIcon), selector: "ChevronRightIcon" }, { kind: "component", type: i0.forwardRef(() => ChevronLeftIcon), selector: "ChevronLeftIcon" }, { kind: "component", type: i0.forwardRef(() => ChevronDownIcon), selector: "ChevronDownIcon" }, { kind: "component", type: i0.forwardRef(() => ChevronUpIcon), selector: "ChevronUpIcon" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
}
|
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: Carousel, decorators: [{
|
|
type: Component,
|
|
args: [{ selector: 'p-carousel', template: `
|
|
<div [attr.id]="id" [ngClass]="{ 'p-carousel p-component': true, 'p-carousel-vertical': isVertical(), 'p-carousel-horizontal': !isVertical() }" [ngStyle]="style" [class]="styleClass" role="region">
|
|
<div class="p-carousel-header" *ngIf="headerFacet || headerTemplate">
|
|
<ng-content select="p-header"></ng-content>
|
|
<ng-container *ngTemplateOutlet="headerTemplate"></ng-container>
|
|
</div>
|
|
<div [class]="contentClass" [ngClass]="'p-carousel-content'">
|
|
<div class="p-carousel-container" [attr.aria-live]="allowAutoplay ? 'polite' : 'off'">
|
|
<button
|
|
type="button"
|
|
*ngIf="showNavigators"
|
|
[ngClass]="{ 'p-carousel-prev p-link': true, 'p-disabled': isBackwardNavDisabled() }"
|
|
[disabled]="isBackwardNavDisabled()"
|
|
[attr.aria-label]="ariaPrevButtonLabel()"
|
|
(click)="navBackward($event)"
|
|
pRipple
|
|
>
|
|
<ng-container *ngIf="!previousIconTemplate">
|
|
<ChevronLeftIcon *ngIf="!isVertical()" [styleClass]="'carousel-prev-icon'" />
|
|
<ChevronUpIcon *ngIf="isVertical()" [styleClass]="'carousel-prev-icon'" />
|
|
</ng-container>
|
|
<span *ngIf="previousIconTemplate" class="p-carousel-prev-icon">
|
|
<ng-template *ngTemplateOutlet="previousIconTemplate"></ng-template>
|
|
</span>
|
|
</button>
|
|
<div class="p-carousel-items-content" [ngStyle]="{ height: isVertical() ? verticalViewPortHeight : 'auto' }" (touchend)="onTouchEnd($event)" (touchstart)="onTouchStart($event)" (touchmove)="onTouchMove($event)">
|
|
<div #itemsContainer class="p-carousel-items-container" (transitionend)="onTransitionEnd()">
|
|
<div
|
|
*ngFor="let item of clonedItemsForStarting; let index = index"
|
|
[ngClass]="{
|
|
'p-carousel-item p-carousel-item-cloned': true,
|
|
'p-carousel-item-active': totalShiftedItems * -1 === value.length,
|
|
'p-carousel-item-start': 0 === index,
|
|
'p-carousel-item-end': clonedItemsForStarting.length - 1 === index
|
|
}"
|
|
[attr.aria-hidden]="!(totalShiftedItems * -1 === value.length)"
|
|
[attr.aria-label]="ariaSlideNumber(index)"
|
|
[attr.aria-roledescription]="ariaSlideLabel()"
|
|
>
|
|
<ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item }"></ng-container>
|
|
</div>
|
|
<div
|
|
*ngFor="let item of value; let index = index"
|
|
[ngClass]="{ 'p-carousel-item': true, 'p-carousel-item-active': firstIndex() <= index && lastIndex() >= index, 'p-carousel-item-start': firstIndex() === index, 'p-carousel-item-end': lastIndex() === index }"
|
|
[attr.aria-hidden]="!(totalShiftedItems * -1 === value.length)"
|
|
[attr.aria-label]="ariaSlideNumber(index)"
|
|
[attr.aria-roledescription]="ariaSlideLabel()"
|
|
>
|
|
<ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item }"></ng-container>
|
|
</div>
|
|
<div
|
|
*ngFor="let item of clonedItemsForFinishing; let index = index"
|
|
[ngClass]="{
|
|
'p-carousel-item p-carousel-item-cloned': true,
|
|
'p-carousel-item-active': totalShiftedItems * -1 === numVisible,
|
|
'p-carousel-item-start': 0 === index,
|
|
'p-carousel-item-end': clonedItemsForFinishing.length - 1 === index
|
|
}"
|
|
>
|
|
<ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item }"></ng-container>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
*ngIf="showNavigators"
|
|
[ngClass]="{ 'p-carousel-next p-link': true, 'p-disabled': isForwardNavDisabled() }"
|
|
[disabled]="isForwardNavDisabled()"
|
|
(click)="navForward($event)"
|
|
pRipple
|
|
[attr.aria-label]="ariaNextButtonLabel()"
|
|
>
|
|
<ng-container *ngIf="!nextIconTemplate">
|
|
<ChevronRightIcon *ngIf="!isVertical()" [styleClass]="'carousel-prev-icon'" />
|
|
<ChevronDownIcon *ngIf="isVertical()" [styleClass]="'carousel-prev-icon'" />
|
|
</ng-container>
|
|
<span *ngIf="nextIconTemplate" class="p-carousel-prev-icon">
|
|
<ng-template *ngTemplateOutlet="nextIconTemplate"></ng-template>
|
|
</span>
|
|
</button>
|
|
</div>
|
|
<ul #indicatorContent [ngClass]="'p-carousel-indicators p-reset'" [class]="indicatorsContentClass" [ngStyle]="indicatorsContentStyle" *ngIf="showIndicators" (keydown)="onIndicatorKeydown($event)">
|
|
<li *ngFor="let totalDot of totalDotsArray(); let i = index" [ngClass]="{ 'p-carousel-indicator': true, 'p-highlight': _page === i }" [attr.data-pc-section]="'indicator'">
|
|
<button
|
|
type="button"
|
|
[ngClass]="'p-link'"
|
|
(click)="onDotClick($event, i)"
|
|
[class]="indicatorStyleClass"
|
|
[ngStyle]="indicatorStyle"
|
|
[attr.aria-label]="ariaPageLabel(i + 1)"
|
|
[attr.aria-current]="_page === i ? 'page' : undefined"
|
|
[tabindex]="_page === i ? 0 : -1"
|
|
></button>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="p-carousel-footer" *ngIf="footerFacet || footerTemplate">
|
|
<ng-content select="p-footer"></ng-content>
|
|
<ng-container *ngTemplateOutlet="footerTemplate"></ng-container>
|
|
</div>
|
|
</div>
|
|
`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
class: 'p-element'
|
|
}, styles: ["@layer primeng{.p-carousel{display:flex;flex-direction:column}.p-carousel-content{display:flex;flex-direction:column;overflow:auto}.p-carousel-prev,.p-carousel-next{align-self:center;flex-grow:0;flex-shrink:0;display:flex;justify-content:center;align-items:center;overflow:hidden;position:relative}.p-carousel-container{display:flex;flex-direction:row}.p-carousel-items-content{overflow:hidden;width:100%}.p-carousel-items-container{display:flex;flex-direction:row}.p-carousel-indicators{display:flex;flex-direction:row;justify-content:center;flex-wrap:wrap}.p-carousel-indicator>button{display:flex;align-items:center;justify-content:center}.p-carousel-vertical .p-carousel-container{flex-direction:column}.p-carousel-vertical .p-carousel-items-container{flex-direction:column;height:100%}.p-items-hidden .p-carousel-item{visibility:hidden}.p-items-hidden .p-carousel-item.p-carousel-item-active{visibility:visible}}\n"] }]
|
|
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i0.Renderer2 }, { type: Document, decorators: [{
|
|
type: Inject,
|
|
args: [DOCUMENT]
|
|
}] }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [PLATFORM_ID]
|
|
}] }, { type: i1.PrimeNGConfig }], propDecorators: { page: [{
|
|
type: Input
|
|
}], numVisible: [{
|
|
type: Input
|
|
}], numScroll: [{
|
|
type: Input
|
|
}], responsiveOptions: [{
|
|
type: Input
|
|
}], orientation: [{
|
|
type: Input
|
|
}], verticalViewPortHeight: [{
|
|
type: Input
|
|
}], contentClass: [{
|
|
type: Input
|
|
}], indicatorsContentClass: [{
|
|
type: Input
|
|
}], indicatorsContentStyle: [{
|
|
type: Input
|
|
}], indicatorStyleClass: [{
|
|
type: Input
|
|
}], indicatorStyle: [{
|
|
type: Input
|
|
}], value: [{
|
|
type: Input
|
|
}], circular: [{
|
|
type: Input,
|
|
args: [{ transform: booleanAttribute }]
|
|
}], showIndicators: [{
|
|
type: Input,
|
|
args: [{ transform: booleanAttribute }]
|
|
}], showNavigators: [{
|
|
type: Input,
|
|
args: [{ transform: booleanAttribute }]
|
|
}], autoplayInterval: [{
|
|
type: Input,
|
|
args: [{ transform: numberAttribute }]
|
|
}], style: [{
|
|
type: Input
|
|
}], styleClass: [{
|
|
type: Input
|
|
}], onPage: [{
|
|
type: Output
|
|
}], itemsContainer: [{
|
|
type: ViewChild,
|
|
args: ['itemsContainer']
|
|
}], indicatorContent: [{
|
|
type: ViewChild,
|
|
args: ['indicatorContent']
|
|
}], headerFacet: [{
|
|
type: ContentChild,
|
|
args: [Header]
|
|
}], footerFacet: [{
|
|
type: ContentChild,
|
|
args: [Footer]
|
|
}], templates: [{
|
|
type: ContentChildren,
|
|
args: [PrimeTemplate]
|
|
}] } });
|
|
export class CarouselModule {
|
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: CarouselModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.7", ngImport: i0, type: CarouselModule, declarations: [Carousel], imports: [CommonModule, SharedModule, RippleModule, ChevronRightIcon, ChevronLeftIcon, ChevronDownIcon, ChevronUpIcon], exports: [CommonModule, Carousel, SharedModule] });
|
|
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: CarouselModule, imports: [CommonModule, SharedModule, RippleModule, ChevronRightIcon, ChevronLeftIcon, ChevronDownIcon, ChevronUpIcon, CommonModule, SharedModule] });
|
|
}
|
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.7", ngImport: i0, type: CarouselModule, decorators: [{
|
|
type: NgModule,
|
|
args: [{
|
|
imports: [CommonModule, SharedModule, RippleModule, ChevronRightIcon, ChevronLeftIcon, ChevronDownIcon, ChevronUpIcon],
|
|
exports: [CommonModule, Carousel, SharedModule],
|
|
declarations: [Carousel]
|
|
}]
|
|
}] });
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwL2NvbXBvbmVudHMvY2Fyb3VzZWwvY2Fyb3VzZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RSxPQUFPLEVBRUgsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osZUFBZSxFQUVmLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLFFBQVEsRUFFUixNQUFNLEVBQ04sV0FBVyxFQUtYLFNBQVMsRUFDVCxpQkFBaUIsRUFDakIsZ0JBQWdCLEVBQ2hCLGVBQWUsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzVELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR2xELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUM7Ozs7O0FBQ3pDOzs7R0FHRztBQWdISCxNQUFNLE9BQU8sUUFBUTtJQWlORTtJQUF1QjtJQUFxQjtJQUErQjtJQUErQztJQUFpRDtJQUF5QjtJQWhOdk47Ozs7T0FJRztJQUNILElBQWEsSUFBSTtRQUNiLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUN0QixD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LGFBQWEsRUFDM0csWUFBWSxFQUFZLFlBQVk7OzJGQUdyQyxjQUFjO2tCQUwxQixRQUFRO21CQUFDO29CQUNOLE9BQU8sRUFBRSxDQUFDLFlBQVksRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLGVBQWUsRUFBRSxlQUFlLEVBQUUsYUFBYSxDQUFDO29CQUN0SCxPQUFPLEVBQUUsQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLFlBQVksQ0FBQztvQkFDL0MsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDO2lCQUMzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSwgRE9DVU1FTlQsIGlzUGxhdGZvcm1Ccm93c2VyIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgQ29udGVudENoaWxkLFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBJbmplY3QsXG4gICAgSW5wdXQsXG4gICAgTmdNb2R1bGUsXG4gICAgTmdab25lLFxuICAgIE91dHB1dCxcbiAgICBQTEFURk9STV9JRCxcbiAgICBRdWVyeUxpc3QsXG4gICAgUmVuZGVyZXIyLFxuICAgIFNpbXBsZUNoYW5nZXMsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVmlld0NoaWxkLFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uLFxuICAgIGJvb2xlYW5BdHRyaWJ1dGUsXG4gICAgbnVtYmVyQXR0cmlidXRlXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9vdGVyLCBIZWFkZXIsIFByaW1lVGVtcGxhdGUsIFNoYXJlZE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IENoZXZyb25Eb3duSWNvbiB9IGZyb20gJ3ByaW1lbmcvaWNvbnMvY2hldnJvbmRvd24nO1xuaW1wb3J0IHsgQ2hldnJvbkxlZnRJY29uIH0gZnJvbSAncHJpbWVuZy9pY29ucy9jaGV2cm9ubGVmdCc7XG5pbXBvcnQgeyBDaGV2cm9uUmlnaHRJY29uIH0gZnJvbSAncHJpbWVuZy9pY29ucy9jaGV2cm9ucmlnaHQnO1xuaW1wb3J0IHsgQ2hldnJvblVwSWNvbiB9IGZyb20gJ3ByaW1lbmcvaWNvbnMvY2hldnJvbnVwJztcbmltcG9ydCB7IFJpcHBsZU1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvcmlwcGxlJztcbmltcG9ydCB7IFVuaXF1ZUNvbXBvbmVudElkIH0gZnJvbSAncHJpbWVuZy91dGlscyc7XG5pbXBvcnQgeyBDYXJvdXNlbFBhZ2VFdmVudCwgQ2Fyb3VzZWxSZXNwb25zaXZlT3B0aW9ucyB9IGZyb20gJy4vY2Fyb3VzZWwuaW50ZXJmYWNlJztcbmltcG9ydCB7IFByaW1lTkdDb25maWcgfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQgeyBEb21IYW5kbGVyIH0gZnJvbSAncHJpbWVuZy9kb20nO1xuLyoqXG4gKiBDYXJvdXNlbCBpcyBhIGNvbnRlbnQgc2xpZGVyIGZlYXR1cmluZyB2YXJpb3VzIGN1c3RvbWl6YXRpb24gb3B0aW9ucy5cbiAqIEBncm91cCBDb21wb25lbnRzXG4gKi9cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAncC1jYXJvdXNlbCcsXG4gICAgdGVtcGxhdGU6IGBcbiAgICAgICAgPGRpdiBbYXR0ci5pZF09XCJpZFwiIFtuZ0NsYXNzXT1cInsgJ3AtY2Fyb3VzZWwgcC1jb21wb25lbnQnOiB0cnVlLCAncC1jYXJvdXNlbC12ZXJ0aWNhbCc6IGlzVmVydGljYWwoKSwgJ3AtY2Fyb3VzZWwtaG9yaXpvbnRhbCc6ICFpc1ZlcnRpY2FsKCkgfVwiIFtuZ1N0eWxlXT1cInN0eWxlXCIgW2NsYXNzXT1cInN0eWxlQ2xhc3NcIiByb2xlPVwicmVnaW9uXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jYXJvdXNlbC1oZWFkZXJcIiAqbmdJZj1cImhlYWRlckZhY2V0IHx8IGhlYWRlclRlbXBsYXRlXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwicC1oZWFkZXJcIj48L25nLWNvbnRlbnQ+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImhlYWRlclRlbXBsYXRlXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgW2NsYXNzXT1cImNvbnRlbnRDbGFzc1wiIFtuZ0NsYXNzXT1cIidwLWNhcm91c2VsLWNvbnRlbnQnXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtY2Fyb3VzZWwtY29udGFpbmVyXCIgW2F0dHIuYXJpYS1saXZlXT1cImFsbG93QXV0b3BsYXkgPyAncG9saXRlJyA6ICdvZmYnXCI+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJzaG93TmF2aWdhdG9yc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdwLWNhcm91c2VsLXByZXYgcC1saW5rJzogdHJ1ZSwgJ3AtZGlzYWJsZWQnOiBpc0JhY2t3YXJkTmF2RGlzYWJsZWQoKSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0JhY2t3YXJkTmF2RGlzYWJsZWQoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFQcmV2QnV0dG9uTGFiZWwoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwibmF2QmFja3dhcmQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBwUmlwcGxlXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcHJldmlvdXNJY29uVGVtcGxhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Q2hldnJvbkxlZnRJY29uICpuZ0lmPVwiIWlzVmVydGljYWwoKVwiIFtzdHlsZUNsYXNzXT1cIidjYXJvdXNlbC1wcmV2LWljb24nXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Q2hldnJvblVwSWNvbiAqbmdJZj1cImlzVmVydGljYWwoKVwiIFtzdHlsZUNsYXNzXT1cIidjYXJvdXNlbC1wcmV2LWljb24nXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJwcmV2aW91c0ljb25UZW1wbGF0ZVwiIGNsYXNzPVwicC1jYXJvdXNlbC1wcmV2LWljb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nVGVtcGxhdGVPdXRsZXQ9XCJwcmV2aW91c0ljb25UZW1wbGF0ZVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicC1jYXJvdXNlbC1pdGVtcy1jb250ZW50XCIgW25nU3R5bGVdPVwieyBoZWlnaHQ6IGlzVmVydGljYWwoKSA/IHZlcnRpY2FsVmlld1BvcnRIZWlnaHQgOiAnYXV0bycgfVwiICh0b3VjaGVuZCk9XCJvblRvdWNoRW5kKCRldmVudClcIiAodG91Y2hzdGFydCk9XCJvblRvdWNoU3RhcnQoJGV2ZW50KVwiICh0b3VjaG1vdmUpPVwib25Ub3VjaE1vdmUoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAjaXRlbXNDb250YWluZXIgY2xhc3M9XCJwLWNhcm91c2VsLWl0ZW1zLWNvbnRhaW5lclwiICh0cmFuc2l0aW9uZW5kKT1cIm9uVHJhbnNpdGlvbkVuZCgpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBjbG9uZWRJdGVtc0ZvclN0YXJ0aW5nOyBsZXQgaW5kZXggPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwLWNhcm91c2VsLWl0ZW0gcC1jYXJvdXNlbC1pdGVtLWNsb25lZCc6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncC1jYXJvdXNlbC1pdGVtLWFjdGl2ZSc6IHRvdGFsU2hpZnRlZEl0ZW1zICogLTEgPT09IHZhbHVlLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwLWNhcm91c2VsLWl0ZW0tc3RhcnQnOiAwID09PSBpbmRleCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwLWNhcm91c2VsLWl0ZW0tZW5kJzogY2xvbmVkSXRlbXNGb3JTdGFydGluZy5sZW5ndGggLSAxID09PSBpbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1oaWRkZW5dPVwiISh0b3RhbFNoaWZ0ZWRJdGVtcyAqIC0xID09PSB2YWx1ZS5sZW5ndGgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhU2xpZGVOdW1iZXIoaW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1yb2xlZGVzY3JpcHRpb25dPVwiYXJpYVNsaWRlTGFiZWwoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaXRlbVRlbXBsYXRlOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogaXRlbSB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiB2YWx1ZTsgbGV0IGluZGV4ID0gaW5kZXhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICdwLWNhcm91c2VsLWl0ZW0nOiB0cnVlLCAncC1jYXJvdXNlbC1pdGVtLWFjdGl2ZSc6IGZpcnN0SW5kZXgoKSA8PSBpbmRleCAmJiBsYXN0SW5kZXgoKSA+PSBpbmRleCwgJ3AtY2Fyb3VzZWwtaXRlbS1zdGFydCc6IGZpcnN0SW5kZXgoKSA9PT0gaW5kZXgsICdwLWNhcm91c2VsLWl0ZW0tZW5kJzogbGFzdEluZGV4KCkgPT09IGluZGV4IH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWhpZGRlbl09XCIhKHRvdGFsU2hpZnRlZEl0ZW1zICogLTEgPT09IHZhbHVlLmxlbmd0aClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFTbGlkZU51bWJlcihpbmRleClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLXJvbGVkZXNjcmlwdGlvbl09XCJhcmlhU2xpZGVMYWJlbCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJpdGVtVGVtcGxhdGU7IGNvbnRleHQ6IHsgJGltcGxpY2l0OiBpdGVtIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIGNsb25lZEl0ZW1zRm9yRmluaXNoaW5nOyBsZXQgaW5kZXggPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwLWNhcm91c2VsLWl0ZW0gcC1jYXJvdXNlbC1pdGVtLWNsb25lZCc6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncC1jYXJvdXNlbC1pdGVtLWFjdGl2ZSc6IHRvdGFsU2hpZnRlZEl0ZW1zICogLTEgPT09IG51bVZpc2libGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncC1jYXJvdXNlbC1pdGVtLXN0YXJ0JzogMCA9PT0gaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncC1jYXJvdXNlbC1pdGVtLWVuZCc6IGNsb25lZEl0ZW1zRm9yRmluaXNoaW5nLmxlbmd0aCAtIDEgPT09IGluZGV4XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cIml0ZW1UZW1wbGF0ZTsgY29udGV4dDogeyAkaW1wbGljaXQ6IGl0ZW0gfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwic2hvd05hdmlnYXRvcnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAncC1jYXJvdXNlbC1uZXh0IHAtbGluayc6IHRydWUsICdwLWRpc2FibGVkJzogaXNGb3J3YXJkTmF2RGlzYWJsZWQoKSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0ZvcndhcmROYXZEaXNhYmxlZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJuYXZGb3J3YXJkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgcFJpcHBsZVxuICAgICAgICAgICAgICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhcmlhTmV4dEJ1dHRvbkxhYmVsKClcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW5leHRJY29uVGVtcGxhdGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Q2hldnJvblJpZ2h0SWNvbiAqbmdJZj1cIiFpc1ZlcnRpY2FsKClcIiBbc3R5bGVDbGFzc109XCInY2Fyb3VzZWwtcHJldi1pY29uJ1wiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPENoZXZyb25Eb3duSWNvbiAqbmdJZj1cImlzVmVydGljYWwoKVwiIFtzdHlsZUNsYXNzXT1cIidjYXJvdXNlbC1wcmV2LWljb24nXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJuZXh0SWNvblRlbXBsYXRlXCIgY2xhc3M9XCJwLWNhcm91c2VsLXByZXYtaWNvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAqbmdUZW1wbGF0ZU91dGxldD1cIm5leHRJY29uVGVtcGxhdGVcIj48L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8dWwgI2luZGljYXRvckNvbnRlbnQgW25nQ2xhc3NdPVwiJ3AtY2Fyb3VzZWwtaW5kaWNhdG9ycyBwLXJlc2V0J1wiIFtjbGFzc109XCJpbmRpY2F0b3JzQ29udGVudENsYXNzXCIgW25nU3R5bGVdPVwiaW5kaWNhdG9yc0NvbnRlbnRTdHlsZVwiICpuZ0lmPVwic2hvd0luZGljYXRvcnNcIiAoa2V5ZG93bik9XCJvbkluZGljYXRvcktleWRvd24oJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICA8bGkgKm5nRm9yPVwibGV0IHRvdGFsRG90IG9mIHRvdGFsRG90c0FycmF5KCk7IGxldCBpID0gaW5kZXhcIiBbbmdDbGFzc109XCJ7ICdwLWNhcm91c2VsLWluZGljYXRvcic6IHRydWUsICdwLWhpZ2hsaWdodCc6IF9wYWdlID09PSBpIH1cIiBbYXR0ci5kYXRhLXBjLXNlY3Rpb25dPVwiJ2luZGljYXRvcidcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCIncC1saW5rJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRG90Q2xpY2soJGV2ZW50LCBpKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzXT1cImluZGljYXRvclN0eWxlQ2xhc3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cImluZGljYXRvclN0eWxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFyaWFQYWdlTGFiZWwoaSArIDEpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLWN1cnJlbnRdPVwiX3BhZ2UgPT09IGkgPyAncGFnZScgOiB1bmRlZmluZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0YWJpbmRleF09XCJfcGFnZSA9PT0gaSA/IDAgOiAtMVwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInAtY2Fyb3VzZWwtZm9vdGVyXCIgKm5nSWY9XCJmb290ZXJGYWNldCB8fCBmb290ZXJUZW1wbGF0ZVwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cInAtZm9vdGVyXCI+PC9uZy1jb250ZW50PlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJmb290ZXJUZW1wbGF0ZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIGAsXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgICBzdHlsZVVybHM6IFsnLi9jYXJvdXNlbC5jc3MnXSxcbiAgICBob3N0OiB7XG4gICAgICAgIGNsYXNzOiAncC1lbGVtZW50J1xuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgQ2Fyb3VzZWwgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0IHtcbiAgICAvKipcbiAgICAgKiBJbmRleCBvZiB0aGUgZmlyc3QgaXRlbS5cbiAgICAgKiBAZGVmYXVsdFZhbHVlIDBcbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBnZXQgcGFnZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fcGFnZTtcbiAgICB9XG4gICAgc2V0IHBhZ2UodmFsOiBudW1iZXIpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNDcmVhdGVkICYmIHZhbCAhPT0gdGhpcy5fcGFnZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuYXV0b3BsYXlJbnRlcnZhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RvcEF1dG9wbGF5KCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh2YWwgPiB0aGlzLl9wYWdlICYmIHZhbCA8PSB0aGlzLnRvdGFsRG90cygpIC0gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RlcCgtMSwgdmFsKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsIDwgdGhpcy5fcGFnZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RlcCgxLCB2YWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fcGFnZSA9IHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTnVtYmVyIG9mIGl0ZW1zIHBlciBwYWdlLlxuICAgICAqIEBkZWZhdWx0VmFsdWUgMVxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIGdldCBudW1WaXNpYmxlKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9udW1WaXNpYmxlO1xuICAgIH1cbiAgICBzZXQgbnVtVmlzaWJsZSh2YWw6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9udW1WaXNpYmxlID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBOdW1iZXIgb2YgaXRlbXMgdG8gc2Nyb2xsLlxuICAgICAqIEBkZWZhdWx0VmFsdWUgMVxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIGdldCBudW1TY3JvbGwoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX251bVZpc2libGU7XG4gICAgfVxuICAgIHNldCBudW1TY3JvbGwodmFsOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5fbnVtU2Nyb2xsID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbiBhcnJheSBvZiBvcHRpb25zIGZvciByZXNwb25zaXZlIGRlc2lnbi5cbiAgICAgKiBAc2VlIHtDYXJvdXNlbFJlc3BvbnNpdmVPcHRpb25zfVxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHJlc3BvbnNpdmVPcHRpb25zOiBDYXJvdXNlbFJlc3BvbnNpdmVPcHRpb25zW10gfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogU3BlY2lmaWVzIHRoZSBsYXlvdXQgb2YgdGhlIGNvbXBvbmVudC5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBvcmllbnRhdGlvbjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJyA9ICdob3Jpem9udGFsJztcbiAgICAvKipcbiAgICAgKiBIZWlnaHQgb2YgdGhlIHZpZXdwb3J0IGluIHZlcnRpY2FsIGxheW91dC5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSB2ZXJ0aWNhbFZpZXdQb3J0SGVpZ2h0OiBzdHJpbmcgPSAnMzAwcHgnO1xuICAgIC8qKlxuICAgICAqIFN0eWxlIGNsYXNzIG9mIG1haW4gY29udGVudC5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBjb250ZW50Q2xhc3M6IHN0cmluZyA9ICcnO1xuICAgIC8qKlxuICAgICAqIFN0eWxlIGNsYXNzIG9mIHRoZSBpbmRpY2F0b3IgaXRlbXMuXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KCkgaW5kaWNhdG9yc0NvbnRlbnRDbGFzczogc3RyaW5nID0gJyc7XG4gICAgLyoqXG4gICAgICogSW5saW5lIHN0eWxlIG9mIHRoZSBpbmRpY2F0b3IgaXRlbXMuXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KCkgaW5kaWNhdG9yc0NvbnRlbnRTdHlsZTogeyBba2xhc3M6IHN0cmluZ106IGFueSB9IHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBTdHlsZSBjbGFzcyBvZiB0aGUgaW5kaWNhdG9ycy5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBpbmRpY2F0b3JTdHlsZUNsYXNzOiBzdHJpbmcgPSAnJztcbiAgICAvKipcbiAgICAgKiBTdHlsZSBvZiB0aGUgaW5kaWNhdG9ycy5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBpbmRpY2F0b3JTdHlsZTogeyBba2xhc3M6IHN0cmluZ106IGFueSB9IHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBBbiBhcnJheSBvZiBvYmplY3RzIHRvIGRpc3BsYXkuXG4gICAgICogQGRlZmF1bHRWYWx1ZSBudWxsXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IHZhbHVlKCk6IGFueVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlIGFzIGFueVtdO1xuICAgIH1cbiAgICBzZXQgdmFsdWUodmFsKSB7XG4gICAgICAgIHRoaXMuX3ZhbHVlID0gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGlmIHNjcm9sbGluZyB3b3VsZCBiZSBpbmZpbml0ZS5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgY2lyY3VsYXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIGRpc3BsYXkgaW5kaWNhdG9yIGNvbnRhaW5lci5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgc2hvd0luZGljYXRvcnM6IGJvb2xlYW4gPSB0cnVlO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdG8gZGlzcGxheSBuYXZpZ2F0aW9uIGJ1dHRvbnMgaW4gY29udGFpbmVyLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBzaG93TmF2aWdhdG9yczogYm9vbGVhbiA9IHRydWU7XG4gICAgLyoqXG4gICAgICogVGltZSBpbiBtaWxsaXNlY29uZHMgdG8gc2Nyb2xsIGl0ZW1zIGF1dG9tYXRpY2FsbHkuXG4gICAgICogQGdyb3VwIFByb3BzXG4gICAgICovXG4gICAgQElucHV0KHsgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUgfSkgYXV0b3BsYXlJbnRlcnZhbDogbnVtYmVyID0gMDtcbiAgICAvKipcbiAgICAgKiBJbmxpbmUgc3R5bGUgb2YgdGhlIGNvbXBvbmVudC5cbiAgICAgKiBAZ3JvdXAgUHJvcHNcbiAgICAgKi9cbiAgICBASW5wdXQoKSBzdHlsZTogeyBba2xhc3M6IHN0cmluZ106IGFueSB9IHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBTdHlsZSBjbGFzcyBvZiB0aGUgdmlld3BvcnQgY29udGFpbmVyLlxuICAgICAqIEBncm91cCBQcm9wc1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHN0eWxlQ2xhc3M6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBDYWxsYmFjayB0byBpbnZva2UgYWZ0ZXIgc2Nyb2xsLlxuICAgICAqIEBwYXJhbSB7Q2Fyb3VzZWxQYWdlRXZlbnR9IGV2ZW50IC0gQ3VzdG9tIHBhZ2UgZXZlbnQuXG4gICAgICogQGdyb3VwIEVtaXRzXG4gICAgICovXG4gICAgQE91dHB1dCgpIG9uUGFnZTogRXZlbnRFbWl0dGVyPENhcm91c2VsUGFnZUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8Q2Fyb3VzZWxQYWdlRXZlbnQ+KCk7XG5cbiAgICBAVmlld0NoaWxkKCdpdGVtc0NvbnRhaW5lcicpIGl0ZW1zQ29udGFpbmVyOiBFbGVtZW50UmVmIHwgdW5kZWZpbmVkO1xuXG4gICAgQFZpZXdDaGlsZCgnaW5kaWNhdG9yQ29udGVudCcpIGluZGljYXRvckNvbnRlbnQ6IEVsZW1lbnRSZWYgfCB1bmRlZmluZWQ7XG5cbiAgICBAQ29udGVudENoaWxkKEhlYWRlcikgaGVhZGVyRmFjZXQ6IFF1ZXJ5TGlzdDxIZWFkZXI+IHwgdW5kZWZpbmVkO1xuXG4gICAgQENvbnRlbnRDaGlsZChGb290ZXIpIGZvb3RlckZhY2V0OiBRdWVyeUxpc3Q8Rm9vdGVyPiB8IHVuZGVmaW5lZDtcblxuICAgIEBDb250ZW50Q2hpbGRyZW4oUHJpbWVUZW1wbGF0ZSkgdGVtcGxhdGVzOiBRdWVyeUxpc3Q8UHJpbWVUZW1wbGF0ZT4gfCB1bmRlZmluZWQ7XG5cbiAgICBfbnVtVmlzaWJsZTogbnVtYmVyID0gMTtcblxuICAgIF9udW1TY3JvbGw6IG51bWJlciA9IDE7XG5cbiAgICBfb2xkTnVtU2Nyb2xsOiBudW1iZXIgPSAwO1xuXG4gICAgcHJldlN0YXRlOiBhbnkgPSB7XG4gICAgICAgIG51bVNjcm9sbDogMCxcbiAgICAgICAgbnVtVmlzaWJsZTogMCxcbiAgICAgICAgdmFsdWU6IFtdXG4gICAgfTtcblxuICAgIGRlZmF1bHROdW1TY3JvbGw6IG51bWJlciA9IDE7XG5cbiAgICBkZWZhdWx0TnVtVmlzaWJsZTogbnVtYmVyID0gMTtcblxuICAgIF9wYWdlOiBudW1iZXIgPSAwO1xuXG4gICAgX3ZhbHVlOiBhbnlbXSB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbiAgICBjYXJvdXNlbFN0eWxlOiBhbnk7XG5cbiAgICBpZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgdG90YWxTaGlmdGVkSXRlbXM7XG5cbiAgICBpc1JlbWFpbmluZ0l0ZW1zQWRkZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGFuaW1hdGlvblRpbWVvdXQ6IGFueTtcblxuICAgIHRyYW5zbGF0ZVRpbWVvdXQ6IGFueTtcblxuICAgIHJlbWFpbmluZ0l0ZW1zOiBudW1iZXIgPSAwO1xuXG4gICAgX2l0ZW1zOiBhbnlbXSB8IHVuZGVmaW5lZDtcblxuICAgIHN0YXJ0UG9zOiBhbnk7XG5cbiAgICBkb2N1bWVudFJlc2l6ZUxpc3RlbmVyOiBhbnk7XG5cbiAgICBjbG9uZWRJdGVtc0ZvclN0YXJ0aW5nOiBhbnlbXSB8IHVuZGVmaW5lZDtcblxuICAgIGNsb25lZEl0ZW1zRm9yRmluaXNoaW5nOiBhbnlbXSB8IHVuZGVmaW5lZDtcblxuICAgIGFsbG93QXV0b3BsYXk6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbiAgICBpbnRlcnZhbDogYW55O1xuXG4gICAgaXNDcmVhdGVkOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gICAgc3dpcGVUaHJlc2hvbGQ6IG51bWJlciA9IDIwO1xuXG4gICAgaXRlbVRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xuXG4gICAgaGVhZGVyVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT4gfCB1bmRlZmluZWQ7XG5cbiAgICBmb290ZXJUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZDtcblxuICAgIHByZXZpb3VzSWNvblRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+IHwgdW5kZWZpbmVkO1xuXG4gICAgbmV4dEljb25UZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PiB8IHVuZGVmaW5lZDtcblxuICAgIHdpbmRvdzogV2luZG93O1xuXG4gICAgY29uc3RydWN0b3IocHVibGljIGVsOiBFbGVtZW50UmVmLCBwdWJsaWMgem9uZTogTmdab25lLCBwdWJsaWMgY2Q6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIsIEBJbmplY3QoRE9DVU1FTlQpIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50LCBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IGFueSwgcHJpdmF0ZSBjb25maWc6IFByaW1lTkdDb25maWcpIHtcbiAgICAgICAgdGhpcy50b3RhbFNoaWZ0ZWRJdGVtcyA9IHRoaXMucGFnZSAqIHRoaXMubnVtU2Nyb2xsICogLTE7XG4gICAgICAgIHRoaXMud2luZG93ID0gdGhpcy5kb2N1bWVudC5kZWZhdWx0VmlldyBhcyBXaW5kb3c7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoc2ltcGxlQ2hhbmdlOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgICAgIGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICAgICAgICBpZiAoc2ltcGxlQ2hhbmdlLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY2lyY3VsYXIgJiYgdGhpcy5fdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRDbG9uZUl0ZW1zKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5pc0NyZWF0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2ltcGxlQ2hhbmdlLm51bVZpc2libGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVzcG9uc2l2ZU9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVmYXVsdE51bVZpc2libGUgPSB0aGlzLm51bVZpc2libGU7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0NpcmN1bGFyKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0Q2xvbmVJdGVtcygpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGN1bGF0ZVBvc2l0aW9uKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHNpbXBsZUNoYW5nZS5udW1TY3JvbGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucmVzcG9uc2l2ZU9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVmYXVsdE51bVNjcm9sbCA9IHRoaXMubnVtU2Nyb2xsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLmlkID0gVW5pcXVlQ29tcG9uZW50SWQoKTtcbiAgICAgICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgICAgICAgIHRoaXMuYWxsb3dBdXRvcGxheSA9ICEhdGhpcy5hdXRvcGxheUludGVydmFsO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5jaXJjdWxhcikge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0Q2xvbmVJdGVtcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5yZXNwb25zaXZlT3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVmYXVsdE51bVNjcm9sbCA9IHRoaXMuX251bVNjcm9sbDtcbiAgICAgICAgICAgICAgICB0aGlzLmRlZmF1bHROdW1WaXNpYmxlID0gdGhpcy5fbnVtVmlzaWJsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jcmVhdGVTdHlsZSgpO1xuICAgICAgICAgICAgdGhpcy5jYWxjdWxhdGVQb3NpdGlvbigpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5yZXNwb25zaXZlT3B0aW9ucykge1xuICAgICAgICAgICAgICAgIHRoaXMuYmluZERvY3VtZW50TGlzdGVuZXJzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRlbXBsYXRlcz8uZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChpdGVtLmdldFR5cGUoKSkge1xuICAgICAgICAgICAgICAgIGNhc2UgJ2l0ZW0nOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLml0ZW1UZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAnaGVhZGVyJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oZWFkZXJUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAnZm9vdGVyJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb290ZXJUZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAncHJldmlvdXNpY29uJzpcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2aW91c0ljb25UZW1wbGF0ZSA9IGl0ZW0udGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAnbmV4dGljb24nOlxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5leHRJY29uVGVtcGxhdGUgPSBpdGVtLnRlbXBsYXRlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXRlbVRlbXBsYXRlID0gaXRlbS50ZW1wbGF0ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XG4gICAgICAgIGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtSWQpKSB7XG4gICAgICAgICAgICBjb25zdCBpc0NpcmN1bGFyID0gdGhpcy5pc0NpcmN1bGFyKCk7XG4gICAgICAgICAgICBsZXQgdG90YWxTaGlmdGVkSXRlbXMgPSB0aGlzLnRvdGFsU2hpZnRlZEl0ZW1zO1xuXG4gICAgICAgICAgICBpZiAodGhpcy52YWx1ZSAmJiB0aGlzLml0ZW1zQ29udGFpbmVyICYmICh0aGlzLnByZXZTdGF0ZS5udW1TY3JvbGwgIT09IHRoaXMuX251bVNjcm9sbCB8fCB0aGlzLnByZXZTdGF0ZS5udW1WaXNpYmxlICE9PSB0aGlzLl9udW1WaXNpYmxlIHx8IHRoaXMucHJldlN0YXRlLnZhbHVlLmxlbmd0aCAhPT0gdGhpcy52YWx1ZS5sZW5ndGgpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYXV0b3BsYXlJbnRlcnZhbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0b3BBdXRvcGxheShmYWxzZSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1haW5pbmdJdGVtcyA9ICh0aGlzLnZhbHVlLmxlbmd0aCAtIHRoaXMuX251bVZpc2libGUpICUgdGhpcy5fbnVtU2Nyb2xsO1xuXG4gICAgICAgICAgICAgICAgbGV0IHBhZ2UgPSB0aGlzLl9wYWdlO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvdGFsRG90cygpICE9PSAwICYmIHBhZ2UgPj0gdGhpcy50b3RhbERvdHMoKSkge1xuICAgICAgICAgICAgICAgICAgICBwYWdlID0gdGhpcy50b3RhbERvdHMoKSAtIDE7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2UgPSBwYWdlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uUGFnZS5lbWl0KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2U6IHRoaXMucGFnZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0b3RhbFNoaWZ0ZWRJdGVtcyA9IHBhZ2UgKiB0aGlzLl9udW1TY3JvbGwgKiAtMTtcbiAgICAgICAgICAgICAgICBpZiAoaXNDaXJjdWxhcikge1xuICAgICAgICAgICAgICAgICAgICB0b3RhbFNoaWZ0ZWRJdGVtcyAtPSB0aGlzLl9udW1WaXNpYmxlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChwYWdlID09PSB0aGlzLnRvdGFsRG90cygpIC0gMSAmJiB0aGlzLnJlbWFpbmluZ0l0ZW1zID4gMCkge1xuICAgICAgICAgICAgICAgICAgICB0b3RhbFNoaWZ0ZWRJdGVtcyArPSAtMSAqIHRoaXMucmVtYWluaW5nSXRlbXMgKyB0aGlzLl9udW1TY3JvbGw7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNSZW1haW5pbmdJdGVtc0FkZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUmVtYWluaW5nSXRlbXNBZGRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh0b3RhbFNoaWZ0ZWRJdGVtcyAhPT0gdGhpcy50b3RhbFNoaWZ0ZWRJdGVtcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvdGFsU2hpZnRlZEl0ZW1zID0gdG90YWxTaGlmdGVkSXRlbXM7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhpcy5fb2xkTnVtU2Nyb2xsID0gdGhpcy5fbnVtU2Nyb2xsO1xuICAgICAgICAgICAgICAgIHRoaXMucHJldlN0YXRlLm51bVNjcm9sbCA9IHRoaXMuX251bVNjcm9sbDtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZTdGF0ZS5udW1WaXNpYmxlID0gdGhpcy5fbnVtVmlzaWJsZTtcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZTdGF0ZS52YWx1ZSA9IFsuLi4odGhpcy5fdmFsdWUgYXMgYW55W10pXTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvdGFsRG90cygpID4gMCAmJiB0aGlzLml0ZW1zQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pdGVtc0NvbnRhaW5lci5uYXRpdmVFbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9IHRoaXMuaXNWZXJ0aWNhbCgpID8gYHRyYW5zbGF0ZTNkKDAsICR7dG90YWxTaGlmdGVkSXRlbXMgKiAoMTAwIC8gdGhpcy5fbnVtVmlzaWJsZSl9JSwgMClgIDogYHRyYW5zbGF0ZTNkKCR7dG90YWxTaGlmdGVkSXRlbXMgKiAoMTAwIC8gdGhpcy5fbnVtVmlzaWJsZSl9JSwgMCwgMClgO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuaXNDcmVhdGVkID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmF1dG9wbGF5SW50ZXJ2YWwgJiYgdGhpcy5pc0F1dG9wbGF5KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGFydEF1dG9wbGF5KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoaXNDaXJjdWxhcikge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBhZ2UgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdG90YWxTaGlmdGVkSXRlbXMgPSAtMSAqIHRoaXMuX251bVZpc2libGU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0b3RhbFNoaWZ0ZWRJdGVtcyA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0b3RhbFNoaWZ0ZWRJdGVtcyA9IC0xICogdGhpcy52YWx1ZS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlbWFpbmluZ0l0ZW1zID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1JlbWFpbmluZ0l0ZW1zQWRkZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRvdGFsU2hpZnRlZEl0ZW1zICE9PSB0aGlzLnRvdGFsU2hpZnRlZEl0ZW1zKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG90YWxTaGlmdGVkSXRlbXMgPSB0b3RhbFNoaWZ0ZWRJdGVtcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjcmVhdGVTdHlsZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNhcm91c2VsU3R5bGUpIHtcbiAgICAgICAgICAgIHRoaXMuY2Fyb3VzZWxTdHlsZSA9IHRoaXMucmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcbiAgICAgICAgICAgIHRoaXMuY2Fyb3VzZWxTdHlsZS50eXBlID0gJ3RleHQvY3NzJztcbiAgICAgICAgICAgIHRoaXMucmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5kb2N1bWVudC5oZWFkLCB0aGlzLmNhcm91c2VsU3R5bGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGlubmVySFRNTCA9IGBcbiAgICAgICAgICAgICMke3RoaXMuaWR9IC5wLWNhcm91c2VsLWl0ZW0ge1xuXHRcdFx0XHRmbGV4OiAxIDAgJHsxMDAgLyB0aGlzLm51bVZpc2libGV9JVxuXHRcdFx0fVxuICAgICAgICBgO1xuXG4gICAgICAgIGlmICh0aGlzLnJlc3BvbnNpdmVPcHRpb25zKSB7XG4gICAgICAgICAgICB0aGlzLnJlc3BvbnNpdmVPcHRpb25zLnNvcnQoKGRhdGExLCBkYXRhMikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlMSA9IGRhdGExLmJyZWFrcG9pbnQ7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUyID0gZGF0YTIuYnJlYWtwb2ludDtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gbnVsbDtcblxuICAgICAgICAgICAgICAgIGlmICh2YWx1ZTEgPT0gbnVsbCAmJiB2YWx1ZTIgIT0gbnVsbCkgcmVzdWx0ID0gLTE7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUxICE9IG51bGwgJiYgdmFsdWUyID09IG51bGwpIHJlc3VsdCA9IDE7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsdWUxID09IG51bGwgJiYgdmFsdWUyID09IG51bGwpIHJlc3VsdCA9IDA7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZhbHVlMSA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIHZhbHVlMiA9PT0gJ3N0cmluZycpIHJlc3VsdCA9IHZhbHVlMS5sb2NhbGVDb21wYXJlKHZhbHVlMiwgdW5kZWZpbmVkLCB7IG51bWVyaWM6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgZWxzZSByZXN1bHQgPSB2YWx1ZTEgPCB2YWx1ZTIgPyAtMSA6IHZhbHVlMSA+IHZhbHVlMiA/IDEgOiAwO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIC0xICogcmVzdWx0O1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5yZXNwb25zaXZlT3B0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCByZXMgPSB0aGlzLnJlc3BvbnNpdmVPcHRpb25zW2ldO1xuXG4gICAgICAgICAgICAgICAgaW5uZXJIVE1MICs9IGBcbiAgICAgICAgICAgICAgICAgICAgQG1lZGlhIHNjcmVlbiBhbmQgKG1heC13aWR0aDogJHtyZXMuYnJlYWtwb2ludH0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICMke3RoaXMuaWR9IC5wLWNhcm91c2VsLWl0ZW0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsZXg6IDEgMCAkezEwMCAvIHJlcy5udW1WaXNpYmxlfSVcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNhcm91c2VsU3R5bGUuaW5uZXJIVE1MID0gaW5uZXJIVE1MO1xuICAgIH1cblxuICAgIGNhbGN1bGF0ZVBvc2l0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5yZXNwb25zaXZlT3B0aW9ucykge1xuICAgICAgICAgICAgbGV0IG1hdGNoZWRSZXNwb25zaXZlRGF0YSA9IHtcbiAgICAgICAgICAgICAgICBudW1WaXNpYmxlOiB0aGlzLmRlZmF1bHROdW1WaXNpYmxlLFxuICAgICAgICAgICAgICAgIG51bVNjcm9sbDogdGhpcy5kZWZhdWx0TnVtU2Nyb2xsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgICAgICBsZXQgd2luZG93V2lkdGggPSB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucmVzcG9uc2l2ZU9wdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlcyA9IHRoaXMucmVzcG9uc2l2ZU9wdGlvbnNbaV07XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlSW50KHJlcy5icmVha3BvaW50LCAxMCkgPj0gd2luZG93V2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoZWRSZXNwb25zaXZlRGF0YSA9IHJlcztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuX251bVNjcm9sbCAhPT0gbWF0Y2hlZFJlc3BvbnNpdmVEYXRhLm51bVNjcm9sbCkge1xuICAgICAgICAgICAgICAgIGxldCBwYWdlID0gdGhpcy5fcGFnZTtcbiAgICAgICAgICAgICAgICBwYWdlID0gTWF0aC5mbG9vcigocGFnZSAqIHRoaXMuX251bVNjcm9sbCkgLyBtYXRjaGVkUmVzcG9uc2l2ZURhdGEubnVtU2Nyb2xsKTtcblxuICAgICAgICAgICAgICAgIGxldCB0b3RhbFNoaWZ0ZWRJdGVtcyA9IG1hdGNoZWRSZXNwb25zaXZlRGF0YS5udW1TY3JvbGwgKiB0aGlzLnBhZ2UgKiAtMTtcblxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQ2lyY3VsYXIoKSkge1xuICAgICAgICAgICAgICAgICAgICB0b3RhbFNoaWZ0ZWRJdGVtcyAtPSBtYXRjaGVkUmVzcG9uc2l2ZURhdGEubnVtVmlzaWJsZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGlzLnRvdGFsU2hpZnRlZEl0ZW1zID0gdG90YWxTaGlmdGVkSXRlbXM7XG4gICAgICAgICAgICAgICAgdGhpcy5fbnVtU2Nyb2xsID0gbWF0Y2hlZFJlc3BvbnNpdmVEYXRhLm51bVNjcm9sbDtcblxuICAgICAgICAgICAgICAgIHRoaXMuX3BhZ2UgPSBwYWdlO1xuICAgICAgICAgICAgICAgIHRoaXMub25QYWdlLmVtaXQoe1xuICAgICAgICAgICAgICAgICAgICBwYWdlOiB0aGlzLnBhZ2VcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuX251bVZpc2libGUgIT09IG1hdGNoZWRSZXNwb25zaXZlRGF0YS5udW1WaXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbnVtVmlzaWJsZSA9IG1hdGNoZWRSZXNwb25zaXZlRGF0YS5udW1WaXNpYmxlO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0Q2xvbmVJdGVtcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0Q2xvbmVJdGVtcygpIHtcbiAgICAgICAgdGhpcy5jbG9uZWRJdGVtc0ZvclN0YXJ0aW5nID0gW107XG4gICAgICAgIHRoaXMuY2xvbmVkSXRlbXNGb3JGaW5pc2hpbmcgPSBbXTtcbiAgICAgICAgaWYgKHRoaXMuaXNDaXJjdWxhcigpKSB7XG4gICAgICAgICAgICB0aGlzLmNsb25lZEl0ZW1zRm9yU3RhcnRpbmcucHVzaCguLi50aGlzLnZhbHVlLnNsaWNlKC0xICogdGhpcy5fbnVtVmlzaWJsZSkpO1xuICAgICAgICAgICAgdGhpcy5jbG9uZWRJdGVtc0ZvckZpbmlzaGluZy5wdXNoKC4uLnRoaXMudmFsdWUuc2xpY2UoMCwgdGhpcy5fbnVtVmlzaWJsZSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZmlyc3RJbmRleCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNDaXJjdWxhcigpID8gLTEgKiAodGhpcy50b3RhbFNoaWZ0ZWRJdGVtcyArIHRoaXMubnVtVmlzaWJsZSkgOiB0aGlzLnRvdGFsU2hpZnRlZEl0ZW1zICogLTE7XG4gICAgfVxuXG4gICAgbGFzdEluZGV4KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5maXJzdEluZGV4KCkgKyB0aGlzLm51bVZpc2libGUgLSAxO1xuICAgIH1cblxuICAgIHRvdGFsRG90cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWU/Lmxlbmd0aCA/IE1hdGguY2VpbCgodGhpcy52YWx1ZS5sZW5ndGggLSB0aGlzLl9udW1WaXNpYmxlKSAvIHRoaXMuX251bVNjcm9sbCkgKyAxIDogMDtcbiAgICB9XG5cbiAgICB0b3RhbERvdHNBcnJheSgpIHtcbiAgICAgICAgY29uc3QgdG90YWxEb3RzID0gdGhpcy50b3RhbERvdHMoKTtcbiAgICAgICAgcmV0dXJuIHRvdGFsRG90cyA8PSAwID8gW10gOiBBcnJheSh0b3RhbERvdHMpLmZpbGwoMCk7XG4gICAgfVxuXG4gICAgaXNWZXJ0aWNhbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3JpZW50YXRpb24gPT09ICd2ZXJ0aWNhbCc7XG4gICAgfVxuXG4gICAgaXNDaXJjdWxhcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2lyY3VsYXIgJiYgdGhpcy52YWx1ZSAmJiB0aGlzLnZhbHVlLmxlbmd0aCA+PSB0aGlzLm51bVZpc2libGU7XG4gICAgfVxuXG4gICAgaXNBdXRvcGxheSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXV0b3BsYXlJbnRlcnZhbCAmJiB0aGlzLmFsbG93QXV0b3BsYXk7XG4gICAgfVxuXG4gICAgaXNGb3J3YXJkTmF2RGlzYWJsZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzRW1wdHkoKSB8fCAodGhpcy5fcGFnZSA+PSB0aGlzLnRvdGFsRG90cygpIC0gMSAmJiAhdGhpcy5pc0NpcmN1bGFyKCkpO1xuICAgIH1cblxuICAgIGlzQmFja3dhcmROYXZEaXNhYmxlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNFbXB0eSgpIHx8ICh0aGlzLl9wYWdlIDw9IDAgJiYgIXRoaXMuaXNDaXJjdWxhcigpKTtcbiAgICB9XG5cbiAgICBpc0VtcHR5KCkge1xuICAgICAgICByZXR1cm4gIXRoaXMudmFsdWUgfHwgdGhpcy52YWx1ZS5sZW5ndGggPT09IDA7XG4gICAgfVxuXG4gICAgbmF2Rm9yd2FyZChlOiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCwgaW5kZXg/OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNDaXJjdWxhcigpIHx8IHRoaXMuX3BhZ2UgPCB0aGlzLnRvdGFsRG90cygpIC0gMSkge1xuICAgICAgICAgICAgdGhpcy5zdGVwKC0xLCBpbmRleCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hdXRvcGxheUludGVydmFsKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3BBdXRvcGxheSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGUgJiYgZS5jYW5jZWxhYmxlKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuYXZCYWNrd2FyZChlOiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCwgaW5kZXg/OiBudW1iZXIpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNDaXJjdWxhcigpIHx8IHRoaXMuX3BhZ2UgIT09IDApIHtcbiAgICAgICAgICAgIHRoaXMuc3RlcCgxLCBpbmRleCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hdXRvcGxheUludGVydmFsKSB7XG4gICAgICAgICAgICB0aGlzLnN0b3BBdXRvcGxheSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGUgJiYgZS5jYW5jZWxhYmxlKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkRvdENsaWNrKGU6IE1vdXNlRXZlbnQsIGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgbGV0IHBhZ2UgPSB0aGlzLl9wYWdlO1xuXG4gICAgICAgIGlmICh0aGlzLmF1dG9wbGF5SW50ZXJ2YWwpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcEF1dG9wbGF5KCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5kZXggPiBwYWdlKSB7XG4gICAgICAgICAgICB0aGlzLm5hdkZvcndhcmQoZSwgaW5kZXgpO1xuICAgICAgICB9IGVsc2UgaWYgKGluZGV4IDwgcGFnZSkge1xuICAgICAgICAgICAgdGhpcy5uYXZCYWNrd2FyZChlLCBpbmRleCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkluZGljYXRvcktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcbiAgICAgICAgc3dpdGNoIChldmVudC5jb2RlKSB7XG4gICAgICAgICAgICBjYXNlICdBcnJvd1JpZ2h0JzpcbiAgICAgICAgICAgICAgICB0aGlzLm9uUmlnaHRLZXkoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnQXJyb3dMZWZ0JzpcbiAgICAgICAgICAgICAgICB0aGlzLm9uTGVmdEtleSgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25SaWdodEtleSgpIHtcbiAgICAgICAgY29uc3QgaW5kaWNhdG9ycyA9IFsuLi5Eb21IYW5kbGVyLmZpbmQodGhpcy5pbmRpY2F0b3JDb250ZW50Lm5hdGl2ZUVsZW1lbnQsICdbZGF0YS1wYy1zZWN0aW9uPVwiaW5kaWNhdG9yXCJdJyldO1xuICAgICAgICBjb25zdCBhY3RpdmVJbmRleCA9IHRoaXMuZmluZEZvY3VzZWRJbmRpY2F0b3JJbmRleCgpO1xuXG4gICAgICAgIHRoaXMuY2hhbmdlZEZvY3VzZWRJbmRpY2F0b3IoYWN0aXZlSW5kZXgsIGFjdGl2ZUluZGV4ICsgMSA9PT0gaW5kaWNhdG9ycy5sZW5ndGggPyBpbmRpY2F0b3JzLmxlbmd0aCAtIDEgOiBhY3RpdmVJbmRleCArIDEpO1xuICAgIH1cblxuICAgIG9uTGVmdEtleSgpIHtcbiAgICAgICAgY29uc3QgYWN0aXZlSW5kZXggPSB0aGlzLmZpbmRGb2N1c2VkSW5kaWNhdG9ySW5kZXgoKTtcblxuICAgICAgICB0aGlzLmNoYW5nZWRGb2N1c2VkSW5kaWNhdG9yKGFjdGl2ZUluZGV4LCBhY3RpdmVJbmRleCAtIDEgPD0gMCA/IDAgOiBhY3RpdmVJbmRleCAtIDEpO1xuICAgIH1cbiAgICBvbkhvbWVLZXkoKSB7XG4gICAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gdGhpcy5maW5kRm9jdXNlZEluZGljYXRvckluZGV4KCk7XG5cbiAgICAgICAgdGhpcy5jaGFuZ2VkRm9jdXNlZEluZGljYXRvcihhY3RpdmVJbmRleCwgMCk7XG4gICAgfVxuXG4gICAgb25FbmRLZXkoKSB7XG4gICAgICAgIGNvbnN0IGluZGljYXRvcnMgPSBbLi4uRG9tSGFuZGxlci5maW5kKHRoaXMuaW5kaWNhdG9yQ29udGVudC5uYXRpdmVFbGVtZW50LCAnW2RhdGEtcGMtc2VjdGlvbj1cImluZGljYXRvclwiXXInKV07XG4gICAgICAgIGNvbnN0IGFjdGl2ZUluZGV4ID0gdGhpcy5maW5kRm9jdXNlZEluZGljYXRvckluZGV4KCk7XG5cbiAgICAgICAgdGhpcy5jaGFuZ2VkRm9jdXNlZEluZGljYXRvcihhY3RpdmVJbmRleCwgaW5kaWNhdG9ycy5sZW5ndGggLSAxKTtcbiAgICB9XG5cbiAgICBvblRhYktleSgpIHtcbiAgICAgICAgY29uc3QgaW5kaWNhdG9ycyA9IFsuLi5Eb21IYW5kbGVyLmZpbmQodGhpcy5pbmRpY2F0b3JDb250ZW50Lm5hdGl2ZUVsZW1lbnQsICdbZGF0YS1wYy1zZWN0aW9uPVwiaW5kaWNhdG9yXCJdJyldO1xuICAgICAgICBjb25zdCBoaWdobGlnaHRlZEluZGV4ID0gaW5kaWNhdG9ycy5maW5kSW5kZXgoKGluZCkgPT4gRG9tSGFuZGxlci5nZXRBdHRyaWJ1dGUoaW5kLCAnZGF0YS1wLWhpZ2hsaWdodCcpID09PSB0cnVlKTtcblxuICAgICAgICBjb25zdCBhY3RpdmVJbmRpY2F0b3IgPSBEb21IYW5kbGVyLmZpbmRTaW5nbGUodGhpcy5pbmRpY2F0b3JDb250ZW50Lm5hdGl2ZUVsZW1lbnQsICdbZGF0YS1wYy1zZWN0aW9uPVwiaW5kaWNhdG9yXCJdID4gYnV0dG9uW3RhYmluZGV4PVwiMFwiXScpO1xuICAgICAgICBjb25zdCBhY3RpdmVJbmRleCA9IGluZGljYXRvcnMuZmluZEluZGV4KChpbmQpID0+IGluZCA9PT0gYWN0aXZlSW5kaWNhdG9yLnBhcmVudEVsZW1lbnQpO1xuXG4gICAgICAgIGluZGljYXRvcnNbYWN0aXZlSW5kZXhdLmNoaWxkcmVuWzBdLnRhYkluZGV4ID0gJy0xJztcbiAgICAgICAgaW5kaWNhdG9yc1toaWdobGlnaHRlZEluZGV4XS5jaGlsZHJlblswXS50YWJJbmRleCA9ICcwJztcbiAgICB9XG5cbiAgICBmaW5kRm9jdXNlZEluZGljYXRvckluZGV4KCkge1xuICAgICAgICBjb25zdCBpbmRpY2F0b3JzID0gWy4uLkRvbUhhbmRsZXIuZmluZCh0aGlzLmluZGljYXRvckNvbnRlbnQubmF0aXZlRWxlbWVudCwgJ1tkYXRhLXBjLXNlY3Rpb249XCJpbmRpY2F0b3JcIl0nKV07XG4gICAgICAgIGNvbnN0IGFjdGl2ZUluZGljYXRvciA9IERvbUhhbmRsZXIuZmluZFNpbmdsZSh0aGlzLmluZGljYXRvckNvbnRlbnQubmF0aXZlRWxlbWVudCwgJ1tkYXRhLXBjLXNlY3Rpb249XCJpbmRpY2F0b3JcIl0gPiBidXR0b25bdGFiaW5kZXg9XCIwXCJdJyk7XG5cbiAgICAgICAgcmV0dXJuIGluZGljYXRvcnMuZmluZEluZGV4KChpbmQpID0+IGluZCA9PT0gYWN0aXZlSW5kaWNhdG9yLnBhcmVudEVsZW1lbnQpO1xuICAgIH1cblxuICAgIGNoYW5nZWRGb2N1c2VkSW5kaWNhdG9yKHByZXZJbmQsIG5leHRJbmQpIHtcbiAgICAgICAgY29uc3QgaW5kaWNhdG9ycyA9IFsuLi5Eb21IYW5kbGVyLmZpbmQodGhpcy5pbmRpY2F0b3JDb250ZW50Lm5hdGl2ZUVsZW1lbnQsICdbZGF0YS1wYy1zZWN0aW9uPVwiaW5kaWNhdG9yXCJdJyldO1xuXG4gICAgICAgIGluZGljYXRvcnNbcHJldkluZF0uY2hpbGRyZW5bMF0udGFiSW5kZXggPSAnLTEnO1xuICAgICAgICBpbmRpY2F0b3JzW25leHRJbmRdLmNoaWxkcmVuWzBdLnRhYkluZGV4ID0gJzAnO1xuICAgICAgICBpbmRpY2F0b3JzW25leHRJbmRdLmNoaWxkcmVuWzBdLmZvY3VzKCk7XG4gICAgfVxuXG4gICAgc3RlcChkaXI6IG51bWJlciwgcGFnZT86IG51bWJlcikge1xuICAgICAgICBsZXQgdG90YWxTaGlmdGVkSXRlbXMgPSB0aGlzLnRvdGFsU2hpZnRlZEl0ZW1zO1xuICAgICAgICBjb25zdCBpc0NpcmN1bGFyID0gdGhpcy5pc0NpcmN1bGFyKCk7XG5cbiAgICAgICAgaWYgKHBhZ2UgIT0gbnVsbCkge1xuICAgICAgICAgICAgdG90YWxTaGlmdGVkSXRlbXMgPSB0aGlzLl9udW1TY3JvbGwgKiBwYWdlICogLTE7XG5cbiAgICAgICAgICAgIGlmIChpc0NpcmN1bGFyKSB7XG4gICAgICAgICAgICAgICAgdG90YWxTaGlmdGVkSXRlbXMgLT0gdGhpcy5fbnVtVmlzaWJsZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5pc1JlbWFpbmluZ0l0ZW1zQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRvdGFsU2hpZnRlZEl0ZW1zICs9IHRoaXMuX251bVNjcm9sbCAqIGRpcjtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzUmVtYWluaW5nSXRlbXNBZGRlZCkge1xuICAgICAgICAgICAgICAgIHRvdGFsU2hpZnRlZEl0ZW1zICs9IHRoaXMucmVtYWluaW5nSXRlbXMgLSB0aGlzLl9udW1TY3JvbGwgKiBkaXI7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1JlbWFpbmluZ0l0ZW1zQWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IG9yaWdpbmFsU2hpZnRlZEl0ZW1zID0gaXNDaXJjdWxhciA/IHRvdGFsU2hpZnRlZEl0ZW1zICsgdGhpcy5fbnVtVmlzaWJsZSA6IHRvdGFsU2hpZnRlZEl0ZW1zO1xuICAgICAgICAgICAgcGFnZSA9IE1hdGguYWJzKE1hdGguZmxvb3Iob3JpZ2luYWxTaGlmdGVkSXRlbXMgLyB0aGlzLl9udW1TY3JvbGwpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpc0NpcmN1bGFyICYmIHRoaXMucGFnZSA9PT0gdGhpcy50b3RhbERvdHMoKSAtIDEgJiYgZGlyID09PSAtMSkge1xuICAgICAgICAgICAgdG90YWxTaGlmdGVkSXRlbXMgPSAtMSAqICh0aGlzLnZhbHVlLmxlbmd0aCArIHRoaXMuX251bVZpc2libGUpO1xuICAgICAgICAgICAgcGFnZSA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNDaXJjdWxhciAmJiB0aGlzLnBhZ2UgPT09IDAgJiYgZGlyID09PSAxKSB7XG4gICAgICAgICAgICB0b3RhbFNoaWZ0ZWRJdGVtcyA9IDA7XG4gICAgICAgICAgICBwYWdlID0gdGhpcy50b3RhbERvdHMoKSAtIDE7XG4gICAgICAgIH0gZWxzZSBpZiAocGFnZSA9PT0gdGhpcy50b3RhbERvdHMoKSAtIDEgJiYgdGhpcy5yZW1haW5pbmdJdGVtcyA+IDApIHtcbiAgICAgICAgICAgIHRvdGFsU2hpZnRlZEl0ZW1zICs9IHRoaXMucmVtYWluaW5nSXRlbXMgKiAtMSAtIHRoaXMuX251bVNjcm9sbCAqIGRpcjtcbiAgICAgICAgICAgIHRoaXMuaXNSZW1haW5pbmdJdGVtc0FkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLml0ZW1zQ29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGlzLml0ZW1zQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuc3R5bGUudHJhbnNmb3JtID0gdGhpcy5pc1ZlcnRpY2FsKCkgPyBgdHJhbnNsYXRlM2QoMCwgJHt0b3RhbFNoaWZ0ZWRJdGVtcyAqICgxMDAgLyB0aGlzLl9udW1WaXNpYmxlKX0lLCAwKWAgOiBgdHJhbnNsYXRlM2QoJHt0b3RhbFNoaWZ0ZWRJdGVtcyAqICgxMDAgLyB0aGlzLl9udW1WaXNpYmxlKX0lLCAwLCAwKWA7XG4gICAgICAgICAgICB0aGlzLml0ZW1zQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuc3R5bGUudHJhbnNpdGlvbiA9ICd0cmFuc2Zvcm0gNTAwbXMgZWFzZSAwcyc7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnRvdGFsU2hpZnRlZEl0ZW1zID0gdG90YWxTaGlmdGVkSXRlbXM7XG4gICAgICAgIHRoaXMuX3BhZ2UgPSBwYWdlO1xuICAgICAgICB0aGlzLm9uUGFnZS5lbWl0KHtcbiAgICAgICAgICAgIHBhZ2U6IHRoaXMucGFnZVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBzdGFydEF1dG9wbGF5KCkge1xuICAgICAgICB0aGlzLmludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMudG90YWxEb3RzKCkgPiAwKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucGFnZSA9PT0gdGhpcy50b3RhbERvdHMoKSAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGVwKC0xLCAwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnN0ZXAoLTEsIHRoaXMucGFnZSArIDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgdGhpcy5hdXRvcGxheUludGVydmFsKTtcbiAgICAgICAgdGhpcy5hbGxvd0F1dG9wbGF5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICBzdG9wQXV0b3BsYXkoY2hhbmdlQWxsb3c6IGJvb2xlYW4gPSB0cnVlKSB7XG4gICAgICAgIGlmICh0aGlzLmludGVydmFsKSB7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKHRoaXMuaW50ZXJ2YWwpO1xuICAgICAgICAgICAgdGhpcy5pbnRlcnZhbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChjaGFuZ2VBbGxvdykge1xuICAgICAgICAgICAgICAgIHRoaXMuYWxsb3dBdXRvcGxheSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuXG4gICAgaXNQbGF5aW5nKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLmludGVydmFsO1xuICAgIH1cblxuICAgIG9uVHJhbnNpdGlvbkVuZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuaXRlbXNDb250YWluZXIpIHtcbiAgICAgICAgICAgIHRoaXMuaXRlbXNDb250YWluZXIubmF0aXZlRWxlbWVudC5zdHlsZS50cmFuc2l0aW9uID0gJyc7XG5cbiAgICAgICAgICAgIGlmICgodGhpcy5wYWdlID09PSAwIHx8IHRoaXMucGFnZSA9PT0gdGhpcy50b3RhbERvdHMoKSAtIDEpICYmIHRoaXMuaXNDaXJjdWxhcigpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pdGVtc0NvbnRhaW5lci5uYXRpdmVFbGVtZW50LnN0eWxlLnRyYW5zZm9ybSA9IHRoaXMuaXNWZXJ0aWNhbCgpID8gYHRyYW5zbGF0ZTNkKDAsICR7dGhpcy50b3RhbFNoaWZ0ZWRJdGVtcyAqICgxMDAgLyB0aGlzLl9udW1WaXNpYmxlKX0lLCAwKWAgOiBgdHJhbnNsYXRlM2QoJHt0aGlzLnRvdGFsU2hpZnRlZEl0ZW1zICogKDEwMCAvIHRoaXMuX251bVZpc2libGUpfSUsIDAsIDApYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uVG91Y2hTdGFydChlOiBUb3VjaEV2ZW50KSB7XG4gICAgICAgIGxldCB0b3VjaG9iaiA9IGUuY2hhbmdlZFRvdWNoZXNbMF07XG5cbiAgICAgICAgdGhpcy5zdGFydFBvcyA9IHtcbiAgICAgICAgICAgIHg6IHRvdWNob2JqLnBhZ2VYLFxuICAgICAgICAgICAgeTogdG91Y2hvYmoucGFnZVlcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBvblRvdWNoTW92ZShlOiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkge1xuICAgICAgICBpZiAoZS5jYW5jZWxhYmxlKSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgb25Ub3VjaEVuZChlOiBUb3VjaEV2ZW50KSB7XG4gICAgICAgIGxldCB0b3VjaG9iaiA9IGUuY2hhbmdlZFRvdWNoZXNbMF07XG5cbiAgICAgICAgaWYgKHRoaXMuaXNWZXJ0aWNhbCgpKSB7XG4gICAgICAgICAgICB0aGlzLmNoYW5nZVBhZ2VPblRvdWNoKGUsIHRvdWNob2JqLnBhZ2VZIC0gdGhpcy5zdGFydFBvcy55KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlUGFnZU9uVG91Y2goZSwgdG91Y2hvYmoucGFnZVggLSB0aGlzLnN0YXJ0UG9zLngpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2hhbmdlUGFnZU9uVG91Y2goZTogVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQsIGRpZmY6IG51bWJlcikge1xuICAgICAgICBpZiAoTWF0aC5hYnMoZGlmZikgPiB0aGlzLnN3aXBlVGhyZXNob2xkKSB7XG4gICAgICAgICAgICBpZiAoZGlmZiA8IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5hdkZvcndhcmQoZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubmF2QmFja3dhcmQoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhcmlhUHJldkJ1dHRvbkxhYmVsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcudHJhbnNsYXRpb24uYXJpYSA/IHRoaXMuY29uZmlnLnRyYW5zbGF0aW9uLmFyaWEucHJldlBhZ2VMYWJlbCA6IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBhcmlhU2xpZGVMYWJlbCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnRyYW5zbGF0aW9uLmFyaWEgPyB0aGlzLmNvbmZpZy50cmFuc2xhdGlvbi5hcmlhLnNsaWRlIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGFyaWFOZXh0QnV0dG9uTGFiZWwoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy50cmFuc2xhdGlvbi5hcmlhID8gdGhpcy5jb25maWcudHJhbnNsYXRpb24uYXJpYS5uZXh0UGFnZUxhYmVsIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGFyaWFTbGlkZU51bWJlcih2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcudHJhbnNsYXRpb24uYXJpYSA/IHRoaXMuY29uZmlnLnRyYW5zbGF0aW9uLmFyaWEuc2xpZGVOdW1iZXIucmVwbGFjZSgve3NsaWRlTnVtYmVyfS9nLCB2YWx1ZSkgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgYXJpYVBhZ2VMYWJlbCh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcudHJhbnNsYXRpb24uYXJpYSA/IHRoaXMuY29uZmlnLnRyYW5zbGF0aW9uLmFyaWEucGFnZUxhYmVsLnJlcGxhY2UoL3twYWdlfS9nLCB2YWx1ZSkgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgYmluZERvY3VtZW50TGlzdGVuZXJzKCkge1xuICAgICAgICBpZiAoaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRvY3VtZW50UmVzaXplTGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50UmVzaXplTGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbih0aGlzLndpbmRvdywgJ3Jlc2l6ZScsIChldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNhbGN1bGF0ZVBvc2l0aW9uKCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1bmJpbmREb2N1bWVudExpc3RlbmVycygpIHtcbiAgICAgICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRvY3VtZW50UmVzaXplTGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50UmVzaXplTGlzdGVuZXIoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRvY3VtZW50UmVzaXplTGlzdGVuZXIgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIGlmICh0aGlzLnJlc3BvbnNpdmVPcHRpb25zKSB7XG4gICAgICAgICAgICB0aGlzLnVuYmluZERvY3VtZW50TGlzdGVuZXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYXV0b3BsYXlJbnRlcnZhbCkge1xuICAgICAgICAgICAgdGhpcy5zdG9wQXV0b3BsYXkoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuQE5nTW9kdWxlKHtcbiAgICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBTaGFyZWRNb2R1bGUsIFJpcHBsZU1vZHVsZSwgQ2hldnJvblJpZ2h0SWNvbiwgQ2hldnJvbkxlZnRJY29uLCBDaGV2cm9uRG93bkljb24sIENoZXZyb25VcEljb25dLFxuICAgIGV4cG9ydHM6IFtDb21tb25Nb2R1bGUsIENhcm91c2VsLCBTaGFyZWRNb2R1bGVdLFxuICAgIGRlY2xhcmF0aW9uczogW0Nhcm91c2VsXVxufSlcbmV4cG9ydCBjbGFzcyBDYXJvdXNlbE1vZHVsZSB7fVxuIl19
|