@cloukit/pagination
Version:
525 lines (515 loc) • 51.2 kB
JavaScript
import { __extends } from 'tslib';
import { CloukitComponentTheme, CloukitThemeService, UiElement } from '@cloukit/theme';
import { EventEmitter, Component, Input, Output, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/*!
* @license MIT
* Copyright (c) 2017 Bernhard Grünewaldt - codeclou.io
* https://github.com/cloukit/legal
*/
var PaginationButtonClickEvent = /** @class */ (function () {
function PaginationButtonClickEvent(type, page) {
this.type = type;
this.page = page;
}
return PaginationButtonClickEvent;
}());
/** @enum {number} */
var PaginationButtonType = {
normal: 1,
previous: 2,
next: 3,
};
PaginationButtonType[PaginationButtonType.normal] = 'normal';
PaginationButtonType[PaginationButtonType.previous] = 'previous';
PaginationButtonType[PaginationButtonType.next] = 'next';
var PaginationItem = /** @class */ (function () {
function PaginationItem(page, isActive, isFiller, label) {
this.page = page;
this.isActive = isActive;
this.isFiller = isFiller;
this.label = label;
}
return PaginationItem;
}());
var Ui = /** @class */ (function () {
function Ui() {
}
Ui.elements = {
filler: 'filler',
button: 'button',
wrapper: 'wrapper',
};
Ui.states = {
normal: 'normal',
active: 'active',
disabled: 'disabled',
};
Ui.modifier = {
base: 'base',
hover: 'hover',
};
return Ui;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var CloukitPaginationComponentThemeDefault = /** @class */ (function (_super) {
__extends(CloukitPaginationComponentThemeDefault, _super);
function CloukitPaginationComponentThemeDefault() {
var _this = _super.call(this) || this;
//
// WRAPPER
//
_this.buildStyle(Ui.elements.wrapper, Ui.states.normal, Ui.modifier.base)
.withStyles((/** @type {?} */ ({
display: 'flex',
})));
//
// BUTTON
//
_this.buildStyle(Ui.elements.button, Ui.states.normal, Ui.modifier.base)
.withStyles((/** @type {?} */ ({
alignSelf: 'center',
display: 'inline-flex',
flexWrap: 'nowrap',
maxWidth: '100%',
color: '#0052cc',
textDecoration: 'none',
fontStyle: 'normal',
fontSize: 'inherit',
margin: 0,
outline: 'none',
textAlign: 'center',
userSelect: 'none',
verticalAlign: 'middle',
whiteSpace: 'nowrap',
boxSizing: 'border-box',
padding: '2px 6px 3px',
border: 0,
backgroundColor: 'transparent',
cursor: 'pointer',
})));
_this.buildStyle(Ui.elements.button, Ui.states.active, Ui.modifier.base)
.inheritFrom(Ui.elements.button, Ui.states.normal, Ui.modifier.base)
.withStyles((/** @type {?} */ ({
backgroundColor: '#0052cc',
color: '#ffffff',
cursor: 'default',
})));
_this.buildStyle(Ui.elements.button, Ui.states.normal, Ui.modifier.hover)
.inheritFrom(Ui.elements.button, Ui.states.normal, Ui.modifier.base)
.withStyles((/** @type {?} */ ({
textDecoration: 'underline',
})));
_this.buildStyle(Ui.elements.button, Ui.states.disabled, Ui.modifier.base)
.inheritFrom(Ui.elements.button, Ui.states.normal, Ui.modifier.base)
.withStyles((/** @type {?} */ ({
color: '#777',
cursor: 'not-allowed',
})));
//
// FILLER
//
_this.buildStyle(Ui.elements.filler, Ui.states.normal, Ui.modifier.base)
.inheritFrom(Ui.elements.button, Ui.states.normal, Ui.modifier.base)
.withStyles((/** @type {?} */ ({
color: '#555',
cursor: 'default',
})));
_this.buildStyle(Ui.elements.filler, Ui.states.disabled, Ui.modifier.base)
.inheritFrom(Ui.elements.filler, Ui.states.normal, Ui.modifier.base)
.withStyles((/** @type {?} */ ({
color: '#efefef',
cursor: 'not-allowed',
})));
return _this;
}
return CloukitPaginationComponentThemeDefault;
}(CloukitComponentTheme));
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
//
// HELPER FUNCTIONS
//
/** @type {?} */
var createFiller = function () { return new PaginationItem(-1, false, true, '...'); };
/** @type {?} */
var createAnItem = function (page, active) { return new PaginationItem(page, active, false, "" + page); };
/**
* Provides the pages with a total of seven. See Unit Test.
* Examples:
* CASE 1: 1 2 3 *4* 5 6 7
* 1 2 3 *4* 5
* CASE 2: 1 2 3 *4* 5 .. 50
* CASE 3: 1 .. 46 *47* 48 49 50
* CASE 4: 1 .. 49 *50* 51 .. 90
* @type {?}
*/
var calculatePaginationItems = function (total, current) {
/** @type {?} */
var paginationItems = [];
if (total === undefined || total === null || current === undefined || current === null) {
return paginationItems;
}
//
// CASE 1: Total is smaller or equal seven
//
if (total <= 7) {
for (var i = 1; i <= total; i++) {
paginationItems.push(new PaginationItem(i, current === i, false, "" + i));
}
}
else
//
// CASE 2: Total is greater than seven AND page is in range of [1-4]
//
if (total > 7 && current <= 4) {
for (var i = 1; i <= 5; i++) {
paginationItems.push(createAnItem(i, current === i));
}
paginationItems.push(createFiller());
paginationItems.push(createAnItem(total, false));
}
else
//
// CASE 3: Total is greater than seven AND page is greater than four AND page is near total
//
if (total > 7 && current > 4 && current + 3 >= total) {
paginationItems.push(createAnItem(1, false));
paginationItems.push(createFiller());
for (var i = total - 4; i <= total; i++) {
paginationItems.push(createAnItem(i, current === i));
}
}
else
//
// CASE 4: Total is greater than seven AND page is greater than four
//
if (total > 7 && current > 4) {
paginationItems.push(createAnItem(1, false));
paginationItems.push(createFiller());
paginationItems.push(createAnItem(current - 1, false));
paginationItems.push(createAnItem(current, true));
paginationItems.push(createAnItem(current + 1, false));
paginationItems.push(createFiller());
paginationItems.push(createAnItem(total, false));
}
//
// END
//
return paginationItems;
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* Pagination Component.
*
* Just use this inside your templates:
*
* ```html
* <cloukit-pagination ...></cloukit-pagination>
* ```
*/
var CloukitPaginationComponent = /** @class */ (function () {
function CloukitPaginationComponent(themeService) {
this.themeService = themeService;
/**
* External way to disable the whole pagination e.g.
* during loading external data
*/
this.disabled = false;
/**
* Event emitted, when page is clicked.
*/
this.onPageSelect = new EventEmitter();
this.PaginationButtonType = PaginationButtonType;
this.state = {
pages: []
};
this.themeSelected = this.themeService.getComponentTheme('pagination');
}
/**
* @param {?} element
* @return {?}
*/
CloukitPaginationComponent.prototype.getStyle = /**
* @param {?} element
* @return {?}
*/
function (element) {
/** @type {?} */
var style = this.themeSelected.getStyle(element, 'normal', 'base');
return this.themeService.prefixStyle(style);
};
/**
* @overrides OnChanges
* @hidden
*/
/**
* \@overrides OnChanges
* @hidden
* @return {?}
*/
CloukitPaginationComponent.prototype.ngOnChanges = /**
* \@overrides OnChanges
* @hidden
* @return {?}
*/
function () {
if (this.theme !== undefined && this.theme !== null) {
this.themeSelected = this.themeService.getComponentTheme(this.theme);
if (this.themeSelected === null) {
console.log("WARN: requested theme " + this.theme + " does not exist. Falling back to default theme for pagination.");
this.themeSelected = this.themeService.getComponentTheme('pagination');
}
}
this.state.pages = calculatePaginationItems(this.total, this.current);
};
/**
* @param {?} event
* @return {?}
*/
CloukitPaginationComponent.prototype.selectPage = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (event.type === PaginationButtonType['previous'] &&
this.isPreviousPossible()) {
this.onPageSelect.emit(this.current - 1);
}
else if (event.type === PaginationButtonType['next'] &&
this.isNextPossible()) {
this.onPageSelect.emit(this.current + 1);
}
else if (event.type === PaginationButtonType['normal']) {
this.onPageSelect.emit(event.page);
}
};
/**
* @return {?}
*/
CloukitPaginationComponent.prototype.previousDummyPaginationItem = /**
* @return {?}
*/
function () {
/** @type {?} */
var label = 'Prev';
if (this.labelPrev !== undefined && this.labelPrev !== null) {
label = this.labelPrev;
}
return new PaginationItem(-1, false, false, label);
};
/**
* @return {?}
*/
CloukitPaginationComponent.prototype.nextDummyPaginationItem = /**
* @return {?}
*/
function () {
/** @type {?} */
var label = 'Next';
if (this.labelNext !== undefined && this.labelNext !== null) {
label = this.labelNext;
}
return new PaginationItem(-1, false, false, label);
};
/**
* @return {?}
*/
CloukitPaginationComponent.prototype.isPreviousPossible = /**
* @return {?}
*/
function () {
return this.current > 1;
};
/**
* @return {?}
*/
CloukitPaginationComponent.prototype.isNextPossible = /**
* @return {?}
*/
function () {
return this.current < this.total;
};
CloukitPaginationComponent.decorators = [
{ type: Component, args: [{
selector: 'cloukit-pagination',
template: "\n <div [ngStyle]=\"getStyle('wrapper').style\">\n <cloukit-pagination-button\n [disabled]=\"!isPreviousPossible() || disabled\"\n [paginationItem]=\"previousDummyPaginationItem()\"\n [themeSelected]=\"themeSelected\"\n [type]=\"PaginationButtonType['previous']\"\n (clicked)=\"selectPage($event)\"\n ></cloukit-pagination-button>\n <cloukit-pagination-button\n *ngFor=\"let page of state.pages\"\n [disabled]=\"disabled\"\n [paginationItem]=\"page\"\n [themeSelected]=\"themeSelected\"\n [type]=\"PaginationButtonType['normal']\"\n (clicked)=\"selectPage($event)\"\n ></cloukit-pagination-button>\n <cloukit-pagination-button\n [disabled]=\"!isNextPossible() || disabled\"\n [paginationItem]=\"nextDummyPaginationItem()\"\n [themeSelected]=\"themeSelected\"\n [type]=\"PaginationButtonType['next']\"\n (clicked)=\"selectPage($event)\"\n ></cloukit-pagination-button>\n </div>"
}] }
];
/** @nocollapse */
CloukitPaginationComponent.ctorParameters = function () { return [
{ type: CloukitThemeService }
]; };
CloukitPaginationComponent.propDecorators = {
theme: [{ type: Input }],
total: [{ type: Input }],
current: [{ type: Input }],
disabled: [{ type: Input }],
labelNext: [{ type: Input }],
labelPrev: [{ type: Input }],
onPageSelect: [{ type: Output }]
};
return CloukitPaginationComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var CloukitPaginationButtonComponent = /** @class */ (function () {
function CloukitPaginationButtonComponent(themeService) {
this.themeService = themeService;
this.clicked = new EventEmitter();
this.isMouseStillOver = false;
}
/**
* @param {?} pageItem
* @return {?}
*/
CloukitPaginationButtonComponent.transform = /**
* @param {?} pageItem
* @return {?}
*/
function (pageItem) {
if (pageItem === undefined || pageItem === null) {
return new UiElement(Ui.elements.filler, Ui.states.disabled, Ui.modifier.base);
}
/** @type {?} */
var uiElement = pageItem.isFiller ? Ui.elements.filler : Ui.elements.button;
/** @type {?} */
var uiState = pageItem.isActive ? Ui.states.active : Ui.states.normal;
return new UiElement(uiElement, uiState, Ui.modifier.base);
};
/**
* @return {?}
*/
CloukitPaginationButtonComponent.prototype.updateStyle = /**
* @return {?}
*/
function () {
/** @type {?} */
var style = this.themeSelected.getUiStyle(this.ui);
if (style !== null) {
this.style = this.themeService.prefixStyle(style);
}
};
/**
* @return {?}
*/
CloukitPaginationButtonComponent.prototype.ngOnChanges = /**
* @return {?}
*/
function () {
// retain mouseEnter and mouseLeave modifier changes!
/** @type {?} */
var modifier = null;
if (this.ui !== null && this.ui !== undefined) {
modifier = this.ui.modifier;
}
this.ui = CloukitPaginationButtonComponent.transform(this.paginationItem);
if (modifier !== null && this.isMouseStillOver) {
this.ui.modifier = modifier;
}
if (this.disabled === true) {
this.ui.state = Ui.states.disabled;
this.ui.modifier = Ui.modifier.base;
}
this.updateStyle();
};
/**
* @return {?}
*/
CloukitPaginationButtonComponent.prototype.mouseEnter = /**
* @return {?}
*/
function () {
this.ui.modifier = Ui.modifier.hover;
this.isMouseStillOver = true;
this.updateStyle();
};
/**
* @return {?}
*/
CloukitPaginationButtonComponent.prototype.mouseLeave = /**
* @return {?}
*/
function () {
this.ui.modifier = Ui.modifier.base;
this.isMouseStillOver = false;
this.updateStyle();
};
/**
* @return {?}
*/
CloukitPaginationButtonComponent.prototype.doClick = /**
* @return {?}
*/
function () {
if (!this.paginationItem.isFiller) {
this.clicked.emit(new PaginationButtonClickEvent(this.type, this.paginationItem.page));
}
};
CloukitPaginationButtonComponent.decorators = [
{ type: Component, args: [{
selector: 'cloukit-pagination-button',
template: "\n <button\n type=\"button\"\n [disabled]=\"disabled\"\n [ngStyle]=\"style?.style\"\n (click)=\"doClick()\"\n (mouseenter)=\"mouseEnter()\"\n (mouseleave)=\"mouseLeave()\"\n >\n {{paginationItem.label}}\n </button>"
}] }
];
/** @nocollapse */
CloukitPaginationButtonComponent.ctorParameters = function () { return [
{ type: CloukitThemeService }
]; };
CloukitPaginationButtonComponent.propDecorators = {
disabled: [{ type: Input }],
type: [{ type: Input }],
paginationItem: [{ type: Input }],
themeSelected: [{ type: Input }],
clicked: [{ type: Output }]
};
return CloukitPaginationButtonComponent;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
var CloukitPaginationModule = /** @class */ (function () {
function CloukitPaginationModule(themeService) {
this.themeService = themeService;
if (this.themeService.getComponentTheme('pagination') === null) {
this.themeService.registerComponentTheme('pagination', new CloukitPaginationComponentThemeDefault());
}
}
CloukitPaginationModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
exports: [CloukitPaginationComponent],
declarations: [CloukitPaginationComponent, CloukitPaginationButtonComponent],
},] }
];
/** @nocollapse */
CloukitPaginationModule.ctorParameters = function () { return [
{ type: CloukitThemeService }
]; };
return CloukitPaginationModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
*/
export { CloukitPaginationComponentThemeDefault, CloukitPaginationComponent, CloukitPaginationModule, PaginationButtonClickEvent, PaginationButtonType, PaginationItem, Ui, CloukitPaginationButtonComponent, calculatePaginationItems, createFiller };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWtpdC1wYWdpbmF0aW9uLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AY2xvdWtpdC9wYWdpbmF0aW9uL2xpYi9wYWdpbmF0aW9uLm1vZGVsLnRzIiwibmc6Ly9AY2xvdWtpdC9wYWdpbmF0aW9uL2xpYi9wYWdpbmF0aW9uLnRoZW1lLnRzIiwibmc6Ly9AY2xvdWtpdC9wYWdpbmF0aW9uL2xpYi9sb2dpYy9wYWdpbmF0aW9uLWhlbHBlci50cyIsIm5nOi8vQGNsb3VraXQvcGFnaW5hdGlvbi9saWIvcGFnaW5hdGlvbi5jb21wb25lbnQudHMiLCJuZzovL0BjbG91a2l0L3BhZ2luYXRpb24vbGliL2NoaWxkcmVuL3BhZ2luYXRpb24tYnV0dG9uLmNvbXBvbmVudC50cyIsIm5nOi8vQGNsb3VraXQvcGFnaW5hdGlvbi9saWIvcGFnaW5hdGlvbi5tb2R1bGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBAbGljZW5zZSBNSVRcbiAqIENvcHlyaWdodCAoYykgMjAxNyBCZXJuaGFyZCBHcsODwrxuZXdhbGR0IC0gY29kZWNsb3UuaW9cbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jbG91a2l0L2xlZ2FsXG4gKi9cblxuZXhwb3J0IGNsYXNzIFBhZ2luYXRpb25CdXR0b25DbGlja0V2ZW50IHtcbiAgY29uc3RydWN0b3IocHVibGljIHR5cGU6IFBhZ2luYXRpb25CdXR0b25UeXBlLCBwdWJsaWMgcGFnZTogbnVtYmVyKSB7fVxufVxuXG5leHBvcnQgZW51bSBQYWdpbmF0aW9uQnV0dG9uVHlwZSB7XG4gIG5vcm1hbCA9IDEsXG4gIHByZXZpb3VzID0gMixcbiAgbmV4dCA9IDMsXG59XG5cbmV4cG9ydCBjbGFzcyBQYWdpbmF0aW9uSXRlbSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBwYWdlOiBudW1iZXIsXG4gICAgcHVibGljIGlzQWN0aXZlOiBib29sZWFuLFxuICAgIHB1YmxpYyBpc0ZpbGxlcjogYm9vbGVhbixcbiAgICBwdWJsaWMgbGFiZWw6IHN0cmluZykge31cbn1cblxuZXhwb3J0IGNsYXNzIFVpIHtcbiAgcHVibGljIHN0YXRpYyBlbGVtZW50czogYW55ID0ge1xuICAgIGZpbGxlcjogJ2ZpbGxlcicsXG4gICAgYnV0dG9uOiAnYnV0dG9uJyxcbiAgICB3cmFwcGVyOiAnd3JhcHBlcicsXG4gIH07XG4gIHB1YmxpYyBzdGF0aWMgc3RhdGVzOiBhbnkgPSB7XG4gICAgbm9ybWFsOiAnbm9ybWFsJyxcbiAgICBhY3RpdmU6ICdhY3RpdmUnLFxuICAgIGRpc2FibGVkOiAnZGlzYWJsZWQnLFxuICB9O1xuICBwdWJsaWMgc3RhdGljIG1vZGlmaWVyOiBhbnkgPSB7XG4gICAgYmFzZTogJ2Jhc2UnLFxuICAgIGhvdmVyOiAnaG92ZXInLFxuICB9O1xufVxuIiwiLyohXG4gKiBAbGljZW5zZSBNSVRcbiAqIENvcHlyaWdodCAoYykgMjAxNyBCZXJuaGFyZCBHcsODwrxuZXdhbGR0IC0gY29kZWNsb3UuaW9cbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jbG91a2l0L2xlZ2FsXG4gKi9cbmltcG9ydCB7IENsb3VraXRCYXNlQ3NzRGVmaW5pdGlvbnMsIENsb3VraXRDb21wb25lbnRUaGVtZSB9IGZyb20gJ0BjbG91a2l0L3RoZW1lJztcbmltcG9ydCB7IFVpIH0gZnJvbSAnLi9wYWdpbmF0aW9uLm1vZGVsJztcblxuZXhwb3J0IGNsYXNzIENsb3VraXRQYWdpbmF0aW9uQ29tcG9uZW50VGhlbWVEZWZhdWx0IGV4dGVuZHMgQ2xvdWtpdENvbXBvbmVudFRoZW1lIHtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIC8vXG4gICAgLy8gV1JBUFBFUlxuICAgIC8vXG4gICAgdGhpcy5idWlsZFN0eWxlKFVpLmVsZW1lbnRzLndyYXBwZXIsIFVpLnN0YXRlcy5ub3JtYWwsIFVpLm1vZGlmaWVyLmJhc2UpXG4gICAgICAud2l0aFN0eWxlcyg8Q2xvdWtpdEJhc2VDc3NEZWZpbml0aW9ucz57XG4gICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgIH0pO1xuXG4gICAgLy9cbiAgICAvLyBCVVRUT05cbiAgICAvL1xuICAgIHRoaXMuYnVpbGRTdHlsZShVaS5lbGVtZW50cy5idXR0b24sIFVpLnN0YXRlcy5ub3JtYWwsIFVpLm1vZGlmaWVyLmJhc2UpXG4gICAgICAud2l0aFN0eWxlcyg8Q2xvdWtpdEJhc2VDc3NEZWZpbml0aW9ucz57XG4gICAgICAgIGFsaWduU2VsZjogJ2NlbnRlcicsXG4gICAgICAgIGRpc3BsYXk6ICdpbmxpbmUtZmxleCcsXG4gICAgICAgIGZsZXhXcmFwOiAnbm93cmFwJyxcbiAgICAgICAgbWF4V2lkdGg6ICcxMDAlJyxcbiAgICAgICAgY29sb3I6ICcjMDA1MmNjJyxcbiAgICAgICAgdGV4dERlY29yYXRpb246ICdub25lJyxcbiAgICAgICAgZm9udFN0eWxlOiAnbm9ybWFsJyxcbiAgICAgICAgZm9udFNpemU6ICdpbmhlcml0JyxcbiAgICAgICAgbWFyZ2luOiAwLFxuICAgICAgICBvdXRsaW5lOiAnbm9uZScsXG4gICAgICAgIHRleHRBbGlnbjogJ2NlbnRlcicsXG4gICAgICAgIHVzZXJTZWxlY3Q6ICdub25lJyxcbiAgICAgICAgdmVydGljYWxBbGlnbjogJ21pZGRsZScsXG4gICAgICAgIHdoaXRlU3BhY2U6ICdub3dyYXAnLFxuICAgICAgICBib3hTaXppbmc6ICdib3JkZXItYm94JyxcbiAgICAgICAgcGFkZGluZzogJzJweCA2cHggM3B4JyxcbiAgICAgICAgYm9yZGVyOiAwLFxuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICd0cmFuc3BhcmVudCcsXG4gICAgICAgIGN1cnNvcjogJ3BvaW50ZXInLFxuICAgICAgfSk7XG5cbiAgICB0aGlzLmJ1aWxkU3R5bGUoVWkuZWxlbWVudHMuYnV0dG9uLCBVaS5zdGF0ZXMuYWN0aXZlLCBVaS5tb2RpZmllci5iYXNlKVxuICAgICAgLmluaGVyaXRGcm9tKFVpLmVsZW1lbnRzLmJ1dHRvbiwgVWkuc3RhdGVzLm5vcm1hbCwgVWkubW9kaWZpZXIuYmFzZSlcbiAgICAgIC53aXRoU3R5bGVzKDxDbG91a2l0QmFzZUNzc0RlZmluaXRpb25zPntcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiAnIzAwNTJjYycsXG4gICAgICAgIGNvbG9yOiAnI2ZmZmZmZicsXG4gICAgICAgIGN1cnNvcjogJ2RlZmF1bHQnLFxuICAgICAgfSk7XG5cbiAgICB0aGlzLmJ1aWxkU3R5bGUoVWkuZWxlbWVudHMuYnV0dG9uLCBVaS5zdGF0ZXMubm9ybWFsLCBVaS5tb2RpZmllci5ob3ZlcilcbiAgICAgIC5pbmhlcml0RnJvbShVaS5lbGVtZW50cy5idXR0b24sIFVpLnN0YXRlcy5ub3JtYWwsIFVpLm1vZGlmaWVyLmJhc2UpXG4gICAgICAud2l0aFN0eWxlcyg8Q2xvdWtpdEJhc2VDc3NEZWZpbml0aW9ucz57XG4gICAgICAgIHRleHREZWNvcmF0aW9uOiAndW5kZXJsaW5lJyxcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5idWlsZFN0eWxlKFVpLmVsZW1lbnRzLmJ1dHRvbiwgVWkuc3RhdGVzLmRpc2FibGVkLCBVaS5tb2RpZmllci5iYXNlKVxuICAgICAgLmluaGVyaXRGcm9tKFVpLmVsZW1lbnRzLmJ1dHRvbiwgVWkuc3RhdGVzLm5vcm1hbCwgVWkubW9kaWZpZXIuYmFzZSlcbiAgICAgIC53aXRoU3R5bGVzKDxDbG91a2l0QmFzZUNzc0RlZmluaXRpb25zPntcbiAgICAgICAgY29sb3I6ICcjNzc3JyxcbiAgICAgICAgY3Vyc29yOiAnbm90LWFsbG93ZWQnLFxuICAgICAgfSk7XG5cbiAgICAvL1xuICAgIC8vIEZJTExFUlxuICAgIC8vXG4gICAgdGhpcy5idWlsZFN0eWxlKFVpLmVsZW1lbnRzLmZpbGxlciwgVWkuc3RhdGVzLm5vcm1hbCwgVWkubW9kaWZpZXIuYmFzZSlcbiAgICAgIC5pbmhlcml0RnJvbShVaS5lbGVtZW50cy5idXR0b24sIFVpLnN0YXRlcy5ub3JtYWwsIFVpLm1vZGlmaWVyLmJhc2UpXG4gICAgICAud2l0aFN0eWxlcyg8Q2xvdWtpdEJhc2VDc3NEZWZpbml0aW9ucz57XG4gICAgICAgIGNvbG9yOiAnIzU1NScsXG4gICAgICAgIGN1cnNvcjogJ2RlZmF1bHQnLFxuICAgICAgfSk7XG5cbiAgICB0aGlzLmJ1aWxkU3R5bGUoVWkuZWxlbWVudHMuZmlsbGVyLCBVaS5zdGF0ZXMuZGlzYWJsZWQsIFVpLm1vZGlmaWVyLmJhc2UpXG4gICAgICAuaW5oZXJpdEZyb20oVWkuZWxlbWVudHMuZmlsbGVyLCBVaS5zdGF0ZXMubm9ybWFsLCBVaS5tb2RpZmllci5iYXNlKVxuICAgICAgLndpdGhTdHlsZXMoPENsb3VraXRCYXNlQ3NzRGVmaW5pdGlvbnM+e1xuICAgICAgICBjb2xvcjogJyNlZmVmZWYnLFxuICAgICAgICBjdXJzb3I6ICdub3QtYWxsb3dlZCcsXG4gICAgICB9KTtcbiAgfVxuXG59XG5cbiIsIi8qIVxuICogQGxpY2Vuc2UgTUlUXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTcgQmVybmhhcmQgR3LDg8K8bmV3YWxkdCAtIGNvZGVjbG91LmlvXG4gKiBodHRwczovL2dpdGh1Yi5jb20vY2xvdWtpdC9sZWdhbFxuICovXG5pbXBvcnQgeyBQYWdpbmF0aW9uSXRlbSB9IGZyb20gJy4uL3BhZ2luYXRpb24ubW9kZWwnO1xuXG4vL1xuLy8gSEVMUEVSIEZVTkNUSU9OU1xuLy9cbmNvbnN0IGNyZWF0ZUZpbGxlciA9ICgpID0+IG5ldyBQYWdpbmF0aW9uSXRlbSgtMSwgZmFsc2UsIHRydWUsICcuLi4nKTtcbmNvbnN0IGNyZWF0ZUFuSXRlbSA9IChwYWdlOiBudW1iZXIsIGFjdGl2ZTogYm9vbGVhbikgPT4gbmV3IFBhZ2luYXRpb25JdGVtKHBhZ2UsIGFjdGl2ZSwgZmFsc2UsIGAke3BhZ2V9YCk7XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIHBhZ2VzIHdpdGggYSB0b3RhbCBvZiBzZXZlbi4gU2VlIFVuaXQgVGVzdC5cbiAqIEV4YW1wbGVzOlxuICogICBDQVNFIDE6ICAxICAgMiAgIDMgICAqNCogICA1ICAgNiAgIDdcbiAqICAgICAgICAgICAgMSAgIDIgICAzICAgKjQqICAgNVxuICogICBDQVNFIDI6ICAxICAgMiAgIDMgICAqNCogICA1ICAgLi4gIDUwXG4gKiAgIENBU0UgMzogIDEgICAuLiAgNDYgICo0NyogIDQ4ICA0OSAgNTBcbiAqICAgQ0FTRSA0OiAgMSAgIC4uICA0OSAgKjUwKiAgNTEgIC4uICA5MFxuICovXG5jb25zdCBjYWxjdWxhdGVQYWdpbmF0aW9uSXRlbXMgPSAodG90YWw6IG51bWJlciwgY3VycmVudDogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IHBhZ2luYXRpb25JdGVtczogUGFnaW5hdGlvbkl0ZW1bXSA9IFtdO1xuICBpZiAodG90YWwgPT09IHVuZGVmaW5lZCB8fCB0b3RhbCA9PT0gbnVsbCB8fCBjdXJyZW50ID09PSB1bmRlZmluZWQgfHwgY3VycmVudCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBwYWdpbmF0aW9uSXRlbXM7XG4gIH1cbiAgLy9cbiAgLy8gQ0FTRSAxOiBUb3RhbCBpcyBzbWFsbGVyIG9yIGVxdWFsIHNldmVuXG4gIC8vXG4gIGlmICh0b3RhbCA8PSA3KSB7XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gdG90YWw7IGkrKykge1xuICAgICAgcGFnaW5hdGlvbkl0ZW1zLnB1c2gobmV3IFBhZ2luYXRpb25JdGVtKGksIGN1cnJlbnQgPT09IGksIGZhbHNlLCBgJHtpfWApKTtcbiAgICB9XG4gIH0gZWxzZVxuICAvL1xuICAvLyBDQVNFIDI6IFRvdGFsIGlzIGdyZWF0ZXIgdGhhbiBzZXZlbiBBTkQgcGFnZSBpcyBpbiByYW5nZSBvZiBbMS00XVxuICAvL1xuICBpZiAodG90YWwgPiA3ICYmIGN1cnJlbnQgPD0gNCkge1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDw9IDU7IGkrKykge1xuICAgICAgcGFnaW5hdGlvbkl0ZW1zLnB1c2goY3JlYXRlQW5JdGVtKGksIGN1cnJlbnQgPT09IGkpKTtcbiAgICB9XG4gICAgcGFnaW5hdGlvbkl0ZW1zLnB1c2goY3JlYXRlRmlsbGVyKCkpO1xuICAgIHBhZ2luYXRpb25JdGVtcy5wdXNoKGNyZWF0ZUFuSXRlbSh0b3RhbCwgZmFsc2UpKTtcbiAgfSBlbHNlXG4gIC8vXG4gIC8vIENBU0UgMzogVG90YWwgaXMgZ3JlYXRlciB0aGFuIHNldmVuIEFORCBwYWdlIGlzIGdyZWF0ZXIgdGhhbiBmb3VyIEFORCBwYWdlIGlzIG5lYXIgdG90YWxcbiAgLy9cbiAgaWYgKHRvdGFsID4gNyAmJiBjdXJyZW50ID4gNCAmJiBjdXJyZW50ICsgMyA+PSB0b3RhbCkge1xuICAgIHBhZ2luYXRpb25JdGVtcy5wdXNoKGNyZWF0ZUFuSXRlbSgxLCBmYWxzZSkpO1xuICAgIHBhZ2luYXRpb25JdGVtcy5wdXNoKGNyZWF0ZUZpbGxlcigpKTtcbiAgICBmb3IgKGxldCBpID0gdG90YWwgLSA0OyBpIDw9IHRvdGFsOyBpKyspIHtcbiAgICAgIHBhZ2luYXRpb25JdGVtcy5wdXNoKGNyZWF0ZUFuSXRlbShpLCBjdXJyZW50ID09PSBpKSk7XG4gICAgfVxuICB9IGVsc2VcbiAgLy9cbiAgLy8gQ0FTRSA0OiBUb3RhbCBpcyBncmVhdGVyIHRoYW4gc2V2ZW4gQU5EIHBhZ2UgaXMgZ3JlYXRlciB0aGFuIGZvdXJcbiAgLy9cbiAgaWYgKHRvdGFsID4gNyAmJiBjdXJyZW50ID4gNCkge1xuICAgIHBhZ2luYXRpb25JdGVtcy5wdXNoKGNyZWF0ZUFuSXRlbSgxLCBmYWxzZSkpO1xuICAgIHBhZ2luYXRpb25JdGVtcy5wdXNoKGNyZWF0ZUZpbGxlcigpKTtcbiAgICBwYWdpbmF0aW9uSXRlbXMucHVzaChjcmVhdGVBbkl0ZW0oY3VycmVudCAtIDEsIGZhbHNlKSk7XG4gICAgcGFnaW5hdGlvbkl0ZW1zLnB1c2goY3JlYXRlQW5JdGVtKGN1cnJlbnQsIHRydWUpKTtcbiAgICBwYWdpbmF0aW9uSXRlbXMucHVzaChjcmVhdGVBbkl0ZW0oY3VycmVudCArIDEsIGZhbHNlKSk7XG4gICAgcGFnaW5hdGlvbkl0ZW1zLnB1c2goY3JlYXRlRmlsbGVyKCkpO1xuICAgIHBhZ2luYXRpb25JdGVtcy5wdXNoKGNyZWF0ZUFuSXRlbSh0b3RhbCwgZmFsc2UpKTtcbiAgfVxuICAvL1xuICAvLyBFTkRcbiAgLy9cbiAgcmV0dXJuIHBhZ2luYXRpb25JdGVtcztcbn07XG5cbmV4cG9ydCB7IGNhbGN1bGF0ZVBhZ2luYXRpb25JdGVtcywgY3JlYXRlRmlsbGVyIH07XG4iLCIvKiFcbiAqIEBsaWNlbnNlIE1JVFxuICogQ29weXJpZ2h0IChjKSAyMDE3IEJlcm5oYXJkIEdyw4PCvG5ld2FsZHQgLSBjb2RlY2xvdS5pb1xuICogaHR0cHM6Ly9naXRodWIuY29tL2Nsb3VraXQvbGVnYWxcbiAqL1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyLCBDb21wb25lbnQsIElucHV0LCBPbkNoYW5nZXMsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgQ2xvdWtpdENvbXBvbmVudFRoZW1lLCBDbG91a2l0U3RhdGVmdWxBbmRNb2RpZmllckF3YXJlRWxlbWVudFRoZW1lU3R5bGVEZWZpbml0aW9uLFxuICBDbG91a2l0VGhlbWVTZXJ2aWNlLFxufSBmcm9tICdAY2xvdWtpdC90aGVtZSc7XG5pbXBvcnQgeyBjYWxjdWxhdGVQYWdpbmF0aW9uSXRlbXMgfSBmcm9tICcuL2xvZ2ljL3BhZ2luYXRpb24taGVscGVyJztcbmltcG9ydCB7IFBhZ2luYXRpb25CdXR0b25DbGlja0V2ZW50LCBQYWdpbmF0aW9uQnV0dG9uVHlwZSwgUGFnaW5hdGlvbkl0ZW0gfSBmcm9tICcuL3BhZ2luYXRpb24ubW9kZWwnO1xuXG4vKipcbiAqIFBhZ2luYXRpb24gQ29tcG9uZW50LlxuICpcbiAqIEp1c3QgdXNlIHRoaXMgaW5zaWRlIHlvdXIgdGVtcGxhdGVzOlxuICpcbiAqIGBgYGh0bWxcbiAqIDxjbG91a2l0LXBhZ2luYXRpb24gLi4uPjwvY2xvdWtpdC1wYWdpbmF0aW9uPlxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2Nsb3VraXQtcGFnaW5hdGlvbicsXG4gIHRlbXBsYXRlOiBgXG4gIDxkaXYgW25nU3R5bGVdPVwiZ2V0U3R5bGUoJ3dyYXBwZXInKS5zdHlsZVwiPlxuICAgIDxjbG91a2l0LXBhZ2luYXRpb24tYnV0dG9uXG4gICAgICBbZGlzYWJsZWRdPVwiIWlzUHJldmlvdXNQb3NzaWJsZSgpIHx8IGRpc2FibGVkXCJcbiAgICAgIFtwYWdpbmF0aW9uSXRlbV09XCJwcmV2aW91c0R1bW15UGFnaW5hdGlvbkl0ZW0oKVwiXG4gICAgICBbdGhlbWVTZWxlY3RlZF09XCJ0aGVtZVNlbGVjdGVkXCJcbiAgICAgIFt0eXBlXT1cIlBhZ2luYXRpb25CdXR0b25UeXBlWydwcmV2aW91cyddXCJcbiAgICAgIChjbGlja2VkKT1cInNlbGVjdFBhZ2UoJGV2ZW50KVwiXG4gICAgPjwvY2xvdWtpdC1wYWdpbmF0aW9uLWJ1dHRvbj5cbiAgICA8Y2xvdWtpdC1wYWdpbmF0aW9uLWJ1dHRvblxuICAgICAgKm5nRm9yPVwibGV0IHBhZ2Ugb2Ygc3RhdGUucGFnZXNcIlxuICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgIFtwYWdpbmF0aW9uSXRlbV09XCJwYWdlXCJcbiAgICAgIFt0aGVtZVNlbGVjdGVkXT1cInRoZW1lU2VsZWN0ZWRcIlxuICAgICAgW3R5cGVdPVwiUGFnaW5hdGlvbkJ1dHRvblR5cGVbJ25vcm1hbCddXCJcbiAgICAgIChjbGlja2VkKT1cInNlbGVjdFBhZ2UoJGV2ZW50KVwiXG4gICAgPjwvY2xvdWtpdC1wYWdpbmF0aW9uLWJ1dHRvbj5cbiAgICA8Y2xvdWtpdC1wYWdpbmF0aW9uLWJ1dHRvblxuICAgICAgW2Rpc2FibGVkXT1cIiFpc05leHRQb3NzaWJsZSgpIHx8IGRpc2FibGVkXCJcbiAgICAgIFtwYWdpbmF0aW9uSXRlbV09XCJuZXh0RHVtbXlQYWdpbmF0aW9uSXRlbSgpXCJcbiAgICAgIFt0aGVtZVNlbGVjdGVkXT1cInRoZW1lU2VsZWN0ZWRcIlxuICAgICAgW3R5cGVdPVwiUGFnaW5hdGlvbkJ1dHRvblR5cGVbJ25leHQnXVwiXG4gICAgICAoY2xpY2tlZCk9XCJzZWxlY3RQYWdlKCRldmVudClcIlxuICAgID48L2Nsb3VraXQtcGFnaW5hdGlvbi1idXR0b24+XG4gIDwvZGl2PmAsXG4gIHN0eWxlczogWyBdLFxufSlcbmV4cG9ydCBjbGFzcyBDbG91a2l0UGFnaW5hdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIHRoZW1lIHNlbGVjdG9yLiBPbmx5IHVzZSBgdGhlbWVgIHdoZW4geW91IGhhdmUgcmVnaXN0ZXJlZCBhIHZhbGlkIHRoZW1lXG4gICAqIHZpYSB0aGUgYENsb3VraXRUaGVtZVNlcnZpY2VgIGZyb20gW2BAY2xvdWtpdC90aGVtZWBde0BsaW5rIGh0dHBzOi8vY2xvdWtpdC5naXRodWIuaW8vIy9jb21wb25lbnQvdGhlbWV9LlxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHRoZW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiB0b3RhbCBQYWdlc1xuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIHRvdGFsOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEN1cnJlbnQgUGFnZVxuICAgKi9cbiAgQElucHV0KClcbiAgcHVibGljIGN1cnJlbnQ6IG51bWJlcjtcblxuICAvKipcbiAgICogRXh0ZXJuYWwgd2F5IHRvIGRpc2FibGUgdGhlIHdob2xlIHBhZ2luYXRpb24gZS5nLlxuICAgKiBkdXJpbmcgbG9hZGluZyBleHRlcm5hbCBkYXRhXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgZGlzYWJsZWQgPSBmYWxzZTtcblxuICAvKipcbiAgICogT3B0aW9uYWwgTGFiZWwgZm9yIHRoZSBcIk5leHRcIiBidXR0b24sIGRlZmF1bHRzIHRvIFwiTmV4dFwiXG4gICAqL1xuICBASW5wdXQoKVxuICBwdWJsaWMgbGFiZWxOZXh0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIExhYmVsIGZvciB0aGUgXCJQcmV2aW91c1wiIGJ1dHRvbiwgZGVmYXVsdHMgdG8gXCJQcmV2XCJcbiAgICovXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBsYWJlbFByZXY6IHN0cmluZztcblxuICAvKipcbiAgICogRXZlbnQgZW1pdHRlZCwgd2hlbiBwYWdlIGlzIGNsaWNrZWQuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG4gIHB1YmxpYyBvblBhZ2VTZWxlY3Q6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIC8vIElOVEVSTkFMIFZBUklBQkxFU1xuICBwdWJsaWMgdGhlbWVTZWxlY3RlZDogQ2xvdWtpdENvbXBvbmVudFRoZW1lO1xuICBwdWJsaWMgUGFnaW5hdGlvbkJ1dHRvblR5cGUgPSBQYWdpbmF0aW9uQnV0dG9uVHlwZTtcbiAgcHVibGljIHN0YXRlID0ge1xuICAgIHBhZ2VzOiBbXVxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgdGhlbWVTZXJ2aWNlOiBDbG91a2l0VGhlbWVTZXJ2aWNlKSB7XG4gICAgdGhpcy50aGVtZVNlbGVjdGVkID0gdGhpcy50aGVtZVNlcnZpY2UuZ2V0Q29tcG9uZW50VGhlbWUoJ3BhZ2luYXRpb24nKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRTdHlsZShlbGVtZW50OiBzdHJpbmcpOiBDbG91a2l0U3RhdGVmdWxBbmRNb2RpZmllckF3YXJlRWxlbWVudFRoZW1lU3R5bGVEZWZpbml0aW9uIHtcbiAgICBjb25zdCBzdHlsZSA9IHRoaXMudGhlbWVTZWxlY3RlZC5nZXRTdHlsZShlbGVtZW50LCAnbm9ybWFsJywgJ2Jhc2UnKTtcbiAgICByZXR1cm4gdGhpcy50aGVtZVNlcnZpY2UucHJlZml4U3R5bGUoc3R5bGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBvdmVycmlkZXMgT25DaGFuZ2VzXG4gICAqIEBoaWRkZW5cbiAgICovXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIGlmICh0aGlzLnRoZW1lICE9PSB1bmRlZmluZWQgJiYgdGhpcy50aGVtZSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy50aGVtZVNlbGVjdGVkID0gdGhpcy50aGVtZVNlcnZpY2UuZ2V0Q29tcG9uZW50VGhlbWUodGhpcy50aGVtZSk7XG4gICAgICBpZiAodGhpcy50aGVtZVNlbGVjdGVkID09PSBudWxsKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBXQVJOOiByZXF1ZXN0ZWQgdGhlbWUgJHt0aGlzLnRoZW1lfSBkb2VzIG5vdCBleGlzdC4gRmFsbGluZyBiYWNrIHRvIGRlZmF1bHQgdGhlbWUgZm9yIHBhZ2luYXRpb24uYCk7XG4gICAgICAgIHRoaXMudGhlbWVTZWxlY3RlZCA9IHRoaXMudGhlbWVTZXJ2aWNlLmdldENvbXBvbmVudFRoZW1lKCdwYWdpbmF0aW9uJyk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuc3RhdGUucGFnZXMgPSBjYWxjdWxhdGVQYWdpbmF0aW9uSXRlbXModGhpcy50b3RhbCwgdGhpcy5jdXJyZW50KTtcbiAgfVxuXG4gIHNlbGVjdFBhZ2UoZXZlbnQ6IFBhZ2luYXRpb25CdXR0b25DbGlja0V2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnR5cGUgPT09IFBhZ2luYXRpb25CdXR0b25UeXBlWydwcmV2aW91cyddICYmXG4gICAgICB0aGlzLmlzUHJldmlvdXNQb3NzaWJsZSgpKSB7XG4gICAgICB0aGlzLm9uUGFnZVNlbGVjdC5lbWl0KHRoaXMuY3VycmVudCAtIDEpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gUGFnaW5hdGlvbkJ1dHRvblR5cGVbJ25leHQnXSAmJlxuICAgICAgdGhpcy5pc05leHRQb3NzaWJsZSgpKSB7XG4gICAgICB0aGlzLm9uUGFnZVNlbGVjdC5lbWl0KHRoaXMuY3VycmVudCArIDEpO1xuICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gUGFnaW5hdGlvbkJ1dHRvblR5cGVbJ25vcm1hbCddKSB7XG4gICAgICB0aGlzLm9uUGFnZVNlbGVjdC5lbWl0KGV2ZW50LnBhZ2UpO1xuICAgIH1cbiAgfVxuXG4gIHByZXZpb3VzRHVtbXlQYWdpbmF0aW9uSXRlbSgpIHtcbiAgICBsZXQgbGFiZWwgPSAnUHJldic7XG4gICAgaWYgKHRoaXMubGFiZWxQcmV2ICE9PSB1bmRlZmluZWQgJiYgdGhpcy5sYWJlbFByZXYgIT09IG51bGwpIHtcbiAgICAgIGxhYmVsID0gdGhpcy5sYWJlbFByZXY7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUGFnaW5hdGlvbkl0ZW0oLTEsIGZhbHNlLCBmYWxzZSwgbGFiZWwpO1xuICB9XG5cbiAgbmV4dER1bW15UGFnaW5hdGlvbkl0ZW0oKSB7XG4gICAgbGV0IGxhYmVsID0gJ05leHQnO1xuICAgIGlmICh0aGlzLmxhYmVsTmV4dCAhPT0gdW5kZWZpbmVkICYmIHRoaXMubGFiZWxOZXh0ICE9PSBudWxsKSB7XG4gICAgICBsYWJlbCA9IHRoaXMubGFiZWxOZXh0O1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFBhZ2luYXRpb25JdGVtKC0xLCBmYWxzZSwgZmFsc2UsIGxhYmVsKTtcbiAgfVxuXG4gIGlzUHJldmlvdXNQb3NzaWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50ID4gMTtcbiAgfVxuXG4gIGlzTmV4dFBvc3NpYmxlKCkge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnQgPCB0aGlzLnRvdGFsO1xuICB9XG5cbn1cblxuIiwiLyohXG4gKiBAbGljZW5zZSBNSVRcbiAqIENvcHlyaWdodCAoYykgMjAxNyBCZXJuaGFyZCBHcsODwrxuZXdhbGR0IC0gY29kZWNsb3UuaW9cbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jbG91a2l0L2xlZ2FsXG4gKi9cbmltcG9ydCB7IEV2ZW50RW1pdHRlciwgQ29tcG9uZW50LCBJbnB1dCwgT3V0cHV0LCBPbkNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENsb3VraXRDb21wb25lbnRUaGVtZSwgQ2xvdWtpdFRoZW1lU2VydmljZSwgVWlFbGVtZW50IH0gZnJvbSAnQGNsb3VraXQvdGhlbWUnO1xuaW1wb3J0IHsgVWkgfSBmcm9tICcuLi9wYWdpbmF0aW9uLm1vZGVsJztcbmltcG9ydCB7IFBhZ2luYXRpb25CdXR0b25DbGlja0V2ZW50LCBQYWdpbmF0aW9uQnV0dG9uVHlwZSwgUGFnaW5hdGlvbkl0ZW0gfSBmcm9tICcuLi9wYWdpbmF0aW9uLm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2xvdWtpdC1wYWdpbmF0aW9uLWJ1dHRvbicsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgW25nU3R5bGVdPVwic3R5bGU/LnN0eWxlXCJcbiAgICAgIChjbGljayk9XCJkb0NsaWNrKClcIlxuICAgICAgKG1vdXNlZW50ZXIpPVwibW91c2VFbnRlcigpXCJcbiAgICAgIChtb3VzZWxlYXZlKT1cIm1vdXNlTGVhdmUoKVwiXG4gICAgPlxuICAgICAge3twYWdpbmF0aW9uSXRlbS5sYWJlbH19XG4gICAgPC9idXR0b24+YCxcbiAgc3R5bGVzOiBbIF0sXG59KVxuZXhwb3J0IGNsYXNzIENsb3VraXRQYWdpbmF0aW9uQnV0dG9uQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgZGlzYWJsZWQ6IGJvb2xlYW47XG5cbiAgQElucHV0KClcbiAgcHVibGljIHR5cGU6IFBhZ2luYXRpb25CdXR0b25UeXBlO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyBwYWdpbmF0aW9uSXRlbTogUGFnaW5hdGlvbkl0ZW07XG5cbiAgQElucHV0KClcbiAgcHVibGljIHRoZW1lU2VsZWN0ZWQ6IENsb3VraXRDb21wb25lbnRUaGVtZTtcblxuICBAT3V0cHV0KClcbiAgcHVibGljIGNsaWNrZWQ6IEV2ZW50RW1pdHRlcjxQYWdpbmF0aW9uQnV0dG9uQ2xpY2tFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgLy9cbiAgLy8gSU5URVJOQUxcbiAgLy9cbiAgcHJpdmF0ZSB1aTogVWlFbGVtZW50O1xuICBwdWJsaWMgc3R5bGU6IGFueTtcbiAgcHJpdmF0ZSBpc01vdXNlU3RpbGxPdmVyID0gZmFsc2U7XG5cbiAgcHVibGljIHN0YXRpYyB0cmFuc2Zvcm0ocGFnZUl0ZW06IFBhZ2luYXRpb25JdGVtKTogVWlFbGVtZW50IHtcbiAgICBpZiAocGFnZUl0ZW0gPT09IHVuZGVmaW5lZCB8fCBwYWdlSXRlbSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG5ldyBVaUVsZW1lbnQoVWkuZWxlbWVudHMuZmlsbGVyLCBVaS5zdGF0ZXMuZGlzYWJsZWQsIFVpLm1vZGlmaWVyLmJhc2UpO1xuICAgIH1cbiAgICBjb25zdCB1aUVsZW1lbnQgPSBwYWdlSXRlbS5pc0ZpbGxlciA/IFVpLmVsZW1lbnRzLmZpbGxlciA6IFVpLmVsZW1lbnRzLmJ1dHRvbjtcbiAgICBjb25zdCB1aVN0YXRlID0gcGFnZUl0ZW0uaXNBY3RpdmUgPyBVaS5zdGF0ZXMuYWN0aXZlIDogVWkuc3RhdGVzLm5vcm1hbDtcbiAgICByZXR1cm4gbmV3IFVpRWxlbWVudCh1aUVsZW1lbnQsIHVpU3RhdGUsIFVpLm1vZGlmaWVyLmJhc2UpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0aGVtZVNlcnZpY2U6IENsb3VraXRUaGVtZVNlcnZpY2UpIHtcbiAgfVxuXG4gIHVwZGF0ZVN0eWxlKCkge1xuICAgIGNvbnN0IHN0eWxlID0gdGhpcy50aGVtZVNlbGVjdGVkLmdldFVpU3R5bGUodGhpcy51aSk7XG4gICAgaWYgKHN0eWxlICE9PSBudWxsKSB7XG4gICAgICB0aGlzLnN0eWxlID0gdGhpcy50aGVtZVNlcnZpY2UucHJlZml4U3R5bGUoc3R5bGUpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIC8vIHJldGFpbiBtb3VzZUVudGVyIGFuZCBtb3VzZUxlYXZlIG1vZGlmaWVyIGNoYW5nZXMhXG4gICAgbGV0IG1vZGlmaWVyOiBzdHJpbmcgPSBudWxsO1xuICAgIGlmICh0aGlzLnVpICE9PSBudWxsICYmIHRoaXMudWkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgbW9kaWZpZXIgPSB0aGlzLnVpLm1vZGlmaWVyO1xuICAgIH1cbiAgICB0aGlzLnVpID0gQ2xvdWtpdFBhZ2luYXRpb25CdXR0b25Db21wb25lbnQudHJhbnNmb3JtKHRoaXMucGFnaW5hdGlvbkl0ZW0pO1xuICAgIGlmIChtb2RpZmllciAhPT0gbnVsbCAmJiB0aGlzLmlzTW91c2VTdGlsbE92ZXIpIHtcbiAgICAgIHRoaXMudWkubW9kaWZpZXIgPSBtb2RpZmllcjtcbiAgICB9XG4gICAgaWYgKHRoaXMuZGlzYWJsZWQgPT09IHRydWUpIHtcbiAgICAgIHRoaXMudWkuc3RhdGUgPSBVaS5zdGF0ZXMuZGlzYWJsZWQ7XG4gICAgICB0aGlzLnVpLm1vZGlmaWVyID0gVWkubW9kaWZpZXIuYmFzZTtcbiAgICB9XG4gICAgdGhpcy51cGRhdGVTdHlsZSgpO1xuICB9XG5cbiAgcHVibGljIG1vdXNlRW50ZXIoKSB7XG4gICAgdGhpcy51aS5tb2RpZmllciA9IFVpLm1vZGlmaWVyLmhvdmVyO1xuICAgIHRoaXMuaXNNb3VzZVN0aWxsT3ZlciA9IHRydWU7XG4gICAgdGhpcy51cGRhdGVTdHlsZSgpO1xuICB9XG5cbiAgcHVibGljIG1vdXNlTGVhdmUoKSB7XG4gICAgdGhpcy51aS5tb2RpZmllciA9IFVpLm1vZGlmaWVyLmJhc2U7XG4gICAgdGhpcy5pc01vdXNlU3RpbGxPdmVyID0gZmFsc2U7XG4gICAgdGhpcy51cGRhdGVTdHlsZSgpO1xuICB9XG5cbiAgcHVibGljIGRvQ2xpY2soKSB7XG4gICAgaWYgKCF0aGlzLnBhZ2luYXRpb25JdGVtLmlzRmlsbGVyKSB7XG4gICAgICB0aGlzLmNsaWNrZWQuZW1pdChuZXcgUGFnaW5hdGlvbkJ1dHRvbkNsaWNrRXZlbnQodGhpcy50eXBlLCB0aGlzLnBhZ2luYXRpb25JdGVtLnBhZ2UpKTtcbiAgICB9XG4gIH1cblxuXG5cbn1cblxuIiwiLyohXG4gKiBAbGljZW5zZSBNSVRcbiAqIENvcHlyaWdodCAoYykgMjAxNyBCZXJuaGFyZCBHcsODwrxuZXdhbGR0IC0gY29kZWNsb3UuaW9cbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jbG91a2l0L2xlZ2FsXG4gKi9cbmltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQ2xvdWtpdFBhZ2luYXRpb25Db21wb25lbnQgfSBmcm9tICcuL3BhZ2luYXRpb24uY29tcG9uZW50JztcbmltcG9ydCB7IENsb3VraXRUaGVtZVNlcnZpY2UgfSBmcm9tICdAY2xvdWtpdC90aGVtZSc7XG5pbXBvcnQgeyBDbG91a2l0UGFnaW5hdGlvbkNvbXBvbmVudFRoZW1lRGVmYXVsdCB9IGZyb20gJy4vcGFnaW5hdGlvbi50aGVtZSc7XG5pbXBvcnQgeyBDbG91a2l0UGFnaW5hdGlvbkJ1dHRvbkNvbXBvbmVudCB9IGZyb20gJy4vY2hpbGRyZW4vcGFnaW5hdGlvbi1idXR0b24uY29tcG9uZW50JztcblxuQE5nTW9kdWxlKHtcbiAgaW1wb3J0czogWyBDb21tb25Nb2R1bGUgXSxcbiAgZXhwb3J0czogWyBDbG91a2l0UGFnaW5hdGlvbkNvbXBvbmVudCBdLFxuICBkZWNsYXJhdGlvbnM6IFsgQ2xvdWtpdFBhZ2luYXRpb25Db21wb25lbnQsIENsb3VraXRQYWdpbmF0aW9uQnV0dG9uQ29tcG9uZW50IF0sXG59KVxuZXhwb3J0IGNsYXNzIENsb3VraXRQYWdpbmF0aW9uTW9kdWxlIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0aGVtZVNlcnZpY2U6IENsb3VraXRUaGVtZVNlcnZpY2UpIHtcbiAgICBpZiAodGhpcy50aGVtZVNlcnZpY2UuZ2V0Q29tcG9uZW50VGhlbWUoJ3BhZ2luYXRpb24nKSA9PT0gbnVsbCkge1xuICAgICAgdGhpcy50aGVtZVNlcnZpY2UucmVnaXN0ZXJDb21wb25lbnRUaGVtZSgncGFnaW5hdGlvbicsIG5ldyBDbG91a2l0UGFnaW5hdGlvbkNvbXBvbmVudFRoZW1lRGVmYXVsdCgpKTtcbiAgICB9XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJ0c2xpYl8xLl9fZXh0ZW5kcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFNQTtJQUNFLG9DQUFtQixJQUEwQixFQUFTLElBQVk7UUFBL0MsU0FBSSxHQUFKLElBQUksQ0FBc0I7UUFBUyxTQUFJLEdBQUosSUFBSSxDQUFRO0tBQUk7SUFDeEUsaUNBQUM7Q0FBQSxJQUFBOzs7SUFHQyxTQUFVO0lBQ1YsV0FBWTtJQUNaLE9BQVE7Ozs7O0FBR1Y7SUFDRSx3QkFDUyxJQUFZLEVBQ1osUUFBaUIsRUFDakIsUUFBaUIsRUFDakIsS0FBYTtRQUhiLFNBQUksR0FBSixJQUFJLENBQVE7UUFDWixhQUFRLEdBQVIsUUFBUSxDQUFTO1FBQ2pCLGFBQVEsR0FBUixRQUFRLENBQVM7UUFDakIsVUFBSyxHQUFMLEtBQUssQ0FBUTtLQUFJO0lBQzVCLHFCQUFDO0NBQUEsSUFBQTs7SUFFRDtLQWVDO0lBZGUsV0FBUSxHQUFRO1FBQzVCLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLE1BQU0sRUFBRSxRQUFRO1FBQ2hCLE9BQU8sRUFBRSxTQUFTO0tBQ25CLENBQUM7SUFDWSxTQUFNLEdBQVE7UUFDMUIsTUFBTSxFQUFFLFFBQVE7UUFDaEIsTUFBTSxFQUFFLFFBQVE7UUFDaEIsUUFBUSxFQUFFLFVBQVU7S0FDckIsQ0FBQztJQUNZLFdBQVEsR0FBUTtRQUM1QixJQUFJLEVBQUUsTUFBTTtRQUNaLEtBQUssRUFBRSxPQUFPO0tBQ2YsQ0FBQztJQUNKLFNBQUM7Q0FmRDs7Ozs7OztJQ2hCNERBLDBEQUFxQjtJQUUvRTtRQUFBLFlBQ0UsaUJBQU8sU0F3RVI7Ozs7UUFwRUMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzthQUNyRSxVQUFVLG9CQUE0QjtZQUNyQyxPQUFPLEVBQUUsTUFBTTtTQUNoQixHQUFDLENBQUM7Ozs7UUFLTCxLQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO2FBQ3BFLFVBQVUsb0JBQTRCO1lBQ3JDLFNBQVMsRUFBRSxRQUFRO1lBQ25CLE9BQU8sRUFBRSxhQUFhO1lBQ3RCLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLFFBQVEsRUFBRSxNQUFNO1lBQ2hCLEtBQUssRUFBRSxTQUFTO1lBQ2hCLGNBQWMsRUFBRSxNQUFNO1lBQ3RCLFNBQVMsRUFBRSxRQUFRO1lBQ25CLFFBQVEsRUFBRSxTQUFTO1lBQ25CLE1BQU0sRUFBRSxDQUFDO1lBQ1QsT0FBTyxFQUFFLE1BQU07WUFDZixTQUFTLEVBQUUsUUFBUTtZQUNuQixVQUFVLEVBQUUsTUFBTTtZQUNsQixhQUFhLEVBQUUsUUFBUTtZQUN2QixVQUFVLEVBQUUsUUFBUTtZQUNwQixTQUFTLEVBQUUsWUFBWTtZQUN2QixPQUFPLEVBQUUsYUFBYTtZQUN0QixNQUFNLEVBQUUsQ0FBQztZQUNULGVBQWUsRUFBRSxhQUFhO1lBQzlCLE1BQU0sRUFBRSxTQUFTO1NBQ2xCLEdBQUMsQ0FBQztRQUVMLEtBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7YUFDcEUsV0FBVyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO2FBQ25FLFVBQVUsb0JBQTRCO1lBQ3JDLGVBQWUsRUFBRSxTQUFTO1lBQzFCLEtBQUssRUFBRSxTQUFTO1lBQ2hCLE1BQU0sRUFBRSxTQUFTO1NBQ2xCLEdBQUMsQ0FBQztRQUVMLEtBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7YUFDckUsV0FBVyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO2FBQ25FLFVBQVUsb0JBQTRCO1lBQ3JDLGNBQWMsRUFBRSxXQUFXO1NBQzVCLEdBQUMsQ0FBQztRQUVMLEtBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7YUFDdEUsV0FBVyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO2FBQ25FLFVBQVUsb0JBQTRCO1lBQ3JDLEtBQUssRUFBRSxNQUFNO1lBQ2IsTUFBTSxFQUFFLGFBQWE7U0FDdEIsR0FBQyxDQUFDOzs7O1FBS0wsS0FBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzthQUNwRSxXQUFXLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7YUFDbkUsVUFBVSxvQkFBNEI7WUFDckMsS0FBSyxFQUFFLE1BQU07WUFDYixNQUFNLEVBQUUsU0FBUztTQUNsQixHQUFDLENBQUM7UUFFTCxLQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO2FBQ3RFLFdBQVcsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQzthQUNuRSxVQUFVLG9CQUE0QjtZQUNyQyxLQUFLLEVBQUUsU0FBUztZQUNoQixNQUFNLEVBQUUsYUFBYTtTQUN0QixHQUFDLENBQUM7O0tBQ047SUFFSCw2Q0FBQztDQTdFRCxDQUE0RCxxQkFBcUI7Ozs7Ozs7Ozs7SUNFM0UsWUFBWSxHQUFHLGNBQU0sT0FBQSxJQUFJLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxHQUFBOztJQUMvRCxZQUFZLEdBQUcsVUFBQyxJQUFZLEVBQUUsTUFBZSxJQUFLLE9BQUEsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsS0FBRyxJQUFNLENBQUMsR0FBQTs7Ozs7Ozs7Ozs7SUFXcEcsd0JBQXdCLEdBQUcsVUFBQyxLQUFhLEVBQUUsT0FBZTs7UUFDeEQsZUFBZSxHQUFxQixFQUFFO0lBQzVDLElBQUksS0FBSyxLQUFLLFNBQVMsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxTQUFTLElBQUksT0FBTyxLQUFLLElBQUksRUFBRTtRQUN0RixPQUFPLGVBQWUsQ0FBQztLQUN4Qjs7OztJQUlELElBQUksS0FBSyxJQUFJLENBQUMsRUFBRTtRQUNkLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDL0IsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLGNBQWMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBRyxDQUFHLENBQUMsQ0FBQyxDQUFDO1NBQzNFO0tBQ0Y7Ozs7O0lBSUQsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLE9BQU8sSUFBSSxDQUFDLEVBQUU7UUFDN0IsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUMzQixlQUFlLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLEVBQUUsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDdEQ7UUFDRCxlQUFlLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDckMsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7S0FDbEQ7Ozs7O0lBSUQsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLE9BQU8sR0FBRyxDQUFDLElBQUksT0FBTyxHQUFHLENBQUMsSUFBSSxLQUFLLEVBQUU7UUFDcEQsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDN0MsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQ3JDLEtBQUssSUFBSSxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3ZDLGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN0RDtLQUNGOzs7OztJQUlELElBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxPQUFPLEdBQUcsQ0FBQyxFQUFFO1FBQzVCLGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzdDLGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUNyQyxlQUFlLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDdkQsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDbEQsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3ZELGVBQWUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUNyQyxlQUFlLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQztLQUNsRDs7OztJQUlELE9BQU8sZUFBZSxDQUFDO0NBQ3hCOzs7Ozs7Ozs7Ozs7Ozs7QUNqREQ7SUFtRkUsb0NBQW9CLFlBQWlDO1FBQWpDLGlCQUFZLEdBQVosWUFBWSxDQUFxQjs7Ozs7UUE1QjlDLGFBQVEsR0FBRyxLQUFLLENBQUM7Ozs7UUFtQmpCLGlCQUFZLEdBQXlCLElBQUksWUFBWSxFQUFFLENBQUM7UUFJeEQseUJBQW9CLEdBQUcsb0JBQW9CLENBQUM7UUFDNUMsVUFBSyxHQUFHO1lBQ2IsS0FBSyxFQUFFLEVBQUU7U0FDVixDQUFDO1FBR0EsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxDQUFDO0tBQ3hFOzs7OztJQUVNLDZDQUFROzs7O0lBQWYsVUFBZ0IsT0FBZTs7WUFDdkIsS0FBSyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDO1FBQ3BFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDN0M7Ozs7Ozs7Ozs7SUFNRCxnREFBVzs7Ozs7SUFBWDtRQUNFLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLEVBQUU7WUFDbkQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRSxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSSxFQUFFO2dCQUMvQixPQUFPLENBQUMsR0FBRyxDQUFDLDJCQUF5QixJQUFJLENBQUMsS0FBSyxtRUFBZ0UsQ0FBQyxDQUFDO2dCQUNqSCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsaUJBQWlCLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDeEU7U0FDRjtRQUNELElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLHdCQUF3QixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0tBQ3ZFOzs7OztJQUVELCtDQUFVOzs7O0lBQVYsVUFBVyxLQUFpQztRQUMxQyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssb0JBQW9CLENBQUMsVUFBVSxDQUFDO1lBQ2pELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxFQUFFO1lBQzNCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUM7U0FDMUM7YUFBTSxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssb0JBQW9CLENBQUMsTUFBTSxDQUFDO1lBQ3BELElBQUksQ0FBQyxjQUFjLEVBQUUsRUFBRTtZQUN2QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQzFDO2FBQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxFQUFFO1lBQ3hELElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNwQztLQUNGOzs7O0lBRUQsZ0VBQTJCOzs7SUFBM0I7O1lBQ00sS0FBSyxHQUFHLE1BQU07UUFDbEIsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUksRUFBRTtZQUMzRCxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztTQUN4QjtRQUNELE9BQU8sSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztLQUNwRDs7OztJQUVELDREQUF1Qjs7O0lBQXZCOztZQUNNLEtBQUssR0FBRyxNQUFNO1FBQ2xCLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxJQUFJLEVBQUU7WUFDM0QsS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7U0FDeEI7UUFDRCxPQUFPLElBQUksY0FBYyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDcEQ7Ozs7SUFFRCx1REFBa0I7OztJQUFsQjtRQUNFLE9BQU8sSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUM7S0FDekI7Ozs7SUFFRCxtREFBYzs7O0lBQWQ7UUFDRSxPQUFPLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztLQUNsQzs7Z0JBN0lGLFNBQVMsU0FBQztvQkFDVCxRQUFRLEVBQUUsb0JBQW9CO29CQUM5QixRQUFRLEVBQUUsazlCQXdCSDtpQkFFUjs7OztnQkExQ0MsbUJBQW1COzs7d0JBaURsQixLQUFLO3dCQU1MLEtBQUs7MEJBTUwsS0FBSzsyQkFPTCxLQUFLOzRCQU1MLEtBQUs7NEJBTUwsS0FBSzsrQkFNTCxNQUFNOztJQXVFVCxpQ0FBQztDQS9JRDs7Ozs7OztJQ29DRSwwQ0FBb0IsWUFBaUM7UUFBakMsaUJBQVksR0FBWixZQUFZLENBQXFCO1FBbEI5QyxZQUFPLEdBQTZDLElBQUksWUFBWSxFQUFFLENBQUM7UUFPdEUscUJBQWdCLEdBQUcsS0FBSyxDQUFDO0tBWWhDOzs7OztJQVZhLDBDQUFTOzs7O0lBQXZCLFVBQXdCLFFBQXdCO1FBQzlDLElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxRQUFRLEtBQUssSUFBSSxFQUFFO1lBQy9DLE9BQU8sSUFBSSxTQUFTLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNoRjs7WUFDSyxTQUFTLEdBQUcsUUFBUSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU07O1lBQ3ZFLE9BQU8sR0FBRyxRQUFRLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTTtRQUN2RSxPQUFPLElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztLQUM1RDs7OztJQUtELHNEQUFXOzs7SUFBWDs7WUFDUSxLQUFLLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNwRCxJQUFJLEtBQUssS0FBSyxJQUFJLEVBQUU7WUFDbEIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNuRDtLQUNGOzs7O0lBRUQsc0RBQVc7OztJQUFYOzs7WUFFTSxRQUFRLEdBQVcsSUFBSTtRQUMzQixJQUFJLElBQUksQ0FBQyxFQUFFLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLEtBQUssU0FBUyxFQUFFO1lBQzdDLFFBQVEsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQztTQUM3QjtRQUNELElBQUksQ0FBQyxFQUFFLEdBQUcsZ0NBQWdDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUMxRSxJQUFJLFFBQVEsS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFO1lBQzlDLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztTQUM3QjtRQUNELElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxJQUFJLEVBQUU7WUFDMUIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDbkMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7U0FDckM7UUFDRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7S0FDcEI7Ozs7SUFFTSxxREFBVTs7O0lBQWpCO1FBQ0UsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7UUFDckMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztRQUM3QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7S0FDcEI7Ozs7SUFFTSxxREFBVTs7O0lBQWpCO1FBQ0UsSUFBSSx