UNPKG

nr-grid

Version:

NR-Grid is basic a datagrid helper that uses Bootstrap and NgbBootstrap and developed for Angular applications.

436 lines 59.4 kB
import { __decorate } from "tslib"; import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output, TemplateRef, ViewChild } from '@angular/core'; import * as _ from 'lodash'; import { Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { NgbDate, NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NRGridColumnType } from './model/column/nr-grid-column-type'; import { FilterType } from './model/filter/filter-type'; import format from 'date-fns/format'; var NRGridComponent = /** @class */ (function () { function NRGridComponent(modalService, cdr) { var _this = this; this.modalService = modalService; this.cdr = cdr; this.onPageChanged = new EventEmitter(); this.onEditClicked = new EventEmitter(); this.onDeleteClicked = new EventEmitter(); this.onFilterChanged = new EventEmitter(); this.onOrderChanged = new EventEmitter(); this.onRowClicked = new EventEmitter(); this.onRowValueChanged = new EventEmitter(); this.onCellLinkClicked = new EventEmitter(); this.onLimitChanged = new EventEmitter(); this.onCustomButtonClicked = new EventEmitter(); this.editingRows = {}; this.limitChangeOptions = { searchable: false, valueMember: 'id', displayMember: 'text', hideLabel: true }; this.pages = [ { id: 10, text: '10' }, { id: 25, text: '25' }, { id: 50, text: '50' }, { id: 100, text: '100' }, ]; this.ranges = {}; this.filterChanged = new Subject(); this.rowFilterChange = new EventEmitter(); this.dataLoaded = new EventEmitter(); this.order = {}; this.typeheads = []; this._rangeValue = ''; this.limit = 10; this.filterChanged.pipe(debounceTime(500)).subscribe(function (val) { if (_this.go.dataSource) { _this.go.dataSource.reload(); } else { _this.onFilterChanged.emit(_this.rowFilter); } }); } Object.defineProperty(NRGridComponent.prototype, "rowFilter", { get: function () { return this._rowFilter; }, set: function (value) { this.changePage(1); this._rowFilter = value; this.rowFilterChange.emit(this._rowFilter); }, enumerable: true, configurable: true }); NRGridComponent.prototype.changePage = function (page) { if (this.options) { this.options.page = page; } }; NRGridComponent.prototype.filteredColumns = function () { var f = _.filter(this.go.columns, function (x) { return !x.denied; }); return _.filter(f, function (x) { return !x.hide; }); }; NRGridComponent.prototype.dataLoad = function (go) { var _this = this; go.loading = true; if (go.dataSource.usePromise) { go.dataSource.loader(go.dataSource.parent, this.rowFilter) .then(function (r) { go.data = r.data; go.rowCount = r.rowCount; go.loading = false; _this.dataLoaded.emit(true); if (r.summary) { go.summary = r.summary; } }) .catch(function (e) { go.loading = false; console.log('qr-grid-data-load-error', e); }); } else { go.dataSource.loader(this.go.dataSource.parent, this.rowFilter).subscribe(function (r) { go.data = r.data; go.rowCount = r.rowCount; go.loading = false; _this.dataLoaded.emit(true); if (r.summary) { go.summary = r.summary; } }, function (err) { go.loading = false; console.log('qr-grid-data-load-error', err); }); } }; NRGridComponent.prototype.ngOnInit = function () { var _this = this; if (!this.rowFilter) { this.rowFilter = {}; } if (this.options && !this.options.limit) { this.options.limit = 10; } if (this.options && !this.options.loading) { this.options.loading = true; } if (this.options && this.options.pager === undefined) { this.options.pager = true; } this.go = this.options; if (!this.go.data) { this.go.data = []; } if (!this.go.page) { this.go.page = 1; } if (!this.go.limit) { this.go.limit = 10; } if (!this.go.rowCount) { this.go.rowCount = 0; } if (!this.go.bootstrapTableClass) { this.go.bootstrapTableClass = 'table-bordered'; } this.columns = this.filteredColumns(); this.loadDropdownData(); if (this.go.dataSource) { this.go.dataSource.reload = function () { _this.editingRows = {}; return _this.dataLoad(_this.go); }; if (!this.go.dataSource.manualLoading) { this.go.dataSource.reload(); } else { this.go.loading = false; } } }; NRGridComponent.prototype.loadDropdownData = function () { var my = this; _.each(this.go.columns, function (x) { if (x.dropdownDataService) { my.loadLookupData(x); } }); }; NRGridComponent.prototype.filterChange = function () { this.changePage(1); this.filterChanged.next(this.rowFilter); this.loadDropdownData(); }; NRGridComponent.prototype.pageChange = function (val) { if (this.go.dataSource) { this.go.page = val; this.go.dataSource.reload(); } this.onPageChanged.emit(val); }; NRGridComponent.prototype.editClicked = function (rowData) { this.onEditClicked.emit(_.clone(rowData)); }; NRGridComponent.prototype.checkEditButtonOption = function (rowData) { if (!this.go.actionButtonsOptions) { return true; } else if (!this.go.actionButtonsOptions.edit) { return false; } if (typeof this.go.actionButtonsOptions.edit == 'boolean') { return this.go.actionButtonsOptions.edit; } else { return this.go.actionButtonsOptions.edit(rowData); } }; NRGridComponent.prototype.checkDeleteButtonOption = function (rowData) { if (!this.go.actionButtonsOptions) { return true; } else if (!this.go.actionButtonsOptions.delete) { return false; } if (typeof this.go.actionButtonsOptions.delete == 'boolean') { return this.go.actionButtonsOptions.delete; } else { return this.go.actionButtonsOptions.delete(rowData); } }; NRGridComponent.prototype.deleteClicked = function (rowData) { this.activeDeleteModal = this.modalService.open(this.deleteModal, { centered: true }); this.deleteData = rowData; }; NRGridComponent.prototype.submitDelete = function () { this.onDeleteClicked.emit(this.deleteData); this.activeDeleteModal.close(); }; NRGridComponent.prototype.linkClicked = function (data) { this.onCellLinkClicked.emit(data); }; NRGridComponent.prototype.isDefaultCell = function (t) { return !t || (t == NRGridColumnType.default || t == NRGridColumnType.inlineEditor); }; NRGridComponent.prototype.isLinkCell = function (t) { return t === NRGridColumnType.link; }; NRGridComponent.prototype.toggleOrder = function (column) { var columnKey = column.orderKey ? column.orderKey : column.name; if (this.order.column === columnKey) { this.order.desc = !this.order.desc; } else { this.order.desc = false; } this.order.column = columnKey; this.onOrderChanged.emit(this.order); }; NRGridComponent.prototype.rowValueChanged = function (e) { this.onRowValueChanged.emit(e); }; NRGridComponent.prototype.rowClicked = function (rowData) { if (this.go.rowClickAction && this.go.rowClickAction.enable) { this.onRowClicked.emit(rowData); } }; NRGridComponent.prototype.isFilterDefault = function (val) { return val === FilterType.default; }; NRGridComponent.prototype.isFilterDateRange = function (val) { return val === FilterType.dateRange; }; NRGridComponent.prototype.isFilterYesNo = function (val) { return val == FilterType.yesNoRadio; }; NRGridComponent.prototype.isFilterTypehead = function (val) { return val == FilterType.typeHead; }; NRGridComponent.prototype.isFilterDropdown = function (c) { return c.filterType == FilterType.dropdown; }; NRGridComponent.prototype.isFilterNumericRange = function (val) { return val == FilterType.numericRange; }; NRGridComponent.prototype.selectTypeheadItem = function ($event, key) { this.rowFilter[key] = $event.item; this.filterChange(); }; NRGridComponent.prototype.onDateSelection = function (date, filterKey) { if (!this.fromDate && !this.toDate) { this.fromDate = date; } else if (this.fromDate && !this.toDate && date.after(this.fromDate)) { this.toDate = date; } else { this.toDate = null; this.fromDate = date; } if (this.fromDate && this.toDate) { var bs = this.fromDate; var be = this.toDate; var s = new Date(bs.year, bs.month - 1, bs.day); var e = new Date(be.year, be.month - 1, be.day); this._rangeValue = format(s, 'dd/MM/yyyy') + ' - ' + format(e, 'dd/MM/yyyy'); this.rangePicker.toggle(); this.rowFilter[filterKey] = s.toISOString() + ',' + e.toISOString(); this.filterChange(); } }; NRGridComponent.prototype.rangeValue = function () { return this._rangeValue; }; NRGridComponent.prototype.isHovered = function (date) { return this.fromDate && !this.toDate && this.hoveredDate && date.after(this.fromDate) && date.before(this.hoveredDate); }; NRGridComponent.prototype.isInside = function (date) { return date.after(this.fromDate) && date.before(this.toDate); }; NRGridComponent.prototype.isRange = function (date) { return date.equals(this.fromDate) || date.equals(this.toDate) || this.isInside(date) || this.isHovered(date); }; NRGridComponent.prototype.getFilterKey = function (c) { return c.filterKey ? c.filterKey : c.name; }; NRGridComponent.prototype.rangeChanged = function (c) { var key = this.getFilterKey(c); var startKey = key + '___start'; var endKey = key + '___end'; var start = this.ranges[startKey]; var end = this.ranges[endKey]; this.rowFilter[key] = (start ? start : '') + '___' + (end ? end : ''); this.filterChange(); }; NRGridComponent.prototype.limitChanged = function (limit) { this.limit = Number(limit.value ? limit.value : limit); if (this.options.dataSource) { this.options.dataSource.reload(); } this.onLimitChanged.emit(this.limit); }; NRGridComponent.prototype.loadLookupData = function (c) { if (!c.dropdownData) { c.dropdownDataService.subscribe(function (result) { c.dropdownData = _.map(result.data, function (x) { return { id: x.id, text: x.name }; }); }); } }; NRGridComponent.prototype.customButtonClick = function (button, row) { this.onCustomButtonClicked.emit({ button: button, data: row }); }; NRGridComponent.prototype.inlineEditorOn = function (cr, rowIndex, rowValue) { if (cr.type == NRGridColumnType.inlineEditor) { this.editingRows['row-' + rowIndex + '-col-' + cr.name] = { firstValue: rowValue[cr.name] }; this.cdr.detectChanges(); var e = document.getElementById('row-' + rowIndex + '-col-' + cr.name); if (e) { e.focus(); } } }; NRGridComponent.prototype.inlineEditorOff = function (cr, rowIndex, rowValue, toggleEvent, revert) { if (rowValue === void 0) { rowValue = undefined; } if (toggleEvent === void 0) { toggleEvent = false; } if (revert === void 0) { revert = false; } if (revert) { rowValue[cr.name] = this.editingRows['row-' + rowIndex + '-col-' + cr.name].firstValue; } this.editingRows['row-' + rowIndex + '-col-' + cr.name] = undefined; if (!revert && toggleEvent) { this.rowValueChanged({ column: cr, row: rowValue }); } }; NRGridComponent.ctorParameters = function () { return [ { type: NgbModal }, { type: ChangeDetectorRef } ]; }; __decorate([ Input() ], NRGridComponent.prototype, "options", void 0); __decorate([ Input() ], NRGridComponent.prototype, "loading", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onPageChanged", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onEditClicked", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onDeleteClicked", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onFilterChanged", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onOrderChanged", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onRowClicked", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onRowValueChanged", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onCellLinkClicked", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onLimitChanged", void 0); __decorate([ Output() ], NRGridComponent.prototype, "onCustomButtonClicked", void 0); __decorate([ ViewChild('deleteModal', { static: false }) ], NRGridComponent.prototype, "deleteModal", void 0); __decorate([ ViewChild('rangePicker', { static: false }) ], NRGridComponent.prototype, "rangePicker", void 0); __decorate([ Input() ], NRGridComponent.prototype, "columnHeaderTemplate", void 0); __decorate([ Input() ], NRGridComponent.prototype, "footerTemplate", void 0); __decorate([ Input() ], NRGridComponent.prototype, "rowFilter", null); __decorate([ Output() ], NRGridComponent.prototype, "rowFilterChange", void 0); __decorate([ Output() ], NRGridComponent.prototype, "dataLoaded", void 0); NRGridComponent = __decorate([ Component({ selector: 'nr-grid', template: "<div class=\"nr-grid\">\n <div class=\"table-responsive\">\n <table class=\"table {{options.bootstrapTableClass}} mb-0\">\n <thead>\n <tr>\n <th *ngFor=\"let c of columns\" class=\"nr-order-trigger\" (click)=\"toggleOrder(c)\"\n [ngClass]=\"{'text-right': c.alignment == 'right' }\"\n [ngStyle]=\"{'width': c.width != undefined ? c.width : 'auto' }\">\n\n <ng-container *ngTemplateOutlet=\"columnHeaderTemplate; context: {column: c}\">\n\n </ng-container>\n <ng-container *ngIf=\"!columnHeaderTemplate\">\n {{c.title}}\n </ng-container>\n <span class=\"nr-grid-orderer\"\n *ngIf=\"order.column === (c.orderKey != null ? c.orderKey : c.name)\">\n <i *ngIf=\"!order.desc\" class=\"fa fa-arrow-up\"></i>\n <i *ngIf=\"order.desc\" class=\"fa fa-arrow-down\"></i>\n </span>\n </th>\n <th *ngIf=\"go.actionButtons\"\n [ngStyle]=\"{'width': (90 + ((go.buttons ? go.buttons.length : 0) * 25)) + 'px' }\"></th>\n </tr>\n <tr class=\"filter-row\" *ngIf=\"go.filterRowEnabled\">\n <td *ngFor=\"let c of columns\">\n <ng-container *ngIf=\"!c.filterDisable\">\n <input *ngIf=\"!c.filterType || isFilterDefault(c.filterType)\" type=\"text\" placeholder=\"Filter\"\n class=\"filter-control\" [(ngModel)]=\"rowFilter[getFilterKey(c)]\"\n (ngModelChange)=\"filterChange()\">\n <input *ngIf=\"isFilterDateRange(c.filterType)\" type=\"text\" class=\"btn-light-disable\"\n ngbDatepicker\n #rangePicker=\"ngbDatepicker\"\n (dateSelect)=\"onDateSelection($event, getFilterKey(c))\"\n [dayTemplate]=\"dayTemplate\"\n [displayMonths]=\"2\" outsideDays=\"visible\" (focus)=\"rangePicker.toggle()\"\n [autoClose]=\"false\"\n placeholder=\"Filter\"\n [value]=\"rangeValue()\"\n class=\"filter-control\">\n <div *ngIf=\"isFilterNumericRange(c.filterType)\" class=\"range-selector\">\n <input type=\"text\" class=\"filter-control\" placeholder=\"Grather\"\n [(ngModel)]=\"ranges[getFilterKey(c) + '___start']\" (ngModelChange)=\"rangeChanged(c)\">\n <input type=\"text\" class=\"filter-control\" placeholder=\"Lower\"\n [(ngModel)]=\"ranges[getFilterKey(c) + '___end']\" (ngModelChange)=\"rangeChanged(c)\">\n </div>\n\n <nr-select *ngIf=\"isFilterDropdown(c)\" [(value)]=\"rowFilter[getFilterKey(c)]\" [options]=\"c.selectOptions\"\n label=\"Select\" (valueChange)=\"filterChange()\"></nr-select>\n <div *ngIf=\"isFilterYesNo(c.filterType)\" class=\"btn-group btn-group-toggle\" ngbRadioGroup\n name=\"radioBasic\"\n [(ngModel)]=\"rowFilter[getFilterKey(c)]\" (ngModelChange)=\"filterChange()\">\n <label ngbButtonLabel class=\"btn-primary btn-xs\">\n <input ngbButton type=\"radio\" [value]=\"true\"> Yes\n </label>\n <label ngbButtonLabel class=\"btn-primary btn-xs\">\n <input ngbButton type=\"radio\" [value]=\"false\"> No\n </label>\n </div>\n </ng-container>\n </td>\n <td *ngIf=\"go.actionButtons\"></td>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let r of go.data; let rowIndex=index;\"\n class=\"data-row\"\n [ngClass]=\"{'nr-row-clickable': go.rowClickAction && go.rowClickAction.enable}\"\n (click)=\"rowClicked(r)\">\n <td *ngFor=\"let cr of columns\"\n [ngClass]=\"{'text-right': cr.alignment == 'right', 'padding-none': editingRows['row-' + rowIndex + '-col-' + cr.name]}\">\n\n <div *ngIf=\"cr.formatter && !isLinkCell(cr.type)\">\n {{r[cr.name]|valueFormat: cr.formatter}}\n </div>\n\n <div class=\"default-view\"\n *ngIf=\"!cr.formatter && isDefaultCell(cr.type) && !editingRows['row-' + rowIndex + '-col-' + cr.name]\"\n [innerHTML]=\"cr.format ? cr.format({row: r, value: r[cr.name], parent: go.parent }) : r[cr.name]\"\n (click)=\"inlineEditorOn(cr, rowIndex, r)\"></div>\n\n <div *ngIf=\"isLinkCell(cr.type)\">\n <a href=\"javascript:void(0)\" (click)=\"linkClicked({row: r, column: cr})\"\n class=\"{{cr.link && cr.link.classes ? cr.link.classes : ''}}\"\n [ngbTooltip]=\"cr.link && cr.link.tooltip ? cr.link.tooltip : ''\">\n <i *ngIf=\"cr.link && cr.link.icon\" class=\"{{cr.link.icon}}\"></i>\n\n <span *ngIf=\"!cr.formatter\"\n [innerHTML]=\"cr.format ? cr.format({row: r, value: r[cr.name], parent: go.parent}) : r[cr.name]\"></span>\n <span *ngIf=\"cr.formatter\">{{r[cr.name]|valueFormat: cr.formatter}}</span>\n </a>\n </div>\n <div *ngIf=\"editingRows['row-' + rowIndex + '-col-' + cr.name]\">\n <div class=\"nr-inline-editor\">\n <input [id]=\"'row-' + rowIndex + '-col-' + cr.name\" type=\"text\" [(ngModel)]=\"r[cr.name]\"/>\n <div class=\"nr-inline-editor-buttons\">\n <button class=\"btn btn-sm btn-primary\" type=\"button\" (click)=\"inlineEditorOff(cr, rowIndex, r, true)\">\n Save\n </button>\n <button class=\"btn btn-sm btn-secondary\" type=\"button\"\n (click)=\"inlineEditorOff(cr, rowIndex, r, false, true)\">Cancel\n </button>\n </div>\n </div>\n </div>\n </td>\n <td class=\"action-buttons-container\" *ngIf=\"go.actionButtons\">\n <ng-container *ngFor=\"let b of go.buttons\">\n <a href=\"javascript:void(0);\" (click)=\"customButtonClick(b, r)\" ngbTooltip=\"{{b.tooltip}}\"\n *ngIf=\"!b.visible || (b.visible && b.visible(r))\">\n <i class=\"{{b.icon}}\"></i>\n </a>\n </ng-container>\n <a href=\"javascript:void(0);\" (click)=\"editClicked(r)\" ngbTooltip=\"Edit\"\n *ngIf=\"!go.actionButtonsOptions || checkEditButtonOption(r)\">\n <i class=\"fa fa-pencil\"></i>\n </a>\n <a href=\"javascript:void(0);\" (click)=\"deleteClicked(r)\" ngbTooltip=\"Delete\"\n *ngIf=\"!go.actionButtonsOptions || checkDeleteButtonOption(r)\">\n <i class=\"fa fa-trash\"></i>\n </a>\n </td>\n </tr>\n <tr *ngIf=\"go.data == undefined || go.data.length == 0\">\n <td [colSpan]=\"columns.length + (go.actionButtons ? 1 : 0)\">\n <div style=\"padding: 20px; text-align: center\">\n No data\n </div>\n </td>\n </tr>\n </tbody>\n <tfoot *ngIf=\"go.summary && !go.hideSummary\">\n <tr>\n <th *ngFor=\"let cr of columns\" [ngClass]=\"{'text-right': cr.alignment == 'right' }\">\n <ng-container *ngIf=\"!cr.hideFromSummary\">\n <div *ngIf=\"cr.formatter\">\n {{go.summary[cr.name]|valueFormat: cr.formatter}}\n </div>\n\n <div *ngIf=\"isDefaultCell(cr.type) && (!cr.formatter)\"\n [innerHTML]=\"cr.format ? cr.format({row: go.summary, value: go.summary[cr.name], parent: go.parent}) : go.summary[cr.name]\"></div>\n\n <div *ngIf=\"isLinkCell(cr.type) && (!cr.formatter)\">\n <a href=\"javascript:void(0)\" (click)=\"linkClicked({row: go.summary, column: cr})\"\n class=\"{{cr.link.classes ? cr.link.classes : ''}}\"\n [ngbTooltip]=\"cr.link && cr.link.tooltip ? cr.link.tooltip : ''\">\n <i *ngIf=\"cr.link.icon\" class=\"{{cr.link.icon}}\"></i>\n <span\n [innerHTML]=\"cr.format ? cr.format({row: go.summary, value: go.summary[cr.name], parent: go.parent}) : go.summary[cr.name]\"></span>\n </a>\n </div>\n </ng-container>\n </th>\n </tr>\n </tfoot>\n </table>\n\n </div>\n <ng-container *ngTemplateOutlet=\"footerTemplate;\">\n\n </ng-container>\n <div class=\"nr-grid-footer row\" *ngIf=\"go.pager\">\n <div class=\"col-md-12\">\n <ngb-pagination class=\"float-right\" [collectionSize]=\"go.rowCount\" [(page)]=\"go.page\" [maxSize]=\"10\"\n [pageSize]=\"go.limit\" (pageChange)=\"pageChange($event)\"></ngb-pagination>\n <div class=\"float-right limit-selector\" style=\"min-width: 150px; width: 150px\">\n <nr-select class=\"float-right\" [data]=\"pages\" [(value)]=\"go.limit\" label=\"Limit\" [options]=\"limitChangeOptions\"\n (valueChange)=\"limitChanged($event)\"></nr-select>\n </div>\n </div>\n </div>\n <div class=\"clearfix\"></div>\n</div>\n<ng-template #deleteModal let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-basic-title\">Delete</h4>\n <button type=\"button\" class=\"close\" aria-label=\"Close\" (click)=\"modal.dismiss('Cross click')\">\n <span aria-hidden=\"true\">&times;</span>\n </button>\n </div>\n <div class=\"modal-body\">\n Data will be deleted, are you sure?\n </div>\n <div class=\"modal-footer\">\n <button type=\"submit\" class=\"btn btn-success\" (click)=\"submitDelete()\">Delete</button>\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"modal.dismiss('Cross click')\">Cancel</button>\n </div>\n</ng-template>\n<ng-template #dayTemplate let-date let-focused=\"focused\">\n <span class=\"custom-day\"\n [class.focused]=\"focused\"\n [class.range]=\"isRange(date)\"\n [class.faded]=\"isHovered(date) || isInside(date)\"\n (mouseenter)=\"hoveredDate = date\"\n (mouseleave)=\"hoveredDate = null\">\n {{ date.day }}\n </span>\n</ng-template>\n" }) ], NRGridComponent); return NRGridComponent; }()); export { NRGridComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnItZ3JpZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uci1ncmlkLyIsInNvdXJjZXMiOlsibGliL25yLWdyaWQvbnItZ3JpZC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFHeEgsT0FBTyxLQUFLLENBQUMsTUFBTSxRQUFRLENBQUM7QUFFNUIsT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQztBQUM3RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUNwRSxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDdEQsT0FBTyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFPckM7SUFxRUUseUJBQW9CLFlBQXNCLEVBQVUsR0FBc0I7UUFBMUUsaUJBUUM7UUFSbUIsaUJBQVksR0FBWixZQUFZLENBQVU7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQS9EaEUsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ3BDLGtCQUFhLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUN4QyxvQkFBZSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDMUMsb0JBQWUsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUM3RCxtQkFBYyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFDekMsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ3ZDLHNCQUFpQixHQUFHLElBQUksWUFB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dmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgVGVtcGxhdGVSZWYsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge05SR3JpZEJ1dHRvbn0gZnJvbSAnLi9tb2RlbC9idXR0b24vbnItZ3JpZC1idXR0b24nO1xuaW1wb3J0IHtOUkdyaWRDb2x1bW59IGZyb20gJy4vbW9kZWwvY29sdW1uL25yLWdyaWQtY29sdW1uJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7TlJHcmlkT3B0aW9uc30gZnJvbSAnLi9tb2RlbC9vcHRpb25zL25yLWdyaWQtb3B0aW9ucyc7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWV9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7TmdiRGF0ZSwgTmdiTW9kYWx9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7TlJHcmlkQ29sdW1uVHlwZX0gZnJvbSAnLi9tb2RlbC9jb2x1bW4vbnItZ3JpZC1jb2x1bW4tdHlwZSc7XG5pbXBvcnQge0ZpbHRlclR5cGV9IGZyb20gJy4vbW9kZWwvZmlsdGVyL2ZpbHRlci10eXBlJztcbmltcG9ydCBmb3JtYXQgZnJvbSAnZGF0ZS1mbnMvZm9ybWF0JztcbmltcG9ydCB7TlJTZWxlY3RPcHRpb25zfSBmcm9tICduci1zZWxlY3QnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduci1ncmlkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL25yLWdyaWQuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIE5SR3JpZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cbiAgYWN0aXZlRGVsZXRlTW9kYWw7XG5cbiAgQElucHV0KCkgb3B0aW9uczogTlJHcmlkT3B0aW9ucztcbiAgQElucHV0KCkgbG9hZGluZzogYm9vbGVhbjtcbiAgQE91dHB1dCgpIG9uUGFnZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBvbkVkaXRDbGlja2VkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgb25EZWxldGVDbGlja2VkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgb25GaWx0ZXJDaGFuZ2VkOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgcHVibGljIG9uT3JkZXJDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgb25Sb3dDbGlja2VkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgb25Sb3dWYWx1ZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBvbkNlbGxMaW5rQ2xpY2tlZCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgcHVibGljIG9uTGltaXRDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgb25DdXN0b21CdXR0b25DbGlja2VkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgQFZpZXdDaGlsZCgnZGVsZXRlTW9kYWwnLCB7c3RhdGljOiBmYWxzZX0pIHByaXZhdGUgZGVsZXRlTW9kYWw7XG4gIEBWaWV3Q2hpbGQoJ3JhbmdlUGlja2VyJywge3N0YXRpYzogZmFsc2V9KSBwcml2YXRlIHJhbmdlUGlja2VyO1xuXG4gIEBJbnB1dCgpIGNvbHVtbkhlYWRlclRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuICBASW5wdXQoKSBmb290ZXJUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBjb2x1bW5zOiBOUkdyaWRDb2x1bW5bXTtcbiAgZWRpdGluZ1Jvd3M6IGFueSA9IHt9O1xuXG4gIGxpbWl0Q2hhbmdlT3B0aW9uczogTlJTZWxlY3RPcHRpb25zID0ge1xuICAgIHNlYXJjaGFibGU6IGZhbHNlLFxuICAgIHZhbHVlTWVtYmVyOiAnaWQnLFxuICAgIGRpc3BsYXlNZW1iZXI6ICd0ZXh0JyxcbiAgICBoaWRlTGFiZWw6IHRydWVcbiAgfTtcbiAgcGFnZXMgPVxuICAgIFtcbiAgICAgIHtpZDogMTAsIHRleHQ6ICcxMCd9LFxuICAgICAge2lkOiAyNSwgdGV4dDogJzI1J30sXG4gICAgICB7aWQ6IDUwLCB0ZXh0OiAnNTAnfSxcbiAgICAgIHtpZDogMTAwLCB0ZXh0OiAnMTAwJ30sXG4gICAgXTtcblxuICBnbzogTlJHcmlkT3B0aW9ucztcblxuICByYW5nZXM6IGFueSA9IHt9O1xuICBmaWx0ZXJDaGFuZ2VkOiBTdWJqZWN0PGFueT4gPSBuZXcgU3ViamVjdDxhbnk+KCk7XG5cbiAgX3Jvd0ZpbHRlcjogYW55O1xuXG4gIEBJbnB1dCgpIGdldCByb3dGaWx0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Jvd0ZpbHRlcjtcbiAgfVxuXG4gIHNldCByb3dGaWx0ZXIodmFsdWUpIHtcbiAgICB0aGlzLmNoYW5nZVBhZ2UoMSk7XG4gICAgdGhpcy5fcm93RmlsdGVyID0gdmFsdWU7XG4gICAgdGhpcy5yb3dGaWx0ZXJDaGFuZ2UuZW1pdCh0aGlzLl9yb3dGaWx0ZXIpO1xuICB9XG5cbiAgQE91dHB1dCgpIHJvd0ZpbHRlckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgZGF0YUxvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIGNoYW5nZVBhZ2UocGFnZSkge1xuICAgIGlmICh0aGlzLm9wdGlvbnMpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5wYWdlID0gcGFnZTtcbiAgICB9XG4gIH1cblxuICBvcmRlcjogYW55ID0ge307XG4gIGRlbGV0ZURhdGE6IGFueTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1vZGFsU2VydmljZTogTmdiTW9kYWwsIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuICAgIHRoaXMuZmlsdGVyQ2hhbmdlZC5waXBlKGRlYm91bmNlVGltZSg1MDApKS5zdWJzY3JpYmUodmFsID0+IHtcbiAgICAgIGlmICh0aGlzLmdvLmRhdGFTb3VyY2UpIHtcbiAgICAgICAgdGhpcy5nby5kYXRhU291cmNlLnJlbG9hZCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5vbkZpbHRlckNoYW5nZWQuZW1pdCh0aGlzLnJvd0ZpbHRlcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmaWx0ZXJlZENvbHVtbnMoKTogTlJHcmlkQ29sdW1uW10ge1xuICAgIGNvbnN0IGYgPSBfLmZpbHRlcih0aGlzLmdvLmNvbHVtbnMsICh4KSA9PiB7XG4gICAgICByZXR1cm4gIXguZGVuaWVkO1xuICAgIH0pO1xuICAgIHJldHVybiBfLmZpbHRlcihmLCAoeCkgPT4ge1xuICAgICAgcmV0dXJuICF4LmhpZGU7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRhdGFMb2FkKGdvOiBOUkdyaWRPcHRpb25zKSB7XG4gICAgZ28ubG9hZGluZyA9IHRydWU7XG4gICAgaWYgKGdvLmRhdGFTb3VyY2UudXNlUHJvbWlzZSkge1xuICAgICAgZ28uZGF0YVNvdXJjZS5sb2FkZXIoZ28uZGF0YVNvdXJjZS5wYXJlbnQsIHRoaXMucm93RmlsdGVyKVxuICAgICAgICAudGhlbihyID0+IHtcbiAgICAgICAgICBnby5kYXRhID0gci5kYXRhO1xuICAgICAgICAgIGdvLnJvd0NvdW50ID0gci5yb3dDb3VudDtcbiAgICAgICAgICBnby5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5kYXRhTG9hZGVkLmVtaXQodHJ1ZSk7XG4gICAgICAgICAgaWYgKHIuc3VtbWFyeSkge1xuICAgICAgICAgICAgZ28uc3VtbWFyeSA9IHIuc3VtbWFyeTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlID0+IHtcbiAgICAgICAgICBnby5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgY29uc29sZS5sb2coJ3FyLWdyaWQtZGF0YS1sb2FkLWVycm9yJywgZSk7XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBnby5kYXRhU291cmNlLmxvYWRlcih0aGlzLmdvLmRhdGFTb3VyY2UucGFyZW50LCB0aGlzLnJvd0ZpbHRlcikuc3Vic2NyaWJlKHIgPT4ge1xuICAgICAgICBnby5kYXRhID0gci5kYXRhO1xuICAgICAgICBnby5yb3dDb3VudCA9IHIucm93Q291bnQ7XG4gICAgICAgIGdvLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5kYXRhTG9hZGVkLmVtaXQodHJ1ZSk7XG4gICAgICAgIGlmIChyLnN1bW1hcnkpIHtcbiAgICAgICAgICBnby5zdW1tYXJ5ID0gci5zdW1tYXJ5O1xuICAgICAgICB9XG4gICAgICB9LCBlcnIgPT4ge1xuICAgICAgICBnby5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIGNvbnNvbGUubG9nKCdxci1ncmlkLWRhdGEtbG9hZC1lcnJvcicsIGVycik7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcblxuICAgIGlmICghdGhpcy5yb3dGaWx0ZXIpIHtcbiAgICAgIHRoaXMucm93RmlsdGVyID0ge307XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucyAmJiAhdGhpcy5vcHRpb25zLmxpbWl0KSB7XG4gICAgICB0aGlzLm9wdGlvbnMubGltaXQgPSAxMDtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zICYmICF0aGlzLm9wdGlvbnMubG9hZGluZykge1xuICAgICAgdGhpcy5vcHRpb25zLmxvYWRpbmcgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMgJiYgdGhpcy5vcHRpb25zLnBhZ2VyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMub3B0aW9ucy5wYWdlciA9IHRydWU7XG4gICAgfVxuXG4gICAgdGhpcy5nbyA9IHRoaXMub3B0aW9ucztcblxuICAgIGlmICghdGhpcy5nby5kYXRhKSB7XG4gICAgICB0aGlz