@hxui/angular
Version:
An Angular library based on the [HXUI design system](https://hxui.io).
258 lines (254 loc) • 34.4 kB
JavaScript
import { Component, ElementRef, EventEmitter, Input, Output, Renderer2, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { PaginationConfig } from './pagination.config';
import * as i0 from "@angular/core";
import * as i1 from "./pagination.config";
import * as i2 from "@angular/common";
export const PAGINATION_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => PaginationComponent),
multi: true
};
const PAGINATION_TEMPLATE = `
<ul class="hx-pagination" [ngClass]="classMap" [class.is-sticky]="sticky">
<li class="is-first"
*ngIf="boundaryLinks"
[class.is-disabled]="noPrevious()||disabled">
<a href (click)="selectPage(1, $event)" [innerHTML]="getText('first')"></a>
</li>
<li class="is-prev"
*ngIf="directionLinks"
[class.is-disabled]="noPrevious()||disabled">
<a href (click)="selectPage(page - 1, $event)" [innerHTML]="getText('previous')"></a>
</li>
<li *ngFor="let pg of pages"
[class.is-current]="pg.active"
[class.is-disabled]="disabled&&!pg.active">
<a href (click)="selectPage(pg.number, $event)" [innerHTML]="pg.text"></a>
</li>
<li class="is-next"
*ngIf="directionLinks"
[class.is-disabled]="noNext()||disabled">
<a class="page-link" href (click)="selectPage(page + 1, $event)" [innerHTML]="getText('next')"></a></li>
<li class="is-last"
*ngIf="boundaryLinks"
[class.is-disabled]="noNext()||disabled">
<a href (click)="selectPage(totalPages, $event)" [innerHTML]="getText('last')"></a></li>
</ul>
`;
export class PaginationComponent {
constructor(renderer, elementRef, paginationConfig) {
/** fired when total pages count changes, $event:number equals to total pages count */
this.numPages = new EventEmitter();
/** fired when page was changed, $event:{page, itemsPerPage} equals to object with current page index and number of items per page */
this.pageChanged = new EventEmitter();
this.onChange = Function.prototype;
this.onTouched = Function.prototype;
this.inited = false;
this._page = 1;
this.renderer = renderer;
this.elementRef = elementRef;
if (!this.config) {
this.configureOptions(paginationConfig.main);
}
}
/** maximum number of items per page. If value less than 1 will display all items on one page */
get itemsPerPage() {
return this._itemsPerPage;
}
set itemsPerPage(v) {
this._itemsPerPage = v;
this.totalPages = this.calculateTotalPages();
}
/** total number of items in all pages */
get totalItems() {
return this._totalItems;
}
set totalItems(v) {
this._totalItems = v;
this.totalPages = this.calculateTotalPages();
}
get totalPages() {
return this._totalPages;
}
set totalPages(v) {
this._totalPages = v;
this.numPages.emit(v);
if (this.inited) {
this.selectPage(this.page);
}
}
set page(value) {
const _previous = this._page;
this._page = (value > this.totalPages) ? this.totalPages : (value || 1);
if (_previous === this._page || typeof _previous === 'undefined') {
return;
}
this.pageChanged.emit({
page: this._page,
itemsPerPage: this.itemsPerPage
});
}
get page() {
return this._page;
}
configureOptions(config) {
this.config = Object.assign({}, config);
}
ngOnInit() {
this.classMap = this.elementRef.nativeElement.getAttribute('class') || '';
// watch for maxSize
this.maxSize = typeof this.maxSize !== 'undefined'
? this.maxSize
: this.config.maxSize;
this.rotate = typeof this.rotate !== 'undefined'
? this.rotate
: this.config.rotate;
this.boundaryLinks = typeof this.boundaryLinks !== 'undefined'
? this.boundaryLinks
: this.config.boundaryLinks;
this.directionLinks = typeof this.directionLinks !== 'undefined'
? this.directionLinks
: this.config.directionLinks;
this.pageBtnClass = typeof this.pageBtnClass !== 'undefined'
? this.pageBtnClass
: this.config.pageBtnClass;
// base class
this.itemsPerPage = typeof this.itemsPerPage !== 'undefined'
? this.itemsPerPage
: this.config.itemsPerPage;
this.totalPages = this.calculateTotalPages();
// this class
this.pages = this.getPages(this.page, this.totalPages);
this.inited = true;
}
writeValue(value) {
this.page = value;
this.pages = this.getPages(this.page, this.totalPages);
}
getText(key) {
return this[key + 'Text'] || this.config[key + 'Text'];
}
noPrevious() {
return this.page === 1;
}
noNext() {
return this.page === this.totalPages;
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
selectPage(page, event) {
if (event) {
event.preventDefault();
}
if (!this.disabled) {
if (event && event.target) {
const target = event.target;
target.blur();
}
this.writeValue(page);
this.onChange(this.page);
}
}
// Create page object used in template
makePage(num, text, active) {
return { text, number: num, active };
}
getPages(currentPage, totalPages) {
const pages = [];
// Default page limits
let startPage = 1;
let endPage = totalPages;
const isMaxSized = typeof this.maxSize !== 'undefined' && this.maxSize < totalPages;
// recompute if maxSize
if (isMaxSized) {
if (this.rotate) {
// Current page is displayed in the middle of the visible ones
startPage = Math.max(currentPage - Math.floor(this.maxSize / 2), 1);
endPage = startPage + this.maxSize - 1;
// Adjust if limit is exceeded
if (endPage > totalPages) {
endPage = totalPages;
startPage = endPage - this.maxSize + 1;
}
}
else {
// Visible pages are paginated with maxSize
startPage = ((Math.ceil(currentPage / this.maxSize) - 1) * this.maxSize) + 1;
// Adjust last page if limit is exceeded
endPage = Math.min(startPage + this.maxSize - 1, totalPages);
}
}
// Add page number links
for (let num = startPage; num <= endPage; num++) {
const page = this.makePage(num, num.toString(), num === currentPage);
pages.push(page);
}
// Add links to move between page sets
if (isMaxSized && !this.rotate) {
if (startPage > 1) {
const previousPageSet = this.makePage(startPage - 1, '...', false);
pages.unshift(previousPageSet);
}
if (endPage < totalPages) {
const nextPageSet = this.makePage(endPage + 1, '...', false);
pages.push(nextPageSet);
}
}
return pages;
}
// base class
calculateTotalPages() {
const totalPages = this.itemsPerPage < 1
? 1
: Math.ceil(this.totalItems / this.itemsPerPage);
return Math.max(totalPages || 0, 1);
}
}
PaginationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PaginationComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i1.PaginationConfig }], target: i0.ɵɵFactoryTarget.Component });
PaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: PaginationComponent, selector: "hx-pagination", inputs: { align: "align", maxSize: "maxSize", boundaryLinks: "boundaryLinks", directionLinks: "directionLinks", firstText: "firstText", previousText: "previousText", nextText: "nextText", lastText: "lastText", rotate: "rotate", sticky: "sticky", pageBtnClass: "pageBtnClass", disabled: "disabled", itemsPerPage: "itemsPerPage", totalItems: "totalItems" }, outputs: { numPages: "numPages", pageChanged: "pageChanged" }, providers: [PAGINATION_CONTROL_VALUE_ACCESSOR], ngImport: i0, template: "\n <ul class=\"hx-pagination\" [ngClass]=\"classMap\" [class.is-sticky]=\"sticky\">\n <li class=\"is-first\"\n *ngIf=\"boundaryLinks\"\n [class.is-disabled]=\"noPrevious()||disabled\">\n <a href (click)=\"selectPage(1, $event)\" [innerHTML]=\"getText('first')\"></a>\n </li>\n\n <li class=\"is-prev\"\n *ngIf=\"directionLinks\"\n [class.is-disabled]=\"noPrevious()||disabled\">\n <a href (click)=\"selectPage(page - 1, $event)\" [innerHTML]=\"getText('previous')\"></a>\n </li>\n\n <li *ngFor=\"let pg of pages\"\n [class.is-current]=\"pg.active\"\n [class.is-disabled]=\"disabled&&!pg.active\">\n <a href (click)=\"selectPage(pg.number, $event)\" [innerHTML]=\"pg.text\"></a>\n </li>\n\n <li class=\"is-next\"\n *ngIf=\"directionLinks\"\n [class.is-disabled]=\"noNext()||disabled\">\n <a class=\"page-link\" href (click)=\"selectPage(page + 1, $event)\" [innerHTML]=\"getText('next')\"></a></li>\n\n <li class=\"is-last\"\n *ngIf=\"boundaryLinks\"\n [class.is-disabled]=\"noNext()||disabled\">\n <a href (click)=\"selectPage(totalPages, $event)\" [innerHTML]=\"getText('last')\"></a></li>\n </ul>\n ", isInline: true, directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PaginationComponent, decorators: [{
type: Component,
args: [{
selector: 'hx-pagination',
template: PAGINATION_TEMPLATE,
providers: [PAGINATION_CONTROL_VALUE_ACCESSOR]
}]
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.PaginationConfig }]; }, propDecorators: { align: [{
type: Input
}], maxSize: [{
type: Input
}], boundaryLinks: [{
type: Input
}], directionLinks: [{
type: Input
}], firstText: [{
type: Input
}], previousText: [{
type: Input
}], nextText: [{
type: Input
}], lastText: [{
type: Input
}], rotate: [{
type: Input
}], sticky: [{
type: Input
}], pageBtnClass: [{
type: Input
}], disabled: [{
type: Input
}], numPages: [{
type: Output
}], pageChanged: [{
type: Output
}], itemsPerPage: [{
type: Input
}], totalItems: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9oeC11aS9zcmMvbGliL3BhZ2luYXRpb24vcGFnaW5hdGlvbi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsU0FBUyxFQUFRLFVBQVUsRUFDeEYsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7O0FBT3ZELE1BQU0sQ0FBQyxNQUFNLGlDQUFpQyxHQUFRO0lBQ3BELE9BQU8sRUFBRSxpQkFBaUI7SUFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztJQUNsRCxLQUFLLEVBQUUsSUFBSTtDQUNaLENBQUM7QUFFRixNQUFNLG1CQUFtQixHQUFHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4QnpCLENBQUM7QUFPSixNQUFNLE9BQU8sbUJBQW1CO0lBb0c5QixZQUFtQixRQUFtQixFQUFFLFVBQXNCLEVBQUUsZ0JBQWtDO1FBdEVsRyxzRkFBc0Y7UUFDckUsYUFBUSxHQUF5QixJQUFJLFlBQVksRUFBVSxDQUFDO1FBQzdFLHFJQUFxSTtRQUNwSCxnQkFBVyxHQUFtQyxJQUFJLFlBQVksRUFBb0IsQ0FBQztRQXNEN0YsYUFBUSxHQUFRLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFDbkMsY0FBUyxHQUFRLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFTakMsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUNmLFVBQUssR0FBRyxDQUFDLENBQUM7UUFHbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFD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ZTtvQkFDekIsUUFBUSxFQUFFLG1CQUFtQjtvQkFDN0IsU0FBUyxFQUFFLENBQUMsaUNBQWlDLENBQUM7aUJBQy9DO3dKQUlpQixLQUFLO3NCQUFwQixLQUFLO2dCQUVVLE9BQU87c0JBQXRCLEtBQUs7Z0JBRVUsYUFBYTtzQkFBNUIsS0FBSztnQkFFVSxjQUFjO3NCQUE3QixLQUFLO2dCQUdVLFNBQVM7c0JBQXhCLEtBQUs7Z0JBRVUsWUFBWTtzQkFBM0IsS0FBSztnQkFFVSxRQUFRO3NCQUF2QixLQUFLO2dCQUVVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBRVUsTUFBTTtzQkFBckIsS0FBSztnQkFFVSxNQUFNO3NCQUFyQixLQUFLO2dCQUdVLFlBQVk7c0JBQTNCLEtBQUs7Z0JBR1UsUUFBUTtzQkFBdkIsS0FBSztnQkFHVyxRQUFRO3NCQUF4QixNQUFNO2dCQUVVLFdBQVc7c0JBQTNCLE1BQU07Z0JBSUksWUFBWTtzQkFEdEIsS0FBSztnQkFZSyxVQUFVO3NCQURwQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBSZW5kZXJlcjIsIFNlbGYsIGZvcndhcmRSZWZcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5cclxuaW1wb3J0IHsgUGFnaW5hdGlvbkNvbmZpZyB9IGZyb20gJy4vcGFnaW5hdGlvbi5jb25maWcnO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBQYWdlQ2hhbmdlZEV2ZW50IHtcclxuICBpdGVtc1BlclBhZ2U6IG51bWJlcjtcclxuICBwYWdlOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBQQUdJTkFUSU9OX0NPTlRST0xfVkFMVUVfQUNDRVNTT1I6IGFueSA9IHtcclxuICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBQYWdpbmF0aW9uQ29tcG9uZW50KSxcclxuICBtdWx0aTogdHJ1ZVxyXG59O1xyXG5cclxuY29uc3QgUEFHSU5BVElPTl9URU1QTEFURSA9IGBcclxuICA8dWwgY2xhc3M9XCJoeC1wYWdpbmF0aW9uXCIgW25nQ2xhc3NdPVwiY2xhc3NNYXBcIiBbY2xhc3MuaXMtc3RpY2t5XT1cInN0aWNreVwiPlxyXG4gICAgPGxpIGNsYXNzPVwiaXMtZmlyc3RcIlxyXG4gICAgICAgICpuZ0lmPVwiYm91bmRhcnlMaW5rc1wiXHJcbiAgICAgICAgW2NsYXNzLmlzLWRpc2FibGVkXT1cIm5vUHJldmlvdXMoKXx8ZGlzYWJsZWRcIj5cclxuICAgICAgPGEgaHJlZiAoY2xpY2spPVwic2VsZWN0UGFnZSgxLCAkZXZlbnQpXCIgW2lubmVySFRNTF09XCJnZXRUZXh0KCdmaXJzdCcpXCI+PC9hPlxyXG4gICAgPC9saT5cclxuXHJcbiAgICA8bGkgY2xhc3M9XCJpcy1wcmV2XCJcclxuICAgICAgICAqbmdJZj1cImRpcmVjdGlvbkxpbmtzXCJcclxuICAgICAgICBbY2xhc3MuaXMtZGlzYWJsZWRdPVwibm9QcmV2aW91cygpfHxkaXNhYmxlZFwiPlxyXG4gICAgICA8YSBocmVmIChjbGljayk9XCJzZWxlY3RQYWdlKHBhZ2UgLSAxLCAkZXZlbnQpXCIgW2lubmVySFRNTF09XCJnZXRUZXh0KCdwcmV2aW91cycpXCI+PC9hPlxyXG4gICAgICA8L2xpPlxyXG5cclxuICAgIDxsaSAqbmdGb3I9XCJsZXQgcGcgb2YgcGFnZXNcIlxyXG4gICAgICAgIFtjbGFzcy5pcy1jdXJyZW50XT1cInBnLmFjdGl2ZVwiXHJcbiAgICAgICAgW2NsYXNzLmlzLWRpc2FibGVkXT1cImRpc2FibGVkJiYhcGcuYWN0aXZlXCI+XHJcbiAgICAgIDxhIGhyZWYgKGNsaWNrKT1cInNlbGVjdFBhZ2UocGcubnVtYmVyLCAkZXZlbnQpXCIgW2lubmVySFRNTF09XCJwZy50ZXh0XCI+PC9hPlxyXG4gICAgPC9saT5cclxuXHJcbiAgICA8bGkgY2xhc3M9XCJpcy1uZXh0XCJcclxuICAgICAgICAqbmdJZj1cImRpcmVjdGlvbkxpbmtzXCJcclxuICAgICAgICBbY2xhc3MuaXMtZGlzYWJsZWRdPVwibm9OZXh0KCl8fGRpc2FibGVkXCI+XHJcbiAgICAgIDxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZiAoY2xpY2spPVwic2VsZWN0UGFnZShwYWdlICsgMSwgJGV2ZW50KVwiIFtpbm5lckhUTUxdPVwiZ2V0VGV4dCgnbmV4dCcpXCI+PC9hPjwvbGk+XHJcblxyXG4gICAgPGxpIGNsYXNzPVwiaXMtbGFzdFwiXHJcbiAgICAgICAgKm5nSWY9XCJib3VuZGFyeUxpbmtzXCJcclxuICAgICAgICBbY2xhc3MuaXMtZGlzYWJsZWRdPVwibm9OZXh0KCl8fGRpc2FibGVkXCI+XHJcbiAgICAgIDxhIGhyZWYgKGNsaWNrKT1cInNlbGVjdFBhZ2UodG90YWxQYWdlcywgJGV2ZW50KVwiIFtpbm5lckhUTUxdPVwiZ2V0VGV4dCgnbGFzdCcpXCI+PC9hPjwvbGk+XHJcbiAgPC91bD5cclxuICBgO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdoeC1wYWdpbmF0aW9uJyxcclxuICB0ZW1wbGF0ZTogUEFHSU5BVElPTl9URU1QTEFURSxcclxuICBwcm92aWRlcnM6IFtQQUdJTkFUSU9OX0NPTlRST0xfVkFMVUVfQUNDRVNTT1JdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQYWdpbmF0aW9uQ29tcG9uZW50IGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uSW5pdCB7XHJcbiAgcHVibGljIGNvbmZpZzogYW55O1xyXG4gIC8qKiBpZiBgdHJ1ZWAgYWxpZ25zIGVhY2ggbGluayB0byB0aGUgc2lkZXMgb2YgcGFnZXIgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgYWxpZ246IGJvb2xlYW47XHJcbiAgLyoqIGxpbWl0IG51bWJlciBmb3IgcGFnZSBsaW5rcyBpbiBwYWdlciAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBtYXhTaXplOiBudW1iZXI7XHJcbiAgLyoqIGlmIGZhbHNlIGZpcnN0IGFuZCBsYXN0IGJ1dHRvbnMgd2lsbCBiZSBoaWRkZW4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgYm91bmRhcnlMaW5rczogYm9vbGVhbjtcclxuICAvKiogaWYgZmFsc2UgcHJldmlvdXMgYW5kIG5leHQgYnV0dG9ucyB3aWxsIGJlIGhpZGRlbiAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBkaXJlY3Rpb25MaW5rczogYm9vbGVhbjtcclxuICAvLyBsYWJlbHNcclxuICAvKiogZmlyc3QgYnV0dG9uIHRleHQgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZmlyc3RUZXh0OiBzdHJpbmc7XHJcbiAgLyoqIHByZXZpb3VzIGJ1dHRvbiB0ZXh0ICovXHJcbiAgQElucHV0KCkgcHVibGljIHByZXZpb3VzVGV4dDogc3RyaW5nO1xyXG4gIC8qKiBuZXh0IGJ1dHRvbiB0ZXh0ICovXHJcbiAgQElucHV0KCkgcHVibGljIG5leHRUZXh0OiBzdHJpbmc7XHJcbiAgLyoqIGxhc3QgYnV0dG9uIHRleHQgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgbGFzdFRleHQ6IHN0cmluZztcclxuICAvKiogaWYgdHJ1ZSBjdXJyZW50IHBhZ2Ugd2lsbCBpbiB0aGUgbWlkZGxlIG9mIHBhZ2VzIGxpc3QgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgcm90YXRlOiBib29sZWFuO1xyXG4gIC8qKiBpZiB0cnVlIHRoZSAuaXMtc3RpY2t5IG1vZGlmaWVyIHdpbGwgYmUgYWRkZWQgdG8gdGhlIHBhZ2luYXRpb24gY29tcG9uZW50Ki9cclxuICBASW5wdXQoKSBwdWJsaWMgc3RpY2t5OiBib29sZWFuO1xyXG4gIC8vIGNzc1xyXG4gIC8qKiBhZGQgY2xhc3MgdG8gPGxpPiAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBwYWdlQnRuQ2xhc3M6IHN0cmluZztcclxuXHJcbiAgLyoqIGlmIHRydWUgcGFnaW5hdGlvbiBjb21wb25lbnQgd2lsbCBiZSBkaXNhYmxlZCAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBkaXNhYmxlZDogYm9vbGVhbjtcclxuXHJcbiAgLyoqIGZpcmVkIHdoZW4gdG90YWwgcGFnZXMgY291bnQgY2hhbmdlcywgJGV2ZW50Om51bWJlciBlcXVhbHMgdG8gdG90YWwgcGFnZXMgY291bnQgKi9cclxuICBAT3V0cHV0KCkgcHVibGljIG51bVBhZ2VzOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xyXG4gIC8qKiBmaXJlZCB3aGVuIHBhZ2Ugd2FzIGNoYW5nZWQsICRldmVudDp7cGFnZSwgaXRlbXNQZXJQYWdlfSBlcXVhbHMgdG8gb2JqZWN0IHdpdGggY3VycmVudCBwYWdlIGluZGV4IGFuZCBudW1iZXIgb2YgaXRlbXMgcGVyIHBhZ2UgKi9cclxuICBAT3V0cHV0KCkgcHVibGljIHBhZ2VDaGFuZ2VkOiBFdmVudEVtaXR0ZXI8UGFnZUNoYW5nZWRFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPFBhZ2VDaGFuZ2VkRXZlbnQ+KCk7XHJcblxyXG4gIC8qKiBtYXhpbXVtIG51bWJlciBvZiBpdGVtcyBwZXIgcGFnZS4gSWYgdmFsdWUgbGVzcyB0aGFuIDEgd2lsbCBkaXNwbGF5IGFsbCBpdGVtcyBvbiBvbmUgcGFnZSAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGdldCBpdGVtc1BlclBhZ2UoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLl9pdGVtc1BlclBhZ2U7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0IGl0ZW1zUGVyUGFnZSh2OiBudW1iZXIpIHtcclxuICAgIHRoaXMuX2l0ZW1zUGVyUGFnZSA9IHY7XHJcbiAgICB0aGlzLnRvdGFsUGFnZXMgPSB0aGlzLmNhbGN1bGF0ZVRvdGFsUGFnZXMoKTtcclxuICB9XHJcblxyXG4gIC8qKiB0b3RhbCBudW1iZXIgb2YgaXRlbXMgaW4gYWxsIHBhZ2VzICovXHJcbiAgQElucHV0KClcclxuICBwdWJsaWMgZ2V0IHRvdGFsSXRlbXMoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLl90b3RhbEl0ZW1zO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldCB0b3RhbEl0ZW1zKHY6IG51bWJlcikge1xyXG4gICAgdGhpcy5fdG90YWxJdGVtcyA9IHY7XHJcbiAgICB0aGlzLnRvdGFsUGFnZXMgPSB0aGlzLmNhbGN1bGF0ZVRvdGFsUGFnZXMoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXQgdG90YWxQYWdlcygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX3RvdGFsUGFnZXM7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0IHRvdGFsUGFnZXModjogbnVtYmVyKSB7XHJcbiAgICB0aGlzLl90b3RhbFBhZ2VzID0gdjtcclxuICAgIHRoaXMubnVtUGFnZXMuZW1pdCh2KTtcclxuICAgIGlmICh0aGlzLmluaXRlZCkge1xyXG4gICAgICB0aGlzLnNlbGVjdFBhZ2UodGhpcy5wYWdlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXQgcGFnZSh2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICBjb25zdCBfcHJldmlvdXMgPSB0aGlzLl9wYWdlO1xyXG4gICAgdGhpcy5fcGFnZSA9ICh2YWx1ZSA+IHRoaXMudG90YWxQYWdlcykgPyB0aGlzLnRvdGFsUGFnZXMgOiAodmFsdWUgfHwgMSk7XHJcblxyXG4gICAgaWYgKF9wcmV2aW91cyA9PT0gdGhpcy5fcGFnZSB8fCB0eXBlb2YgX3ByZXZpb3VzID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5wYWdlQ2hhbmdlZC5lbWl0KHtcclxuICAgICAgcGFnZTogdGhpcy5fcGFnZSxcclxuICAgICAgaXRlbXNQZXJQYWdlOiB0aGlzLml0ZW1zUGVyUGFnZVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IHBhZ2UoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLl9wYWdlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG9uQ2hhbmdlOiBhbnkgPSBGdW5jdGlvbi5wcm90b3R5cGU7XHJcbiAgcHVibGljIG9uVG91Y2hlZDogYW55ID0gRnVuY3Rpb24ucHJvdG90eXBlO1xyXG4gIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIyO1xyXG4gIHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmO1xyXG4gIHB1YmxpYyBjbGFzc01hcDogc3RyaW5nO1xyXG4gIHB1YmxpYyBwYWdlczogYW55W107XHJcblxyXG4gIHByb3RlY3RlZCBfaXRlbXNQZXJQYWdlOiBudW1iZXI7XHJcbiAgcHJvdGVjdGVkIF90b3RhbEl0ZW1zOiBudW1iZXI7XHJcbiAgcHJvdGVjdGVkIF90b3RhbFBhZ2VzOiBudW1iZXI7XHJcbiAgcHJvdGVjdGVkIGluaXRlZCA9IGZhbHNlO1xyXG4gIHByb3RlY3RlZCBfcGFnZSA9IDE7XHJcblxyXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihyZW5kZXJlcjogUmVuZGVyZXIyLCBlbGVtZW50UmVmOiBFbGVtZW50UmVmLCBwYWdpbmF0aW9uQ29uZmlnOiBQYWdpbmF0aW9uQ29uZmlnKSB7XHJcbiAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XHJcbiAgICB0aGlzLmVsZW1lbnRSZWYgPSBlbGVtZW50UmVmO1xyXG4gICAgaWYgKCF0aGlzLmNvbmZpZykge1xyXG4gICAgICB0aGlzLmNvbmZpZ3VyZU9wdGlvbnMocGFnaW5hdGlvbkNvbmZpZy5tYWluKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBjb25maWd1cmVPcHRpb25zKGNvbmZpZzogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLmNvbmZpZyA9IE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZyk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmNsYXNzTWFwID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCdjbGFzcycpIHx8ICcnO1xyXG4gICAgLy8gd2F0Y2ggZm9yIG1heFNpemVcclxuICAgIHRoaXMubWF4U2l6ZSA9IHR5cGVvZiB0aGlzLm1heFNpemUgIT09ICd1bmRlZmluZWQnXHJcbiAgICAgID8gdGhpcy5tYXhTaXplXHJcbiAgICAgIDogdGhpcy5jb25maWcubWF4U2l6ZTtcclxuICAgIHRoaXMucm90YXRlID0gdHlwZW9mIHRoaXMucm90YXRlICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgICA/IHRoaXMucm90YXRlXHJcbiAgICAgIDogdGhpcy5jb25maWcucm90YXRlO1xyXG4gICAgdGhpcy5ib3VuZGFyeUxpbmtzID0gdHlwZW9mIHRoaXMuYm91bmRhcnlMaW5rcyAhPT0gJ3VuZGVmaW5lZCdcclxuICAgICAgPyB0aGlzLmJvdW5kYXJ5TGlua3NcclxuICAgICAgOiB0aGlzLmNvbmZpZy5ib3VuZGFyeUxpbmtzO1xyXG4gICAgdGhpcy5kaXJlY3Rpb25MaW5rcyA9IHR5cGVvZiB0aGlzLmRpcmVjdGlvbkxpbmtzICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgICA/IHRoaXMuZGlyZWN0aW9uTGlua3NcclxuICAgICAgOiB0aGlzLmNvbmZpZy5kaXJlY3Rpb25MaW5rcztcclxuICAgIHRoaXMucGFnZUJ0bkNsYXNzID0gdHlwZW9mIHRoaXMucGFnZUJ0bkNsYXNzICE9PSAndW5kZWZpbmVkJ1xyXG4gICAgPyB0aGlzLnBhZ2VCdG5DbGFzc1xyXG4gICAgOiB0aGlzLmNvbmZpZy5wYWdlQnRuQ2xhc3M7XHJcblxyXG4gICAgLy8gYmFzZSBjbGFzc1xyXG4gICAgdGhpcy5pdGVtc1BlclBhZ2UgPSB0eXBlb2YgdGhpcy5pdGVtc1BlclBhZ2UgIT09ICd1bmRlZmluZWQnXHJcbiAgICAgID8gdGhpcy5pdGVtc1BlclBhZ2VcclxuICAgICAgOiB0aGlzLmNvbmZpZy5pdGVtc1BlclBhZ2U7XHJcbiAgICB0aGlzLnRvdGFsUGFnZXMgPSB0aGlzLmNhbGN1bGF0ZVRvdGFsUGFnZXMoKTtcclxuICAgIC8vIHRoaXMgY2xhc3NcclxuICAgIHRoaXMucGFnZXMgPSB0aGlzLmdldFBhZ2VzKHRoaXMucGFnZSwgdGhpcy50b3RhbFBhZ2VzKTtcclxuICAgIHRoaXMuaW5pdGVkID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB3cml0ZVZhbHVlKHZhbHVlOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIHRoaXMucGFnZSA9IHZhbHVlO1xyXG4gICAgdGhpcy5wYWdlcyA9IHRoaXMuZ2V0UGFnZXModGhpcy5wYWdlLCB0aGlzLnRvdGFsUGFnZXMpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldFRleHQoa2V5OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuICh0aGlzIGFzIGFueSlba2V5ICsgJ1RleHQnXSB8fCB0aGlzLmNvbmZpZ1trZXkgKyAnVGV4dCddO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5vUHJldmlvdXMoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5wYWdlID09PSAxO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIG5vTmV4dCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLnBhZ2UgPT09IHRoaXMudG90YWxQYWdlcztcclxuICB9XHJcblxyXG4gIHB1YmxpYyByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoXzogYW55KSA9PiB7fSk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB7fSk6IHZvaWQge1xyXG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZWxlY3RQYWdlKHBhZ2U6IG51bWJlciwgZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xyXG4gICAgaWYgKGV2ZW50KSB7XHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLmRpc2FibGVkKSB7XHJcbiAgICAgIGlmIChldmVudCAmJiBldmVudC50YXJnZXQpIHtcclxuICAgICAgICBjb25zdCB0YXJnZXQ6IGFueSA9IGV2ZW50LnRhcmdldDtcclxuICAgICAgICB0YXJnZXQuYmx1cigpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMud3JpdGVWYWx1ZShwYWdlKTtcclxuICAgICAgdGhpcy5vbkNoYW5nZSh0aGlzLnBhZ2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gQ3JlYXRlIHBhZ2Ugb2JqZWN0IHVzZWQgaW4gdGVtcGxhdGVcclxuICBwcm90ZWN0ZWQgbWFrZVBhZ2UobnVtOiBudW1iZXIsIHRleHQ6IHN0cmluZywgYWN0aXZlOiBib29sZWFuKToge251bWJlcjogbnVtYmVyLCB0ZXh0OiBzdHJpbmcsIGFjdGl2ZTogYm9vbGVhbn0ge1xyXG4gICAgcmV0dXJuIHsgdGV4dCwgbnVtYmVyOiBudW0sIGFjdGl2ZSB9O1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGdldFBhZ2VzKGN1cnJlbnRQYWdlOiBudW1iZXIsIHRvdGFsUGFnZXM6IG51bWJlcik6IGFueVtdIHtcclxuICAgIGNvbnN0IHBhZ2VzOiBhbnlbXSA9IFtdO1xyXG5cclxuICAgIC8vIERlZmF1bHQgcGFnZSBsaW1pdHNcclxuICAgIGxldCBzdGFydFBhZ2UgPSAxO1xyXG4gICAgbGV0IGVuZFBhZ2UgPSB0b3RhbFBhZ2VzO1xyXG4gICAgY29uc3QgaXNNYXhTaXplZCA9IHR5cGVvZiB0aGlzLm1heFNpemUgIT09ICd1bmRlZmluZWQnICYmIHRoaXMubWF4U2l6ZSA8IHRvdGFsUGFnZXM7XHJcblxyXG4gICAgLy8gcmVjb21wdXRlIGlmIG1heFNpemVcclxuICAgIGlmIChpc01heFNpemVkKSB7XHJcbiAgICAgIGlmICh0aGlzLnJvdGF0ZSkge1xyXG4gICAgICAgIC8vIEN1cnJlbnQgcGFnZSBpcyBkaXNwbGF5ZWQgaW4gdGhlIG1pZGRsZSBvZiB0aGUgdmlzaWJsZSBvbmVzXHJcbiAgICAgICAgc3RhcnRQYWdlID0gTWF0aC5tYXgoY3VycmVudFBhZ2UgLSBNYXRoLmZsb29yKHRoaXMubWF4U2l6ZSAvIDIpLCAxKTtcclxuICAgICAgICBlbmRQYWdlID0gc3RhcnRQYWdlICsgdGhpcy5tYXhTaXplIC0gMTtcclxuXHJcbiAgICAgICAgLy8gQWRqdXN0IGlmIGxpbWl0IGlzIGV4Y2VlZGVkXHJcbiAgICAgICAgaWYgKGVuZFBhZ2UgPiB0b3RhbFBhZ2VzKSB7XHJcbiAgICAgICAgICBlbmRQYWdlID0gdG90YWxQYWdlcztcclxuICAgICAgICAgIHN0YXJ0UGFnZSA9IGVuZFBhZ2UgLSB0aGlzLm1heFNpemUgKyAxO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBWaXNpYmxlIHBhZ2VzIGFyZSBwYWdpbmF0ZWQgd2l0aCBtYXhTaXplXHJcbiAgICAgICAgc3RhcnRQYWdlID0gKChNYXRoLmNlaWwoY3VycmVudFBhZ2UgLyB0aGlzLm1heFNpemUpIC0gMSkgKiB0aGlzLm1heFNpemUpICsgMTtcclxuXHJcbiAgICAgICAgLy8gQWRqdXN0IGxhc3QgcGFnZSBpZiBsaW1pdCBpcyBleGNlZWRlZFxyXG4gICAgICAgIGVuZFBhZ2UgPSBNYXRoLm1pbihzdGFydFBhZ2UgKyB0aGlzLm1heFNpemUgLSAxLCB0b3RhbFBhZ2VzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIEFkZCBwYWdlIG51bWJlciBsaW5rc1xyXG4gICAgZm9yIChsZXQgbnVtID0gc3RhcnRQYWdlOyBudW0gPD0gZW5kUGFnZTsgbnVtKyspIHtcclxuICAgICAgY29uc3QgcGFnZSA9IHRoaXMubWFrZVBhZ2UobnVtLCBudW0udG9TdHJpbmcoKSwgbnVtID09PSBjdXJyZW50UGFnZSk7XHJcbiAgICAgIHBhZ2VzLnB1c2gocGFnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWRkIGxpbmtzIHRvIG1vdmUgYmV0d2VlbiBwYWdlIHNldHNcclxuICAgIGlmIChpc01heFNpemVkICYmICF0aGlzLnJvdGF0ZSkge1xyXG4gICAgICBpZiAoc3RhcnRQYWdlID4gMSkge1xyXG4gICAgICAgIGNvbnN0IHByZXZpb3VzUGFnZVNldCA9IHRoaXMubWFrZVBhZ2Uoc3RhcnRQYWdlIC0gMSwgJy4uLicsIGZhbHNlKTtcclxuICAgICAgICBwYWdlcy51bnNoaWZ0KHByZXZpb3VzUGFnZVNldCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChlbmRQYWdlIDwgdG90YWxQYWdlcykge1xyXG4gICAgICAgIGNvbnN0IG5leHRQYWdlU2V0ID0gdGhpcy5tYWtlUGFnZShlbmRQYWdlICsgMSwgJy4uLicsIGZhbHNlKTtcclxuICAgICAgICBwYWdlcy5wdXNoKG5leHRQYWdlU2V0KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwYWdlcztcclxuICB9XHJcblxyXG4gIC8vIGJhc2UgY2xhc3NcclxuICBwcm90ZWN0ZWQgY2FsY3VsYXRlVG90YWxQYWdlcygpOiBudW1iZXIge1xyXG4gICAgY29uc3QgdG90YWxQYWdlcyA9IHRoaXMuaXRlbXNQZXJQYWdlIDwgMVxyXG4gICAgICA/IDFcclxuICAgICAgOiBNYXRoLmNlaWwodGhpcy50b3RhbEl0ZW1zIC8gdGhpcy5pdGVtc1BlclBhZ2UpO1xyXG4gICAgcmV0dXJuIE1hdGgubWF4KHRvdGFsUGFnZXMgfHwgMCwgMSk7XHJcbiAgfVxyXG59XHJcbiJdfQ==