@junte/ui
Version:
Quality Angular UI components kit
170 lines • 29.5 kB
JavaScript
import { __decorate, __metadata, __read, __spread } from "tslib";
import { Component, ContentChild, ContentChildren, EventEmitter, forwardRef, HostBinding, HostListener, Input, Output, QueryList, TemplateRef } from '@angular/core';
import { ControlValueAccessor, FormBuilder, NG_VALUE_ACCESSOR } from '@angular/forms';
import { NGXLogger } from 'ngx-logger';
import { Subscription } from 'rxjs';
import { debounceTime, filter as filtering, finalize } from 'rxjs/operators';
import { ContentApi, MethodApi, PropertyApi } from '../../core/decorators/api';
import { Feature } from '../../core/enums/feature';
import { UI } from '../../core/enums/ui';
import { I18N_PROVIDERS } from '../../core/i18n/providers';
import { TableColumnComponent } from './table-column';
var FIRST = 10;
var FILTER_DELAY = 500;
var TableComponent = /** @class */ (function () {
function TableComponent(logger, fb) {
var _this = this;
this.logger = logger;
this.fb = fb;
this.ui = UI;
this.subscriptions = { fetcher: new Subscription() };
this.progress = { loading: false };
this.source = [];
this.orderByControl = this.fb.control(null);
this.firstControl = this.fb.control(FIRST);
this.form = this.fb.group({
q: [null],
orderBy: this.orderByControl,
first: this.firstControl,
offset: [0]
});
this.host = 'jnt-table-host';
this.features = [];
this.reloaded = new EventEmitter();
this.onChange = function () { return _this.logger.error('value accessor is not registered'); };
this.onTouched = function () { return _this.logger.error('value accessor is not registered'); };
this.registerOnChange = function (fn) { return _this.onChange = fn; };
this.registerOnTouched = function (fn) { return _this.onTouched = fn; };
this.onBlur = function () { return _this.onTouched(); };
}
TableComponent_1 = TableComponent;
TableComponent.prototype.ngOnInit = function () {
var _this = this;
this.form.valueChanges.pipe(filtering(function () { return !!_this.fetcher; }), debounceTime(FILTER_DELAY)).subscribe(function (_a) {
var q = _a.q, orderBy = _a.orderBy, first = _a.first, offset = _a.offset;
_this.onChange({ q: q, orderBy: orderBy, first: first, offset: offset });
});
};
TableComponent.prototype.ngOnDestroy = function () {
this.subscriptions.fetcher.unsubscribe();
};
TableComponent.prototype.load = function (filter) {
var _this = this;
if (filter === void 0) { filter = this.form.getRawValue(); }
if (!!this.fetcher) {
this.progress.loading = true;
this.subscriptions.fetcher.unsubscribe();
this.subscriptions.fetcher = this.fetcher(filter)
.pipe(finalize(function () { return _this.progress.loading = false; }))
.subscribe(function (resp) {
_this.source = resp.results;
_this.count = resp.count;
});
}
};
TableComponent.prototype.sorting = function (field) {
this.orderByControl.setValue(this.orderByControl.value === field ? "-" + field : field);
};
TableComponent.prototype.writeValue = function (_a) {
var q = _a.q, orderBy = _a.orderBy, first = _a.first, offset = _a.offset;
this.form.patchValue({ q: q, orderBy: orderBy, first: first, offset: offset }, { emitEvent: false });
};
TableComponent.prototype.hideActions = function () {
this.popover.hide();
};
var TableComponent_1;
TableComponent.ctorParameters = function () { return [
{ type: NGXLogger },
{ type: FormBuilder }
]; };
__decorate([
HostBinding('attr.host'),
__metadata("design:type", Object)
], TableComponent.prototype, "host", void 0);
__decorate([
PropertyApi({
description: 'Table features',
path: 'ui.feature',
options: [Feature.search, Feature.reload]
}),
Input(),
__metadata("design:type", Array)
], TableComponent.prototype, "features", void 0);
__decorate([
PropertyApi({
description: 'Table fetch function',
type: 'Function'
}),
Input(),
__metadata("design:type", Function)
], TableComponent.prototype, "fetcher", void 0);
__decorate([
PropertyApi({
description: 'Output event of reload table'
}),
Output(),
__metadata("design:type", Object)
], TableComponent.prototype, "reloaded", void 0);
__decorate([
ContentChildren(TableColumnComponent),
__metadata("design:type", QueryList)
], TableComponent.prototype, "columns", void 0);
__decorate([
ContentApi({
selector: '#tableRowActionsTemplate',
description: 'table row actions template'
}),
ContentChild('tableRowActionsTemplate'),
__metadata("design:type", TemplateRef)
], TableComponent.prototype, "rowActionsTemplate", void 0);
__decorate([
ContentApi({
selector: '#tableActionsTemplate',
description: 'table actions template'
}),
ContentChild('tableActionsTemplate'),
__metadata("design:type", TemplateRef)
], TableComponent.prototype, "actionsTemplate", void 0);
__decorate([
ContentApi({
selector: '#tableFiltersTemplate',
description: 'table filters template'
}),
ContentChild('tableFiltersTemplate'),
__metadata("design:type", TemplateRef)
], TableComponent.prototype, "filtersTemplate", void 0);
__decorate([
HostListener('blur'),
__metadata("design:type", Object)
], TableComponent.prototype, "onBlur", void 0);
__decorate([
MethodApi({ description: 'reload table' }),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", void 0)
], TableComponent.prototype, "load", null);
__decorate([
MethodApi({ description: 'sorting data table by field' }),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], TableComponent.prototype, "sorting", null);
TableComponent = TableComponent_1 = __decorate([
Component({
selector: 'jnt-table',
template: "<form child-of=\"jnt-table-host\" [formGroup]=\"form\">\n <jnt-stack child-of=\"jnt-table-host\" [align]=\"ui.align.stretch\" [gutter]=\"ui.gutter.none\">\n <ng-container *jntMinFor=\"ui.breakpoint.desktop\">\n <jnt-stack child-of=\"jnt-table-host\" data-feature *ngIf=\"(features | includes : [ui.feature.reload, ui.feature.search]) || !!actionsTemplate\"\n [orientation]=\"ui.orientation.horizontal\"\n [align]=\"ui.align.center\"\n [justify]=\"ui.justify.between\">\n <jnt-stack child-of=\"jnt-table-host\" *ngIf=\"(features | includes : ui.feature.reload) || !!actionsTemplate\"\n [orientation]=\"ui.orientation.horizontal\"\n [align]=\"ui.align.center\">\n <jnt-button child-of=\"jnt-table-host\" data-button *ngIf=\"features | includes : ui.feature.reload\"\n [text]=\"'action.reload' | translate\"\n [icon]=\"progress.loading ? ui.icons.animated.reload : ui.icons.reload\"\n [outline]=\"ui.outline.transparent\"\n [disabled]=\"progress.loading\"\n (click)=\"load(); reloaded.emit()\">\n </jnt-button>\n <ng-container *ngTemplateOutlet=\"actionsTemplate\"></ng-container>\n </jnt-stack>\n <jnt-input child-of=\"jnt-table-host\" data-search *ngIf=\"features | includes : ui.feature.search\"\n formControlName=\"q\"\n [icon]=\"ui.icons.search\"\n [features]=\"[ui.feature.allowEmpty]\"\n [placeholder]=\"'label.search' | translate\">\n </jnt-input>\n </jnt-stack>\n\n <div child-of=\"jnt-table-host\" data-filters *ngIf=\"!!filtersTemplate\">\n <ng-container *ngTemplateOutlet=\"filtersTemplate\"></ng-container>\n </div>\n </ng-container>\n\n <jnt-stack child-of=\"jnt-table-host\" [align]=\"ui.align.stretch\">\n <div child-of=\"jnt-table-host\" *jntMinFor=\"ui.breakpoint.desktop\" data-table>\n <table child-of=\"jnt-table-host\" >\n <div child-of=\"jnt-table-host\" data-spinner *ngIf=\"source.length && progress.loading\">\n <jnt-spinner child-of=\"jnt-table-host\" [size]=\"ui.size.large\"></jnt-spinner>\n </div>\n\n <thead child-of=\"jnt-table-host\" >\n <tr child-of=\"jnt-table-host\" >\n <th child-of=\"jnt-table-host\" data-actions *ngIf=\"!!rowActionsTemplate\"></th>\n <th child-of=\"jnt-table-host\" *ngFor=\"let column of columns\"\n [attr.data-sortable]=\"!!column.orderBy\"\n [style.text-align]=\"column.align\"\n [style.width]=\"column.width\"\n (click)=\"column.orderBy ? sorting(column.orderBy) : null\">\n <span child-of=\"jnt-table-host\" >\n {{column.title}}\n <i child-of=\"jnt-table-host\" *ngIf=\"!!orderByControl.value && (orderByControl.value === '-' + column.orderBy\n || orderByControl.value === column.orderBy)\"\n [innerHTML]=\"(orderByControl.value === column.orderBy) ? '↑' : '↓'\"></i>\n </span>\n </th>\n </tr>\n </thead>\n\n <tbody child-of=\"jnt-table-host\" >\n <ng-container *ngIf=\"source.length; else noDataTemplate\">\n <tr child-of=\"jnt-table-host\" *ngFor=\"let row of source; let i = index\" [class.even]=\"!(i % 2)\">\n <td child-of=\"jnt-table-host\" *ngIf=\"!!rowActionsTemplate\" data-actions>\n <jnt-button child-of=\"jnt-table-host\" data-trigger\n [outline]=\"ui.outline.transparent\"\n [icon]=\"ui.icons.actions\"\n (attached)=\"popover = $event\"\n [jntPopover]=\"{\n context: 'table-row-action',\n contentTemplate: dropdownTemplate,\n behaviour: ui.behaviour.dropdown,\n trigger: ui.trigger.click,\n padding: ui.gutter.small,\n minWidth: '150px'\n }\">\n </jnt-button>\n <ng-template #dropdownTemplate>\n <ng-container *ngTemplateOutlet=\"rowActionsTemplate;\n context: {row: row, hide: hideActions.bind(this)}\">\n </ng-container>\n </ng-template>\n </td>\n <td child-of=\"jnt-table-host\" *ngFor=\"let column of columns\">\n <ng-container *ngTemplateOutlet=\"column.tableCellTemplate; context: row\"></ng-container>\n </td>\n </tr>\n </ng-container>\n <ng-template #noDataTemplate>\n <ng-container *ngIf=\"!progress.loading; else skeletonTemplate\">\n <tr child-of=\"jnt-table-host\" data-nodata>\n <td child-of=\"jnt-table-host\" [attr.colspan]=\"!!rowActionsTemplate ? columns.length + 1 : columns.length\">\n <jnt-icon child-of=\"jnt-table-host\" [icon]=\"ui.icons.neutral\"></jnt-icon>\n </td>\n </tr>\n </ng-container>\n <ng-template #skeletonTemplate>\n <tr child-of=\"jnt-table-host\" data-loading>\n <td child-of=\"jnt-table-host\" [attr.colspan]=\"!!rowActionsTemplate ? columns.length + 1 : columns.length\">\n <jnt-skeleton child-of=\"jnt-table-host\" [lines]=\"4\"></jnt-skeleton>\n </td>\n </tr>\n </ng-template>\n </ng-template>\n </tbody>\n </table>\n </div>\n\n <jnt-stack child-of=\"jnt-table-host\" *jntMaxFor=\"ui.breakpoint.tablet\" [align]=\"ui.align.stretch\">\n <jnt-stack child-of=\"jnt-table-host\" data-feature [align]=\"ui.align.stretch\">\n <jnt-stack child-of=\"jnt-table-host\" *ngIf=\"(features | includes : ui.feature.reload) || !!actionsTemplate\"\n [orientation]=\"ui.orientation.horizontal\" [wrap]=\"ui.wrap.wrap\">\n <jnt-button child-of=\"jnt-table-host\" data-button *ngIf=\"features | includes : ui.feature.reload\"\n [text]=\"'action.reload' | translate\"\n [icon]=\"progress.loading ? ui.icons.animated.reload : ui.icons.reload\"\n [outline]=\"ui.outline.transparent\"\n [disabled]=\"progress.loading\"\n (click)=\"load(); reloaded.emit()\">\n </jnt-button>\n <jnt-stack child-of=\"jnt-table-host\" *ngIf=\"!!actionsTemplate\" [orientation]=\"ui.orientation.horizontal\" [wrap]=\"ui.wrap.wrap\">\n <ng-container *ngTemplateOutlet=\"actionsTemplate\"></ng-container>\n </jnt-stack>\n </jnt-stack>\n <jnt-input child-of=\"jnt-table-host\" data-search *ngIf=\"features | includes : ui.feature.search\"\n formControlName=\"q\"\n [icon]=\"ui.icons.search\"\n [features]=\"[ui.feature.allowEmpty]\"\n [placeholder]=\"'label.search' | translate\">\n </jnt-input>\n <ng-container *ngIf=\"!!filtersTemplate\">\n <ng-container *ngTemplateOutlet=\"filtersTemplate\"></ng-container>\n </ng-container>\n </jnt-stack>\n <ng-template #noDataCardTemplate>\n <jnt-stack child-of=\"jnt-table-host\" *ngIf=\"!progress.loading; else skeletonCardTemplate\" [align]=\"ui.align.center\">\n <jnt-icon child-of=\"jnt-table-host\" data-nodata [icon]=\"ui.icons.neutral\"></jnt-icon>\n </jnt-stack>\n <ng-template #skeletonCardTemplate>\n <ng-container *ngFor=\"let card of 5 | mockArray\">\n <jnt-skeleton child-of=\"jnt-table-host\" [type]=\"ui.skeleton.type.card\"></jnt-skeleton>\n </ng-container>\n </ng-template>\n </ng-template>\n <div child-of=\"jnt-table-host\" data-spinner *ngIf=\"source.length && progress.loading\">\n <jnt-spinner child-of=\"jnt-table-host\" [size]=\"ui.size.large\"></jnt-spinner>\n </div>\n <ng-container *ngIf=\"source.length; else noDataCardTemplate\">\n <jnt-card child-of=\"jnt-table-host\" *ngFor=\"let row of source; let i = index\">\n <table child-of=\"jnt-table-host\" data-line cellpadding=\"0\" cellspacing=\"0\">\n <tr child-of=\"jnt-table-host\" *ngFor=\"let column of columns\">\n <td child-of=\"jnt-table-host\" >\n <b child-of=\"jnt-table-host\" *ngIf=\"!!column.title\">{{column.title}}</b>\n </td>\n <td child-of=\"jnt-table-host\" >\n <ng-container *ngTemplateOutlet=\"column.tableCellTemplate; context: row\"></ng-container>\n </td>\n </tr>\n </table>\n <ng-template *ngIf=\"!!rowActionsTemplate\" #cardActionsTemplate let-hide=\"hide\">\n <ng-container *ngTemplateOutlet=\"rowActionsTemplate;\n context: {row: row, hide: hideActions.bind(this)}\">\n </ng-container>\n </ng-template>\n </jnt-card>\n </ng-container>\n </jnt-stack>\n\n <ng-container *ngIf=\"!!count\">\n <div child-of=\"jnt-table-host\" data-pagination>\n <jnt-pager child-of=\"jnt-table-host\" data-pages formControlName=\"offset\"\n [count]=\"count\" [pageSize]=\"firstControl.value\">\n </jnt-pager>\n <jnt-select child-of=\"jnt-table-host\" *jntMinFor=\"ui.breakpoint.desktop\" formControlName=\"first\" [size]=\"ui.size.small\">\n <jnt-select-option child-of=\"jnt-table-host\" label=\"10\" key=\"10\"></jnt-select-option>\n <jnt-select-option child-of=\"jnt-table-host\" label=\"20\" key=\"20\"></jnt-select-option>\n <jnt-select-option child-of=\"jnt-table-host\" label=\"30\" key=\"30\"></jnt-select-option>\n </jnt-select>\n </div>\n </ng-container>\n </jnt-stack>\n </jnt-stack>\n</form>",
providers: __spread([
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return TableComponent_1; }),
multi: true
}
], I18N_PROVIDERS)
}),
__metadata("design:paramtypes", [NGXLogger,
FormBuilder])
], TableComponent);
return TableComponent;
}());
export { TableComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGp1bnRlL3VpLyIsInNvdXJjZXMiOlsibGliL2NvbGxlY3Rpb25zL3RhYmxlL3RhYmxlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ1osZUFBZSxFQUNmLFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxXQUFXLEVBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLG9CQUFvQixFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdkMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNwQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sSUFBSSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0UsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDL0UsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFM0QsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHdEQsSUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO0FBQ2pCLElBQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQztBQWF6QjtJQTBFRSx3QkFBb0IsTUFBaUIsRUFDakIsRUFBZTtRQURuQyxpQkFFQztRQUZtQixXQUFNLEdBQU4sTUFBTSxDQUFXO1FBQ2pCLE9BQUUsR0FB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QUNaO2VBQUssY0FBYyxDQUNyQjtTQUNGLENBQUM7eUNBMkU0QixTQUFTO1lBQ2IsV0FBVztPQTNFeEIsY0FBYyxDQW9IMUI7SUFBRCxxQkFBQztDQUFBLEFBcEhELElBb0hDO1NBcEhZLGNBQWMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBRdWVyeUxpc3QsXG4gIFRlbXBsYXRlUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIEZvcm1CdWlsZGVyLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IE5HWExvZ2dlciB9IGZyb20gJ25neC1sb2dnZXInO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGZpbHRlciBhcyBmaWx0ZXJpbmcsIGZpbmFsaXplIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQ29udGVudEFwaSwgTWV0aG9kQXBpLCBQcm9wZXJ0eUFwaSB9IGZyb20gJy4uLy4uL2NvcmUvZGVjb3JhdG9ycy9hcGknO1xuaW1wb3J0IHsgRmVhdHVyZSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvZmVhdHVyZSc7XG5pbXBvcnQgeyBVSSB9IGZyb20gJy4uLy4uL2NvcmUvZW51bXMvdWknO1xuaW1wb3J0IHsgSTE4Tl9QUk9WSURFUlMgfSBmcm9tICcuLi8uLi9jb3JlL2kxOG4vcHJvdmlkZXJzJztcbmltcG9ydCB7IFBvcG92ZXJDb21wb25lbnQgfSBmcm9tICcuLi8uLi9vdmVybGF5cy9wb3BvdmVyL3BvcG92ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IFRhYmxlQ29sdW1uQ29tcG9uZW50IH0gZnJvbSAnLi90YWJsZS1jb2x1bW4nO1xuaW1wb3J0IHsgRGVmYXVsdFNlYXJjaEZpbHRlciB9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBGSVJTVCA9IDEwO1xuY29uc3QgRklMVEVSX0RFTEFZID0gNTAwO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdqbnQtdGFibGUnLFxuICB0ZW1wbGF0ZVVybDogJy4vdGFibGUuZW5jYXBzdWxhdGVkLmh0bWwnLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFRhYmxlQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfSwgLi4uSTE4Tl9QUk9WSURFUlNcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBUYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cbiAgdWkgPSBVSTtcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbnMgPSB7ZmV0Y2hlcjogbmV3IFN1YnNjcmlwdGlvbigpfTtcbiAgcG9wb3ZlcjogUG9wb3ZlckNvbXBvbmVudDtcblxuICBwcm9ncmVzcyA9IHtsb2FkaW5nOiBmYWxzZX07XG4gIHNvdXJjZTogT2JqZWN0W10gPSBbXTtcbiAgY291bnQ6IG51bWJlcjtcblxuICBvcmRlckJ5Q29udHJvbCA9IHRoaXMuZmIuY29udHJvbChudWxsKTtcbiAgZmlyc3RDb250cm9sID0gdGhpcy5mYi5jb250cm9sKEZJUlNUKTtcblxuICBmb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgcTogW251bGxdLFxuICAgIG9yZGVyQnk6IHRoaXMub3JkZXJCeUNvbnRyb2wsXG4gICAgZmlyc3Q6IHRoaXMuZmlyc3RDb250cm9sLFxuICAgIG9mZnNldDogWzBdXG4gIH0pO1xuXG4gIEBIb3N0QmluZGluZygnYXR0ci5ob3N0JykgcmVhZG9ubHkgaG9zdCA9ICdqbnQtdGFibGUtaG9zdCc7XG5cbiAgQFByb3BlcnR5QXBpKHtcbiAgICBkZXNjcmlwdGlvbjogJ1RhYmxlIGZlYXR1cmVzJyxcbiAgICBwYXRoOiAndWkuZmVhdHVyZScsXG4gICAgb3B0aW9uczogW0ZlYXR1cmUuc2VhcmNoLCBGZWF0dXJlLnJlbG9hZF1cbiAgfSlcbiAgQElucHV0KClcbiAgZmVhdHVyZXM6IEZlYXR1cmVbXSA9IFtdO1xuXG4gIEBQcm9wZXJ0eUFwaSh7XG4gICAgZGVzY3JpcHRpb246ICdUYWJsZSBmZXRjaCBmdW5jdGlvbicsXG4gICAgdHlwZTogJ0Z1bmN0aW9uJ1xuICB9KVxuICBASW5wdXQoKVxuICBmZXRjaGVyOiBGdW5jdGlvbjtcblxuICBAUHJvcGVydHlBcGkoe1xuICAgIGRlc2NyaXB0aW9uOiAnT3V0cHV0IGV2ZW50IG9mIHJlbG9hZCB0YWJsZSdcbiAgfSlcbiAgQE91dHB1dCgpXG4gIHJlbG9hZGVkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgQENvbnRlbnRDaGlsZHJlbihUYWJsZUNvbHVtbkNvbXBvbmVudClcbiAgY29sdW1uczogUXVlcnlMaXN0PFRhYmxlQ29sdW1uQ29tcG9uZW50PjtcblxuICBAQ29udGVudEFwaSh7XG4gICAgc2VsZWN0b3I6ICcjdGFibGVSb3dBY3Rpb25zVGVtcGxhdGUnLFxuICAgIGRlc2NyaXB0aW9uOiAndGFibGUgcm93IGFjdGlvbnMgdGVtcGxhdGUnXG4gIH0pXG4gIEBDb250ZW50Q2hpbGQoJ3RhYmxlUm93QWN0aW9uc1RlbXBsYXRlJylcbiAgcm93QWN0aW9uc1RlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIEBDb250ZW50QXBpKHtcbiAgICBzZWxlY3RvcjogJyN0YWJsZUFjdGlvbnNUZW1wbGF0ZScsXG4gICAgZGVzY3JpcHRpb246ICd0YWJsZSBhY3Rpb25zIHRlbXBsYXRlJ1xuICB9KVxuICBAQ29udGVudENoaWxkKCd0YWJsZUFjdGlvbnNUZW1wbGF0ZScpXG4gIGFjdGlvbnNUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBAQ29udGVudEFwaSh7XG4gICAgc2VsZWN0b3I6ICcjdGFibGVGaWx0ZXJzVGVtcGxhdGUnLFxuICAgIGRlc2NyaXB0aW9uOiAndGFibGUgZmlsdGVycyB0ZW1wbGF0ZSdcbiAgfSlcbiAgQENvbnRlbnRDaGlsZCgndGFibGVGaWx0ZXJzVGVtcGxhdGUnKVxuICBmaWx0ZXJzVGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgb25DaGFuZ2U6IChmaWx0ZXI6IERlZmF1bHRTZWFyY2hGaWx0ZXIpID0+IHZvaWQgPSAoKSA9PiB0aGlzLmxvZ2dlci5lcnJvcigndmFsdWUgYWNjZXNzb3IgaXMgbm90IHJlZ2lzdGVyZWQnKTtcbiAgb25Ub3VjaGVkOiAoKSA9PiB2b2lkID0gKCkgPT4gdGhpcy5sb2dnZXIuZXJyb3IoJ3ZhbHVlIGFjY2Vzc29yIGlzIG5vdCByZWdpc3RlcmVkJyk7XG4gIHJlZ2lzdGVyT25DaGFuZ2UgPSBmbiA9PiB0aGlzLm9uQ2hhbmdlID0gZm47XG4gIHJlZ2lzdGVyT25Ub3VjaGVkID0gZm4gPT4gdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgQEhvc3RMaXN0ZW5lcignYmx1cicpIG9uQmx1ciA9ICgpID0+IHRoaXMub25Ub3VjaGVkKCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBsb2dnZXI6IE5HWExvZ2dlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZm9ybS52YWx1ZUNoYW5nZXMucGlwZShmaWx0ZXJpbmcoKCkgPT4gISF0aGlzLmZldGNoZXIpLFxuICAgICAgZGVib3VuY2VUaW1lKEZJTFRFUl9ERUxBWSkpLnN1YnNjcmliZSgoe3EsIG9yZGVyQnksIGZpcnN0LCBvZmZzZXR9KSA9PiB7XG4gICAgICB0aGlzLm9uQ2hhbmdlKHtxLCBvcmRlckJ5LCBmaXJzdCwgb2Zmc2V0fSk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZmV0Y2hlci51bnN1YnNjcmliZSgpO1xuICB9XG5cbiAgQE1ldGhvZEFwaSh7ZGVzY3JpcHRpb246ICdyZWxvYWQgdGFibGUnfSlcbiAgbG9hZChmaWx0ZXIgPSB0aGlzLmZvcm0uZ2V0UmF3VmFsdWUoKSkge1xuICAgIGlmICghIXRoaXMuZmV0Y2hlcikge1xuICAgICAgdGhpcy5wcm9ncmVzcy5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mZXRjaGVyLnVuc3Vic2NyaWJlKCk7XG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZmV0Y2hlciA9IHRoaXMuZmV0Y2hlcihmaWx0ZXIpXG4gICAgICAgIC5waXBlKGZpbmFsaXplKCgpID0+IHRoaXMucHJvZ3Jlc3MubG9hZGluZyA9IGZhbHNlKSlcbiAgICAgICAgLnN1YnNjcmliZShyZXNwID0+IHtcbiAgICAgICAgICB0aGlzLnNvdXJjZSA9IHJlc3AucmVzdWx0cztcbiAgICAgICAgICB0aGlzLmNvdW50ID0gcmVzcC5jb3VudDtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgQE1ldGhvZEFwaSh7ZGVzY3JpcHRpb246ICdzb3J0aW5nIGRhdGEgdGFibGUgYnkgZmllbGQnfSlcbiAgc29ydGluZyhmaWVsZDogc3RyaW5nKSB7XG4gICAgdGhpcy5vcmRlckJ5Q29udHJvbC5zZXRWYWx1ZSh0aGlzLm9yZGVyQnlDb250cm9sLnZhbHVlID09PSBmaWVsZCA/IGAtJHtmaWVsZH1gIDogZmllbGQpO1xuICB9XG5cbiAgd3JpdGVWYWx1ZSh7cSwgb3JkZXJCeSwgZmlyc3QsIG9mZnNldH06IERlZmF1bHRTZWFyY2hGaWx0ZXIpIHtcbiAgICB0aGlzLmZvcm0ucGF0Y2hWYWx1ZSh7cSwgb3JkZXJCeSwgZmlyc3QsIG9mZnNldH0sXG4gICAgICB7ZW1pdEV2ZW50OiBmYWxzZX0pO1xuICB9XG5cbiAgaGlkZUFjdGlvbnMoKSB7XG4gICAgdGhpcy5wb3BvdmVyLmhpZGUoKTtcbiAgfVxufVxuIl19