material-dynamic-table
Version:
Dynamic table component for angular built on top of angular material table. It offers sorting, pagination, filtering per column and the ability to specify content types and components used for displaying them.
195 lines • 30.5 kB
JavaScript
import { DataSource } from '@angular/cdk/collections';
import { _isNumberValue } from '@angular/cdk/coercion';
import { BehaviorSubject, Subject, of, merge, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
const MAX_SAFE_INTEGER = 9007199254740991;
export class MdtTableDataSource extends DataSource {
constructor(initialData = []) {
super();
/** Stream emitting render data to the table (depends on ordered data changes). */
this._renderData = new BehaviorSubject([]);
/** Stream that emits when a new filter string is set on the data source. */
this._filter = new BehaviorSubject('');
this._filters = new BehaviorSubject([]);
/** Used to react to internal changes of the paginator that are made by the data source itself. */
this._internalPageChanges = new Subject();
this._renderChangesSubscription = null;
this.sortingDataAccessor = (data, sortHeaderId) => {
const value = data[sortHeaderId];
if (_isNumberValue(value)) {
const numberValue = Number(value);
// Numbers beyond `MAX_SAFE_INTEGER` can't be compared reliably so we
// leave them as strings. For more info: https://goo.gl/y5vbSg
return numberValue < MAX_SAFE_INTEGER ? numberValue : value;
}
return value;
};
this.filterPredicate = (data, filter) => {
const dataStr = Object.keys(data)
.reduce((currentTerm, key) => {
return currentTerm + data[key] + '◬';
}, '')
.toLowerCase();
const transformedFilter = filter.trim().toLowerCase();
return dataStr.indexOf(transformedFilter) != -1;
};
this.sortData = (data, sort) => {
let sortedBy = sort.sortedBy;
if (!Array.isArray(sortedBy) || !sortedBy.length) {
return data;
}
return data.sort((a, b) => {
// Get effective sort value after comparing all sorted properties, if values were equal for
// previous propery then compare the next pair
return sortedBy.reduce((previous, sort) => {
if (previous !== 0) {
return previous;
}
let valueA = this.sortingDataAccessor(a, sort.id);
let valueB = this.sortingDataAccessor(b, sort.id);
return this.compareValues(valueA, valueB, sort.direction);
}, 0);
});
};
this._data = new BehaviorSubject(initialData);
this._updateChangeSubscription();
}
/** Array of data that should be rendered by the table, where each object represents one row. */
get data() {
return this._data.value;
}
set data(data) {
data = Array.isArray(data) ? data : [];
this._data.next(data);
if (!this._renderChangesSubscription) {
this._filterData(data);
}
}
get filter() {
return this._filter.value;
}
set filter(filter) {
this._filter.next(filter);
if (!this._renderChangesSubscription) {
this._filterData(this.data);
}
}
get filters() {
return this._filters.value;
}
set filters(filters) {
this._filters.next(filters);
this._updateChangeSubscription();
}
get sort() { return this._multiSort; }
set sort(sort) {
this._multiSort = sort;
this._updateChangeSubscription();
}
get paginator() {
return this._paginator;
}
set paginator(paginator) {
this._paginator = paginator;
this._updateChangeSubscription();
}
connect() {
if (!this._renderChangesSubscription) {
this._updateChangeSubscription();
}
return this._renderData;
}
disconnect() {
this._renderChangesSubscription?.unsubscribe();
this._renderChangesSubscription = null;
}
_updateChangeSubscription() {
const sortChange = this._multiSort
? merge(this._multiSort.multiSortChange, this._multiSort.initialized)
: of(null);
const pageChange = this._paginator
? merge(this._paginator.page, this._internalPageChanges, this._paginator.initialized)
: of(null);
const dataStream = this._data;
// Watch for base data or filter changes to provide a filtered set of data.
const filteredData = combineLatest([dataStream, this._filter]).pipe(map(([data]) => this._filterData(data)));
const filteredData2 = combineLatest([filteredData, this._filters]).pipe(map(([data]) => this._filterData(data)));
// Watch for filtered data or sort changes to provide an ordered set of data.
const orderedData = combineLatest([filteredData2, sortChange]).pipe(map(([data]) => this._orderData(data)));
// Watch for ordered data or page changes to provide a paged set of data.
const paginatedData = combineLatest([orderedData, pageChange]).pipe(map(([data]) => this._pageData(data)));
// Watched for paged data changes and send the result to the table to render.
this._renderChangesSubscription?.unsubscribe();
this._renderChangesSubscription = paginatedData.subscribe(data => this._renderData.next(data));
}
_filterData(data) {
// If there is a filter string, filter out data that does not contain it.
// Each data object is converted to a string using the function defined by filterPredicate.
// May be overridden for customization.
this.filteredData =
(this.filter == null || this.filter === '') && !this.filters?.length
? data
: data.filter(obj => this.filterPredicate(obj, this.filter));
if (this.paginator) {
this._updatePaginator(this.filteredData.length);
}
return this.filteredData;
}
_pageData(data) {
if (!this.paginator) {
return data;
}
const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
return data.slice(startIndex, startIndex + this.paginator.pageSize);
}
_orderData(data) {
// If there is no active sort or direction, return the data without trying to sort.
if (!this.sort) {
return data;
}
return this.sortData(data.slice(), this.sort);
}
compareValues(valueA, valueB, direction) {
let comparatorResult = 0;
if (direction == '') {
return comparatorResult;
}
if (valueA != null && valueB != null) {
// Check if one value is greater than the other; if equal, comparatorResult should remain 0.
if (valueA > valueB) {
comparatorResult = 1;
}
else if (valueA < valueB) {
comparatorResult = -1;
}
}
else if (valueA != null) {
comparatorResult = 1;
}
else if (valueB != null) {
comparatorResult = -1;
}
return comparatorResult * (direction == 'asc' ? 1 : -1);
}
_updatePaginator(filteredDataLength) {
Promise.resolve().then(() => {
const paginator = this.paginator;
if (!paginator) {
return;
}
paginator.length = filteredDataLength;
// If the page index is set beyond the page, reduce it to the last page.
if (paginator.pageIndex > 0) {
const lastPageIndex = Math.ceil(paginator.length / paginator.pageSize) - 1 || 0;
const newPageIndex = Math.min(paginator.pageIndex, lastPageIndex);
if (newPageIndex !== paginator.pageIndex) {
paginator.pageIndex = newPageIndex;
// Since the paginator only emits after user-generated changes,
// we need our own stream so we know to should re-render the data.
this._internalPageChanges.next();
}
}
});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktc29ydC1kYXRhLXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL21hdGVyaWFsLWR5bmFtaWMtdGFibGUvc3JjL2xpYi9tdWx0aS1zb3J0L211bHRpLXNvcnQtZGF0YS1zb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUd2RCxPQUFPLEVBQWMsZUFBZSxFQUFFLE9BQU8sRUFBZ0IsRUFBRSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDcEcsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBS3JDLE1BQU0sZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7QUFFMUMsTUFBTSxPQUFPLGtCQUFzQixTQUFRLFVBQWE7SUFtQnRELFlBQVksY0FBbUIsRUFBRTtRQUMvQixLQUFLLEVBQUUsQ0FBQztRQWhCVixrRkFBa0Y7UUFDakUsZ0JBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBTSxFQUFFLENBQUMsQ0FBQztRQUU1RCw0RUFBNEU7UUFDM0QsWUFBTyxHQUFHLElBQUksZUFBZSxDQUFTLEVBQUUsQ0FBQyxDQUFDO1FBRTFDLGFBQVEsR0FBRyxJQUFJLGVBQWUsQ0FBZ0IsRUFBRSxDQUFDLENBQUM7UUFFbkUsa0dBQWtHO1FBQ2pGLHlCQUFvQixHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFFNUQsK0JBQTBCLEdBQXdCLElBQUksQ0FBQztRQTBEdkQsd0JBQW1CLEdBQXVELENBQ3hFLElBQU8sRUFDUCxZQUFvQixFQUNILEVBQUU7WUFDbkIsTUFBTSxLQUFLLEdBQUksSUFBdUMsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUVyRSxJQUFJLGNBQWMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFD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LENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGF0YVNvdXJjZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2xsZWN0aW9ucyc7XHJcbmltcG9ydCB7IF9pc051bWJlclZhbHVlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvZXJjaW9uJztcclxuaW1wb3J0IHsgU29ydCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NvcnQnO1xyXG5pbXBvcnQgeyBNYXRQYWdpbmF0b3IsIFBhZ2VFdmVudCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3BhZ2luYXRvcic7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIEJlaGF2aW9yU3ViamVjdCwgU3ViamVjdCwgU3Vic2NyaXB0aW9uLCBvZiwgbWVyZ2UsIGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuaW1wb3J0IHsgTWR0TXVsdGlTb3J0IH0gZnJvbSAnLi9tdWx0aS1zb3J0LmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IFRhYmxlRmlsdGVyIH0gZnJvbSAnLi90YWJsZS1maWx0ZXInO1xyXG5cclxuY29uc3QgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7XHJcblxyXG5leHBvcnQgY2xhc3MgTWR0VGFibGVEYXRhU291cmNlPFQ+IGV4dGVuZHMgRGF0YVNvdXJjZTxUPiB7XHJcbiAgXHJcbiAgcHJpdmF0ZSByZWFkb25seSBfZGF0YTogQmVoYXZpb3JTdWJqZWN0PFRbXT47XHJcblxyXG4gIC8qKiBTdHJlYW0gZW1pdHRpbmcgcmVuZGVyIGRhdGEgdG8gdGhlIHRhYmxlIChkZXBlbmRzIG9uIG9yZGVyZWQgZGF0YSBjaGFuZ2VzKS4gKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IF9yZW5kZXJEYXRhID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUW10+KFtdKTtcclxuXHJcbiAgLyoqIFN0cmVhbSB0aGF0IGVtaXRzIHdoZW4gYSBuZXcgZmlsdGVyIHN0cmluZyBpcyBzZXQgb24gdGhlIGRhdGEgc291cmNlLiAqL1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZpbHRlciA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignJyk7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZpbHRlcnMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRhYmxlRmlsdGVyW10+KFtdKTtcclxuXHJcbiAgLyoqIFVzZWQgdG8gcmVhY3QgdG8gaW50ZXJuYWwgY2hhbmdlcyBvZiB0aGUgcGFnaW5hdG9yIHRoYXQgYXJlIG1hZGUgYnkgdGhlIGRhdGEgc291cmNlIGl0c2VsZi4gKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IF9pbnRlcm5hbFBhZ2VDaGFuZ2VzID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuXHJcbiAgX3JlbmRlckNoYW5nZXNTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xyXG5cclxuICBmaWx0ZXJlZERhdGE6IFRbXTtcclxuXHJcbiAgY29uc3RydWN0b3IoaW5pdGlhbERhdGE6IFRbXSA9IFtdKSB7XHJcbiAgICBzdXBlcigpO1xyXG4gICAgdGhpcy5fZGF0YSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8VFtdPihpbml0aWFsRGF0YSk7XHJcbiAgICB0aGlzLl91cGRhdGVDaGFuZ2VTdWJzY3JpcHRpb24oKTtcclxuICB9XHJcblxyXG4gIC8qKiBBcnJheSBvZiBkYXRhIHRoYXQgc2hvdWxkIGJlIHJlbmRlcmVkIGJ5IHRoZSB0YWJsZSwgd2hlcmUgZWFjaCBvYmplY3QgcmVwcmVzZW50cyBvbmUgcm93LiAqL1xyXG4gIGdldCBkYXRhKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2RhdGEudmFsdWU7XHJcbiAgfVxyXG5cclxuICBzZXQgZGF0YShkYXRhOiBUW10pIHtcclxuICAgIGRhdGEgPSBBcnJheS5pc0FycmF5KGRhdGEpID8gZGF0YSA6IFtdO1xyXG4gICAgdGhpcy5fZGF0YS5uZXh0KGRhdGEpO1xyXG4gICAgaWYgKCF0aGlzLl9yZW5kZXJDaGFuZ2VzU3Vic2NyaXB0aW9uKSB7XHJcbiAgICAgIHRoaXMuX2ZpbHRlckRhdGEoZGF0YSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgZmlsdGVyKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5fZmlsdGVyLnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgc2V0IGZpbHRlcihmaWx0ZXI6IHN0cmluZykge1xyXG4gICAgdGhpcy5fZmlsdGVyLm5leHQoZmlsdGVyKTtcclxuICAgIGlmICghdGhpcy5fcmVuZGVyQ2hhbmdlc1N1YnNjcmlwdGlvbikge1xyXG4gICAgICB0aGlzLl9maWx0ZXJEYXRhKHRoaXMuZGF0YSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgZmlsdGVycygpOiBUYWJsZUZpbHRlcltdIHtcclxuICAgIHJldHVybiB0aGlzLl9maWx0ZXJzLnZhbHVlO1xyXG4gIH1cclxuICBzZXQgZmlsdGVycyhmaWx0ZXJzOiBUYWJsZUZpbHRlcltdKSB7XHJcbiAgICB0aGlzLl9maWx0ZXJzLm5leHQoZmlsdGVycyk7XHJcbiAgICB0aGlzLl91cGRhdGVDaGFuZ2VTdWJzY3JpcHRpb24oKTtcclxuICB9XHJcblxyXG4gIGdldCBzb3J0KCk6IE1kdE11bHRpU29ydCB8IG51bGwgeyByZXR1cm4gdGhpcy5fbXVsdGlTb3J0OyB9XHJcbiAgc2V0IHNvcnQoc29ydDogTWR0TXVsdGlTb3J0IHwgbnVsbCkge1xyXG4gICAgdGhpcy5fbXVsdGlTb3J0ID0gc29ydDtcclxuICAgIHRoaXMuX3VwZGF0ZUNoYW5nZVN1YnNjcmlwdGlvbigpO1xyXG4gIH1cclxuICBwcml2YXRlIF9tdWx0aVNvcnQ6IE1kdE11bHRpU29ydCB8IG51bGw7XHJcbiBcclxuICBnZXQgcGFnaW5hdG9yKCk6IE1hdFBhZ2luYXRvciB8IG51bGwge1xyXG4gICAgcmV0dXJuIHRoaXMuX3BhZ2luYXRvcjtcclxuICB9XHJcbiAgc2V0IHBhZ2luYXRvcihwYWdpbmF0b3I6IE1hdFBhZ2luYXRvciB8IG51bGwpIHtcclxuICAgIHRoaXMuX3BhZ2luYXRvciA9IHBhZ2luYXRvcjtcclxuICAgIHRoaXMuX3VwZGF0ZUNoYW5nZVN1YnNjcmlwdGlvbigpO1xyXG4gIH1cclxuICBwcml2YXRlIF9wYWdpbmF0b3I6IE1hdFBhZ2luYXRvciB8IG51bGw7XHJcblxyXG4gIHNvcnRpbmdEYXRhQWNjZXNzb3I6IChkYXRhOiBULCBzb3J0SGVhZGVySWQ6IHN0cmluZykgPT4gc3RyaW5nIHwgbnVtYmVyID0gKFxyXG4gICAgZGF0YTogVCxcclxuICAgIHNvcnRIZWFkZXJJZDogc3RyaW5nLFxyXG4gICk6IHN0cmluZyB8IG51bWJlciA9PiB7XHJcbiAgICBjb25zdCB2YWx1ZSA9IChkYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgYW55Pilbc29ydEhlYWRlcklkXTtcclxuXHJcbiAgICBpZiAoX2lzTnVtYmVyVmFsdWUodmFsdWUpKSB7XHJcbiAgICAgIGNvbnN0IG51bWJlclZhbHVlID0gTnVtYmVyKHZhbHVlKTtcclxuXHJcbiAgICAgIC8vIE51bWJlcnMgYmV5b25kIGBNQVhfU0FGRV9JTlRFR0VSYCBjYW4ndCBiZSBjb21wYXJlZCByZWxpYWJseSBzbyB3ZVxyXG4gICAgICAvLyBsZWF2ZSB0aGVtIGFzIHN0cmluZ3MuIEZvciBtb3JlIGluZm86IGh0dHBzOi8vZ29vLmdsL3k1dmJTZ1xyXG4gICAgICByZXR1cm4gbnVtYmVyVmFsdWUgPCBNQVhfU0FGRV9JTlRFR0VSID8gbnVtYmVyVmFsdWUgOiB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbiAgfTtcclxuXHJcbiAgY29ubmVjdCgpIHtcclxuICAgIGlmICghdGhpcy5fcmVuZGVyQ2hhbmdlc1N1YnNjcmlwdGlvbikge1xyXG4gICAgICB0aGlzLl91cGRhdGVDaGFuZ2VTdWJzY3JpcHRpb24oKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5fcmVuZGVyRGF0YTtcclxuICB9XHJcblxyXG4gIGRpc2Nvbm5lY3QoKSB7XHJcbiAgICB0aGlzLl9yZW5kZXJDaGFuZ2VzU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xyXG4gICAgdGhpcy5fcmVuZGVyQ2hhbmdlc1N1YnNjcmlwdGlvbiA9IG51bGw7XHJcbiAgfVxyXG5cclxuICBfdXBkYXRlQ2hhbmdlU3Vic2NyaXB0aW9uKCkge1xyXG4gICAgY29uc3Qgc29ydENoYW5nZTogT2JzZXJ2YWJsZTxTb3J0IHwgbnVsbCB8IHZvaWQ+ID0gdGhpcy5fbXVsdGlTb3J0XHJcbiAgICAgID8gKG1lcmdlKHRoaXMuX211bHRpU29ydC5tdWx0aVNvcnRDaGFuZ2UsIHRoaXMuX211bHRpU29ydC5pbml0aWFsaXplZCkgYXMgT2JzZXJ2YWJsZTxTb3J0IHwgdm9pZD4pXHJcbiAgICAgIDogb2YobnVsbCk7XHJcbiAgICBjb25zdCBwYWdlQ2hhbmdlOiBPYnNlcnZhYmxlPFBhZ2VFdmVudCB8IG51bGwgfCB2b2lkPiA9IHRoaXMuX3BhZ2luYXRvclxyXG4gICAgICA/IChtZXJnZShcclxuICAgICAgICB0aGlzLl9wYWdpbmF0b3IucGFnZSxcclxuICAgICAgICB0aGlzLl9pbnRlcm5hbFBhZ2VDaGFuZ2VzLFxyXG4gICAgICAgIHRoaXMuX3BhZ2luYXRvci5pbml0aWFsaXplZCxcclxuICAgICAgKSBhcyBPYnNlcnZhYmxlPFBhZ2VFdmVudCB8IHZvaWQ+KVxyXG4gICAgICA6IG9mKG51bGwpO1xyXG4gICAgY29uc3QgZGF0YVN0cmVhbSA9IHRoaXMuX2RhdGE7XHJcbiAgICAvLyBXYXRjaCBmb3IgYmFzZSBkYXRhIG9yIGZpbHRlciBjaGFuZ2VzIHRvIHByb3ZpZGUgYSBmaWx0ZXJlZCBzZXQgb2YgZGF0YS5cclxuICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IGNvbWJpbmVMYXRlc3QoW2RhdGFTdHJlYW0sIHRoaXMuX2ZpbHRlcl0pLnBpcGUoXHJcbiAgICAgIG1hcCgoW2RhdGFdKSA9PiB0aGlzLl9maWx0ZXJEYXRhKGRhdGEpKSxcclxuICAgICk7XHJcbiAgICBjb25zdCBmaWx0ZXJlZERhdGEyID0gY29tYmluZUxhdGVzdChbZmlsdGVyZWREYXRhLCB0aGlzLl9maWx0ZXJzXSkucGlwZShcclxuICAgICAgbWFwKChbZGF0YV0pID0+IHRoaXMuX2ZpbHRlckRhdGEoZGF0YSkpLFxyXG4gICAgKTtcclxuICAgIC8vIFdhdGNoIGZvciBmaWx0ZXJlZCBkYXRhIG9yIHNvcnQgY2hhbmdlcyB0byBwcm92aWRlIGFuIG9yZGVyZWQgc2V0IG9mIGRhdGEuXHJcbiAgICBjb25zdCBvcmRlcmVkRGF0YSA9IGNvbWJpbmVMYXRlc3QoW2ZpbHRlcmVkRGF0YTIsIHNvcnRDaGFuZ2VdKS5waXBlKFxyXG4gICAgICBtYXAoKFtkYXRhXSkgPT4gdGhpcy5fb3JkZXJEYXRhKGRhdGEpKSxcclxuICAgICk7XHJcbiAgICAvLyBXYXRjaCBmb3Igb3JkZXJlZCBkYXRhIG9yIHBhZ2UgY2hhbmdlcyB0byBwcm92aWRlIGEgcGFnZWQgc2V0IG9mIGRhdGEuXHJcbiAgICBjb25zdCBwYWdpbmF0ZWREYXRhID0gY29tYmluZUxhdGVzdChbb3JkZXJlZERhdGEsIHBhZ2VDaGFuZ2VdKS5waXBlKFxyXG4gICAgICBtYXAoKFtkYXRhXSkgPT4gdGhpcy5fcGFnZURhdGEoZGF0YSkpLFxyXG4gICAgKTtcclxuICAgIC8vIFdhdGNoZWQgZm9yIHBhZ2VkIGRhdGEgY2hhbmdlcyBhbmQgc2VuZCB0aGUgcmVzdWx0IHRvIHRoZSB0YWJsZSB0byByZW5kZXIuXHJcbiAgICB0aGlzLl9yZW5kZXJDaGFuZ2VzU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xyXG4gICAgdGhpcy5fcmVuZGVyQ2hhbmdlc1N1YnNjcmlwdGlvbiA9IHBhZ2luYXRlZERhdGEuc3Vic2NyaWJlKGRhdGEgPT4gdGhpcy5fcmVuZGVyRGF0YS5uZXh0KGRhdGEpKTtcclxuICB9XHJcblxyXG4gIF9maWx0ZXJEYXRhKGRhdGE6IFRbXSkge1xyXG4gICAgLy8gSWYgdGhlcmUgaXMgYSBmaWx0ZXIgc3RyaW5nLCBmaWx0ZXIgb3V0IGRhdGEgdGhhdCBkb2VzIG5vdCBjb250YWluIGl0LlxyXG4gICAgLy8gRWFjaCBkYXRhIG9iamVjdCBpcyBjb252ZXJ0ZWQgdG8gYSBzdHJpbmcgdXNpbmcgdGhlIGZ1bmN0aW9uIGRlZmluZWQgYnkgZmlsdGVyUHJlZGljYXRlLlxyXG4gICAgLy8gTWF5IGJlIG92ZXJyaWRkZW4gZm9yIGN1c3RvbWl6YXRpb24uXHJcbiAgICB0aGlzLmZpbHRlcmVkRGF0YSA9XHJcbiAgICAgICh0aGlzLmZpbHRlciA9PSBudWxsIHx8IHRoaXMuZmlsdGVyID09PSAnJykgJiYgIXRoaXMuZmlsdGVycz8ubGVuZ3RoXHJcbiAgICAgICAgPyBkYXRhXHJcbiAgICAgICAgOiBkYXRhLmZpbHRlcihvYmogPT4gdGhpcy5maWx0ZXJQcmVkaWNhdGUob2JqLCB0aGlzLmZpbHRlcikpO1xyXG5cclxuICAgIGlmICh0aGlzLnBhZ2luYXRvcikge1xyXG4gICAgICB0aGlzLl91cGRhdGVQYWdpbmF0b3IodGhpcy5maWx0ZXJlZERhdGEubGVuZ3RoKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJlZERhdGE7XHJcbiAgfVxyXG5cclxuICBmaWx0ZXJQcmVkaWNhdGU6IChkYXRhOiBULCBmaWx0ZXI6IHN0cmluZykgPT4gYm9vbGVhbiA9IChkYXRhOiBULCBmaWx0ZXI6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xyXG4gICAgY29uc3QgZGF0YVN0ciA9IE9iamVjdC5rZXlzKGRhdGEgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxyXG4gICAgICAucmVkdWNlKChjdXJyZW50VGVybTogc3RyaW5nLCBrZXk6IHN0cmluZykgPT4ge1xyXG4gICAgICAgIHJldHVybiBjdXJyZW50VGVybSArIChkYXRhIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSArICfil6wnO1xyXG4gICAgICB9LCAnJylcclxuICAgICAgLnRvTG93ZXJDYXNlKCk7XHJcblxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRGaWx0ZXIgPSBmaWx0ZXIudHJpbSgpLnRvTG93ZXJDYXNlKCk7XHJcblxyXG4gICAgcmV0dXJuIGRhdGFTdHIuaW5kZXhPZih0cmFuc2Zvcm1lZEZpbHRlcikgIT0gLTE7XHJcbiAgfTtcclxuXHJcbiAgX3BhZ2VEYXRhKGRhdGE6IFRbXSk6IFRbXSB7XHJcbiAgICBpZiAoIXRoaXMucGFnaW5hdG9yKSB7XHJcbiAgICAgIHJldHVybiBkYXRhO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHN0YXJ0SW5kZXggPSB0aGlzLnBhZ2luYXRvci5wYWdlSW5kZXggKiB0aGlzLnBhZ2luYXRvci5wYWdlU2l6ZTtcclxuICAgIHJldHVybiBkYXRhLnNsaWNlKHN0YXJ0SW5kZXgsIHN0YXJ0SW5kZXggKyB0aGlzLnBhZ2luYXRvci5wYWdlU2l6ZSk7XHJcbiAgfVxyXG5cclxuICBfb3JkZXJEYXRhKGRhdGE6IFRbXSk6IFRbXSB7XHJcbiAgICAvLyBJZiB0aGVyZSBpcyBubyBhY3RpdmUgc29ydCBvciBkaXJlY3Rpb24sIHJldHVybiB0aGUgZGF0YSB3aXRob3V0IHRyeWluZyB0byBzb3J0LlxyXG4gICAgaWYgKCF0aGlzLnNvcnQpIHtcclxuICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuc29ydERhdGEoZGF0YS5zbGljZSgpLCB0aGlzLnNvcnQpO1xyXG4gIH1cclxuXHJcbiAgc29ydERhdGE6ICgoZGF0YTogVFtdLCBzb3J0OiBNZHRNdWx0aVNvcnQpID0+IFRbXSkgPVxyXG4gICAgKGRhdGE6IFRbXSwgc29ydDogTWR0TXVsdGlTb3J0KTogVFtdID0+IHtcclxuICAgICAgbGV0IHNvcnRlZEJ5ID0gc29ydC5zb3J0ZWRCeTtcclxuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHNvcnRlZEJ5KSB8fCAhc29ydGVkQnkubGVuZ3RoKSB7XHJcbiAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBkYXRhLnNvcnQoKGEsIGIpID0+IHtcclxuICAgICAgICAvLyBHZXQgZWZmZWN0aXZlIHNvcnQgdmFsdWUgYWZ0ZXIgY29tcGFyaW5nIGFsbCBzb3J0ZWQgcHJvcGVydGllcywgaWYgdmFsdWVzIHdlcmUgZXF1YWwgZm9yXHJcbiAgICAgICAgLy8gcHJldmlvdXMgcHJvcGVyeSB0aGVuIGNvbXBhcmUgdGhlIG5leHQgcGFpclxyXG4gICAgICAgIHJldHVybiBzb3J0ZWRCeS5yZWR1Y2UoKHByZXZpb3VzLCBzb3J0KSA9PiB7XHJcbiAgICAgICAgICBpZiAocHJldmlvdXMgIT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIHByZXZpb3VzO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGxldCB2YWx1ZUEgPSB0aGlzLnNvcnRpbmdEYXRhQWNjZXNzb3IoYSwgc29ydC5pZCk7XHJcbiAgICAgICAgICBsZXQgdmFsdWVCID0gdGhpcy5zb3J0aW5nRGF0YUFjY2Vzc29yKGIsIHNvcnQuaWQpO1xyXG5cclxuICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmVWYWx1ZXModmFsdWVBLCB2YWx1ZUIsIHNvcnQuZGlyZWN0aW9uKTtcclxuICAgICAgICB9LCAwKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gIGNvbXBhcmVWYWx1ZXModmFsdWVBOiBzdHJpbmcgfCBudW1iZXIsIHZhbHVlQjogc3RyaW5nIHwgbnVtYmVyLCBkaXJlY3Rpb246IHN0cmluZykge1xyXG4gICAgbGV0IGNvbXBhcmF0b3JSZXN1bHQgPSAwO1xyXG4gICAgaWYgKGRpcmVjdGlvbiA9PSAnJykge1xyXG4gICAgICByZXR1cm4gY29tcGFyYXRvclJlc3VsdDtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodmFsdWVBICE9IG51bGwgJiYgdmFsdWVCICE9IG51bGwpIHtcclxuICAgICAgLy8gQ2hlY2sgaWYgb25lIHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiB0aGUgb3RoZXI7IGlmIGVxdWFsLCBjb21wYXJhdG9yUmVzdWx0IHNob3VsZCByZW1haW4gMC5cclxuICAgICAgaWYgKHZhbHVlQSA+IHZhbHVlQikge1xyXG4gICAgICAgIGNvbXBhcmF0b3JSZXN1bHQgPSAxO1xyXG4gICAgICB9IGVsc2UgaWYgKHZhbHVlQSA8IHZhbHVlQikge1xyXG4gICAgICAgIGNvbXBhcmF0b3JSZXN1bHQgPSAtMTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmICh2YWx1ZUEgIT0gbnVsbCkge1xyXG4gICAgICBjb21wYXJhdG9yUmVzdWx0ID0gMTtcclxuICAgIH0gZWxzZSBpZiAodmFsdWVCICE9IG51bGwpIHtcclxuICAgICAgY29tcGFyYXRvclJlc3VsdCA9IC0xO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjb21wYXJhdG9yUmVzdWx0ICogKGRpcmVjdGlvbiA9PSAnYXNjJyA/IDEgOiAtMSk7XHJcbiAgfVxyXG5cclxuICBfdXBkYXRlUGFnaW5hdG9yKGZpbHRlcmVkRGF0YUxlbmd0aDogbnVtYmVyKSB7XHJcbiAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcclxuICAgICAgY29uc3QgcGFnaW5hdG9yID0gdGhpcy5wYWdpbmF0b3I7XHJcblxyXG4gICAgICBpZiAoIXBhZ2luYXRvcikge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgcGFnaW5hdG9yLmxlbmd0aCA9IGZpbHRlcmVkRGF0YUxlbmd0aDtcclxuXHJcbiAgICAgIC8vIElmIHRoZSBwYWdlIGluZGV4IGlzIHNldCBiZXlvbmQgdGhlIHBhZ2UsIHJlZHVjZSBpdCB0byB0aGUgbGFzdCBwYWdlLlxyXG4gICAgICBpZiAocGFnaW5hdG9yLnBhZ2VJbmRleCA+IDApIHtcclxuICAgICAgICBjb25zdCBsYXN0UGFnZUluZGV4ID0gTWF0aC5jZWlsKHBhZ2luYXRvci5sZW5ndGggLyBwYWdpbmF0b3IucGFnZVNpemUpIC0gMSB8fCAwO1xyXG4gICAgICAgIGNvbnN0IG5ld1BhZ2VJbmRleCA9IE1hdGgubWluKHBhZ2luYXRvci5wYWdlSW5kZXgsIGxhc3RQYWdlSW5kZXgpO1xyXG5cclxuICAgICAgICBpZiAobmV3UGFnZUluZGV4ICE9PSBwYWdpbmF0b3IucGFnZUluZGV4KSB7XHJcbiAgICAgICAgICBwYWdpbmF0b3IucGFnZUluZGV4ID0gbmV3UGFnZUluZGV4O1xyXG5cclxuICAgICAgICAgIC8vIFNpbmNlIHRoZSBwYWdpbmF0b3Igb25seSBlbWl0cyBhZnRlciB1c2VyLWdlbmVyYXRlZCBjaGFuZ2VzLFxyXG4gICAgICAgICAgLy8gd2UgbmVlZCBvdXIgb3duIHN0cmVhbSBzbyB3ZSBrbm93IHRvIHNob3VsZCByZS1yZW5kZXIgdGhlIGRhdGEuXHJcbiAgICAgICAgICB0aGlzLl9pbnRlcm5hbFBhZ2VDaGFuZ2VzLm5leHQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG4iXX0=