@angular-generic-table/column-settings
Version:
angular-generic-table extension that makes it easy to toggle column visibility and reoder columns.
368 lines (367 loc) • 35 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, Input, ViewChild, TemplateRef, ElementRef, Pipe, ChangeDetectorRef, HostListener, Output, EventEmitter } from '@angular/core';
import { GenericTableComponent } from '@angular-generic-table/core';
import { DragulaService } from 'ng2-dragula';
var GtColumnPipe = /** @class */ (function () {
function GtColumnPipe() {
}
/**
* Sort by column order
* @param {?} a
* @param {?} b
* @return {?}
*/
GtColumnPipe.prototype.getColumnOrder = /**
* Sort by column order
* @param {?} a
* @param {?} b
* @return {?}
*/
function (a, b) {
if (a.columnOrder < b.columnOrder) {
return -1;
}
if (a.columnOrder > b.columnOrder || typeof a.columnOrder === 'undefined') {
return 1;
}
return 0;
};
/**
* return enabled columns that are not locked for editing
* @param {?} column
* @return {?}
*/
GtColumnPipe.prototype.getEnabled = /**
* return enabled columns that are not locked for editing
* @param {?} column
* @return {?}
*/
function (column) {
return column.enabled !== false && column.lockSettings !== true
? column
: null;
};
/**
* @param {?} settings
* @return {?}
*/
GtColumnPipe.prototype.transform = /**
* @param {?} settings
* @return {?}
*/
function (settings) {
return settings.filter(this.getEnabled).sort(this.getColumnOrder);
};
GtColumnPipe.decorators = [
{ type: Pipe, args: [{
name: 'gtColumn'
},] },
];
return GtColumnPipe;
}());
export { GtColumnPipe };
function GtColumnPipe_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
GtColumnPipe.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
GtColumnPipe.ctorParameters;
}
var GtColumnSettingsComponent = /** @class */ (function () {
function GtColumnSettingsComponent(dragulaService, changeDetectorRef) {
var _this = this;
this.dragulaService = dragulaService;
this.changeDetectorRef = changeDetectorRef;
this.gtHeaderClasses = 'px-3 pt-3 pb-2 table-bordered border-left-0 border-right-0 border-bottom-0 alert-info';
this.gtWrapperClasses = 'px-3 pb-3 table-bordered border-left-0 border-right-0 border-top-0 alert-info';
this.overlay = true;
this.gtDefaultTexts = {
title: 'Columns',
help: 'Double click to toggle visibility, drag and drop to reorder.'
};
this.gtTexts = this.gtDefaultTexts;
this.gtEvent = new EventEmitter();
this.active = false;
this.reordered = false;
/**
* Extend object function.
*/
this.extend = function (a, b) {
for (var /** @type {?} */ key in b) {
if (b.hasOwnProperty(key)) {
a[key] = b[key];
}
}
return a;
};
dragulaService.drop.subscribe(function (value) {
if (value[0] === _this.bagId) {
_this._onDrop(value.slice(1));
}
});
}
Object.defineProperty(GtColumnSettingsComponent.prototype, "genericTable", {
get: /**
* @return {?}
*/
function () {
return this._genericTable;
},
set: /**
* @param {?} value
* @return {?}
*/
function (value) {
this._genericTable = value;
},
enumerable: true,
configurable: true
});
/**
* Check offset height on window resize.
* @return {?}
*/
GtColumnSettingsComponent.prototype.onResize = /**
* Check offset height on window resize.
* @return {?}
*/
function () {
this.offset = this._getTableHeadHeight();
this.heightAdjust = this._getColumnSettingsHeaderHeight();
};
/**
* @return {?}
*/
GtColumnSettingsComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.bagId = this.generateId();
// setup texts
this.gtTexts = /** @type {?} */ (this.extend(this.gtDefaultTexts, this.gtTexts));
};
/**
* Toggle column settings visibility.
* @return {?}
*/
GtColumnSettingsComponent.prototype.toggleColumnSettings = /**
* Toggle column settings visibility.
* @return {?}
*/
function () {
var _this = this;
this.active = !this.active;
if (this.active) {
this.offset = this._getTableHeadHeight();
// check and adjust height offset
setTimeout(function () {
_this.heightAdjust = _this._getColumnSettingsHeaderHeight();
}, 0);
}
};
/**
* Toggle column visibility.
* @param {?} column - column object.
* @return {?}
*/
GtColumnSettingsComponent.prototype.toggleColumnVisibility = /**
* Toggle column visibility.
* @param {?} column - column object.
* @return {?}
*/
function (column) {
var _this = this;
// toggle column visibility
column.visible =
typeof column.visible === 'undefined' ? false : !column.visible;
// redraw table
this._genericTable.redraw();
// emit event
this.gtEvent.emit({
name: 'gt-column-visibility-change',
value: {
column: tslib_1.__assign({}, column),
settings: tslib_1.__spread(this._genericTable.gtSettings)
}
});
// check and reset offset
setTimeout(function () {
_this.offset = _this._getTableHeadHeight();
}, 0);
};
/**
* Order table by object key.
* @param {?} args - name of key to sort on.
* @return {?}
*/
GtColumnSettingsComponent.prototype._onDrop = /**
* Order table by object key.
* @param {?} args - name of key to sort on.
* @return {?}
*/
function (args) {
this.reordered = true;
var _a = tslib_1.__read(args, 2), e = _a[0], target = _a[1];
var /** @type {?} */ order = {};
for (var /** @type {?} */ i = 0; i < target.children.length; i++) {
order[target.children[i].getAttribute('data-object-key')] = i;
}
for (var /** @type {?} */ i = 0; i < this._genericTable.gtSettings.length; i++) {
this._genericTable.gtSettings[i].columnOrder =
order[this._genericTable.gtSettings[i].objectKey];
}
// reset array to trigger change detection
this._genericTable.gtSettings = tslib_1.__spread(this._genericTable.gtSettings);
this.changeDetectorRef.markForCheck();
this._genericTable.redraw();
this.gtEvent.emit({
name: 'gt-column-order-change',
value: {
settings: tslib_1.__spread(this._genericTable.gtSettings)
}
});
};
/**
* Get height of table head element ie. first row containing table headers.
* @return {?} offset height for table header in px.
*/
GtColumnSettingsComponent.prototype._getTableHeadHeight = /**
* Get height of table head element ie. first row containing table headers.
* @return {?} offset height for table header in px.
*/
function () {
try {
if (this.elementView.elementRef.nativeElement.nextElementSibling
.firstElementChild.firstElementChild.tagName === 'THEAD') {
return (this.elementView.elementRef.nativeElement.nextElementSibling
.firstElementChild.firstElementChild.offsetHeight + 'px');
}
if (this.elementView.elementRef.nativeElement.nextElementSibling
.firstElementChild.firstElementChild.firstElementChild.tagName ===
'THEAD') {
return (this.elementView.elementRef.nativeElement.nextElementSibling
.firstElementChild.firstElementChild.firstElementChild
.offsetHeight + 'px');
}
return '0px';
}
catch (/** @type {?} */ error) {
return '0px';
}
};
/**
* Get height of table head element ie. first row containing table headers.
* @return {?} offset height for table header in px.
*/
GtColumnSettingsComponent.prototype._getColumnSettingsHeaderHeight = /**
* Get height of table head element ie. first row containing table headers.
* @return {?} offset height for table header in px.
*/
function () {
try {
return this.gtColumnSettingsHeader.nativeElement.offsetHeight + 'px';
}
catch (/** @type {?} */ error) {
return '0px';
}
};
/**
* generate a unique id for dragula instance i.e. a unique bag name
* @return {?}
*/
GtColumnSettingsComponent.prototype.generateId = /**
* generate a unique id for dragula instance i.e. a unique bag name
* @return {?}
*/
function () {
var /** @type {?} */ d = new Date().getTime();
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var /** @type {?} */ r = ((d + Math.random() * 16) % 16) | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
});
};
GtColumnSettingsComponent.decorators = [
{ type: Component, args: [{
selector: 'gt-column-settings',
template: "\n <ng-template #columnItem let-column let-index=\"index\">\n <span class=\"badge badge-secondary\">{{index}}</span>\n <span (dblclick)=\"toggleColumnVisibility(column)\" class=\"badge\" [ngClass]=\"{'badge-success':column.visible !== false, 'badge-danger':column.visible === false}\">{{genericTable.gtFields | gtProperty:column.objectKey:'name'}}</span>\n </ng-template>\n <div class=\"gt-column-settings\">\n <div class=\"gt-column-settings-panel\" *ngIf=\"active\" [style.padding-top]=\"offset\" [style.height]=\"'calc(100% - '+offset+')'\">\n <div #gtColumnSettingsHeader class=\"gt-column-settings-header border-bottom-0\" [ngClass]=\"gtHeaderClasses\">\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"toggleColumnSettings()\">\n <span aria-hidden=\"true\">×</span>\n </button>\n <h6 class=\"gt-column-settings-title\" *ngIf=\"gtTexts.title\">{{gtTexts.title}}</h6>\n <small class=\"gt-column-settings-help form-text text-muted\" *ngIf=\"gtTexts.help\">{{gtTexts.help}}</small>\n </div>\n <div class=\"gt-column-settings-item-wrapper\" [ngClass]=\"gtWrapperClasses\" [dragula]='bagId' data-visible=\"true\" [style.max-height]=\"'calc(100% - '+heightAdjust+')'\">\n <div class=\"gt-column-settings-item pr-0 pr-sm-4\" *ngFor=\"let i = index;let column of genericTable.gtSettings | gtColumn\" [attr.data-object-key]=\"column.objectKey\">\n <ng-template [ngTemplateOutlet]=\"gtColumnItem ? gtColumnItem:columnItem\" [ngTemplateOutletContext]=\"{$implicit: column,index: this.reordered ? column.columnOrder+1:i+1, name: (genericTable.gtFields | gtProperty:column.objectKey:'name')}\"></ng-template>\n </div>\n </div>\n <div class=\"gt-overlay\" *ngIf=\"active && overlay\" (click)=\"toggleColumnSettings()\" [style.height]=\"'calc(100% - -'+offset+')'\"></div>\n </div>\n <ng-template #genericTableElement [ngIf]=\"genericTable\">\n <ng-content></ng-content>\n </ng-template>\n </div>\n "
},] },
];
/* tslint:enable */
/** @nocollapse */
GtColumnSettingsComponent.ctorParameters = function () { return [
{ type: DragulaService, },
{ type: ChangeDetectorRef, },
]; };
GtColumnSettingsComponent.propDecorators = {
"genericTable": [{ type: Input },],
"elementView": [{ type: ViewChild, args: ['genericTableElement',] },],
"gtColumnSettingsHeader": [{ type: ViewChild, args: ['gtColumnSettingsHeader',] },],
"gtHeaderClasses": [{ type: Input },],
"gtWrapperClasses": [{ type: Input },],
"overlay": [{ type: Input },],
"gtColumnItem": [{ type: Input },],
"gtTexts": [{ type: Input },],
"gtEvent": [{ type: Output },],
"onResize": [{ type: HostListener, args: ['window:resize', [],] },],
};
return GtColumnSettingsComponent;
}());
export { GtColumnSettingsComponent };
function GtColumnSettingsComponent_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
GtColumnSettingsComponent.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
GtColumnSettingsComponent.ctorParameters;
/** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
GtColumnSettingsComponent.propDecorators;
/** @type {?} */
GtColumnSettingsComponent.prototype.elementView;
/** @type {?} */
GtColumnSettingsComponent.prototype.gtColumnSettingsHeader;
/** @type {?} */
GtColumnSettingsComponent.prototype._genericTable;
/** @type {?} */
GtColumnSettingsComponent.prototype.gtHeaderClasses;
/** @type {?} */
GtColumnSettingsComponent.prototype.gtWrapperClasses;
/** @type {?} */
GtColumnSettingsComponent.prototype.overlay;
/** @type {?} */
GtColumnSettingsComponent.prototype.gtColumnItem;
/** @type {?} */
GtColumnSettingsComponent.prototype.gtDefaultTexts;
/** @type {?} */
GtColumnSettingsComponent.prototype.gtTexts;
/** @type {?} */
GtColumnSettingsComponent.prototype.gtEvent;
/** @type {?} */
GtColumnSettingsComponent.prototype.active;
/** @type {?} */
GtColumnSettingsComponent.prototype.offset;
/** @type {?} */
GtColumnSettingsComponent.prototype.heightAdjust;
/** @type {?} */
GtColumnSettingsComponent.prototype.reordered;
/** @type {?} */
GtColumnSettingsComponent.prototype.bagId;
/**
* Extend object function.
* @type {?}
*/
GtColumnSettingsComponent.prototype.extend;
/** @type {?} */
GtColumnSettingsComponent.prototype.dragulaService;
/** @type {?} */
GtColumnSettingsComponent.prototype.changeDetectorRef;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3QtY29sdW1uLXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29sdW1uLXNldHRpbmdzLyIsInNvdXJjZXMiOlsiY29tcG9uZW50cy9ndC1jb2x1bW4tc2V0dGluZ3MuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNOLFNBQVMsRUFDVCxLQUFLLEVBQ0wsU0FBUyxFQUNULFdBQVcsRUFDWCxVQUFVLEVBQ1YsSUFBSSxFQUdKLGlCQUFpQixFQUNqQixZQUFZLEVBQ1osTUFBTSxFQUNOLFlBQVksRUFDWixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ04scUJBQXFCLEVBR3JCLE1BQU0sNkJBQTZCLENBQUM7QUFDckMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQzs7Ozs7Ozs7OztJQVNwQyxxQ0FBYzs7Ozs7O2NBQUMsQ0FBTSxFQUFFLENBQU07UUFDcEMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDVjtRQUNELEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsQ0FBQyxXQUFXLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztZQUMzRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1NBQ1Q7UUFDRCxNQUFNLENBQUMsQ0FBQyxDQUFDOzs7Ozs7O0lBSUYsaUNBQVU7Ozs7O2NBQUMsTUFBdUI7UUFDekMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEtBQUssS0FBSyxJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssSUFBSTtZQUM5RCxDQUFDLENBQUMsTUFBTTtZQUNSLENBQUMsQ0FBQyxJQUFJLENBQUM7Ozs7OztJQUdULGdDQUFTOzs7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OzRCQUtMLEtBQUs7NEJBRUwsTUFBTTs2QkFXTixZQUFZLFNBQUMsZUFBZSxFQUFFLEVBQUU7O29DQXBIbEM7O1NBK0VhLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0SW5wdXQsXG5cdFZpZXdDaGlsZCxcblx0VGVtcGxhdGVSZWYsXG5cdEVsZW1lbnRSZWYsXG5cdFBpcGUsXG5cdFBpcGVUcmFuc2Zvcm0sXG5cdE9uSW5pdCxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdEhvc3RMaXN0ZW5lcixcblx0T3V0cHV0LFxuXHRFdmVudEVtaXR0ZXJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuXHRHZW5lcmljVGFibGVDb21wb25lbnQsXG5cdEd0Um93LFxuXHRHdENvbmZpZ1NldHRpbmdcbn0gZnJvbSAnQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlJztcbmltcG9ydCB7IERyYWd1bGFTZXJ2aWNlIH0gZnJvbSAnbmcyLWRyYWd1bGEnO1xuaW1wb3J0IHsgR3RDb2x1bW5TZXR0aW5nc1RleHRzIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb2x1bW4tc2V0dGluZ3MtdGV4dHMnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndENvbHVtbidcbn0pXG5leHBvcnQgY2xhc3MgR3RDb2x1bW5QaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdC8vIFRPRE86IG1vdmUgdG8gaGVscGVyIGZ1bmN0aW9uc1xuXHQvKiogU29ydCBieSBjb2x1bW4gb3JkZXIgKi9cblx0cHJpdmF0ZSBnZXRDb2x1bW5PcmRlcihhOiBhbnksIGI6IGFueSkge1xuXHRcdGlmIChhLmNvbHVtbk9yZGVyIDwgYi5jb2x1bW5PcmRlcikge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoYS5jb2x1bW5PcmRlciA+IGIuY29sdW1uT3JkZXIgfHwgdHlwZW9mIGEuY29sdW1uT3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHQvKiogcmV0dXJuIGVuYWJsZWQgY29sdW1ucyB0aGF0IGFyZSBub3QgbG9ja2VkIGZvciBlZGl0aW5nICovXG5cdHByaXZhdGUgZ2V0RW5hYmxlZChjb2x1bW46IEd0Q29uZmlnU2V0dGluZykge1xuXHRcdHJldHVybiBjb2x1bW4uZW5hYmxlZCAhPT0gZmFsc2UgJiYgY29sdW1uLmxvY2tTZXR0aW5ncyAhPT0gdHJ1ZVxuXHRcdFx0PyBjb2x1bW5cblx0XHRcdDogbnVsbDtcblx0fVxuXG5cdHRyYW5zZm9ybShzZXR0aW5nczogQXJyYXk8R3RDb25maWdTZXR0aW5nPik6IEFycmF5PEd0Q29uZmlnU2V0dGluZz4ge1xuXHRcdHJldHVybiBzZXR0aW5ncy5maWx0ZXIodGhpcy5nZXRFbmFibGVkKS5zb3J0KHRoaXMuZ2V0Q29sdW1uT3JkZXIpO1xuXHR9XG59XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2d0LWNvbHVtbi1zZXR0aW5ncycsXG5cdHRlbXBsYXRlOiBgXG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjY29sdW1uSXRlbSBsZXQtY29sdW1uIGxldC1pbmRleD1cImluZGV4XCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJhZGdlLXNlY29uZGFyeVwiPnt7aW5kZXh9fTwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuIChkYmxjbGljayk9XCJ0b2dnbGVDb2x1bW5WaXNpYmlsaXR5KGNvbHVtbilcIiBjbGFzcz1cImJhZGdlXCIgW25nQ2xhc3NdPVwieydiYWRnZS1zdWNjZXNzJzpjb2x1bW4udmlzaWJsZSAhPT0gZmFsc2UsICdiYWRnZS1kYW5nZXInOmNvbHVtbi52aXNpYmxlID09PSBmYWxzZX1cIj57e2dlbmVyaWNUYWJsZS5ndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZSd9fTwvc3Bhbj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5nc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5ncy1wYW5lbFwiICAqbmdJZj1cImFjdGl2ZVwiIFtzdHlsZS5wYWRkaW5nLXRvcF09XCJvZmZzZXRcIiBbc3R5bGUuaGVpZ2h0XT1cIidjYWxjKDEwMCUgLSAnK29mZnNldCsnKSdcIj5cbiAgICAgICAgICAgICAgICA8ZGl2ICNndENvbHVtblNldHRpbmdzSGVhZGVyIGNsYXNzPVwiZ3QtY29sdW1uLXNldHRpbmdzLWhlYWRlciBib3JkZXItYm90dG9tLTBcIiBbbmdDbGFzc109XCJndEhlYWRlckNsYXNzZXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJjbG9zZVwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiIChjbGljayk9XCJ0b2dnbGVDb2x1bW5TZXR0aW5ncygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj4mdGltZXM7PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPGg2IGNsYXNzPVwiZ3QtY29sdW1uLXNldHRpbmdzLXRpdGxlXCIgKm5nSWY9XCJndFRleHRzLnRpdGxlXCI+e3tndFRleHRzLnRpdGxlfX08L2g2PlxuICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJndC1jb2x1bW4tc2V0dGluZ3MtaGVscCBmb3JtLXRleHQgdGV4dC1tdXRlZFwiICpuZ0lmPVwiZ3RUZXh0cy5oZWxwXCI+e3tndFRleHRzLmhlbHB9fTwvc21hbGw+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImd0LWNvbHVtbi1zZXR0aW5ncy1pdGVtLXdyYXBwZXJcIiBbbmdDbGFzc109XCJndFdyYXBwZXJDbGFzc2VzXCIgW2RyYWd1bGFdPSdiYWdJZCcgIGRhdGEtdmlzaWJsZT1cInRydWVcIiBbc3R5bGUubWF4LWhlaWdodF09XCInY2FsYygxMDAlIC0gJytoZWlnaHRBZGp1c3QrJyknXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJndC1jb2x1bW4tc2V0dGluZ3MtaXRlbSBwci0wIHByLXNtLTRcIiAqbmdGb3I9XCJsZXQgaSA9IGluZGV4O2xldCBjb2x1bW4gb2YgZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3MgfCBndENvbHVtblwiIFthdHRyLmRhdGEtb2JqZWN0LWtleV09XCJjb2x1bW4ub2JqZWN0S2V5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiZ3RDb2x1bW5JdGVtID8gZ3RDb2x1bW5JdGVtOmNvbHVtbkl0ZW1cIiBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwieyRpbXBsaWNpdDogY29sdW1uLGluZGV4OiB0aGlzLnJlb3JkZXJlZCA/IGNvbHVtbi5jb2x1bW5PcmRlcisxOmkrMSwgbmFtZTogKGdlbmVyaWNUYWJsZS5ndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZScpfVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJndC1vdmVybGF5XCIgKm5nSWY9XCJhY3RpdmUgJiYgb3ZlcmxheVwiIChjbGljayk9XCJ0b2dnbGVDb2x1bW5TZXR0aW5ncygpXCIgW3N0eWxlLmhlaWdodF09XCInY2FsYygxMDAlIC0gLScrb2Zmc2V0KycpJ1wiPjwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI2dlbmVyaWNUYWJsZUVsZW1lbnQgW25nSWZdPVwiZ2VuZXJpY1RhYmxlXCI+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9kaXY+XG4gICAgYFxufSlcbmV4cG9ydCBjbGFzcyBHdENvbHVtblNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblx0Z2V0IGdlbmVyaWNUYWJsZSgpOiBHZW5lcmljVGFibGVDb21wb25lbnQ8YW55LCBhbnk+IHtcblx0XHRyZXR1cm4gdGhpcy5fZ2VuZXJpY1RhYmxlO1xuXHR9XG5cblx0QElucHV0KClcblx0c2V0IGdlbmVyaWNUYWJsZSh2YWx1ZTogR2VuZXJpY1RhYmxlQ29tcG9uZW50PGFueSwgYW55Pikge1xuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZSA9IHZhbHVlO1xuXHR9XG5cblx0QFZpZXdDaGlsZCgnZ2VuZXJpY1RhYmxlRWxlbWVudCcpIGVsZW1lbnRWaWV3OiBUZW1wbGF0ZVJlZjxFbGVtZW50UmVmPjtcblx0QFZpZXdDaGlsZCgnZ3RDb2x1bW5TZXR0aW5nc0hlYWRlcicpIGd0Q29sdW1uU2V0dGluZ3NIZWFkZXI6IEVsZW1lbnRSZWY7XG5cblx0cHJpdmF0ZSBfZ2VuZXJpY1RhYmxlOiBHZW5lcmljVGFibGVDb21wb25lbnQ8R3RSb3csIGFueT47XG5cdEBJbnB1dCgpXG5cdGd0SGVhZGVyQ2xhc3NlcyA9ICdweC0zIHB0LTMgcGItMiB0YWJsZS1ib3JkZXJlZCBib3JkZXItbGVmdC0wIGJvcmRlci1yaWdodC0wIGJvcmRlci1ib3R0b20tMCBhbGVydC1pbmZvJztcblx0QElucHV0KClcblx0Z3RXcmFwcGVyQ2xhc3NlcyA9ICdweC0zIHBiLTMgdGFibGUtYm9yZGVyZWQgYm9yZGVyLWxlZnQtMCBib3JkZXItcmlnaHQtMCBib3JkZXItdG9wLTAgYWxlcnQtaW5mbyc7XG5cdEBJbnB1dCgpIG92ZXJsYXkgPSB0cnVlO1xuXHRASW5wdXQoKSBndENvbHVtbkl0ZW06IFRlbXBsYXRlUmVmPEVsZW1lbnRSZWY+O1xuXHRwdWJsaWMgZ3REZWZhdWx0VGV4dHM6IEd0Q29sdW1uU2V0dGluZ3NUZXh0cyA9IHtcblx0XHR0aXRsZTogJ0NvbHVtbnMnLFxuXHRcdGhlbHA6ICdEb3VibGUgY2xpY2sgdG8gdG9nZ2xlIHZpc2liaWxpdHksIGRyYWcgYW5kIGRyb3AgdG8gcmVvcmRlci4nXG5cdH07XG5cdEBJbnB1dCgpIGd0VGV4dHM6IEd0Q29sdW1uU2V0dGluZ3NUZXh0cyA9IHRoaXMuZ3REZWZhdWx0VGV4dHM7XG5cblx0QE91dHB1dCgpIHB1YmxpYyBndEV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG5cdHB1YmxpYyBhY3RpdmUgPSBmYWxzZTtcblx0cHVibGljIG9mZnNldDogc3RyaW5nO1xuXHRwdWJsaWMgaGVpZ2h0QWRqdXN0OiBzdHJpbmc7XG5cdHB1YmxpYyByZW9yZGVyZWQgPSBmYWxzZTtcblx0cHVibGljIGJhZ0lkOiBzdHJpbmc7XG5cblx0LyoqXG5cdCAqIENoZWNrIG9mZnNldCBoZWlnaHQgb24gd2luZG93IHJlc2l6ZS5cblx0ICovXG5cdEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbXSlcblx0cHVibGljIG9uUmVzaXplKCkge1xuXHRcdHRoaXMub2Zmc2V0ID0gdGhpcy5fZ2V0VGFibGVIZWFkSGVpZ2h0KCk7XG5cdFx0dGhpcy5oZWlnaHRBZGp1c3QgPSB0aGlzLl9nZXRDb2x1bW5TZXR0aW5nc0hlYWRlckhlaWdodCgpO1xuXHR9XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBkcmFndWxhU2VydmljZTogRHJhZ3VsYVNlcnZpY2UsXG5cdFx0cHJpdmF0ZSBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWZcblx0KSB7XG5cdFx0ZHJhZ3VsYVNlcnZpY2UuZHJvcC5zdWJzY3JpYmUoKHZhbHVlOiBBcnJheTxhbnk+KSA9PiB7XG5cdFx0XHRpZiAodmFsdWVbMF0gPT09IHRoaXMuYmFnSWQpIHtcblx0XHRcdFx0dGhpcy5fb25Ecm9wKHZhbHVlLnNsaWNlKDEpKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdG5nT25Jbml0KCkge1xuXHRcdHRoaXMuYmFnSWQgPSB0aGlzLmdlbmVyYXRlSWQoKTtcblx0XHQvLyBzZXR1cCB0ZXh0c1xuXHRcdHRoaXMuZ3RUZXh0cyA9IDxHdENvbHVtblNldHRpbmdzVGV4dHM+dGhpcy5leHRlbmQoXG5cdFx0XHR0aGlzLmd0RGVmYXVsdFRleHRzLFxuXHRcdFx0dGhpcy5ndFRleHRzXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiAgRXh0ZW5kIG9iamVjdCBmdW5jdGlvbi5cblx0ICovXG5cdHByaXZhdGUgZXh0ZW5kID0gZnVuY3Rpb24oYTogT2JqZWN0LCBiOiBPYmplY3QpIHtcblx0XHRmb3IgKGNvbnN0IGtleSBpbiBiKSB7XG5cdFx0XHRpZiAoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHRcdGFba2V5XSA9IGJba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGE7XG5cdH07XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSBjb2x1bW4gc2V0dGluZ3MgdmlzaWJpbGl0eS5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGVDb2x1bW5TZXR0aW5ncygpIHtcblx0XHR0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcblxuXHRcdGlmICh0aGlzLmFjdGl2ZSkge1xuXHRcdFx0dGhpcy5vZmZzZXQgPSB0aGlzLl9nZXRUYWJsZUhlYWRIZWlnaHQoKTtcblxuXHRcdFx0Ly8gY2hlY2sgYW5kIGFkanVzdCBoZWlnaHQgb2Zmc2V0XG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0dGhpcy5oZWlnaHRBZGp1c3QgPSB0aGlzLl9nZXRDb2x1bW5TZXR0aW5nc0hlYWRlckhlaWdodCgpO1xuXHRcdFx0fSwgMCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSBjb2x1bW4gdmlzaWJpbGl0eS5cblx0ICogQHBhcmFtIGNvbHVtbiAtIGNvbHVtbiBvYmplY3QuXG5cdCAqL1xuXHRwdWJsaWMgdG9nZ2xlQ29sdW1uVmlzaWJpbGl0eShjb2x1bW46IGFueSkge1xuXHRcdC8vIHRvZ2dsZSBjb2x1bW4gdmlzaWJpbGl0eVxuXHRcdGNvbHVtbi52aXNpYmxlID1cblx0XHRcdHR5cGVvZiBjb2x1bW4udmlzaWJsZSA9PT0gJ3VuZGVmaW5lZCcgPyBmYWxzZSA6ICFjb2x1bW4udmlzaWJsZTtcblxuXHRcdC8vIHJlZHJhdyB0YWJsZVxuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5yZWRyYXcoKTtcblxuXHRcdC8vIGVtaXQgZXZlbnRcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3QtY29sdW1uLXZpc2liaWxpdHktY2hhbmdlJyxcblx0XHRcdHZhbHVlOiB7XG5cdFx0XHRcdGNvbHVtbjogeyAuLi5jb2x1bW4gfSxcblx0XHRcdFx0c2V0dGluZ3M6IFsuLi50aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5nc11cblx0XHRcdH1cblx0XHR9KTtcblxuXHRcdC8vIGNoZWNrIGFuZCByZXNldCBvZmZzZXRcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMub2Zmc2V0ID0gdGhpcy5fZ2V0VGFibGVIZWFkSGVpZ2h0KCk7XG5cdFx0fSwgMCk7XG5cdH1cblxuXHQvKipcblx0ICogT3JkZXIgdGFibGUgYnkgb2JqZWN0IGtleS5cblx0ICogQHBhcmFtIGFyZ3MgLSBuYW1lIG9mIGtleSB0byBzb3J0IG9uLlxuXHQgKi9cblx0cHJpdmF0ZSBfb25Ecm9wKGFyZ3M6IEFycmF5PGFueT4pIHtcblx0XHR0aGlzLnJlb3JkZXJlZCA9IHRydWU7XG5cdFx0Y29uc3QgW2UsIHRhcmdldF0gPSBhcmdzO1xuXHRcdGNvbnN0IG9yZGVyID0ge307XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcblx0XHRcdG9yZGVyW3RhcmdldC5jaGlsZHJlbltpXS5nZXRBdHRyaWJ1dGUoJ2RhdGEtb2JqZWN0LWtleScpXSA9IGk7XG5cdFx0fVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5ndFNldHRpbmdzW2ldLmNvbHVtbk9yZGVyID1cblx0XHRcdFx0b3JkZXJbdGhpcy5fZ2VuZXJpY1RhYmxlLmd0U2V0dGluZ3NbaV0ub2JqZWN0S2V5XTtcblx0XHR9XG5cblx0XHQvLyByZXNldCBhcnJheSB0byB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb25cblx0XHR0aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5ncyA9IFsuLi50aGlzLl9nZW5lcmljVGFibGUuZ3RTZXR0aW5nc107XG5cdFx0dGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblxuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZS5yZWRyYXcoKTtcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3QtY29sdW1uLW9yZGVyLWNoYW5nZScsXG5cdFx0XHR2YWx1ZToge1xuXHRcdFx0XHRzZXR0aW5nczogWy4uLnRoaXMuX2dlbmVyaWNUYWJsZS5ndFNldHRpbmdzXVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIEdldCBoZWlnaHQgb2YgdGFibGUgaGVhZCBlbGVtZW50IGllLiBmaXJzdCByb3cgY29udGFpbmluZyB0YWJsZSBoZWFkZXJzLlxuXHQgKiBAcmV0dXJucyBvZmZzZXQgaGVpZ2h0IGZvciB0YWJsZSBoZWFkZXIgaW4gcHguXG5cdCAqL1xuXHRwcml2YXRlIF9nZXRUYWJsZUhlYWRIZWlnaHQoKTogc3RyaW5nIHtcblx0XHR0cnkge1xuXHRcdFx0aWYgKFxuXHRcdFx0XHR0aGlzLmVsZW1lbnRWaWV3LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmdcblx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQudGFnTmFtZSA9PT0gJ1RIRUFEJ1xuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAoXG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50Vmlldy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nXG5cdFx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQub2Zmc2V0SGVpZ2h0ICsgJ3B4J1xuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKFxuXHRcdFx0XHR0aGlzLmVsZW1lbnRWaWV3LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5uZXh0RWxlbWVudFNpYmxpbmdcblx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQudGFnTmFtZSA9PT1cblx0XHRcdFx0J1RIRUFEJ1xuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAoXG5cdFx0XHRcdFx0dGhpcy5lbGVtZW50Vmlldy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nXG5cdFx0XHRcdFx0XHQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGQuZmlyc3RFbGVtZW50Q2hpbGRcblx0XHRcdFx0XHRcdC5vZmZzZXRIZWlnaHQgKyAncHgnXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gJzBweCc7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdHJldHVybiAnMHB4Jztcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogR2V0IGhlaWdodCBvZiB0YWJsZSBoZWFkIGVsZW1lbnQgaWUuIGZpcnN0IHJvdyBjb250YWluaW5nIHRhYmxlIGhlYWRlcnMuXG5cdCAqIEByZXR1cm5zIG9mZnNldCBoZWlnaHQgZm9yIHRhYmxlIGhlYWRlciBpbiBweC5cblx0ICovXG5cdHByaXZhdGUgX2dldENvbHVtblNldHRpbmdzSGVhZGVySGVpZ2h0KCk6IHN0cmluZyB7XG5cdFx0dHJ5IHtcblx0XHRcdHJldHVybiB0aGlzLmd0Q29sdW1uU2V0dGluZ3NIZWFkZXIubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQgKyAncHgnO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRyZXR1cm4gJzBweCc7XG5cdFx0fVxuXHR9XG5cblx0LyoqIGdlbmVyYXRlIGEgdW5pcXVlIGlkIGZvciBkcmFndWxhIGluc3RhbmNlIGkuZS4gYSB1bmlxdWUgYmFnIG5hbWUqL1xuXHQvKiB0c2xpbnQ6ZGlzYWJsZSAqL1xuXHRwcml2YXRlIGdlbmVyYXRlSWQoKSB7XG5cdFx0bGV0IGQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcblx0XHRyZXR1cm4gJ3h4eHh4eHh4LXh4eHgtNHh4eC15eHh4LXh4eHh4eHh4eHh4eCcucmVwbGFjZSgvW3h5XS9nLCBmdW5jdGlvbihjKSB7XG5cdFx0XHRjb25zdCByID0gKChkICsgTWF0aC5yYW5kb20oKSAqIDE2KSAlIDE2KSB8IDA7XG5cdFx0XHRkID0gTWF0aC5mbG9vcihkIC8gMTYpO1xuXHRcdFx0cmV0dXJuIChjID09PSAneCcgPyByIDogKHIgJiAweDMpIHwgMHg4KS50b1N0cmluZygxNik7XG5cdFx0fSk7XG5cdH1cblx0LyogdHNsaW50OmVuYWJsZSAqL1xufVxuIl19