@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
124 lines • 23.4 kB
JavaScript
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Component, EventEmitter, forwardRef, HostBinding, Input, Output } from '@angular/core';
import { PRODUCT_EXPERIENCE_EVENT_SOURCE } from '@c8y/ngx-components';
import { ACTIONS_OPERATIONS } from '@c8y/ngx-components/operations/product-experience';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components";
import * as i2 from "@angular/common";
import * as i3 from "ngx-bootstrap/dropdown";
export class StatusFilterComponent {
constructor() {
this.ACTIONS = ACTIONS_OPERATIONS;
this.statusOptions = [];
this.onFilterChanged = new EventEmitter();
this.isAllButtonSelected = true;
}
/** List of filter options to be displayed */
set options(options) {
this.statusOptions = (Object.values(options) || []).map(option => ({
selected: false,
option
}));
}
/**
* Allows multiple options to be active simultaneosly.
*/
set _multiple(multiple) {
this.multiple = coerceBooleanProperty(multiple);
}
/** Display the filter as a small button group */
set _small(small) {
this.small = coerceBooleanProperty(small);
}
get displaySmall() {
return this.small;
}
changeFilter(option) {
this.isAllButtonSelected = false;
let emitNeeded = false;
if (this.multiple) {
option.selected = !option.selected;
emitNeeded = true;
}
else if (!option.selected) {
option.selected = true;
this.statusOptions.filter(op => op !== option).forEach(op => (op.selected = false));
emitNeeded = true;
}
if (emitNeeded) {
this.emitSelectedOptions();
}
}
removeFilter() {
this.isAllButtonSelected = true;
this.statusOptions.forEach(op => (op.selected = false));
this.emitSelectedOptions();
}
/**
* Allows the filter to be initalliy displayed with some preset filters.
*
* @param filters An `StatusOption` array defining filter options to be preset.
* @param emit (optional) If `true` component will emit `onFilterChanged` event.
*/
preset(filters, emit = true) {
let firstSelected = false;
this.statusOptions.forEach(option => (option.selected = false));
this.statusOptions
.filter(option => (filters || []).map(o => o.label).includes(option.option.label))
.filter(() => {
// only first option passed will be set in single selection mode
const include = this.multiple || !firstSelected;
if (include) {
firstSelected = true;
}
return include;
})
.forEach(option => (option.selected = true));
this.isAllButtonSelected = !(filters && filters.length);
if (emit) {
this.emitSelectedOptions();
}
}
reset() {
this.removeFilter();
}
activeFilters() {
return this.statusOptions.filter(option => option.selected).map(option => option.option);
}
isFilterApplied() {
return this.statusOptions.some(option => option.selected);
}
emitSelectedOptions() {
this.onFilterChanged.emit(this.statusOptions.filter(option => option.selected).map(option => option.option));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StatusFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StatusFilterComponent, selector: "c8y-status-filter", inputs: { options: "options", _multiple: ["multiple", "_multiple"], _small: ["small", "_small"] }, outputs: { onFilterChanged: "onFilterChanged" }, host: { properties: { "class.btn-group-sm": "this.displaySmall" } }, providers: [
{
provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
useExisting: forwardRef(() => StatusFilterComponent)
}
], ngImport: i0, template: "<div dropdown placement=\"bottom left\" class=\"dropdown c8y-child-assets-selector\">\n <button\n class=\"btn dropdown-toggle d-flex a-i-center c8y-dropdown\"\n type=\"button\"\n title=\"{{ 'Status filter' | translate }}\"\n dropdownToggle\n >\n <span *ngFor=\"let option of statusOptions\" class=\"d-contents\">\n <span class=\"text-truncate\" *ngIf=\"option.selected\">\n <i [c8yIcon]=\"option.option.icon\" [ngClass]=\"option.option.styleClass\"></i>\n <span class=\"m-l-4\">{{ option.option.label | translate }}</span>\n </span>\n </span>\n <span class=\"text-truncate\" *ngIf=\"isAllButtonSelected\">\n <i c8yIcon=\"c8y-energy\" class=\"m-r-4 text-info\"></i>\n {{ 'All statuses' | translate }}\n </span>\n </button>\n <ul\n id=\"dropdown-status-filter\"\n *dropdownMenu\n class=\"dropdown-menu\"\n role=\"menu\"\n aria-labelledby=\"status-filter\"\n >\n <li *ngFor=\"let option of statusOptions\" [ngClass]=\"{ active: option.selected }\">\n <button\n type=\"button\"\n [title]=\"option.option.label | translate\"\n (click)=\"changeFilter(option)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: ACTIONS.FILTER,\n filterBy: 'status',\n filterValue: option.option.label\n }\"\n >\n <i [c8yIcon]=\"option.option.icon\" [ngClass]=\"option.option.styleClass\"></i>\n <span class=\"m-l-4\">{{ option.option.label | translate }}</span>\n </button>\n </li>\n <li [ngClass]=\"{ active: isAllButtonSelected }\">\n <button\n type=\"button\"\n title=\"{{ 'All statuses' | translate }}\"\n (click)=\"removeFilter()\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: ACTIONS.FILTER,\n filterBy: 'status'\n }\"\n >\n <i c8yIcon=\"c8y-energy\" class=\"m-r-4 text-info\"></i>\n {{ 'All statuses' | translate }}\n </button>\n </li>\n </ul>\n</div>\n", dependencies: [{ kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.ProductExperienceDirective, selector: "[c8yProductExperience]", inputs: ["actionName", "actionData", "inherit", "suppressDataOverriding"] }, { kind: "directive", type: i3.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i3.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i3.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StatusFilterComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-status-filter', providers: [
{
provide: PRODUCT_EXPERIENCE_EVENT_SOURCE,
useExisting: forwardRef(() => StatusFilterComponent)
}
], template: "<div dropdown placement=\"bottom left\" class=\"dropdown c8y-child-assets-selector\">\n <button\n class=\"btn dropdown-toggle d-flex a-i-center c8y-dropdown\"\n type=\"button\"\n title=\"{{ 'Status filter' | translate }}\"\n dropdownToggle\n >\n <span *ngFor=\"let option of statusOptions\" class=\"d-contents\">\n <span class=\"text-truncate\" *ngIf=\"option.selected\">\n <i [c8yIcon]=\"option.option.icon\" [ngClass]=\"option.option.styleClass\"></i>\n <span class=\"m-l-4\">{{ option.option.label | translate }}</span>\n </span>\n </span>\n <span class=\"text-truncate\" *ngIf=\"isAllButtonSelected\">\n <i c8yIcon=\"c8y-energy\" class=\"m-r-4 text-info\"></i>\n {{ 'All statuses' | translate }}\n </span>\n </button>\n <ul\n id=\"dropdown-status-filter\"\n *dropdownMenu\n class=\"dropdown-menu\"\n role=\"menu\"\n aria-labelledby=\"status-filter\"\n >\n <li *ngFor=\"let option of statusOptions\" [ngClass]=\"{ active: option.selected }\">\n <button\n type=\"button\"\n [title]=\"option.option.label | translate\"\n (click)=\"changeFilter(option)\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: ACTIONS.FILTER,\n filterBy: 'status',\n filterValue: option.option.label\n }\"\n >\n <i [c8yIcon]=\"option.option.icon\" [ngClass]=\"option.option.styleClass\"></i>\n <span class=\"m-l-4\">{{ option.option.label | translate }}</span>\n </button>\n </li>\n <li [ngClass]=\"{ active: isAllButtonSelected }\">\n <button\n type=\"button\"\n title=\"{{ 'All statuses' | translate }}\"\n (click)=\"removeFilter()\"\n c8yProductExperience\n inherit\n [actionData]=\"{\n action: ACTIONS.FILTER,\n filterBy: 'status'\n }\"\n >\n <i c8yIcon=\"c8y-energy\" class=\"m-r-4 text-info\"></i>\n {{ 'All statuses' | translate }}\n </button>\n </li>\n </ul>\n</div>\n" }]
}], propDecorators: { options: [{
type: Input
}], _multiple: [{
type: Input,
args: ['multiple']
}], _small: [{
type: Input,
args: ['small']
}], displaySmall: [{
type: HostBinding,
args: ['class.btn-group-sm']
}], onFilterChanged: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdHVzLWZpbHRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9vcGVyYXRpb25zL3N0YXR1cy1maWx0ZXIvc3RhdHVzLWZpbHRlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9vcGVyYXRpb25zL3N0YXR1cy1maWx0ZXIvc3RhdHVzLWZpbHRlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEcsT0FBTyxFQUdMLCtCQUErQixFQUNoQyxNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG1EQUFtRCxDQUFDOzs7OztBQWdCdkYsTUFBTSxPQUFPLHFCQUFxQjtJQVZsQztRQVdFLFlBQU8sR0FBRyxrQkFBa0IsQ0FBQztRQUU3QixrQkFBYSxHQUFnRSxFQUFFLENBQUM7UUEwQnRFLG9CQUFlLEdBQTBDLElBQUksWUFBWSxFQUFFLENBQUM7UUFFdEYsd0JBQW1CLEdBQUcsSUFBSSxDQUFDO0tBOEU1QjtJQXhHQyw2Q0FBNkM7SUFDN0MsSUFBYSxPQUFPLENBQUMsT0FBd0M7UUFDM0QsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNqRSxRQUFRLEVBQUUsS0FBSztZQUNmLE1BQU07U0FDUCxDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFFRDs7T0FFRztJQUNILElBQXVCLFNBQVMsQ0FBQyxRQUFpQjtRQUNoRCxJQUFJLENBQUMsUUFBUSxH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LCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb2VyY2VCb29sZWFuUHJvcGVydHkgfSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIGZvcndhcmRSZWYsIEhvc3RCaW5kaW5nLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBQcm9kdWN0RXhwZXJpZW5jZUV2ZW50LFxuICBQcm9kdWN0RXhwZXJpZW5jZUV2ZW50U291cmNlLFxuICBQUk9EVUNUX0VYUEVSSUVOQ0VfRVZFTlRfU09VUkNFXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgQUNUSU9OU19PUEVSQVRJT05TIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9vcGVyYXRpb25zL3Byb2R1Y3QtZXhwZXJpZW5jZSc7XG5pbXBvcnQge1xuICBPcGVyYXRpb25TdGF0dXNPcHRpb25zTWFwU2hhcmVkLFxuICBPcGVyYXRpb25TdGF0dXNPcHRpb25cbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9vcGVyYXRpb25zL3NoYXJlZCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS1zdGF0dXMtZmlsdGVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3N0YXR1cy1maWx0ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBQUk9EVUNUX0VYUEVSSUVOQ0VfRVZFTlRfU09VUkNFLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gU3RhdHVzRmlsdGVyQ29tcG9uZW50KVxuICAgIH1cbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBTdGF0dXNGaWx0ZXJDb21wb25lbnQgaW1wbGVtZW50cyBQcm9kdWN0RXhwZXJpZW5jZUV2ZW50U291cmNlIHtcbiAgQUNUSU9OUyA9IEFDVElPTlNfT1BFUkFUSU9OUztcbiAgcHJvZHVjdEV4cGVyaWVuY2VFdmVudDogUHJvZHVjdEV4cGVyaWVuY2VFdmVudDtcbiAgc3RhdHVzT3B0aW9uczogQXJyYXk8eyBzZWxlY3RlZDogYm9vbGVhbjsgb3B0aW9uOiBPcGVyYXRpb25TdGF0dXNPcHRpb24gfT4gPSBbXTtcblxuICAvKiogTGlzdCBvZiBmaWx0ZXIgb3B0aW9ucyB0byBiZSBkaXNwbGF5ZWQgKi9cbiAgQElucHV0KCkgc2V0IG9wdGlvbnMob3B0aW9uczogT3BlcmF0aW9uU3RhdHVzT3B0aW9uc01hcFNoYXJlZCkge1xuICAgIHRoaXMuc3RhdHVzT3B0aW9ucyA9IChPYmplY3QudmFsdWVzKG9wdGlvbnMpIHx8IFtdKS5tYXAob3B0aW9uID0+ICh7XG4gICAgICBzZWxlY3RlZDogZmFsc2UsXG4gICAgICBvcHRpb25cbiAgICB9KSk7XG4gIH1cblxuICAvKipcbiAgICogQWxsb3dzIG11bHRpcGxlIG9wdGlvbnMgdG8gYmUgYWN0aXZlIHNpbXVsdGFuZW9zbHkuXG4gICAqL1xuICBASW5wdXQoJ211bHRpcGxlJykgc2V0IF9tdWx0aXBsZShtdWx0aXBsZTogYm9vbGVhbikge1xuICAgIHRoaXMubXVsdGlwbGUgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkobXVsdGlwbGUpO1xuICB9XG5cbiAgLyoqIERpc3BsYXkgdGhlIGZpbHRlciBhcyBhIHNtYWxsIGJ1dHRvbiBncm91cCAqL1xuICBASW5wdXQoJ3NtYWxsJykgc2V0IF9zbWFsbChzbWFsbDogYm9vbGVhbikge1xuICAgIHRoaXMuc21hbGwgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkoc21hbGwpO1xuICB9XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5idG4tZ3JvdXAtc20nKSBnZXQgZGlzcGxheVNtYWxsKCkge1xuICAgIHJldHVybiB0aGlzLnNtYWxsO1xuICB9XG5cbiAgQE91dHB1dCgpIG9uRmlsdGVyQ2hhbmdlZDogRXZlbnRFbWl0dGVyPE9wZXJhdGlvblN0YXR1c09wdGlvbltdPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBpc0FsbEJ1dHRvblNlbGVjdGVkID0gdHJ1ZTtcblxuICBwcml2YXRlIG11bHRpcGxlOiBib29sZWFuO1xuICBwcml2YXRlIHNtYWxsOiBib29sZWFuO1xuXG4gIGNoYW5nZUZpbHRlcihvcHRpb246IHsgc2VsZWN0ZWQ6IGJvb2xlYW47IG9wdGlvbjogT3BlcmF0aW9uU3RhdHVzT3B0aW9uIH0pIHtcbiAgICB0aGlzLmlzQWxsQnV0dG9uU2VsZWN0ZWQgPSBmYWxzZTtcbiAgICBsZXQgZW1pdE5lZWRlZCA9IGZhbHNlO1xuXG4gICAgaWYgKHRoaXMubXVsdGlwbGUpIHtcbiAgICAgIG9wdGlvbi5zZWxlY3RlZCA9ICFvcHRpb24uc2VsZWN0ZWQ7XG4gICAgICBlbWl0TmVlZGVkID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFvcHRpb24uc2VsZWN0ZWQpIHtcbiAgICAgIG9wdGlvbi5zZWxlY3RlZCA9IHRydWU7XG4gICAgICB0aGlzLnN0YXR1c09wdGlvbnMuZmlsdGVyKG9wID0+IG9wICE9PSBvcHRpb24pLmZvckVhY2gob3AgPT4gKG9wLnNlbGVjdGVkID0gZmFsc2UpKTtcbiAgICAgIGVtaXROZWVkZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChlbWl0TmVlZGVkKSB7XG4gICAgICB0aGlzLmVtaXRTZWxlY3RlZE9wdGlvbnMoKTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVGaWx0ZXIoKSB7XG4gICAgdGhpcy5pc0FsbEJ1dHRvblNlbGVjdGVkID0gdHJ1ZTtcbiAgICB0aGlzLnN0YXR1c09wdGlvbnMuZm9yRWFjaChvcCA9PiAob3Auc2VsZWN0ZWQgPSBmYWxzZSkpO1xuXG4gICAgdGhpcy5lbWl0U2VsZWN0ZWRPcHRpb25zKCk7XG4gIH1cblxuICAvKipcbiAgICogQWxsb3dzIHRoZSBmaWx0ZXIgdG8gYmUgaW5pdGFsbGl5IGRpc3BsYXllZCB3aXRoIHNvbWUgcHJlc2V0IGZpbHRlcnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXJzIEFuIGBTdGF0dXNPcHRpb25gIGFycmF5IGRlZmluaW5nIGZpbHRlciBvcHRpb25zIHRvIGJlIHByZXNldC5cbiAgICogQHBhcmFtIGVtaXQgIChvcHRpb25hbCkgSWYgYHRydWVgIGNvbXBvbmVudCB3aWxsIGVtaXQgYG9uRmlsdGVyQ2hhbmdlZGAgZXZlbnQuXG4gICAqL1xuICBwcmVzZXQoZmlsdGVyczogT3BlcmF0aW9uU3RhdHVzT3B0aW9uW10sIGVtaXQgPSB0cnVlKSB7XG4gICAgbGV0IGZpcnN0U2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgIHRoaXMuc3RhdHVzT3B0aW9ucy5mb3JFYWNoKG9wdGlvbiA9PiAob3B0aW9uLnNlbGVjdGVkID0gZmFsc2UpKTtcblxuICAgIHRoaXMuc3RhdHVzT3B0aW9uc1xuICAgICAgLmZpbHRlcihvcHRpb24gPT4gKGZpbHRlcnMgfHwgW10pLm1hcChvID0+IG8ubGFiZWwpLmluY2x1ZGVzKG9wdGlvbi5vcHRpb24ubGFiZWwpKVxuICAgICAgLmZpbHRlcigoKSA9PiB7XG4gICAgICAgIC8vIG9ubHkgZmlyc3Qgb3B0aW9uIHBhc3NlZCB3aWxsIGJlIHNldCBpbiBzaW5nbGUgc2VsZWN0aW9uIG1vZGVcbiAgICAgICAgY29uc3QgaW5jbHVkZTogYm9vbGVhbiA9IHRoaXMubXVsdGlwbGUgfHwgIWZpcnN0U2VsZWN0ZWQ7XG4gICAgICAgIGlmIChpbmNsdWRlKSB7XG4gICAgICAgICAgZmlyc3RTZWxlY3RlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gaW5jbHVkZTtcbiAgICAgIH0pXG4gICAgICAuZm9yRWFjaChvcHRpb24gPT4gKG9wdGlvbi5zZWxlY3RlZCA9IHRydWUpKTtcblxuICAgIHRoaXMuaXNBbGxCdXR0b25TZWxlY3RlZCA9ICEoZmlsdGVycyAmJiBmaWx0ZXJzLmxlbmd0aCk7XG5cbiAgICBpZiAoZW1pdCkge1xuICAgICAgdGhpcy5lbWl0U2VsZWN0ZWRPcHRpb25zKCk7XG4gICAgfVxuICB9XG5cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5yZW1vdmVGaWx0ZXIoKTtcbiAgfVxuXG4gIGFjdGl2ZUZpbHRlcnMoKTogT3BlcmF0aW9uU3RhdHVzT3B0aW9uW10ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1c09wdGlvbnMuZmlsdGVyKG9wdGlvbiA9PiBvcHRpb24uc2VsZWN0ZWQpLm1hcChvcHRpb24gPT4gb3B0aW9uLm9wdGlvbik7XG4gIH1cblxuICBpc0ZpbHRlckFwcGxpZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzT3B0aW9ucy5zb21lKG9wdGlvbiA9PiBvcHRpb24uc2VsZWN0ZWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0U2VsZWN0ZWRPcHRpb25zKCkge1xuICAgIHRoaXMub25GaWx0ZXJDaGFuZ2VkLmVtaXQoXG4gICAgICB0aGlzLnN0YXR1c09wdGlvbnMuZmlsdGVyKG9wdGlvbiA9PiBvcHRpb24uc2VsZWN0ZWQpLm1hcChvcHRpb24gPT4gb3B0aW9uLm9wdGlvbilcbiAgICApO1xuICB9XG59XG4iLCI8ZGl2IGRyb3Bkb3duIHBsYWNlbWVudD1cImJvdHRvbSBsZWZ0XCIgY2xhc3M9XCJkcm9wZG93biBjOHktY2hpbGQtYXNzZXRzLXNlbGVjdG9yXCI+XG4gIDxidXR0b25cbiAgICBjbGFzcz1cImJ0biBkcm9wZG93bi10b2dnbGUgZC1mbGV4IGEtaS1jZW50ZXIgYzh5LWRyb3Bkb3duXCJcbiAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICB0aXRsZT1cInt7ICdTdGF0dXMgZmlsdGVyJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgZHJvcGRvd25Ub2dnbGVcbiAgPlxuICAgIDxzcGFuICpuZ0Zvcj1cImxldCBvcHRpb24gb2Ygc3RhdHVzT3B0aW9uc1wiIGNsYXNzPVwiZC1jb250ZW50c1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCIgKm5nSWY9XCJvcHRpb24uc2VsZWN0ZWRcIj5cbiAgICAgICAgPGkgW2M4eUljb25dPVwib3B0aW9uLm9wdGlvbi5pY29uXCIgW25nQ2xhc3NdPVwib3B0aW9uLm9wdGlvbi5zdHlsZUNsYXNzXCI+PC9pPlxuICAgICAgICA8c3BhbiBjbGFzcz1cIm0tbC00XCI+e3sgb3B0aW9uLm9wdGlvbi5sYWJlbCB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgIDwvc3Bhbj5cbiAgICA8L3NwYW4+XG4gICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCIgKm5nSWY9XCJpc0FsbEJ1dHRvblNlbGVjdGVkXCI+XG4gICAgICA8aSBjOHlJY29uPVwiYzh5LWVuZXJneVwiIGNsYXNzPVwibS1yLTQgdGV4dC1pbmZvXCI+PC9pPlxuICAgICAge3sgJ0FsbCBzdGF0dXNlcycgfCB0cmFuc2xhdGUgfX1cbiAgICA8L3NwYW4+XG4gIDwvYnV0dG9uPlxuICA8dWxcbiAgICBpZD1cImRyb3Bkb3duLXN0YXR1cy1maWx0ZXJcIlxuICAgICpkcm9wZG93bk1lbnVcbiAgICBjbGFzcz1cImRyb3Bkb3duLW1lbnVcIlxuICAgIHJvbGU9XCJtZW51XCJcbiAgICBhcmlhLWxhYmVsbGVkYnk9XCJzdGF0dXMtZmlsdGVyXCJcbiAgPlxuICAgIDxsaSAqbmdGb3I9XCJsZXQgb3B0aW9uIG9mIHN0YXR1c09wdGlvbnNcIiBbbmdDbGFzc109XCJ7IGFjdGl2ZTogb3B0aW9uLnNlbGVjdGVkIH1cIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIFt0aXRsZV09XCJvcHRpb24ub3B0aW9uLmxhYmVsIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgKGNsaWNrKT1cImNoYW5nZUZpbHRlcihvcHRpb24pXCJcbiAgICAgICAgYzh5UHJvZHVjdEV4cGVyaWVuY2VcbiAgICAgICAgaW5oZXJpdFxuICAgICAgICBbYWN0aW9uRGF0YV09XCJ7XG4gICAgICAgICAgYWN0aW9uOiBBQ1RJT05TLkZJTFRFUixcbiAgICAgICAgICBmaWx0ZXJCeTogJ3N0YXR1cycsXG4gICAgICAgICAgZmlsdGVyVmFsdWU6IG9wdGlvbi5vcHRpb24ubGFiZWxcbiAgICAgICAgfVwiXG4gICAgICA+XG4gICAgICAgIDxpIFtjOHlJY29uXT1cIm9wdGlvbi5vcHRpb24uaWNvblwiIFtuZ0NsYXNzXT1cIm9wdGlvbi5vcHRpb24uc3R5bGVDbGFzc1wiPjwvaT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJtLWwtNFwiPnt7IG9wdGlvbi5vcHRpb24ubGFiZWwgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2xpPlxuICAgIDxsaSBbbmdDbGFzc109XCJ7IGFjdGl2ZTogaXNBbGxCdXR0b25TZWxlY3RlZCB9XCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICB0aXRsZT1cInt7ICdBbGwgc3RhdHVzZXMnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgKGNsaWNrKT1cInJlbW92ZUZpbHRlcigpXCJcbiAgICAgICAgYzh5UHJvZHVjdEV4cGVyaWVuY2VcbiAgICAgICAgaW5oZXJpdFxuICAgICAgICBbYWN0aW9uRGF0YV09XCJ7XG4gICAgICAgICAgYWN0aW9uOiBBQ1RJT05TLkZJTFRFUixcbiAgICAgICAgICBmaWx0ZXJCeTogJ3N0YXR1cydcbiAgICAgICAgfVwiXG4gICAgICA+XG4gICAgICAgIDxpIGM4eUljb249XCJjOHktZW5lcmd5XCIgY2xhc3M9XCJtLXItNCB0ZXh0LWluZm9cIj48L2k+XG4gICAgICAgIHt7ICdBbGwgc3RhdHVzZXMnIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2xpPlxuICA8L3VsPlxuPC9kaXY+XG4iXX0=