ontimize-web-ngx
Version:
Ontimize Web framework using Angular 15
258 lines • 38.8 kB
JavaScript
import { Component, forwardRef, Inject, Injector, ViewEncapsulation } from '@angular/core';
import { Router } from '@angular/router';
import { OntimizeServiceProvider } from '../../../services/factories';
import { NavigationService } from '../../../services/navigation.service';
import { OntimizeService } from '../../../services/ontimize/ontimize.service';
import { Codes } from '../../../util/codes';
import { Util } from '../../../util/util';
import { OFormBase } from '../o-form-base.class';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "@angular/common";
import * as i3 from "@angular/material/button";
import * as i4 from "@angular/material/icon";
import * as i5 from "../o-form-base.class";
export class OFormNavigationComponent {
constructor(injector, _form, router) {
this.injector = injector;
this._form = _form;
this.router = router;
this.navigationData = [];
this._currentIndex = 0;
this.formNavigation = this._form.getFormNavigation();
this.navigationService = this.injector.get(NavigationService);
this.formLayoutManager = this._form.getFormManager();
let navData;
if (this.formLayoutManager && this.formLayoutManager.allowNavigation()) {
navData = this.navigationService.getLastItem();
}
else {
navData = this.navigationService.getPreviousRouteData();
}
if (Util.isDefined(navData)) {
this.navigationData = navData.keysValues || [];
this.queryConf = navData.queryConfiguration;
}
this.currentIndex = this.getCurrentIndex();
this.configureService();
}
configureService() {
if (!this.queryConf) {
return;
}
const configureService = {
injector: this.injector,
baseService: OntimizeService,
entity: this.queryConf.entity,
service: this.queryConf.service,
serviceType: this.queryConf.serviceType
};
this.dataService = Util.configureService(configureService);
}
queryNavigationData(offset, length) {
const self = this;
return new Promise((resolve, reject) => {
const conf = self.queryConf;
const queryArgs = conf.queryArguments;
queryArgs[1] = self.getKeysArray();
queryArgs[4] = offset;
queryArgs[5] = length ? length : conf.queryRows;
self.querySubscription = self.dataService[conf.queryMethod].apply(self.dataService, queryArgs).subscribe(res => {
if (res.isSuccessful()) {
self.navigationData = res.data;
self.queryConf.queryRecordOffset = offset;
}
resolve();
}, () => {
reject();
});
});
}
ngOnDestroy() {
if (this.querySubscription) {
this.querySubscription.unsubscribe();
}
}
getKeysArray() {
const navData = this.navigationData ? (this.navigationData[0] || {}) : {};
const keysArray = [];
this._form.keysArray.forEach(key => {
if (navData.hasOwnProperty(key)) {
keysArray.push(key);
}
});
return keysArray;
}
getCurrentIndex() {
const keysArray = this.getKeysArray();
const currentKeys = {};
const currentItem = this.formNavigation.getUrlParams();
keysArray.forEach(key => {
currentKeys[key] = currentItem[key];
});
const index = (this.navigationData || []).findIndex((item) => {
const itemKeys = {};
keysArray.forEach(key => {
itemKeys[key] = item[key];
});
return Util.isEquivalent(itemKeys, currentKeys);
});
return index >= 0 ? index : 0;
}
next() {
const total = this.navigationData.length;
const index = this.currentIndex + 1;
if (total > index) {
this.move(index);
}
else if (this.queryConf) {
const offset = (this.queryConf.queryRecordOffset || 0) + this.queryConf.queryRows;
this.queryNavigationData(offset).then(() => {
this.move(0);
});
}
else {
console.error('form-toolbar->next(): total > index');
}
}
previous() {
const index = this.currentIndex - 1;
if (index >= 0) {
this.move(index);
}
else if (this.queryConf) {
const offset = this.queryConf.queryRecordOffset - this.queryConf.queryRows;
this.queryNavigationData(offset).then(() => {
this.move(this.navigationData.length - 1);
});
}
else {
console.error('form-toolbar->next(): index < 0');
}
}
first() {
if (!this.queryConf || this.queryConf.queryRecordOffset === 0) {
this.move(0);
}
else {
this.queryNavigationData(0).then(() => {
this.move(0);
});
}
}
last() {
if (!this.queryConf || this.isLast()) {
const index = this.navigationData.length - 1;
this.move(index);
}
else {
const offset = this.queryConf.totalRecordsNumber - this.queryConf.queryRows;
this.queryNavigationData(offset, this.queryConf.queryRows).then(() => {
this.move(this.navigationData.length - 1);
});
}
}
isFirst() {
let result = this.currentIndex === 0;
if (result && this.queryConf) {
result = this.queryConf.queryRecordOffset === 0;
}
return result;
}
isLast() {
let result = this.currentIndex === (this.navigationData.length - 1);
if (result && this.queryConf) {
result = (this.queryConf.queryRecordOffset + this.queryConf.queryRows)
>= this.queryConf.totalRecordsNumber;
}
return result;
}
move(index) {
this._form.showConfirmDiscardChanges().then(res => {
if (res === true) {
this.currentIndex = index;
if (this.formLayoutManager && this.formLayoutManager.allowNavigation()) {
this.moveInFormLayoutManager(index);
}
else {
this.moveWithoutManager(index);
}
}
});
}
moveWithoutManager(index) {
const route = this.getRouteOfSelectedRow(this.navigationData[index]);
if (route.length > 0) {
const navData = this.navigationService.getLastItem();
if (navData) {
this._form.canDiscardChanges = true;
const extras = {};
extras[Codes.QUERY_PARAMS] = Codes.getIsDetailObject();
const urlArray = navData.url.split(Codes.ROUTE_SEPARATOR);
const url = urlArray.splice(0, urlArray.length - route.length).join(Codes.ROUTE_SEPARATOR);
route.unshift(url);
this.router.navigate(route, extras).then((navigationDone) => {
if (navigationDone) {
this.currentIndex = index;
const url = this.router.routerState.snapshot.url.split('?')[0];
if (url !== navData.url) {
this.navigationService.removeLastItem();
}
}
});
}
}
}
moveInFormLayoutManager(index) {
this._form.setUrlParamsAndReload(this.navigationData[index]);
}
getRouteOfSelectedRow(item) {
const route = [];
if (Util.isObject(item)) {
this._form.keysArray.forEach(key => {
if (Util.isDefined(item[key])) {
route.push(item[key]);
}
});
}
return route;
}
showNavigation() {
return (Util.isDefined(this.queryConf) && Util.isDefined(this.queryConf.totalRecordsNumber)) ? this.queryConf.totalRecordsNumber > 1 : this.navigationData.length > 1;
}
set currentIndex(arg) {
this._currentIndex = arg;
}
get currentIndex() {
return this._currentIndex;
}
getRecordIndex() {
let index = this.currentIndex + 1;
if (this.queryConf) {
index += this.queryConf.queryRecordOffset;
}
return index;
}
getTotalRecordsNumber() {
if (this.queryConf && this.queryConf.totalRecordsNumber) {
return this.queryConf.totalRecordsNumber;
}
return this.navigationData.length;
}
}
OFormNavigationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OFormNavigationComponent, deps: [{ token: i0.Injector }, { token: forwardRef(() => OFormBase) }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
OFormNavigationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OFormNavigationComponent, selector: "o-form-navigation", host: { properties: { "class.o-form-navigation": "true" } }, providers: [
OntimizeServiceProvider
], ngImport: i0, template: "<ng-container *ngIf=\"showNavigation()\">\n <button mat-icon-button class=\"o-form-toolbar-button\" [disabled]=\"isFirst()\" (click)=\"first()\">\n <mat-icon aria-label=\"First\" layout-padding svgIcon=\"ontimize:first_page\"></mat-icon>\n </button>\n <button mat-icon-button class=\"o-form-toolbar-button\" [disabled]=\"isFirst()\" (click)=\"previous()\">\n <mat-icon aria-label=\"Previous\" layout-padding svgIcon=\"ontimize:keyboard_arrow_left\"></mat-icon>\n </button>\n <span layout-padding>{{ getRecordIndex() }} / {{ getTotalRecordsNumber() }}</span>\n <button mat-icon-button class=\"o-form-toolbar-button\" [disabled]=\"isLast()\" (click)=\"next()\">\n <mat-icon aria-label=\"Next\" layout-padding svgIcon=\"ontimize:keyboard_arrow_right\"></mat-icon>\n </button>\n <button mat-icon-button class=\"o-form-toolbar-button\" [disabled]=\"isLast()\" (click)=\"last()\">\n <mat-icon aria-label=\"Last\" layout-padding svgIcon=\"ontimize:last_page\"></mat-icon>\n </button>\n</ng-container>", styles: [".o-form-navigation .mat-icon{cursor:pointer}.o-form-navigation span{cursor:default}\n"], dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OFormNavigationComponent, decorators: [{
type: Component,
args: [{ selector: 'o-form-navigation', encapsulation: ViewEncapsulation.None, host: {
'[class.o-form-navigation]': 'true'
}, providers: [
OntimizeServiceProvider
], template: "<ng-container *ngIf=\"showNavigation()\">\n <button mat-icon-button class=\"o-form-toolbar-button\" [disabled]=\"isFirst()\" (click)=\"first()\">\n <mat-icon aria-label=\"First\" layout-padding svgIcon=\"ontimize:first_page\"></mat-icon>\n </button>\n <button mat-icon-button class=\"o-form-toolbar-button\" [disabled]=\"isFirst()\" (click)=\"previous()\">\n <mat-icon aria-label=\"Previous\" layout-padding svgIcon=\"ontimize:keyboard_arrow_left\"></mat-icon>\n </button>\n <span layout-padding>{{ getRecordIndex() }} / {{ getTotalRecordsNumber() }}</span>\n <button mat-icon-button class=\"o-form-toolbar-button\" [disabled]=\"isLast()\" (click)=\"next()\">\n <mat-icon aria-label=\"Next\" layout-padding svgIcon=\"ontimize:keyboard_arrow_right\"></mat-icon>\n </button>\n <button mat-icon-button class=\"o-form-toolbar-button\" [disabled]=\"isLast()\" (click)=\"last()\">\n <mat-icon aria-label=\"Last\" layout-padding svgIcon=\"ontimize:last_page\"></mat-icon>\n </button>\n</ng-container>", styles: [".o-form-navigation .mat-icon{cursor:pointer}.o-form-navigation span{cursor:default}\n"] }]
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i5.OFormBase, decorators: [{
type: Inject,
args: [forwardRef(() => OFormBase)]
}] }, { type: i1.Router }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby1mb3JtLW5hdmlnYXRpb24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb250aW1pemUtd2ViLW5neC9zcmMvbGliL2NvbXBvbmVudHMvZm9ybS9uYXZpZ2F0aW9uL28tZm9ybS1uYXZpZ2F0aW9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2Zvcm0vbmF2aWdhdGlvbi9vLWZvcm0tbmF2aWdhdGlvbi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFtQixpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1RyxPQUFPLEVBQW9CLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBSTNELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3RFLE9BQU8sRUFBRSxpQkFBaUIsRUFBbUIsTUFBTSxzQ0FBc0MsQ0FBQztBQUMxRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDOUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMxQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7Ozs7Ozs7QUEwQmpELE1BQU0sT0FBTyx3QkFBd0I7SUFhbkMsWUFDWSxRQUFrQixFQUNpQixLQUFnQixFQUNyRCxNQUFjO1FBRlosYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNpQixVQUFLLEdBQUwsS0FBSyxDQUFXO1FBQ3JELFdBQU0sR0FBTixNQUFNLENBQVE7UUFkakIsbUJBQWMsR0FBZSxFQUFFLENBQUM7UUFDL0Is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ICcuLy4uLy4uLy4uL3R5cGVzL2NvbmZpZ3VyZS1zZXJ2aWNlLWFyZ3MudHlwZSc7XG5pbXBvcnQgeyBDb21wb25lbnQsIGZvcndhcmRSZWYsIEluamVjdCwgSW5qZWN0b3IsIE9uRGVzdHJveSwgVHlwZSwgVmlld0VuY2Fwc3VsYXRpb24gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5hdmlnYXRpb25FeHRyYXMsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgT0Zvcm1MYXlvdXRNYW5hZ2VyQmFzZSB9IGZyb20gJy4uLy4uLy4uL2xheW91dHMvZm9ybS1sYXlvdXQvby1mb3JtLWxheW91dC1tYW5hZ2VyLWJhc2UuY2xhc3MnO1xuaW1wb3J0IHsgT250aW1pemVTZXJ2aWNlUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9mYWN0b3JpZXMnO1xuaW1wb3J0IHsgTmF2aWdhdGlvblNlcnZpY2UsIE9OYXZpZ2F0aW9uSXRlbSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL25hdmlnYXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBPbnRpbWl6ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9vbnRpbWl6ZS9vbnRpbWl6ZS5zZXJ2aWNlJztcbmltcG9ydCB7IENvZGVzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9jb2Rlcyc7XG5pbXBvcnQgeyBVdGlsIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC91dGlsJztcbmltcG9ydCB7IE9Gb3JtQmFzZSB9IGZyb20gJy4uL28tZm9ybS1iYXNlLmNsYXNzJztcbmltcG9ydCB7IE9Gb3JtTmF2aWdhdGlvbkNsYXNzIH0gZnJvbSAnLi9vLWZvcm0ubmF2aWdhdGlvbi5jbGFzcyc7XG5cbmV4cG9ydCB0eXBlIFF1ZXJ5Q29uZmlndXJhdGlvbiA9IHtcbiAgc2VydmljZVR5cGU6IHN0cmluZztcbiAgcXVlcnlBcmd1bWVudHM6IGFueVtdO1xuICBlbnRpdHk6IHN0cmluZztcbiAgc2VydmljZTogc3RyaW5nO1xuICBxdWVyeU1ldGhvZDogc3RyaW5nO1xuICB0b3RhbFJlY29yZHNOdW1iZXI6IG51bWJlcjtcbiAgcXVlcnlSb3dzOiBudW1iZXI7XG4gIHF1ZXJ5UmVjb3JkT2Zmc2V0OiBudW1iZXI7XG59O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdvLWZvcm0tbmF2aWdhdGlvbicsXG4gIHRlbXBsYXRlVXJsOiAnLi9vLWZvcm0tbmF2aWdhdGlvbi5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL28tZm9ybS1uYXZpZ2F0aW9uLmNvbXBvbmVudC5zY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGhvc3Q6IHtcbiAgICAnW2NsYXNzLm8tZm9ybS1uYXZpZ2F0aW9uXSc6ICd0cnVlJ1xuICB9LFxuICBwcm92aWRlcnM6IFtcbiAgICBPbnRpbWl6ZVNlcnZpY2VQcm92aWRlclxuICBdXG59KVxuZXhwb3J0IGNsYXNzIE9Gb3JtTmF2aWdhdGlvbkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgcHVibGljIG5hdmlnYXRpb25EYXRhOiBBcnJheTxhbnk+ID0gW107XG4gIHByaXZhdGUgX2N1cnJlbnRJbmRleCA9IDA7XG5cbiAgcHJvdGVjdGVkIGZvcm1OYXZpZ2F0aW9uOiBPRm9ybU5hdmlnYXRpb25DbGFzcztcbiAgcHJvdGVjdGVkIG5hdmlnYXRpb25TZXJ2aWNlOiBOYXZpZ2F0aW9uU2VydmljZTtcbiAgcHJvdGVjdGVkIGZvcm1MYXlvdXRNYW5hZ2VyOiBPRm9ybUxheW91dE1hbmFnZXJCYXNlO1xuXG4gIHByb3RlY3RlZCBxdWVyeVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBwcm90ZWN0ZWQgZGF0YVNlcnZpY2U6IGFueTtcbiAgcHJvdGVjdGVkIHF1ZXJ5Q29uZjogUXVlcnlDb25maWd1cmF0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgQEluamVjdChmb3J3YXJkUmVmKCgpID0+IE9Gb3JtQmFzZSkpIHByaXZhdGUgX2Zvcm06IE9Gb3JtQmFzZSxcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyXG4gICkge1xuICAgIHRoaXMuZm9ybU5hdmlnYXRpb24gPSB0aGlzLl9mb3JtLmdldEZvcm1OYXZpZ2F0aW9uKCk7XG4gICAgdGhpcy5uYXZpZ2F0aW9uU2VydmljZSA9IHRoaXMuaW5qZWN0b3IuZ2V0PE5hdmlnYXRpb25TZXJ2aWNlPihOYXZpZ2F0aW9uU2VydmljZSBhcyBUeXBlPE5hdmlnYXRpb25TZXJ2aWNlPik7XG5cbiAgICB0aGlzLmZvcm1MYXlvdXRNYW5hZ2VyID0gdGhpcy5fZm9ybS5nZXRGb3JtTWFuYWdlcigpO1xuXG4gICAgbGV0IG5hdkRhdGE7XG4gICAgaWYgKHRoaXMuZm9ybUxheW91dE1hbmFnZXIgJiYgdGhpcy5mb3JtTGF5b3V0TWFuYWdlci5hbGxvd05hdmlnYXRpb24oKSkge1xuICAgICAgbmF2RGF0YSA9IHRoaXMubmF2aWdhdGlvblNlcnZpY2UuZ2V0TGFzdEl0ZW0oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmF2RGF0YSA9IHRoaXMubmF2aWdhdGlvblNlcnZpY2UuZ2V0UHJldmlvdXNSb3V0ZURhdGEoKTtcbiAgICB9XG4gICAgaWYgKFV0aWwuaXNEZWZpbmVkKG5hdkRhdGEpKSB7XG4gICAgICB0aGlzLm5hdmlnYXRpb25EYXRhID0gbmF2RGF0YS5rZXlzVmFsdWVzIHx8IFtdO1xuICAgICAgdGhpcy5xdWVyeUNvbmYgPSBuYXZEYXRhLnF1ZXJ5Q29uZmlndXJhdGlvbjtcbiAgICB9XG4gICAgdGhpcy5jdXJyZW50SW5kZXggPSB0aGlzLmdldEN1cnJlbnRJbmRleCgpO1xuICAgIHRoaXMuY29uZmlndXJlU2VydmljZSgpO1xuICB9XG5cbiAgY29uZmlndXJlU2VydmljZSgpIHtcbiAgICBpZiAoIXRoaXMucXVlcnlDb25mKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNvbmZpZ3VyZVNlcnZpY2U6IE9Db25maWd1cmVTZXJ2aWNlQXJncyA9IHtcbiAgICAgIGluamVjdG9yOiB0aGlzLmluamVjdG9yLFxuICAgICAgYmFzZVNlcnZpY2U6IE9udGltaXplU2VydmljZSxcbiAgICAgIGVudGl0eTogdGhpcy5xdWVyeUNvbmYuZW50aXR5LFxuICAgICAgc2VydmljZTogdGhpcy5xdWVyeUNvbmYuc2VydmljZSxcbiAgICAgIHNlcnZpY2VUeXBlOiB0aGlzLnF1ZXJ5Q29uZi5zZXJ2aWNlVHlwZVxuICAgIH07XG4gICAgdGhpcy5kYXRhU2VydmljZSA9IFV0aWwuY29uZmlndXJlU2VydmljZShjb25maWd1cmVTZXJ2aWNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBxdWVyeU5hdmlnYXRpb25EYXRhKG9mZnNldDogbnVtYmVyLCBsZW5ndGg/OiBudW1iZXIpOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTxhbnk+KChyZXNvbHZlOiBhbnksIHJlamVjdDogYW55KSA9PiB7XG4gICAgICBjb25zdCBjb25mID0gc2VsZi5xdWVyeUNvbmY7XG4gICAgICBjb25zdCBxdWVyeUFyZ3MgPSBjb25mLnF1ZXJ5QXJndW1lbnRzO1xuXG4gICAgICBxdWVyeUFyZ3NbMV0gPSBzZWxmLmdldEtleXNBcnJheSgpO1xuICAgICAgcXVlcnlBcmdzWzRdID0gb2Zmc2V0O1xuICAgICAgcXVlcnlBcmdzWzVdID0gbGVuZ3RoID8gbGVuZ3RoIDogY29uZi5xdWVyeVJvd3M7XG5cbiAgICAgIHNlbGYucXVlcnlTdWJzY3JpcHRpb24gPSBzZWxmLmRhdGFTZXJ2aWNlW2NvbmYucXVlcnlNZXRob2RdLmFwcGx5KHNlbGYuZGF0YVNlcnZpY2UsIHF1ZXJ5QXJncykuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICAgIGlmIChyZXMuaXNTdWNjZXNzZnVsKCkpIHtcbiAgICAgICAgICBzZWxmLm5hdmlnYXRpb25EYXRhID0gcmVzLmRhdGE7XG4gICAgICAgICAgc2VsZi5xdWVyeUNvbmYucXVlcnlSZWNvcmRPZmZzZXQgPSBvZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSwgKCkgPT4ge1xuICAgICAgICByZWplY3QoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucXVlcnlTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMucXVlcnlTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0S2V5c0FycmF5KCk6IHN0cmluZ1tdIHtcbiAgICAvLyBnZXR0aW5nIGF2YWlsYWJsZSBuYXZpZ2F0aW9uRGF0YSBrZXlzXG4gICAgY29uc3QgbmF2RGF0YSA9IHRoaXMubmF2aWdhdGlvbkRhdGEgPyAodGhpcy5uYXZpZ2F0aW9uRGF0YVswXSB8fCB7fSkgOiB7fTtcbiAgICBjb25zdCBrZXlzQXJyYXkgPSBbXTtcbiAgICB0aGlzLl9mb3JtLmtleXNBcnJheS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAobmF2RGF0YS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIGtleXNBcnJheS5wdXNoKGtleSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGtleXNBcnJheTtcbiAgfVxuXG4gIGdldEN1cnJlbnRJbmRleCgpOiBudW1iZXIge1xuICAgIGNvbnN0IGtleXNBcnJheSA9IHRoaXMuZ2V0S2V5c0FycmF5KCk7XG4gICAgLy8gY3VycmVudCB1cmwga2V5cyBvYmplY3RcbiAgICBjb25zdCBjdXJyZW50S2V5cyA9IHt9O1xuICAgIGNvbnN0IGN1cnJlbnRJdGVtID0gdGhpcy5mb3JtTmF2aWdhdGlvbi5nZXRVcmxQYXJhbXMoKTtcbiAgICBrZXlzQXJyYXkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY3VycmVudEtleXNba2V5XSA9IGN1cnJlbnRJdGVtW2tleV07XG4gICAgfSk7XG4gICAgY29uc3QgaW5kZXg6IG51bWJlciA9ICh0aGlzLm5hdmlnYXRpb25EYXRhIHx8IFtdKS5maW5kSW5kZXgoKGl0ZW06IGFueSkgPT4ge1xuICAgICAgY29uc3QgaXRlbUtleXMgPSB7fTtcbiAgICAgIGtleXNBcnJheS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGl0ZW1LZXlzW2tleV0gPSBpdGVtW2tleV07XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBVdGlsLmlzRXF1aXZhbGVudChpdGVtS2V5cywgY3VycmVudEtleXMpO1xuICAgIH0pO1xuICAgIHJldHVybiBpbmRleCA+PSAwID8gaW5kZXggOiAwO1xuICB9XG5cbiAgbmV4dCgpIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMubmF2aWdhdGlvbkRhdGEubGVuZ3RoO1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5jdXJyZW50SW5kZXggKyAxO1xuICAgIGlmICh0b3RhbCA+IGluZGV4KSB7XG4gICAgICB0aGlzLm1vdmUoaW5kZXgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5xdWVyeUNvbmYpIHtcbiAgICAgIGNvbnN0IG9mZnNldDogbnVtYmVyID0gKHRoaXMucXVlcnlDb25mLnF1ZXJ5UmVjb3JkT2Zmc2V0IHx8IDApICsgdGhpcy5xdWVyeUNvbmYucXVlcnlSb3dzO1xuICAgICAgdGhpcy5xdWVyeU5hdmlnYXRpb25EYXRhKG9mZnNldCkudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMubW92ZSgwKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdmb3JtLXRvb2xiYXItPm5leHQoKTogdG90YWwgPiBpbmRleCcpO1xuICAgIH1cbiAgfVxuXG4gIHByZXZpb3VzKCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5jdXJyZW50SW5kZXggLSAxO1xuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICB0aGlzLm1vdmUoaW5kZXgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5xdWVyeUNvbmYpIHtcbiAgICAgIGNvbnN0IG9mZnNldDogbnVtYmVyID0gdGhpcy5xdWVyeUNvbmYucXVlcnlSZWNvcmRPZmZzZXQgLSB0aGlzLnF1ZXJ5Q29uZi5xdWVyeVJvd3M7XG4gICAgICB0aGlzLnF1ZXJ5TmF2aWdhdGlvbkRhdGEob2Zmc2V0KS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5tb3ZlKHRoaXMubmF2aWdhdGlvbkRhdGEubGVuZ3RoIC0gMSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcignZm9ybS10b29sYmFyLT5uZXh0KCk6IGluZGV4IDwgMCcpO1xuICAgIH1cbiAgfVxuXG4gIGZpcnN0KCkge1xuICAgIGlmICghdGhpcy5xdWVyeUNvbmYgfHwgdGhpcy5xdWVyeUNvbmYucXVlcnlSZWNvcmRPZmZzZXQgPT09IDApIHtcbiAgICAgIHRoaXMubW92ZSgwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5xdWVyeU5hdmlnYXRpb25EYXRhKDApLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLm1vdmUoMCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBsYXN0KCkge1xuICAgIGlmICghdGhpcy5xdWVyeUNvbmYgfHwgdGhpcy5pc0xhc3QoKSkge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLm5hdmlnYXRpb25EYXRhLmxlbmd0aCAtIDE7XG4gICAgICB0aGlzLm1vdmUoaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBvZmZzZXQgPSB0aGlzLnF1ZXJ5Q29uZi50b3RhbFJlY29yZHNOdW1iZXIgLSB0aGlzLnF1ZXJ5Q29uZi5xdWVyeVJvd3M7XG4gICAgICB0aGlzLnF1ZXJ5TmF2aWdhdGlvbkRhdGEob2Zmc2V0LCB0aGlzLnF1ZXJ5Q29uZi5xdWVyeVJvd3MpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLm1vdmUodGhpcy5uYXZpZ2F0aW9uRGF0YS5sZW5ndGggLSAxKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGlzRmlyc3QoKSB7XG4gICAgbGV0IHJlc3VsdDogYm9vbGVhbiA9IHRoaXMuY3VycmVudEluZGV4ID09PSAwO1xuICAgIGlmIChyZXN1bHQgJiYgdGhpcy5xdWVyeUNvbmYpIHtcbiAgICAgIHJlc3VsdCA9IHRoaXMucXVlcnlDb25mLnF1ZXJ5UmVjb3JkT2Zmc2V0ID09PSAwO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaXNMYXN0KCkge1xuICAgIGxldCByZXN1bHQ6IGJvb2xlYW4gPSB0aGlzLmN1cnJlbnRJbmRleCA9PT0gKHRoaXMubmF2aWdhdGlvbkRhdGEubGVuZ3RoIC0gMSk7XG4gICAgaWYgKHJlc3VsdCAmJiB0aGlzLnF1ZXJ5Q29uZikge1xuICAgICAgcmVzdWx0ID0gKHRoaXMucXVlcnlDb25mLnF1ZXJ5UmVjb3JkT2Zmc2V0ICsgdGhpcy5xdWVyeUNvbmYucXVlcnlSb3dzKVxuICAgICAgICA+PSB0aGlzLnF1ZXJ5Q29uZi50b3RhbFJlY29yZHNOdW1iZXI7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBtb3ZlKGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLl9mb3JtLnNob3dDb25maXJtRGlzY2FyZENoYW5nZXMoKS50aGVuKHJlcyA9PiB7XG4gICAgICBpZiAocmVzID09PSB0cnVlKSB7XG4gICAgICAgIHRoaXMuY3VycmVudEluZGV4ID0gaW5kZXg7XG4gICAgICAgIGlmICh0aGlzLmZvcm1MYXlvdXRNYW5hZ2VyICYmIHRoaXMuZm9ybUxheW91dE1hbmFnZXIuYWxsb3dOYXZpZ2F0aW9uKCkpIHtcbiAgICAgICAgICB0aGlzLm1vdmVJbkZvcm1MYXlvdXRNYW5hZ2VyKGluZGV4KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm1vdmVXaXRob3V0TWFuYWdlcihpbmRleCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbW92ZVdpdGhvdXRNYW5hZ2VyKGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCByb3V0ZSA9IHRoaXMuZ2V0Um91dGVPZlNlbGVjdGVkUm93KHRoaXMubmF2aWdhdGlvbkRhdGFbaW5kZXhdKTtcbiAgICBpZiAocm91dGUubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgbmF2RGF0YTogT05hdmlnYXRpb25JdGVtID0gdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXRMYXN0SXRlbSgpO1xuICAgICAgaWYgKG5hdkRhdGEpIHtcbiAgICAgICAgdGhpcy5fZm9ybS5jYW5EaXNjYXJkQ2hhbmdlcyA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgZXh0cmFzOiBOYXZpZ2F0aW9uRXh0cmFzID0ge307XG4gICAgICAgIGV4dHJhc1tDb2Rlcy5RVUVSWV9QQVJBTVNdID0gQ29kZXMuZ2V0SXNEZXRhaWxPYmplY3QoKTtcblxuICAgICAgICBjb25zdCB1cmxBcnJheSA9IG5hdkRhdGEudXJsLnNwbGl0KENvZGVzLlJPVVRFX1NFUEFSQVRPUik7XG4gICAgICAgIGNvbnN0IHVybCA9IHVybEFycmF5LnNwbGljZSgwLCB1cmxBcnJheS5sZW5ndGggLSByb3V0ZS5sZW5ndGgpLmpvaW4oQ29kZXMuUk9VVEVfU0VQQVJBVE9SKTtcbiAgICAgICAgcm91dGUudW5zaGlmdCh1cmwpO1xuXG4gICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKHJvdXRlLCBleHRyYXMpLnRoZW4oKG5hdmlnYXRpb25Eb25lOiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgaWYgKG5hdmlnYXRpb25Eb25lKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRJbmRleCA9IGluZGV4O1xuICAgICAgICAgICAgY29uc3QgdXJsID0gdGhpcy5yb3V0ZXIucm91dGVyU3RhdGUuc25hcHNob3QudXJsLnNwbGl0KCc/JylbMF07XG4gICAgICAgICAgICBpZiAodXJsICE9PSBuYXZEYXRhLnVybCkge1xuICAgICAgICAgICAgICB0aGlzLm5hdmlnYXRpb25TZXJ2aWNlLnJlbW92ZUxhc3RJdGVtKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1vdmVJbkZvcm1MYXlvdXRNYW5hZ2VyKGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLl9mb3JtLnNldFVybFBhcmFtc0FuZFJlbG9hZCh0aGlzLm5hdmlnYXRpb25EYXRhW2luZGV4XSk7XG4gIH1cblxuICBnZXRSb3V0ZU9mU2VsZWN0ZWRSb3coaXRlbTogYW55KSB7XG4gICAgY29uc3Qgcm91dGUgPSBbXTtcbiAgICBpZiAoVXRpbC5pc09iamVjdChpdGVtKSkge1xuICAgICAgdGhpcy5fZm9ybS5rZXlzQXJyYXkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBpZiAoVXRpbC5pc0RlZmluZWQoaXRlbVtrZXldKSkge1xuICAgICAgICAgIHJvdXRlLnB1c2goaXRlbVtrZXldKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByb3V0ZTtcbiAgfVxuXG4gIHNob3dOYXZpZ2F0aW9uKCkge1xuICAgIC8qXG4gICAgICBxdWVyeUNvbmYgaXMgb25seSBkZWZpbmVkIHdoZW4gdGhlIHNlcnZpY2UgaXMgcGFnZWFibGVcbiAgICAqL1xuICAgIHJldHVybiAoVXRpbC5pc0RlZmluZWQodGhpcy5xdWVyeUNvbmYpICYmIFV0aWwuaXNEZWZpbmVkKHRoaXMucXVlcnlDb25mLnRvdGFsUmVjb3Jkc051bWJlcikpID8gdGhpcy5xdWVyeUNvbmYudG90YWxSZWNvcmRzTnVtYmVyID4gMSA6IHRoaXMubmF2aWdhdGlvbkRhdGEubGVuZ3RoID4gMVxuICB9XG5cbiAgc2V0IGN1cnJlbnRJbmRleChhcmc6IG51bWJlcikge1xuICAgIHRoaXMuX2N1cnJlbnRJbmRleCA9IGFyZztcbiAgfVxuXG4gIGdldCBjdXJyZW50SW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudEluZGV4O1xuICB9XG5cbiAgZ2V0UmVjb3JkSW5kZXgoKTogbnVtYmVyIHtcbiAgICBsZXQgaW5kZXggPSB0aGlzLmN1cnJlbnRJbmRleCArIDE7XG4gICAgaWYgKHRoaXMucXVlcnlDb25mKSB7XG4gICAgICBpbmRleCArPSB0aGlzLnF1ZXJ5Q29uZi5xdWVyeVJlY29yZE9mZnNldDtcbiAgICB9XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgZ2V0VG90YWxSZWNvcmRzTnVtYmVyKCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMucXVlcnlDb25mICYmIHRoaXMucXVlcnlDb25mLnRvdGFsUmVjb3Jkc051bWJlcikge1xuICAgICAgcmV0dXJuIHRoaXMucXVlcnlDb25mLnRvdGFsUmVjb3Jkc051bWJlcjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubmF2aWdhdGlvbkRhdGEubGVuZ3RoO1xuICB9XG59XG4iLCI8bmctY29udGFpbmVyICpuZ0lmPVwic2hvd05hdmlnYXRpb24oKVwiPlxuICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjbGFzcz1cIm8tZm9ybS10b29sYmFyLWJ1dHRvblwiIFtkaXNhYmxlZF09XCJpc0ZpcnN0KClcIiAoY2xpY2spPVwiZmlyc3QoKVwiPlxuICAgIDxtYXQtaWNvbiBhcmlhLWxhYmVsPVwiRmlyc3RcIiBsYXlvdXQtcGFkZGluZyBzdmdJY29uPVwib250aW1pemU6Zmlyc3RfcGFnZVwiPjwvbWF0LWljb24+XG4gIDwvYnV0dG9uPlxuICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjbGFzcz1cIm8tZm9ybS10b29sYmFyLWJ1dHRvblwiIFtkaXNhYmxlZF09XCJpc0ZpcnN0KClcIiAoY2xpY2spPVwicHJldmlvdXMoKVwiPlxuICAgIDxtYXQtaWNvbiBhcmlhLWxhYmVsPVwiUHJldmlvdXNcIiBsYXlvdXQtcGFkZGluZyBzdmdJY29uPVwib250aW1pemU6a2V5Ym9hcmRfYXJyb3dfbGVmdFwiPjwvbWF0LWljb24+XG4gIDwvYnV0dG9uPlxuICA8c3BhbiBsYXlvdXQtcGFkZGluZz57eyBnZXRSZWNvcmRJbmRleCgpIH19IC8ge3sgZ2V0VG90YWxSZWNvcmRzTnVtYmVyKCkgfX08L3NwYW4+XG4gIDxidXR0b24gbWF0LWljb24tYnV0dG9uIGNsYXNzPVwiby1mb3JtLXRvb2xiYXItYnV0dG9uXCIgW2Rpc2FibGVkXT1cImlzTGFzdCgpXCIgKGNsaWNrKT1cIm5leHQoKVwiPlxuICAgIDxtYXQtaWNvbiBhcmlhLWxhYmVsPVwiTmV4dFwiIGxheW91dC1wYWRkaW5nIHN2Z0ljb249XCJvbnRpbWl6ZTprZXlib2FyZF9hcnJvd19yaWdodFwiPjwvbWF0LWljb24+XG4gIDwvYnV0dG9uPlxuICA8YnV0dG9uIG1hdC1pY29uLWJ1dHRvbiBjbGFzcz1cIm8tZm9ybS10b29sYmFyLWJ1dHRvblwiIFtkaXNhYmxlZF09XCJpc0xhc3QoKVwiIChjbGljayk9XCJsYXN0KClcIj5cbiAgICA8bWF0LWljb24gYXJpYS1sYWJlbD1cIkxhc3RcIiBsYXlvdXQtcGFkZGluZyBzdmdJY29uPVwib250aW1pemU6bGFzdF9wYWdlXCI+PC9tYXQtaWNvbj5cbiAgPC9idXR0b24+XG48L25nLWNvbnRhaW5lcj4iXX0=