@paddls/ngx-easy-table
Version:
Angular easy table
210 lines • 25 kB
JavaScript
import { Directive, EventEmitter, Input, Output } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "./pagination.service";
/**
* This directive is what powers all pagination controls components, including the default one.
* It exposes an API which is hooked up to the PaginationService to keep the PaginatePipe in sync
* with the pagination controls.
*/
export class PaginationControlsDirective {
constructor(service, changeDetectorRef) {
this.service = service;
this.changeDetectorRef = changeDetectorRef;
this.maxSize = 7;
this.pageChange = new EventEmitter();
this.pageBoundsCorrection = new EventEmitter();
this.pages = [];
this.changeSub = this.service.change
.subscribe(id => {
if (this.id === id) {
this.updatePageLinks();
this.changeDetectorRef.markForCheck();
this.changeDetectorRef.detectChanges();
}
});
}
ngOnInit() {
if (this.id === undefined) {
this.id = this.service.defaultId();
}
this.updatePageLinks();
}
ngOnChanges() {
this.updatePageLinks();
}
ngOnDestroy() {
this.changeSub.unsubscribe();
}
/**
* Go to the previous page
*/
previous() {
this.checkValidId();
this.setCurrent(this.getCurrent() - 1);
}
/**
* Go to the next page
*/
next() {
this.checkValidId();
this.setCurrent(this.getCurrent() + 1);
}
/**
* Returns true if current page is first page
*/
isFirstPage() {
return this.getCurrent() === 1;
}
/**
* Returns true if current page is last page
*/
isLastPage() {
return this.getLastPage() === this.getCurrent();
}
/**
* Set the current page number.
*/
setCurrent(page) {
this.pageChange.emit(page);
}
/**
* Get the current page number.
*/
getCurrent() {
return this.service.getCurrentPage(this.id);
}
/**
* Returns the last page number
*/
getLastPage() {
let inst = this.service.getInstance(this.id);
const totalItems = inst.totalItems ?? 0;
if (totalItems < 1) {
// when there are 0 or fewer (an error case) items, there are no "pages" as such,
// but it makes sense to consider a single, empty page as the last page.
return 1;
}
return Math.ceil(totalItems / inst.itemsPerPage);
}
getTotalItems() {
return this.service.getInstance(this.id).totalItems ?? 0;
}
checkValidId() {
if (this.service.getInstance(this.id).id == null) {
console.warn(`PaginationControlsDirective: the specified id "${this.id}" does not match any registered PaginationInstance`);
}
}
/**
* Updates the page links and checks that the current page is valid. Should run whenever the
* PaginationService.change stream emits a value matching the current ID, or when any of the
* input values changes.
*/
updatePageLinks() {
let inst = this.service.getInstance(this.id);
const correctedCurrentPage = this.outOfBoundCorrection(inst);
if (correctedCurrentPage !== inst.currentPage) {
setTimeout(() => {
this.pageBoundsCorrection.emit(correctedCurrentPage);
this.pages = this.createPageArray(inst.currentPage, inst.itemsPerPage, (inst.totalItems ?? 0), this.maxSize);
});
}
else {
this.pages = this.createPageArray(inst.currentPage, inst.itemsPerPage, (inst.totalItems ?? 0), this.maxSize);
}
}
/**
* Checks that the instance.currentPage property is within bounds for the current page range.
* If not, return a correct value for currentPage, or the current value if OK.
*/
outOfBoundCorrection(instance) {
const totalPages = Math.ceil((instance.totalItems ?? 0) / instance.itemsPerPage);
if (totalPages < instance.currentPage && 0 < totalPages) {
return totalPages;
}
else if (instance.currentPage < 1) {
return 1;
}
return instance.currentPage;
}
/**
* Returns an array of Page objects to use in the pagination controls.
*/
createPageArray(currentPage, itemsPerPage, totalItems, paginationRange) {
// paginationRange could be a string if passed from attribute, so cast to number.
paginationRange = +paginationRange;
let pages = [];
// Return 1 as default page number
// Make sense to show 1 instead of empty when there are no items
const totalPages = Math.max(Math.ceil(totalItems / itemsPerPage), 1);
const halfWay = Math.ceil(paginationRange / 2);
const isStart = currentPage <= halfWay;
const isEnd = totalPages - halfWay < currentPage;
const isMiddle = !isStart && !isEnd;
let ellipsesNeeded = paginationRange < totalPages;
let i = 1;
while (i <= totalPages && i <= paginationRange) {
let label;
let pageNumber = this.calculatePageNumber(i, currentPage, paginationRange, totalPages);
let openingEllipsesNeeded = (i === 2 && (isMiddle || isEnd));
let closingEllipsesNeeded = (i === paginationRange - 1 && (isMiddle || isStart));
if (ellipsesNeeded && (openingEllipsesNeeded || closingEllipsesNeeded)) {
label = '...';
}
else {
label = pageNumber;
}
// @ts-ignore don't know why it considers the object as never :shrug:
pages.push({
label: label,
value: pageNumber
});
i++;
}
return pages;
}
/**
* Given the position in the sequence of pagination links [i],
* figure out what page number corresponds to that position.
*/
calculatePageNumber(i, currentPage, paginationRange, totalPages) {
let halfWay = Math.ceil(paginationRange / 2);
if (i === paginationRange) {
return totalPages;
}
else if (i === 1) {
return i;
}
else if (paginationRange < totalPages) {
if (totalPages - halfWay < currentPage) {
return totalPages - paginationRange + i;
}
else if (halfWay < currentPage) {
return currentPage - halfWay + i;
}
else {
return i;
}
}
else {
return i;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationControlsDirective, deps: [{ token: i1.PaginationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: PaginationControlsDirective, selector: "pagination-template,[pagination-template]", inputs: { id: "id", maxSize: "maxSize" }, outputs: { pageChange: "pageChange", pageBoundsCorrection: "pageBoundsCorrection" }, exportAs: ["paginationApi"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: PaginationControlsDirective, decorators: [{
type: Directive,
args: [{
selector: 'pagination-template,[pagination-template]',
exportAs: 'paginationApi'
}]
}], ctorParameters: function () { return [{ type: i1.PaginationService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { id: [{
type: Input
}], maxSize: [{
type: Input
}], pageChange: [{
type: Output
}], pageBoundsCorrection: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdGlvbi1jb250cm9scy5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtZWFzeS10YWJsZS9zcmMvbGliL2ZlYXR1cmVzL3BhZ2luYXRpb24vcGFnaW5hdGlvbi1jb250cm9scy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7OztBQVd4Rjs7OztHQUlHO0FBS0gsTUFBTSxPQUFPLDJCQUEyQjtJQVNwQyxZQUFvQixPQUEwQixFQUMxQixpQkFBb0M7UUFEcEMsWUFBTyxHQUFQLE9BQU8sQ0FBbUI7UUFDMUIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQVIvQyxZQUFPLEdBQVcsQ0FBQyxDQUFDO1FBQ25CLGVBQVUsR0FBeUIsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUM5RCx5QkFBb0IsR0FBeUIsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUNsRixVQUFLLEdBQVcsRUFBRSxDQUFDO1FBTWYsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU07YUFDL0IsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1lBQ1osSUFBSSxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRTtnQkFDaEIsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQzthQUMxQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVELFFBQVE7UUFDSixJQUFJLElBQUksQ0FBQyxFQUFFLEtBQUssU0FBUyxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFD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QUFHLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdDLElBQUksQ0FBQyxLQUFLLGVBQWUsRUFBRTtZQUN2QixPQUFPLFVBQVUsQ0FBQztTQUNyQjthQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUNoQixPQUFPLENBQUMsQ0FBQztTQUNaO2FBQU0sSUFBSSxlQUFlLEdBQUcsVUFBVSxFQUFFO1lBQ3JDLElBQUksVUFBVSxHQUFHLE9BQU8sR0FBRyxXQUFXLEVBQUU7Z0JBQ3BDLE9BQU8sVUFBVSxHQUFHLGVBQWUsR0FBRyxDQUFDLENBQUM7YUFDM0M7aUJBQU0sSUFBSSxPQUFPLEdBQUcsV0FBVyxFQUFFO2dCQUM5QixPQUFPLFdBQVcsR0FBRyxPQUFPLEdBQUcsQ0FBQyxDQUFDO2FBQ3BDO2lCQUFNO2dCQUNILE9BQU8sQ0FBQyxDQUFDO2FBQ1o7U0FDSjthQUFNO1lBQ0gsT0FBTyxDQUFDLENBQUM7U0FDWjtJQUNMLENBQUM7OEdBdk1RLDJCQUEyQjtrR0FBM0IsMkJBQTJCOzsyRkFBM0IsMkJBQTJCO2tCQUp2QyxTQUFTO21CQUFDO29CQUNQLFFBQVEsRUFBRSwyQ0FBMkM7b0JBQ3JELFFBQVEsRUFBRSxlQUFlO2lCQUM1Qjt3SUFFWSxFQUFFO3NCQUFWLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNJLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csb0JBQW9CO3NCQUE3QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3RvclJlZiwgRGlyZWN0aXZlLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge1BhZ2luYXRpb25TZXJ2aWNlfSBmcm9tICcuL3BhZ2luYXRpb24uc2VydmljZSc7XG5pbXBvcnQge1BhZ2luYXRpb25JbnN0YW5jZUludGVyZmFjZX0gZnJvbSAnLi9pbnRlcmZhY2VzL3BhZ2luYXRpb24taW5zdGFuY2UuaW50ZXJmYWNlJztcblxuZXhwb3J0IGludGVyZmFjZSBQYWdlIHtcbiAgICBsYWJlbDogc3RyaW5nO1xuICAgIHZhbHVlOiBhbnk7XG59XG5cbi8qKlxuICogVGhpcyBkaXJlY3RpdmUgaXMgd2hhdCBwb3dlcnMgYWxsIHBhZ2luYXRpb24gY29udHJvbHMgY29tcG9uZW50cywgaW5jbHVkaW5nIHRoZSBkZWZhdWx0IG9uZS5cbiAqIEl0IGV4cG9zZXMgYW4gQVBJIHdoaWNoIGlzIGhvb2tlZCB1cCB0byB0aGUgUGFnaW5hdGlvblNlcnZpY2UgdG8ga2VlcCB0aGUgUGFnaW5hdGVQaXBlIGluIHN5bmNcbiAqIHdpdGggdGhlIHBhZ2luYXRpb24gY29udHJvbHMuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAncGFnaW5hdGlvbi10ZW1wbGF0ZSxbcGFnaW5hdGlvbi10ZW1wbGF0ZV0nLFxuICAgIGV4cG9ydEFzOiAncGFnaW5hdGlvbkFwaSdcbn0pXG5leHBvcnQgY2xhc3MgUGFnaW5hdGlvbkNvbnRyb2xzRGlyZWN0aXZlIHtcbiAgICBASW5wdXQoKSBpZDogc3RyaW5nO1xuICAgIEBJbnB1dCgpIG1heFNpemU6IG51bWJlciA9IDc7XG4gICAgQE91dHB1dCgpIHBhZ2VDaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG4gICAgQE91dHB1dCgpIHBhZ2VCb3VuZHNDb3JyZWN0aW9uOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xuICAgIHBhZ2VzOiBQYWdlW10gPSBbXTtcblxuICAgIHByaXZhdGUgY2hhbmdlU3ViOiBTdWJzY3JpcHRpb247XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNlcnZpY2U6IFBhZ2luYXRpb25TZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlU3ViID0gdGhpcy5zZXJ2aWNlLmNoYW5nZVxuICAgICAgICAgICAgLnN1YnNjcmliZShpZCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaWQgPT09IGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlUGFnZUxpbmtzKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICBpZiAodGhpcy5pZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmlkID0gdGhpcy5zZXJ2aWNlLmRlZmF1bHRJZCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlUGFnZUxpbmtzKCk7XG4gICAgfVxuXG4gICAgbmdPbkNoYW5nZXMoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlUGFnZUxpbmtzKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR28gdG8gdGhlIHByZXZpb3VzIHBhZ2VcbiAgICAgKi9cbiAgICBwcmV2aW91cygpIHtcbiAgICAgICAgdGhpcy5jaGVja1ZhbGlkSWQoKTtcbiAgICAgICAgdGhpcy5zZXRDdXJyZW50KHRoaXMuZ2V0Q3VycmVudCgpIC0gMSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR28gdG8gdGhlIG5leHQgcGFnZVxuICAgICAqL1xuICAgIG5leHQoKSB7XG4gICAgICAgIHRoaXMuY2hlY2tWYWxpZElkKCk7XG4gICAgICAgIHRoaXMuc2V0Q3VycmVudCh0aGlzLmdldEN1cnJlbnQoKSArIDEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdHJ1ZSBpZiBjdXJyZW50IHBhZ2UgaXMgZmlyc3QgcGFnZVxuICAgICAqL1xuICAgIGlzRmlyc3RQYWdlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50KCkgPT09IDE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0cnVlIGlmIGN1cnJlbnQgcGFnZSBpcyBsYXN0IHBhZ2VcbiAgICAgKi9cbiAgICBpc0xhc3RQYWdlKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRMYXN0UGFnZSgpID09PSB0aGlzLmdldEN1cnJlbnQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgdGhlIGN1cnJlbnQgcGFnZSBudW1iZXIuXG4gICAgICovXG4gICAgc2V0Q3VycmVudChwYWdlOiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5wYWdlQ2hhbmdlLmVtaXQocGFnZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50IHBhZ2UgbnVtYmVyLlxuICAgICAqL1xuICAgIGdldEN1cnJlbnQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VydmljZS5nZXRDdXJyZW50UGFnZSh0aGlzLmlkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IHBhZ2UgbnVtYmVyXG4gICAgICovXG4gICAgZ2V0TGFzdFBhZ2UoKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGluc3QgPSB0aGlzLnNlcnZpY2UuZ2V0SW5zdGFuY2UodGhpcy5pZCk7XG4gICAgICAgIGNvbnN0IHRvdGFsSXRlbXMgPSBpbnN0LnRvdGFsSXRlbXMgPz8gMDtcbiAgICAgICAgaWYgKHRvdGFsSXRlbXMgPCAxKSB7XG4gICAgICAgICAgICAvLyB3aGVuIHRoZXJlIGFyZSAwIG9yIGZld2VyIChhbiBlcnJvciBjYXNlKSBpdGVtcywgdGhlcmUgYXJlIG5vIFwicGFnZXNcIiBhcyBzdWNoLFxuICAgICAgICAgICAgLy8gYnV0IGl0IG1ha2VzIHNlbnNlIHRvIGNvbnNpZGVyIGEgc2luZ2xlLCBlbXB0eSBwYWdlIGFzIHRoZSBsYXN0IHBhZ2UuXG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gTWF0aC5jZWlsKHRvdGFsSXRlbXMgLyBpbnN0Lml0ZW1zUGVyUGFnZSk7XG4gICAgfVxuXG4gICAgZ2V0VG90YWxJdGVtcygpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5zZXJ2aWNlLmdldEluc3RhbmNlKHRoaXMuaWQpLnRvdGFsSXRlbXMgPz8gMDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrVmFsaWRJZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuc2VydmljZS5nZXRJbnN0YW5jZSh0aGlzLmlkKS5pZCA9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFBhZ2luYXRpb25Db250cm9sc0RpcmVjdGl2ZTogdGhlIHNwZWNpZmllZCBpZCBcIiR7dGhpcy5pZH1cIiBkb2VzIG5vdCBtYXRjaCBhbnkgcmVnaXN0ZXJlZCBQYWdpbmF0aW9uSW5zdGFuY2VgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgdGhlIHBhZ2UgbGlua3MgYW5kIGNoZWNrcyB0aGF0IHRoZSBjdXJyZW50IHBhZ2UgaXMgdmFsaWQuIFNob3VsZCBydW4gd2hlbmV2ZXIgdGhlXG4gICAgICogUGFnaW5hdGlvblNlcnZpY2UuY2hhbmdlIHN0cmVhbSBlbWl0cyBhIHZhbHVlIG1hdGNoaW5nIHRoZSBjdXJyZW50IElELCBvciB3aGVuIGFueSBvZiB0aGVcbiAgICAgKiBpbnB1dCB2YWx1ZXMgY2hhbmdlcy5cbiAgICAgKi9cbiAgICBwcml2YXRlIHVwZGF0ZVBhZ2VMaW5rcygpIHtcbiAgICAgICAgbGV0IGluc3QgPSB0aGlzLnNlcnZpY2UuZ2V0SW5zdGFuY2UodGhpcy5pZCk7XG4gICAgICAgIGNvbnN0IGNvcnJlY3RlZEN1cnJlbnRQYWdlID0gdGhpcy5vdXRPZkJvdW5kQ29ycmVjdGlvbihpbnN0KTtcblxuICAgICAgICBpZiAoY29ycmVjdGVkQ3VycmVudFBhZ2UgIT09IGluc3QuY3VycmVudFBhZ2UpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucGFnZUJvdW5kc0NvcnJlY3Rpb24uZW1pdChjb3JyZWN0ZWRDdXJyZW50UGFnZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5wYWdlcyA9IHRoaXMuY3JlYXRlUGFnZUFycmF5KGluc3QuY3VycmVudFBhZ2UsIGluc3QuaXRlbXNQZXJQYWdlLCAoaW5zdC50b3RhbEl0ZW1zID8/IDApLCB0aGlzLm1heFNpemUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnBhZ2VzID0gdGhpcy5jcmVhdGVQYWdlQXJyYXkoaW5zdC5jdXJyZW50UGFnZSwgaW5zdC5pdGVtc1BlclBhZ2UsIChpbnN0LnRvdGFsSXRlbXMgPz8gMCksIHRoaXMubWF4U2l6ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgdGhhdCB0aGUgaW5zdGFuY2UuY3VycmVudFBhZ2UgcHJvcGVydHkgaXMgd2l0aGluIGJvdW5kcyBmb3IgdGhlIGN1cnJlbnQgcGFnZSByYW5nZS5cbiAgICAgKiBJZiBub3QsIHJldHVybiBhIGNvcnJlY3QgdmFsdWUgZm9yIGN1cnJlbnRQYWdlLCBvciB0aGUgY3VycmVudCB2YWx1ZSBpZiBPSy5cbiAgICAgKi9cbiAgICBwcml2YXRlIG91dE9mQm91bmRDb3JyZWN0aW9uKGluc3RhbmNlOiBQYWdpbmF0aW9uSW5zdGFuY2VJbnRlcmZhY2UpOiBudW1iZXIge1xuICAgICAgICBjb25zdCB0b3RhbFBhZ2VzID0gTWF0aC5jZWlsKChpbnN0YW5jZS50b3RhbEl0ZW1zID8/IDApIC8gaW5zdGFuY2UuaXRlbXNQZXJQYWdlKTtcbiAgICAgICAgaWYgKHRvdGFsUGFnZXMgPCBpbnN0YW5jZS5jdXJyZW50UGFnZSAmJiAwIDwgdG90YWxQYWdlcykge1xuICAgICAgICAgICAgcmV0dXJuIHRvdGFsUGFnZXM7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5zdGFuY2UuY3VycmVudFBhZ2UgPCAxKSB7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpbnN0YW5jZS5jdXJyZW50UGFnZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIGFycmF5IG9mIFBhZ2Ugb2JqZWN0cyB0byB1c2UgaW4gdGhlIHBhZ2luYXRpb24gY29udHJvbHMuXG4gICAgICovXG4gICAgcHJpdmF0ZSBjcmVhdGVQYWdlQXJyYXkoY3VycmVudFBhZ2U6IG51bWJlciwgaXRlbXNQZXJQYWdlOiBudW1iZXIsIHRvdGFsSXRlbXM6IG51bWJlciwgcGFnaW5hdGlvblJhbmdlOiBudW1iZXIpOiBQYWdlW10ge1xuICAgICAgICAvLyBwYWdpbmF0aW9uUmFuZ2UgY291bGQgYmUgYSBzdHJpbmcgaWYgcGFzc2VkIGZyb20gYXR0cmlidXRlLCBzbyBjYXN0IHRvIG51bWJlci5cbiAgICAgICAgcGFnaW5hdGlvblJhbmdlID0gK3BhZ2luYXRpb25SYW5nZTtcbiAgICAgICAgbGV0IHBhZ2VzID0gW107XG5cbiAgICAgICAgLy8gUmV0dXJuIDEgYXMgZGVmYXVsdCBwYWdlIG51bWJlclxuICAgICAgICAvLyBNYWtlIHNlbnNlIHRvIHNob3cgMSBpbnN0ZWFkIG9mIGVtcHR5IHdoZW4gdGhlcmUgYXJlIG5vIGl0ZW1zXG4gICAgICAgIGNvbnN0IHRvdGFsUGFnZXMgPSBNYXRoLm1heChNYXRoLmNlaWwodG90YWxJdGVtcyAvIGl0ZW1zUGVyUGFnZSksIDEpO1xuICAgICAgICBjb25zdCBoYWxmV2F5ID0gTWF0aC5jZWlsKHBhZ2luYXRpb25SYW5nZSAvIDIpO1xuXG4gICAgICAgIGNvbnN0IGlzU3RhcnQgPSBjdXJyZW50UGFnZSA8PSBoYWxmV2F5O1xuICAgICAgICBjb25zdCBpc0VuZCA9IHRvdGFsUGFnZXMgLSBoYWxmV2F5IDwgY3VycmVudFBhZ2U7XG4gICAgICAgIGNvbnN0IGlzTWlkZGxlID0gIWlzU3RhcnQgJiYgIWlzRW5kO1xuXG4gICAgICAgIGxldCBlbGxpcHNlc05lZWRlZCA9IHBhZ2luYXRpb25SYW5nZSA8IHRvdGFsUGFnZXM7XG4gICAgICAgIGxldCBpID0gMTtcblxuICAgICAgICB3aGlsZSAoaSA8PSB0b3RhbFBhZ2VzICYmIGkgPD0gcGFnaW5hdGlvblJhbmdlKSB7XG4gICAgICAgICAgICBsZXQgbGFiZWw7XG4gICAgICAgICAgICBsZXQgcGFnZU51bWJlciA9IHRoaXMuY2FsY3VsYXRlUGFnZU51bWJlcihpLCBjdXJyZW50UGFnZSwgcGFnaW5hdGlvblJhbmdlLCB0b3RhbFBhZ2VzKTtcbiAgICAgICAgICAgIGxldCBvcGVuaW5nRWxsaXBzZXNOZWVkZWQgPSAoaSA9PT0gMiAmJiAoaXNNaWRkbGUgfHwgaXNFbmQpKTtcbiAgICAgICAgICAgIGxldCBjbG9zaW5nRWxsaXBzZXNOZWVkZWQgPSAoaSA9PT0gcGFnaW5hdGlvblJhbmdlIC0gMSAmJiAoaXNNaWRkbGUgfHwgaXNTdGFydCkpO1xuICAgICAgICAgICAgaWYgKGVsbGlwc2VzTmVlZGVkICYmIChvcGVuaW5nRWxsaXBzZXNOZWVkZWQgfHwgY2xvc2luZ0VsbGlwc2VzTmVlZGVkKSkge1xuICAgICAgICAgICAgICAgIGxhYmVsID0gJy4uLic7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxhYmVsID0gcGFnZU51bWJlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmUgZG9uJ3Qga25vdyB3aHkgaXQgY29uc2lkZXJzIHRoZSBvYmplY3QgYXMgbmV2ZXIgOnNocnVnOlxuICAgICAgICAgICAgcGFnZXMucHVzaCh7XG4gICAgICAgICAgICAgIGxhYmVsOiBsYWJlbCxcbiAgICAgICAgICAgICAgdmFsdWU6IHBhZ2VOdW1iZXJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaSArKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFnZXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2l2ZW4gdGhlIHBvc2l0aW9uIGluIHRoZSBzZXF1ZW5jZSBvZiBwYWdpbmF0aW9uIGxpbmtzIFtpXSxcbiAgICAgKiBmaWd1cmUgb3V0IHdoYXQgcGFnZSBudW1iZXIgY29ycmVzcG9uZHMgdG8gdGhhdCBwb3NpdGlvbi5cbiAgICAgKi9cbiAgICBwcml2YXRlIGNhbGN1bGF0ZVBhZ2VOdW1iZXIoaTogbnVtYmVyLCBjdXJyZW50UGFnZTogbnVtYmVyLCBwYWdpbmF0aW9uUmFuZ2U6IG51bWJlciwgdG90YWxQYWdlczogbnVtYmVyKSB7XG4gICAgICAgIGxldCBoYWxmV2F5ID0gTWF0aC5jZWlsKHBhZ2luYXRpb25SYW5nZSAvIDIpO1xuICAgICAgICBpZiAoaSA9PT0gcGFnaW5hdGlvblJhbmdlKSB7XG4gICAgICAgICAgICByZXR1cm4gdG90YWxQYWdlcztcbiAgICAgICAgfSBlbHNlIGlmIChpID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfSBlbHNlIGlmIChwYWdpbmF0aW9uUmFuZ2UgPCB0b3RhbFBhZ2VzKSB7XG4gICAgICAgICAgICBpZiAodG90YWxQYWdlcyAtIGhhbGZXYXkgPCBjdXJyZW50UGFnZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0b3RhbFBhZ2VzIC0gcGFnaW5hdGlvblJhbmdlICsgaTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFsZldheSA8IGN1cnJlbnRQYWdlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRQYWdlIC0gaGFsZldheSArIGk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=