UNPKG

carbon-components-angular

Version:
300 lines 26.4 kB
import { Component, Input, Output, EventEmitter } from "@angular/core"; import { merge } from "carbon-components-angular/utils"; import { range } from "carbon-components-angular/common"; import * as i0 from "@angular/core"; import * as i1 from "carbon-components-angular/i18n"; import * as i2 from "carbon-components-angular/experimental"; import * as i3 from "@angular/common"; import * as i4 from "carbon-components-angular/icon"; import * as i5 from "carbon-components-angular/forms"; import * as i6 from "./pagination-item.component"; import * as i7 from "./pagination-overflow.component"; /** * Use pagination when you have multiple pages of data to handle. Get started with importing the module: * * ```typescript * import { PaginationModule } from 'carbon-components-angular'; * ``` * * ```html * <cds-pagination-nav [model]="model" (selectPage)="selectPage($event)"></cds-pagination-nav> * ``` * * In your `selectPage()` method set the `model.currentPage` to selected page, _after_ * you load the page. * * ```typescript * selectPage(page) { * // ... your code to load the page goes here * * this.model.currentPage = page; * * // ... anything you want to do after page selection changes goes here * } * ``` * * [See demo](../../?path=/story/components-pagination-nav--basic) */ export class PaginationNav { constructor(i18n, experimental) { this.i18n = i18n; this.experimental = experimental; /** * Set to `true` to disable the backward/forward buttons. */ this.disabled = false; /** * Number of items to show in pagination. Minimum is 4. */ this.numOfItemsToShow = 4; /** * Emits the new page number. * * You should tie into this and update `model.currentPage` once the fresh * data is finally loaded. */ this.selectPage = new EventEmitter(); this.nextItemText = this.i18n.getOverridable("PAGINATION.NEXT"); this.previousItemText = this.i18n.getOverridable("PAGINATION.PREVIOUS"); PaginationNav.paginationCounter++; } /** * Expects an object that contains some or all of: * ``` * { * "NEXT": "Next", * "PREVIOUS": "Previous", * } * ``` */ set translations(value) { const valueWithDefaults = merge(this.i18n.getMultiple("PAGINATION"), value); this.nextItemText.override(valueWithDefaults.NEXT); this.previousItemText.override(valueWithDefaults.PREVIOUS); } get totalNumbersArray() { return range(this.totalDataLength + 1, 1); } get currentPage() { return this.model.currentPage; } set currentPage(value) { value = Number(value); // emits the value to allow the user to update current page // in the model once the page is loaded this.selectPage.emit(value); } get totalDataLength() { return this.model.totalDataLength; } get startOffset() { return this.numOfItemsToShow <= 4 && this.currentPage > 1 ? 0 : 1; } get frontCuts() { const cuts = this.getCuts(); return cuts.front; } get backCuts() { const cuts = this.getCuts(); return cuts.back; } get leftArrowDisabled() { return this.disabled || this.currentPage === 1; } get rightArrowDisabled() { return this.disabled || this.currentPage === this.totalDataLength; } handleOverflowSelection(page) { if (typeof page === "number") { this.currentPage = page; } } jumpToNext() { this.currentPage = this.currentPage < this.totalDataLength ? this.currentPage + 1 : this.totalDataLength; } jumpToPrevious() { this.currentPage = this.currentPage > 1 ? this.currentPage - 1 : 1; } getPages() { if (this.totalDataLength <= 1) { return null; } const cuts = this.getCuts(); return this.totalNumbersArray.slice(this.startOffset + cuts.front, (1 + cuts.back) * -1); } getCuts(splitPoint = null) { const page = this.currentPage - 1; const totalItems = this.totalDataLength; const itemsThatFit = this.numOfItemsToShow; if (itemsThatFit >= totalItems) { return { front: 0, back: 0 }; } const split = splitPoint || Math.ceil(itemsThatFit / 2) - 1; let frontHidden = page + 1 - split; let backHidden = totalItems - page - (itemsThatFit - split) + 1; if (frontHidden <= 1) { backHidden -= frontHidden <= 0 ? Math.abs(frontHidden) + 1 : 0; frontHidden = 0; } if (backHidden <= 1) { frontHidden -= backHidden <= 0 ? Math.abs(backHidden) + 1 : 0; backHidden = 0; } return { front: frontHidden, back: backHidden }; } } PaginationNav.paginationCounter = 0; PaginationNav.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationNav, deps: [{ token: i1.I18n }, { token: i2.ExperimentalService }], target: i0.ɵɵFactoryTarget.Component }); PaginationNav.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PaginationNav, selector: "cds-pagination-nav, ibm-pagination-navm", inputs: { model: "model", disabled: "disabled", numOfItemsToShow: "numOfItemsToShow", translations: "translations" }, outputs: { selectPage: "selectPage" }, ngImport: i0, template: ` <div> <div class="cds--pagination-nav"> <ul class="cds--pagination-nav__list"> <li class="cds--pagination-nav__list-item"> <cds-icon-button kind="ghost" size="md" (click)="jumpToPrevious()" [disabled]="leftArrowDisabled" [description]="previousItemText.subject | async"> <svg cdsIcon="caret--left" size="16" class="cds--btn__icon"> </svg> </cds-icon-button> </li> <cds-pagination-nav-item *ngIf="this.numOfItemsToShow >= 5 || (this.numOfItemsToShow <= 4 && currentPage <= 1)" page="1" (click)="currentPage = 1" [isActive]="currentPage == 1"> </cds-pagination-nav-item> <cds-pagination-overflow *ngIf="frontCuts" [count]="frontCuts" [fromIndex]="startOffset" (change)="handleOverflowSelection($event)"> </cds-pagination-overflow> <cds-pagination-nav-item *ngFor="let page of getPages();" [page]="page" (click)="currentPage = page" [isActive]="currentPage == page"> </cds-pagination-nav-item> <cds-pagination-overflow *ngIf="backCuts" [count]="backCuts" [fromIndex]="totalNumbersArray.length - backCuts - 1" (change)="handleOverflowSelection($event)"> </cds-pagination-overflow> <cds-pagination-nav-item *ngIf="totalDataLength > 1" [page]="totalNumbersArray.length" (click)="currentPage = totalNumbersArray.length" [isActive]="currentPage == totalNumbersArray.length"> </cds-pagination-nav-item> <li class="cds--pagination-nav__list-item"> <cds-icon-button kind="ghost" (click)="jumpToNext()" [disabled]="rightArrowDisabled" [description]="nextItemText.subject | async"> <svg cdsIcon="caret--right" size="16" class="cds--btn__icon"> </svg> </cds-icon-button> </li> </ul> </div> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "component", type: i5.IconButton, selector: "cds-icon-button, ibm-icon-button", inputs: ["buttonNgClass", "buttonAttributes", "buttonId", "kind", "size", "type", "isExpressive", "disabled", "description"], outputs: ["click", "focus", "blur", "tooltipClick"] }, { kind: "component", type: i6.PaginationNavItem, selector: "cds-pagination-nav-item, ibm-pagination-nav-item", inputs: ["page", "isActive"], outputs: ["click"] }, { kind: "component", type: i7.PaginationOverflow, selector: "cds-pagination-overflow, ibm-pagination-overflow", inputs: ["fromIndex", "count", "ariaLabel"], outputs: ["change"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PaginationNav, decorators: [{ type: Component, args: [{ selector: "cds-pagination-nav, ibm-pagination-navm", template: ` <div> <div class="cds--pagination-nav"> <ul class="cds--pagination-nav__list"> <li class="cds--pagination-nav__list-item"> <cds-icon-button kind="ghost" size="md" (click)="jumpToPrevious()" [disabled]="leftArrowDisabled" [description]="previousItemText.subject | async"> <svg cdsIcon="caret--left" size="16" class="cds--btn__icon"> </svg> </cds-icon-button> </li> <cds-pagination-nav-item *ngIf="this.numOfItemsToShow >= 5 || (this.numOfItemsToShow <= 4 && currentPage <= 1)" page="1" (click)="currentPage = 1" [isActive]="currentPage == 1"> </cds-pagination-nav-item> <cds-pagination-overflow *ngIf="frontCuts" [count]="frontCuts" [fromIndex]="startOffset" (change)="handleOverflowSelection($event)"> </cds-pagination-overflow> <cds-pagination-nav-item *ngFor="let page of getPages();" [page]="page" (click)="currentPage = page" [isActive]="currentPage == page"> </cds-pagination-nav-item> <cds-pagination-overflow *ngIf="backCuts" [count]="backCuts" [fromIndex]="totalNumbersArray.length - backCuts - 1" (change)="handleOverflowSelection($event)"> </cds-pagination-overflow> <cds-pagination-nav-item *ngIf="totalDataLength > 1" [page]="totalNumbersArray.length" (click)="currentPage = totalNumbersArray.length" [isActive]="currentPage == totalNumbersArray.length"> </cds-pagination-nav-item> <li class="cds--pagination-nav__list-item"> <cds-icon-button kind="ghost" (click)="jumpToNext()" [disabled]="rightArrowDisabled" [description]="nextItemText.subject | async"> <svg cdsIcon="caret--right" size="16" class="cds--btn__icon"> </svg> </cds-icon-button> </li> </ul> </div> </div> ` }] }], ctorParameters: function () { return [{ type: i1.I18n }, { type: i2.ExperimentalService }]; }, propDecorators: { model: [{ type: Input }], disabled: [{ type: Input }], numOfItemsToShow: [{ type: Input }], translations: [{ type: Input }], selectPage: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFnaW5hdGlvbi1uYXYuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3BhZ2luYXRpb24vcGFnaW5hdGlvbi1uYXYvcGFnaW5hdGlvbi1uYXYuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTixTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFJdkIsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3hELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQzs7Ozs7Ozs7O0FBT3pEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBcUVILE1BQU0sT0FBTyxhQUFhO0lBbUZ6QixZQUFzQixJQUFVLEVBQVksWUFBaUM7UUFBdkQsU0FBSSxHQUFKLElBQUksQ0FBTTtRQUFZLGlCQUFZLEdBQVosWUFBWSxDQUFxQjtRQTdFN0U7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQzFCOztXQUVHO1FBQ00scUJBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBa0I5Qjs7Ozs7V0FLRztRQUNPLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBMkNsRCxpQkFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDM0QscUJBQWdCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUdsRSxhQUFhLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUNuQyxDQUFDO0lBdEVEOzs7Ozs7OztPQVFHO0lBQ0gsSUFDSSxZQUFZLENBQUMsS0FBZ0M7UUFDaEQsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsWUFBWSxDQUFDLEVBQUUs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Zjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQWdFVDsyRkFFVyxhQUFhO2tCQXBFekIsU0FBUzttQkFBQztvQkFDVixRQUFRLEVBQUUseUNBQXlDO29CQUNuRCxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUFnRVQ7aUJBQ0Q7NkhBTVMsS0FBSztzQkFBYixLQUFLO2dCQUlHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBSUcsZ0JBQWdCO3NCQUF4QixLQUFLO2dCQVlGLFlBQVk7c0JBRGYsS0FBSztnQkFhSSxVQUFVO3NCQUFuQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFnaW5hdGlvbk1vZGVsIH0gZnJvbSBcIi4uL3BhZ2luYXRpb24tbW9kZWwuY2xhc3NcIjtcbmltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SW5wdXQsXG5cdE91dHB1dCxcblx0RXZlbnRFbWl0dGVyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5cbmltcG9ydCB7IEkxOG4sIE92ZXJyaWRhYmxlIH0gZnJvbSBcImNhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXIvaTE4blwiO1xuaW1wb3J0IHsgRXhwZXJpbWVudGFsU2VydmljZSB9IGZyb20gXCJjYXJib24tY29tcG9uZW50cy1hbmd1bGFyL2V4cGVyaW1lbnRhbFwiO1xuaW1wb3J0IHsgbWVyZ2UgfSBmcm9tIFwiY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhci91dGlsc1wiO1xuaW1wb3J0IHsgcmFuZ2UgfSBmcm9tIFwiY2FyYm9uLWNvbXBvbmVudHMtYW5ndWxhci9jb21tb25cIjtcblxuZXhwb3J0IGludGVyZmFjZSBQYWdpbmF0aW9uTmF2VHJhbnNsYXRpb25zIHtcblx0TkVYVDogc3RyaW5nO1xuXHRQUkVWSU9VUzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFVzZSBwYWdpbmF0aW9uIHdoZW4geW91IGhhdmUgbXVsdGlwbGUgcGFnZXMgb2YgZGF0YSB0byBoYW5kbGUuIEdldCBzdGFydGVkIHdpdGggaW1wb3J0aW5nIHRoZSBtb2R1bGU6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgUGFnaW5hdGlvbk1vZHVsZSB9IGZyb20gJ2NhcmJvbi1jb21wb25lbnRzLWFuZ3VsYXInO1xuICogYGBgXG4gKlxuICogYGBgaHRtbFxuICogPGNkcy1wYWdpbmF0aW9uLW5hdiBbbW9kZWxdPVwibW9kZWxcIiAoc2VsZWN0UGFnZSk9XCJzZWxlY3RQYWdlKCRldmVudClcIj48L2Nkcy1wYWdpbmF0aW9uLW5hdj5cbiAqIGBgYFxuICpcbiAqIEluIHlvdXIgYHNlbGVjdFBhZ2UoKWAgbWV0aG9kIHNldCB0aGUgYG1vZGVsLmN1cnJlbnRQYWdlYCB0byBzZWxlY3RlZCBwYWdlLCBfYWZ0ZXJfXG4gKiB5b3UgbG9hZCB0aGUgcGFnZS5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBzZWxlY3RQYWdlKHBhZ2UpIHtcbiAqIFx0Ly8gLi4uIHlvdXIgY29kZSB0byBsb2FkIHRoZSBwYWdlIGdvZXMgaGVyZVxuICpcbiAqIFx0dGhpcy5tb2RlbC5jdXJyZW50UGFnZSA9IHBhZ2U7XG4gKlxuICogXHQvLyAuLi4gYW55dGhpbmcgeW91IHdhbnQgdG8gZG8gYWZ0ZXIgcGFnZSBzZWxlY3Rpb24gY2hhbmdlcyBnb2VzIGhlcmVcbiAqIH1cbiAqIGBgYFxuICpcbiAqIFtTZWUgZGVtb10oLi4vLi4vP3BhdGg9L3N0b3J5L2NvbXBvbmVudHMtcGFnaW5hdGlvbi1uYXYtLWJhc2ljKVxuICovXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6IFwiY2RzLXBhZ2luYXRpb24tbmF2LCBpYm0tcGFnaW5hdGlvbi1uYXZtXCIsXG5cdHRlbXBsYXRlOiBgXG5cdDxkaXY+XG5cdFx0PGRpdiBjbGFzcz1cImNkcy0tcGFnaW5hdGlvbi1uYXZcIj5cblx0XHRcdDx1bCBjbGFzcz1cImNkcy0tcGFnaW5hdGlvbi1uYXZfX2xpc3RcIj5cblx0XHRcdFx0PGxpIGNsYXNzPVwiY2RzLS1wYWdpbmF0aW9uLW5hdl9fbGlzdC1pdGVtXCI+XG5cdFx0XHRcdFx0PGNkcy1pY29uLWJ1dHRvblxuXHRcdFx0XHRcdFx0a2luZD1cImdob3N0XCJcblx0XHRcdFx0XHRcdHNpemU9XCJtZFwiXG5cdFx0XHRcdFx0XHQoY2xpY2spPVwianVtcFRvUHJldmlvdXMoKVwiXG5cdFx0XHRcdFx0XHRbZGlzYWJsZWRdPVwibGVmdEFycm93RGlzYWJsZWRcIlxuXHRcdFx0XHRcdFx0W2Rlc2NyaXB0aW9uXT1cInByZXZpb3VzSXRlbVRleHQuc3ViamVjdCB8IGFzeW5jXCI+XG5cdFx0XHRcdFx0XHQ8c3ZnXG5cdFx0XHRcdFx0XHRcdGNkc0ljb249XCJjYXJldC0tbGVmdFwiXG5cdFx0XHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0XHRcdGNsYXNzPVwiY2RzLS1idG5fX2ljb25cIj5cblx0XHRcdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHRcdDwvY2RzLWljb24tYnV0dG9uPlxuXHRcdFx0XHQ8L2xpPlxuXHRcdFx0XHQ8Y2RzLXBhZ2luYXRpb24tbmF2LWl0ZW1cblx0XHRcdFx0XHQqbmdJZj1cInRoaXMubnVtT2ZJdGVtc1RvU2hvdyA+PSA1IHx8ICh0aGlzLm51bU9mSXRlbXNUb1Nob3cgPD0gNCAmJiBjdXJyZW50UGFnZSA8PSAxKVwiXG5cdFx0XHRcdFx0cGFnZT1cIjFcIlxuXHRcdFx0XHRcdChjbGljayk9XCJjdXJyZW50UGFnZSA9IDFcIlxuXHRcdFx0XHRcdFtpc0FjdGl2ZV09XCJjdXJyZW50UGFnZSA9PSAxXCI+XG5cdFx0XHRcdDwvY2RzLXBhZ2luYXRpb24tbmF2LWl0ZW0+XG5cdFx0XHRcdDxjZHMtcGFnaW5hdGlvbi1vdmVyZmxvd1xuXHRcdFx0XHRcdCpuZ0lmPVwiZnJvbnRDdXRzXCJcblx0XHRcdFx0XHRbY291bnRdPVwiZnJvbnRDdXRzXCJcblx0XHRcdFx0XHRbZnJvbUluZGV4XT1cInN0YXJ0T2Zmc2V0XCJcblx0XHRcdFx0XHQoY2hhbmdlKT1cImhhbmRsZU92ZXJmbG93U2VsZWN0aW9uKCRldmVudClcIj5cblx0XHRcdFx0PC9jZHMtcGFnaW5hdGlvbi1vdmVyZmxvdz5cblx0XHRcdFx0PGNkcy1wYWdpbmF0aW9uLW5hdi1pdGVtXG5cdFx0XHRcdFx0Km5nRm9yPVwibGV0IHBhZ2Ugb2YgZ2V0UGFnZXMoKTtcIlxuXHRcdFx0XHRcdFtwYWdlXT1cInBhZ2VcIlxuXHRcdFx0XHRcdChjbGljayk9XCJjdXJyZW50UGFnZSA9IHBhZ2VcIlxuXHRcdFx0XHRcdFtpc0FjdGl2ZV09XCJjdXJyZW50UGFnZSA9PSBwYWdlXCI+XG5cdFx0XHRcdDwvY2RzLXBhZ2luYXRpb24tbmF2LWl0ZW0+XG5cdFx0XHRcdDxjZHMtcGFnaW5hdGlvbi1vdmVyZmxvd1xuXHRcdFx0XHRcdCpuZ0lmPVwiYmFja0N1dHNcIlxuXHRcdFx0XHRcdFtjb3VudF09XCJiYWNrQ3V0c1wiXG5cdFx0XHRcdFx0W2Zyb21JbmRleF09XCJ0b3RhbE51bWJlcnNBcnJheS5sZW5ndGggLSBiYWNrQ3V0cyAtIDFcIlxuXHRcdFx0XHRcdChjaGFuZ2UpPVwiaGFuZGxlT3ZlcmZsb3dTZWxlY3Rpb24oJGV2ZW50KVwiPlxuXHRcdFx0XHQ8L2Nkcy1wYWdpbmF0aW9uLW92ZXJmbG93PlxuXHRcdFx0XHQ8Y2RzLXBhZ2luYXRpb24tbmF2LWl0ZW1cblx0XHRcdFx0XHQqbmdJZj1cInRvdGFsRGF0YUxlbmd0aCA+IDFcIlxuXHRcdFx0XHRcdFtwYWdlXT1cInRvdGFsTnVtYmVyc0FycmF5Lmxlbmd0aFwiXG5cdFx0XHRcdFx0KGNsaWNrKT1cImN1cnJlbnRQYWdlID0gdG90YWxOdW1iZXJzQXJyYXkubGVuZ3RoXCJcblx0XHRcdFx0XHRbaXNBY3RpdmVdPVwiY3VycmVudFBhZ2UgPT0gdG90YWxOdW1iZXJzQXJyYXkubGVuZ3RoXCI+XG5cdFx0XHRcdDwvY2RzLXBhZ2luYXRpb24tbmF2LWl0ZW0+XG5cdFx0XHRcdDxsaSBjbGFzcz1cImNkcy0tcGFnaW5hdGlvbi1uYXZfX2xpc3QtaXRlbVwiPlxuXHRcdFx0XHRcdDxjZHMtaWNvbi1idXR0b25cblx0XHRcdFx0XHRcdGtpbmQ9XCJnaG9zdFwiXG5cdFx0XHRcdFx0XHQoY2xpY2spPVwianVtcFRvTmV4dCgpXCJcblx0XHRcdFx0XHRcdFtkaXNhYmxlZF09XCJyaWdodEFycm93RGlzYWJsZWRcIlxuXHRcdFx0XHRcdFx0W2Rlc2NyaXB0aW9uXT1cIm5leHRJdGVtVGV4dC5zdWJqZWN0IHwgYXN5bmNcIj5cblx0XHRcdFx0XHRcdDxzdmdcblx0XHRcdFx0XHRcdFx0Y2RzSWNvbj1cImNhcmV0LS1yaWdodFwiXG5cdFx0XHRcdFx0XHRcdHNpemU9XCIxNlwiXG5cdFx0XHRcdFx0XHRcdGNsYXNzPVwiY2RzLS1idG5fX2ljb25cIj5cblx0XHRcdFx0XHRcdDwvc3ZnPlxuXHRcdFx0XHRcdDwvY2RzLWljb24tYnV0dG9uPlxuXHRcdFx0XHQ8L2xpPlxuXHRcdFx0PC91bD5cblx0XHQ8L2Rpdj5cblx0PC9kaXY+XG5cdGBcbn0pXG5leHBvcnQgY2xhc3MgUGFnaW5hdGlvbk5hdiB7XG5cdHN0YXRpYyBwYWdpbmF0aW9uQ291bnRlciA9IDA7XG5cdC8qKlxuXHQgKiBgUGFnaW5hdGlvbk5hdk1vZGVsYCB3aXRoIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBwYWdlcyB5b3UncmUgY29udHJvbGxpbmcuXG5cdCAqL1xuXHRASW5wdXQoKSBtb2RlbDogUGFnaW5hdGlvbk1vZGVsO1xuXHQvKipcblx0ICAgKiBTZXQgdG8gYHRydWVgIHRvIGRpc2FibGUgdGhlIGJhY2t3YXJkL2ZvcndhcmQgYnV0dG9ucy5cblx0ICovXG5cdEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XG5cdC8qKlxuXHQgKiBOdW1iZXIgb2YgaXRlbXMgdG8gc2hvdyBpbiBwYWdpbmF0aW9uLiBNaW5pbXVtIGlzIDQuXG5cdCAqL1xuXHRASW5wdXQoKSBudW1PZkl0ZW1zVG9TaG93ID0gNDtcblxuXHQvKipcblx0ICogRXhwZWN0cyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBzb21lIG9yIGFsbCBvZjpcblx0ICogYGBgXG5cdCAqIHtcblx0ICpcdFx0XCJORVhUXCI6IFwiTmV4dFwiLFxuXHQgKlx0XHRcIlBSRVZJT1VTXCI6IFwiUHJldmlvdXNcIixcblx0ICogfVxuXHQgKiBgYGBcblx0ICovXG5cdEBJbnB1dCgpXG5cdHNldCB0cmFuc2xhdGlvbnModmFsdWU6IFBhZ2luYXRpb25OYXZUcmFuc2xhdGlvbnMpIHtcblx0XHRjb25zdCB2YWx1ZVdpdGhEZWZhdWx0cyA9IG1lcmdlKHRoaXMuaTE4bi5nZXRNdWx0aXBsZShcIlBBR0lOQVRJT05cIiksIHZhbHVlKTtcblx0XHR0aGlzLm5leHRJdGVtVGV4dC5vdmVycmlkZSh2YWx1ZVdpdGhEZWZhdWx0cy5ORVhUKTtcblx0XHR0aGlzLnByZXZpb3VzSXRlbVRleHQub3ZlcnJpZGUodmFsdWVXaXRoRGVmYXVsdHMuUFJFVklPVVMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIEVtaXRzIHRoZSBuZXcgcGFnZSBudW1iZXIuXG5cdCAqXG5cdCAqIFlvdSBzaG91bGQgdGllIGludG8gdGhpcyBhbmQgdXBkYXRlIGBtb2RlbC5jdXJyZW50UGFnZWAgb25jZSB0aGUgZnJlc2hcblx0ICogZGF0YSBpcyBmaW5hbGx5IGxvYWRlZC5cblx0ICovXG5cdEBPdXRwdXQoKSBzZWxlY3RQYWdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XG5cblx0Z2V0IHRvdGFsTnVtYmVyc0FycmF5KCkge1xuXHRcdHJldHVybiByYW5nZSh0aGlzLnRvdGFsRGF0YUxlbmd0aCArIDEsIDEpO1xuXHR9XG5cblx0Z2V0IGN1cnJlbnRQYWdlKCkge1xuXHRcdHJldHVybiB0aGlzLm1vZGVsLmN1cnJlbnRQYWdlO1xuXHR9XG5cblx0c2V0IGN1cnJlbnRQYWdlKHZhbHVlKSB7XG5cdFx0dmFsdWUgPSBOdW1iZXIodmFsdWUpO1xuXHRcdC8vIGVtaXRzIHRoZSB2YWx1ZSB0byBhbGxvdyB0aGUgdXNlciB0byB1cGRhdGUgY3VycmVudCBwYWdlXG5cdFx0Ly8gaW4gdGhlIG1vZGVsIG9uY2UgdGhlIHBhZ2UgaXMgbG9hZGVkXG5cdFx0dGhpcy5zZWxlY3RQYWdlLmVtaXQodmFsdWUpO1xuXHR9XG5cblx0Z2V0IHRvdGFsRGF0YUxlbmd0aCgpIHtcblx0XHRyZXR1cm4gdGhpcy5tb2RlbC50b3RhbERhdGFMZW5ndGg7XG5cdH1cblxuXHRnZXQgc3RhcnRPZmZzZXQoKSB7XG5cdFx0cmV0dXJuIHRoaXMubnVtT2ZJdGVtc1RvU2hvdyA8PSA0ICYmIHRoaXMuY3VycmVudFBhZ2UgPiAxID8gMCA6IDE7XG5cdH1cblxuXHRnZXQgZnJvbnRDdXRzKCkge1xuXHRcdGNvbnN0IGN1dHMgPSB0aGlzLmdldEN1dHMoKTtcblx0XHRyZXR1cm4gY3V0cy5mcm9udDtcblx0fVxuXG5cdGdldCBiYWNrQ3V0cygpIHtcblx0XHRjb25zdCBjdXRzID0gdGhpcy5nZXRDdXRzKCk7XG5cdFx0cmV0dXJuIGN1dHMuYmFjaztcblx0fVxuXG5cdGdldCBsZWZ0QXJyb3dEaXNhYmxlZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5kaXNhYmxlZCB8fCB0aGlzLmN1cnJlbnRQYWdlID09PSAxO1xuXHR9XG5cblx0Z2V0IHJpZ2h0QXJyb3dEaXNhYmxlZCgpIHtcblx0XHRyZXR1cm4gdGhpcy5kaXNhYmxlZCB8fCB0aGlzLmN1cnJlbnRQYWdlID09PSB0aGlzLnRvdGFsRGF0YUxlbmd0aDtcblx0fVxuXG5cdG5leHRJdGVtVGV4dCA9IHRoaXMuaTE4bi5nZXRPdmVycmlkYWJsZShcIlBBR0lOQVRJT04uTkVYVFwiKTtcblx0cHJldmlvdXNJdGVtVGV4dCA9IHRoaXMuaTE4bi5nZXRPdmVycmlkYWJsZShcIlBBR0lOQVRJT04uUFJFVklPVVNcIik7XG5cblx0Y29uc3RydWN0b3IocHJvdGVjdGVkIGkxOG46IEkxOG4sIHByb3RlY3RlZCBleHBlcmltZW50YWw6IEV4cGVyaW1lbnRhbFNlcnZpY2UpIHtcblx0XHRQYWdpbmF0aW9uTmF2LnBhZ2luYXRpb25Db3VudGVyKys7XG5cdH1cblxuXHRoYW5kbGVPdmVyZmxvd1NlbGVjdGlvbihwYWdlKSB7XG5cdFx0aWYgKHR5cGVvZiBwYWdlID09PSBcIm51bWJlclwiKSB7XG5cdFx0XHR0aGlzLmN1cnJlbnRQYWdlID0gcGFnZTtcblx0XHR9XG5cdH1cblxuXHRwdWJsaWMganVtcFRvTmV4dCgpIHtcblx0XHR0aGlzLmN1cnJlbnRQYWdlID0gdGhpcy5jdXJyZW50UGFnZSA8IHRoaXMudG90YWxEYXRhTGVuZ3RoID8gdGhpcy5jdXJyZW50UGFnZSArIDEgOiB0aGlzLnRvdGFsRGF0YUxlbmd0aDtcblx0fVxuXG5cdHB1YmxpYyBqdW1wVG9QcmV2aW91cygpIHtcblx0XHR0aGlzLmN1cnJlbnRQYWdlID0gdGhpcy5jdXJyZW50UGFnZSA+IDEgPyB0aGlzLmN1cnJlbnRQYWdlIC0gMSA6IDE7XG5cdH1cblxuXHRwdWJsaWMgZ2V0UGFnZXMoKSB7XG5cdFx0aWYgKHRoaXMudG90YWxEYXRhTGVuZ3RoIDw9IDEpIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0XHRjb25zdCBjdXRzID0gdGhpcy5nZXRDdXRzKCk7XG5cdFx0cmV0dXJuIHRoaXMudG90YWxOdW1iZXJzQXJyYXkuc2xpY2UodGhpcy5zdGFydE9mZnNldCArIGN1dHMuZnJvbnQsICgxICsgY3V0cy5iYWNrKSAqIC0xKTtcblx0fVxuXG5cdHByaXZhdGUgZ2V0Q3V0cyhzcGxpdFBvaW50ID0gbnVsbCkge1xuXHRcdGNvbnN0IHBhZ2UgPSB0aGlzLmN1cnJlbnRQYWdlIC0gMTtcblx0XHRjb25zdCB0b3RhbEl0ZW1zID0gdGhpcy50b3RhbERhdGFMZW5ndGg7XG5cdFx0Y29uc3QgaXRlbXNUaGF0Rml0ID0gdGhpcy5udW1PZkl0ZW1zVG9TaG93O1xuXG5cdFx0aWYgKGl0ZW1zVGhhdEZpdCA+PSB0b3RhbEl0ZW1zKSB7XG5cdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRmcm9udDogMCxcblx0XHRcdFx0YmFjazogMFxuXHRcdFx0fTtcblx0XHR9XG5cdFx0Y29uc3Qgc3BsaXQgPSBzcGxpdFBvaW50IHx8IE1hdGguY2VpbChpdGVtc1RoYXRGaXQgLyAyKSAtIDE7XG5cdFx0bGV0IGZyb250SGlkZGVuID0gcGFnZSArIDEgLSBzcGxpdDtcblx0XHRsZXQgYmFja0hpZGRlbiA9IHRvdGFsSXRlbXMgLSBwYWdlIC0gKGl0ZW1zVGhhdEZpdCAtIHNwbGl0KSArIDE7XG5cblx0XHRpZiAoZnJvbnRIaWRkZW4gPD0gMSkge1xuXHRcdFx0YmFja0hpZGRlbiAtPSBmcm9udEhpZGRlbiA8PSAwID8gTWF0aC5hYnMoZnJvbnRIaWRkZW4pICsgMSA6IDA7XG5cdFx0XHRmcm9udEhpZGRlbiA9IDA7XG5cdFx0fVxuXHRcdGlmIChiYWNrSGlkZGVuIDw9IDEpIHtcblx0XHRcdGZyb250SGlkZGVuIC09IGJhY2tIaWRkZW4gPD0gMCA/IE1hdGguYWJzKGJhY2tIaWRkZW4pICsgMSA6IDA7XG5cdFx0XHRiYWNrSGlkZGVuID0gMDtcblx0XHR9XG5cdFx0cmV0dXJuIHtcblx0XHRcdGZyb250OiBmcm9udEhpZGRlbixcblx0XHRcdGJhY2s6IGJhY2tIaWRkZW5cblx0XHR9O1xuXHR9XG59XG4iXX0=