UNPKG

@firestitch/filter

Version:
710 lines 62.7 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, EventEmitter, Input, ViewChild, ViewEncapsulation, HostListener, ApplicationRef, Injector } from '@angular/core'; import { Location } from '@angular/common'; import { ActivatedRoute, Router } from '@angular/router'; import { FsDocumentScrollService } from '@firestitch/scroll'; import { FsStore } from '@firestitch/store'; import { Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators'; import { isAfter, subMinutes } from 'date-fns'; import { FsFilterConfig } from '../../models/filter-config'; import { objectsAreEquals } from '../../helpers/compare'; import { FilterParams } from '../../models/filter-params'; import { FsFilterOverlayService } from '../../services/filter-overlay.service'; import { ItemType } from '../../enums/item-type.enum'; export class FilterComponent { /** * @param {?} _store * @param {?} _location * @param {?} _route * @param {?} _router * @param {?} _appRef * @param {?} _injector * @param {?} _documentScrollService * @param {?} _filterOverlay */ constructor(_store, _location, _route, _router, _appRef, _injector, _documentScrollService, _filterOverlay) { this._store = _store; this._location = _location; this._route = _route; this._router = _router; this._appRef = _appRef; this._injector = _injector; this._documentScrollService = _documentScrollService; this._filterOverlay = _filterOverlay; this._config = null; this.sortUpdate = null; this.showSortBy = true; this.showFilterInput = true; this.changedFilters = []; this.searchText = ''; this.persists = null; this.activeFiltersCount = 0; this.activeFiltersWithInputCount = 0; this.showFilterMenu = false; this.modelChanged = new EventEmitter(); this.windowDesktop = false; this._searchTextInput = null; this._firstOpen = true; this._sort = {}; this._destroy$ = new Subject(); this.updateWindowWidth(); this._filterOverlay.attach$ .pipe(takeUntil(this._destroy$)) .subscribe((/** * @return {?} */ () => { this.showFilterMenu = true; })); this._filterOverlay.detach$ .pipe(takeUntil(this._destroy$)) .subscribe((/** * @return {?} */ () => { this.updateFilledCounter(); this.showFilterMenu = false; })); } /** * @param {?} config * @return {?} */ set setConfig(config) { this.config = config; } /** * @param {?} config * @return {?} */ set setFilter(config) { this.config = config; } /** * @param {?} event * @return {?} */ keyEvent(event) { if (event.code === 'Escape' && this.showFilterMenu) { this.changeVisibility(false); } } /** * @return {?} */ updateWindowWidth() { this.windowDesktop = window.innerWidth > 1200; } /** * @param {?} value * @return {?} */ set searchTextInput(value) { this._searchTextInput = value; } /** * @param {?} config * @return {?} */ set config(config) { this._config = new FsFilterConfig(config); this._restorePersistValues(); this.config.initItems(config.items, this._route, this.persists); this._filterParams = new FilterParams(this._router, this._route, this.config.items); if (this.config.queryParam) { this._filterParams.updateFromQueryParams(this._route.snapshot.queryParams); } this._searchTextItem = this.config.items.find((/** * @param {?} item * @return {?} */ (item) => item.isTypeKeyword)); if (this._searchTextItem) { this.searchText = this._searchTextItem.model; } // Count active filters after restore this.updateFilledCounter(); if (this.config.persist) { this._storePersistValues(); } if (!!this.config.reloadWhenConfigChanged) { this.change(); } } /** * @return {?} */ get config() { return this._config; } /** * @return {?} */ ngOnInit() { // Avoid ngChanges error setTimeout((/** * @return {?} */ () => { this.focus(); })); this._watchSearchInput(); if (this.sortUpdate) { this.sortUpdate .pipe(takeUntil(this.config.destroy$)) .subscribe((/** * @param {?} data * @return {?} */ (data) => { this.config.updateSort(data); })); } if (this.config.init) { this.init(); } } /** * @return {?} */ focus() { if (this._searchTextInput && this.config.autofocus) { this._searchTextInput.nativeElement.focus(); } } /** * @return {?} */ ngOnDestroy() { this._destroyFilterDrawer(); this._destroy$.next(); this._destroy$.complete(); if (this.config) { this.config.destroy(); } } /** * * Do update value of some field * * * To update text value just pass new text value * * public updateSelectValue(val) { * this.filterEl.updateValues({ keyword: val }); * } * * To update select or observable select you could pass suitable value * * public updateSelectValue(val: number) { * this.filterEl.updateValues({ simple_select: val }, { observable_select: val }); * } * * To update checkbox value just pass true/false as value * * public updateCheckox(val: boolean) { * this.filterEl.updateValues({ checkbox: val }); * } * * To update range value just pass object with min&max object or just with one of targets * * Ex.: { min: 10, max 15 }, { min: 5 }, { max 5 } * * public updateRange(val) { * this.filterEl.updateValues({ range: val }); * } * * To update autocomplete just pass object with name/value fields * * Ex.: { name: 'John Doe', value: 1 } * * public updateAutocomplete(val) { * this.filterEl.updateValues({ autocomplete_user_id: val }); * } * * To update autocompletechips just pass: * * 1) object with name/value fields - will be appended to existing set of values * * { name: 'John Doe', value: 1 } * * 2) array of objects - will be appended to existing set of values * * [{ name: 'John Doe', value: 1 }, { name: 'Darya Filipova', value: 2 }] * * 3) null - clear existing set of values * * public updateAutocomplete(val) { * this.filterEl.updateValues({ autocompletechips_user_id: val }); * } * * @param {?} values * @param {?=} changeEvent * @return {?} */ updateValues(values, changeEvent = true) { Object.keys(values).forEach((/** * @param {?} key * @return {?} */ (key) => { /** @type {?} */ const filterItem = this.config.items.find((/** * @param {?} item * @return {?} */ (item) => item.name === key)); if (!filterItem) { return; } filterItem.updateValue(values[key]); })); this.updateFilledCounter(); if (changeEvent) { this._filterChange(); } } /** * @param {?} text * @return {?} */ modelChange(text) { this.modelChanged.next(text); } /** * @return {?} */ hide() { this.changeVisibility(false); } /** * @return {?} */ show() { this.changeVisibility(true); } /** * @param {?} value * @param {?=} event * @return {?} */ changeVisibilityClick(value, event = null) { if (event) { event.stopPropagation(); } this.changeVisibility(value); } /** * @param {?} event * @return {?} */ filterInputEvent(event) { if (!this.windowDesktop) { return; } if (['Enter', 'NumpadEnter', 'Escape'].indexOf(event.code) >= 0) { this.changeVisibility(false); if (this._searchTextInput) { this._searchTextInput.nativeElement.blur(); } } else { this.changeVisibility(true); } } /** * @param {?} state * @return {?} */ changeVisibility(state) { if (state === this.showFilterMenu) { return; } if (!state) { return this._destroyFilterDrawer(); } /** @type {?} */ const notTextItem = this.config.items.find((/** * @param {?} item * @return {?} */ (item) => { return item.type !== ItemType.Keyword; })); if (!notTextItem) { return; } this._filterOverlay.open(this._injector, { items: this.config.items, showSortBy: 'showSortBy', sortBy: this.config.sortByItem, sortDirection: this.config.sortDirectionItem, filterChanged: this._filterChange.bind(this), search: this.search.bind(this), done: this.hide.bind(this), clear: this.clear.bind(this) }); if (this._firstOpen) { this.config.loadValuesForPendingItems(); this._firstOpen = false; } } /** * @param {?} event * @return {?} */ clearSearchText(event) { event.stopPropagation(); this.searchText = ''; this.modelChanged.next(''); } /** * @return {?} */ init() { /** @type {?} */ const data = this._filterParams.getFlattenedParams(); this._sort = this.config.getSort(); this.config.init(data, this.config.getSort()); } /** * @param {?=} event * @return {?} */ clear(event = null) { if (event) { event.stopPropagation(); } this.searchText = ''; this.changedFilters = []; this.config.filtersClear(); this.activeFiltersCount = 0; this.activeFiltersWithInputCount = 0; this._filterChange(); this.changeVisibility(false); } /** * Close filter window and do change callback * @param {?} event * @return {?} */ search(event) { this.changeVisibilityClick(false, event); this._filterChange(); } /** * @param {?=} event * @return {?} */ reload(event = null) { if (event) { event.stopPropagation(); } /** @type {?} */ const data = this._filterParams.getFlattenedParams(); if (this.config.reload) { this.config.reload(data, this.config.getSort()); } } /** * Reset filter * @param {?} event * @return {?} */ resetFilter(event) { /** @type {?} */ const item = event.item; /** @type {?} */ const type = event.type; /** @type {?} */ const index = this.changedFilters.indexOf(item); if (index > -1) { if (type) { item.partialClear(type); if (!item.valueChanged) { this.changedFilters.splice(index, 1); } } else { this.changedFilters.splice(index, 1); item.clear(); } } this.change(); } /** * Call change callback and apply new filter values * @return {?} */ change() { this.config.updateModelValues(); /** @type {?} */ const data = this._filterParams.getFlattenedParams(); /** @type {?} */ const sort = this.config.getSort(); /** @type {?} */ const sortingChanged = ((!sort || !this._sort) && sort !== this._sort) || (sort && this._sort && !objectsAreEquals(this._sort, sort)); if (sortingChanged) { this._sort = sort; if (this.config.sortChange) { this.config.sortChange(data, sort); } } // This should be an option or a done with an wrapping helper function // because it restricts functionality ie. reload // const queryChanged = !objectsAreEquals(this._query, query); // if (queryChanged) { this._storePersistValues(); this.updateFilledCounter(); if (this.config.change) { this.config.change(data, sort); } if (this.config.queryParam) { this._filterParams.updateQueryParams(); } } /** * Do update count of filled filters * @private * @return {?} */ updateFilledCounter() { this.changedFilters = this.config.getFilledItems(); this.changedFilters .filter((/** * @param {?} item * @return {?} */ (item) => item.hasPendingValues)) .forEach((/** * @param {?} item * @return {?} */ (item) => item.loadValues(false))); this.activeFiltersWithInputCount = this.changedFilters .filter((/** * @param {?} item * @return {?} */ (item) => item.type !== ItemType.Keyword)) .length; } /** * Store updated filter data into localstorage * @private * @param {?=} changedItem * @return {?} */ _filterChange(changedItem = null) { if (changedItem) { changedItem.checkIfValueChanged(); } this._storePersistValues(); this.change(); } /** * @private * @return {?} */ _destroyFilterDrawer() { this._filterOverlay.close(); } /** * @private * @return {?} */ _watchSearchInput() { this.modelChanged .pipe(distinctUntilChanged(), debounceTime(500), takeUntil(this.config.destroy$)) .subscribe((/** * @param {?} value * @return {?} */ (value) => { if (this._searchTextItem) { this._searchTextItem.model = value; } this._filterChange(); })); } /** * Restoring values from local storage * @private * @return {?} */ _restorePersistValues() { this.persists = this._store.get(this.config.namespace + '-persist', {}); if (this.persists === undefined) { this.persists = {}; } if (this.config.persist) { if (typeof this.config.persist.persist !== 'object') { this.config.persist = { name: this.config.persist }; } if (!this.config.persist.name) { this.config.persist.name = this._location.path(); } if (!this.persists[this.config.persist.name] || !this.persists[this.config.persist.name].data) { this.persists[this.config.persist.name] = { data: {}, date: new Date() }; } if (this.config.persist.timeout) { /** @type {?} */ const date = new Date(this.persists[this.config.persist.name].date); if (isAfter(subMinutes(date, this.config.persist.timeout), new Date())) { this.persists[this.config.persist.name] = { data: {}, date: new Date() }; } } } } /** * Store values to local storage * @private * @return {?} */ _storePersistValues() { if (this.config.persist) { this.persists[this.config.persist.name] = { data: this._filterParams.getValues(), date: new Date() }; this._store.set(this.config.namespace + '-persist', this.persists, {}); } } } FilterComponent.decorators = [ { type: Component, args: [{ selector: 'fs-filter', template: "<div class=\"fs-filter\"\n *ngIf=\"config?.items?.length\"\n [ngClass]=\"{\n 'filters-open': showFilterMenu,\n 'no-input': !showFilterInput,\n 'window-desktop': windowDesktop,\n 'keyword-filter': config.keywordFilter\n }\">\n <div fxLayou=\"row\" fxLayoutAlign=\"start center\" class=\"menu-filter\" fxFlex=\"1 1 0\">\n <div class=\"menu-filter-input\" fxFlex=\"grow\">\n <div class=\"main-filter-bar\" fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <form autocomplete=\"off\" role=\"presentation\">\n <mat-form-field\n class=\"filter-input-field\"\n (click)=\"($event)\"\n floatLabel=\"never\">\n <span matPrefix>\n <mat-icon\n matPrefix\n (click)=\"changeVisibilityClick(true, $event)\">search</mat-icon>\n </span>\n\n <input matInput\n [(ngModel)]=\"searchText\"\n name=\"filter-input\"\n #searchTextInput\n (keydown)=\"filterInputEvent($event)\"\n (click)=\"filterInputEvent($event)\"\n class=\"filter-input\"\n (ngModelChange)=\"modelChange(searchText)\">\n\n <mat-placeholder>Search</mat-placeholder>\n <a matSuffix\n *ngIf=\"searchText && showFilterInput\"\n (click)=\"clearSearchText($event)\"\n href=\"javascript:void(0)\"\n class=\"clear\">\n <mat-icon>clear</mat-icon>\n </a>\n <a matSuffix\n (click)=\"reload($event)\"\n href=\"javascript:void(0)\"\n class=\"reload\"\n *ngIf=\"config.reload\">\n <mat-icon>refresh</mat-icon>\n </a>\n <!-- <a (click)=\"changeVisibilityClick(true, $event)\"\n matSuffix\n href=\"javascript:void(0)\"\n class=\"filter\"\n *ngIf=\"config.nonKeywordFilters\">\n <mat-icon>filter_list</mat-icon>\n </a>\n <span class=\"active-filters-counter\"\n matSuffix\n (click)=\"changeVisibilityClick(true,$event)\"\n *ngIf=\"!config.chips && activeFiltersCount > 0\">\n {{ activeFiltersCount }}\n </span>\n <span class=\"active-filters-counter\"\n matSuffix\n (click)=\"changeVisibilityClick(true,$event)\"\n *ngIf=\"!config.chips && activeFiltersWithInputCount > 0\">\n {{ activeFiltersWithInputCount }}\n </span> -->\n </mat-form-field>\n </form>\n </div>\n </div>\n <div class=\"filter-actions\">\n <button (click)=\"changeVisibilityClick(true, $event)\"\n mat-raised-button\n class=\"filter\">\n <mat-icon>tune</mat-icon>\n FILTER\n </button>\n </div>\n </div>\n\n <fs-filter-chips\n class=\"filter-chips\"\n *ngIf=\"config.chips\"\n [filters]=\"changedFilters\"\n (remove)=\"resetFilter($event)\"\n [ngClass]=\"{ 'has-filter-chips': activeFiltersWithInputCount }\">\n </fs-filter-chips>\n</div>\n", encapsulation: ViewEncapsulation.None, providers: [ FsFilterOverlayService, ], styles: [".fs-filter{flex-direction:column;box-sizing:border-box;place-content:stretch flex-start;align-items:stretch;max-width:100%;position:relative;margin-bottom:20px}.fs-filter .title{display:none}.fs-filter.no-input .filter-input-field .mat-input-infix,.fs-filter.no-input .filter-input-field .mat-input-prefix,.fs-filter.no-input .filter-input-field .mat-input-underline{display:none!important}.fs-filter .results{min-height:90px;position:relative;overflow-x:auto;overflow-y:hidden}.fs-filter .status{position:relative}.fs-filter .status .progress-infinite{position:absolute;top:0;width:100%}.fs-filter .filter-chips{display:block}.fs-filter .menu-filter{position:relative}.fs-filter .menu-filter .search{top:8px;position:absolute;margin-left:1px;left:0}.fs-filter .menu-filter .search mat-icon{-webkit-transform:scale(.9);transform:scale(.9)}.fs-filter .menu-filter .menu-filter-input{width:100%}.fs-filter .menu-filter .menu-filter-input .main-filter-bar{height:40px}.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-input-infix{padding-bottom:.3em}.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-prefix,.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-suffix{align-self:flex-end;display:flex;align-items:center;white-space:nowrap}.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-prefix a,.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-prefix mat-icon,.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-suffix a,.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-suffix mat-icon{cursor:pointer;color:initial}.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-prefix a:hover,.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-prefix mat-icon:hover,.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-suffix a:hover,.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-suffix mat-icon:hover{color:inherit}.fs-filter .menu-filter .menu-filter-input .main-filter-bar .mat-form-field-infix{width:auto}.fs-filter .infinite-records{color:#999;font-size:13px;margin-left:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}.fs-filter .infinite-records .order-toggle{cursor:pointer;padding-left:4px}.fs-filter.keyword-filter .filter-input-field .filter{display:none}.fs-filter.keyword-filter .filter-input-field .mat-form-field-infix,.fs-filter.keyword-filter .filter-input-field .mat-form-field-prefix,.fs-filter.keyword-filter .filter-input-field .mat-form-field-underline{visibility:visible}.main-filter-bar{overflow:hidden}.main-filter-bar .filter-input-field,.main-filter-bar form{width:100%}.main-filter-bar .filter-input-field .mat-form-field-infix,.main-filter-bar .filter-input-field .mat-form-field-prefix,.main-filter-bar .filter-input-field .mat-form-field-underline{visibility:hidden}.main-filter-bar .filter-input-field .mat-form-field-underline{bottom:auto}.main-filter-bar .filter-input-field .mat-form-field-infix{border-top:0}.main-filter-bar .filter-input-field .mat-form-field-wrapper{padding-bottom:0}.main-filter-bar .filter-input-field .mat-form-field-flex{align-items:center}.active-filters-counter{min-width:22px;line-height:22px;height:22px;-webkit-transform:scale(.65);transform:scale(.65);font-size:116%;margin-left:-2px;background:#ccc;border-radius:50%;text-align:center;padding:3px;color:#fff;cursor:pointer}.active-filters-counter.with-input{display:none}button.filter{margin-left:10px}button.reload{margin-left:-40px;right:-9px}@media screen and (max-width:1199px){.fs-filter .reload{display:none}.main-filter-bar .filter-input-field .filter{display:block!important}}@media screen and (min-width:1200px){button.filter{display:none}body.fs-filter-open{margin-right:350px}.fs-filter-backdrop{display:none}}body.fs-filter-open::-webkit-scrollbar{width:0;background:0 0}"] }] } ]; /** @nocollapse */ FilterComponent.ctorParameters = () => [ { type: FsStore }, { type: Location }, { type: ActivatedRoute }, { type: Router }, { type: ApplicationRef }, { type: Injector }, { type: FsDocumentScrollService }, { type: FsFilterOverlayService } ]; FilterComponent.propDecorators = { setConfig: [{ type: Input, args: ['config',] }], setFilter: [{ type: Input, args: ['filter',] }], sortUpdate: [{ type: Input }], showSortBy: [{ type: Input }], showFilterInput: [{ type: Input }], keyEvent: [{ type: HostListener, args: ['window:keyup', ['$event'],] }], updateWindowWidth: [{ type: HostListener, args: ['window:resize',] }], searchTextInput: [{ type: ViewChild, args: ['searchTextInput',] }] }; if (false) { /** * @type {?} * @protected */ FilterComponent.prototype._config; /** @type {?} */ FilterComponent.prototype.sortUpdate; /** @type {?} */ FilterComponent.prototype.showSortBy; /** @type {?} */ FilterComponent.prototype.showFilterInput; /** @type {?} */ FilterComponent.prototype.changedFilters; /** @type {?} */ FilterComponent.prototype.searchText; /** @type {?} */ FilterComponent.prototype.persists; /** @type {?} */ FilterComponent.prototype.activeFiltersCount; /** @type {?} */ FilterComponent.prototype.activeFiltersWithInputCount; /** @type {?} */ FilterComponent.prototype.showFilterMenu; /** @type {?} */ FilterComponent.prototype.modelChanged; /** @type {?} */ FilterComponent.prototype.windowDesktop; /** * @type {?} * @private */ FilterComponent.prototype._searchTextItem; /** * @type {?} * @private */ FilterComponent.prototype._searchTextInput; /** * @type {?} * @private */ FilterComponent.prototype._firstOpen; /** * @type {?} * @private */ FilterComponent.prototype._filterParams; /** * @type {?} * @private */ FilterComponent.prototype._sort; /** * @type {?} * @private */ FilterComponent.prototype._destroy$; /** * @type {?} * @private */ FilterComponent.prototype._store; /** * @type {?} * @private */ FilterComponent.prototype._location; /** * @type {?} * @private */ FilterComponent.prototype._route; /** * @type {?} * @private */ FilterComponent.prototype._router; /** * @type {?} * @private */ FilterComponent.prototype._appRef; /** * @type {?} * @private */ FilterComponent.prototype._injector; /** * @type {?} * @private */ FilterComponent.prototype._documentScrollService; /** * @type {?} * @private */ FilterComponent.prototype._filterOverlay; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BmaXJlc3RpdGNoL2ZpbHRlci8iLCJzb3VyY2VzIjpbImFwcC9jb21wb25lbnRzL2ZpbHRlci9maWx0ZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsU0FBUyxFQUNULGlCQUFpQixFQUNqQixZQUFZLEVBQ1osY0FBYyxFQUNkLFFBQVEsRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUV6RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRS9DLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUU1RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDMUQsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDL0UsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBWXRELE1BQU0sT0FBTyxlQUFlOzs7Ozs7Ozs7OztJQWlEMUIsWUFDVSxNQUFlLEVBQ2YsU0FBbUIsRUFD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UTtZQUtELHVCQUF1QjtZQVd2QixzQkFBc0I7Ozt3QkFpQjVCLEtBQUssU0FBQyxRQUFRO3dCQUlkLEtBQUssU0FBQyxRQUFRO3lCQUlkLEtBQUs7eUJBQ0wsS0FBSzs4QkFDTCxLQUFLO3VCQUVMLFlBQVksU0FBQyxjQUFjLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0NBT3ZDLFlBQVksU0FBQyxlQUFlOzhCQUs1QixTQUFTLFNBQUMsaUJBQWlCOzs7Ozs7O0lBMUI1QixrQ0FBeUM7O0lBVXpDLHFDQUFxRDs7SUFDckQscUNBQXVDOztJQUN2QywwQ0FBdUM7O0lBbUJ2Qyx5Q0FBMkI7O0lBQzNCLHFDQUF1Qjs7SUFDdkIsbUNBQXVCOztJQUN2Qiw2Q0FBOEI7O0lBQzlCLHNEQUF1Qzs7SUFDdkMseUNBQThCOztJQUM5Qix1Q0FBeUM7O0lBQ3pDLHdDQUE2Qjs7Ozs7SUFFN0IsMENBQTRDOzs7OztJQUM1QywyQ0FBNEM7Ozs7O0lBQzVDLHFDQUEwQjs7Ozs7SUFDMUIsd0NBQW9DOzs7OztJQUNwQyxnQ0FBbUI7Ozs7O0lBQ25CLG9DQUFrQzs7Ozs7SUFHaEMsaUNBQXVCOzs7OztJQUN2QixvQ0FBMkI7Ozs7O0lBQzNCLGlDQUE4Qjs7Ozs7SUFDOUIsa0NBQXVCOzs7OztJQUN2QixrQ0FBK0I7Ozs7O0lBQy9CLG9DQUEyQjs7Ozs7SUFDM0IsaURBQXVEOzs7OztJQUN2RCx5Q0FBOEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBIb3N0TGlzdGVuZXIsXG4gIEFwcGxpY2F0aW9uUmVmLFxuICBJbmplY3RvclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuXG5pbXBvcnQgeyBGc0RvY3VtZW50U2Nyb2xsU2VydmljZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3Njcm9sbCc7XG5pbXBvcnQgeyBGc1N0b3JlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvc3RvcmUnO1xuXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBpc0FmdGVyLCBzdWJNaW51dGVzIH0gZnJvbSAnZGF0ZS1mbnMnO1xuXG5pbXBvcnQgeyBGc0ZpbHRlckNvbmZpZyB9IGZyb20gJy4uLy4uL21vZGVscy9maWx0ZXItY29uZmlnJztcbmltcG9ydCB7IEZzRmlsdGVyQ29uZmlnSXRlbSB9IGZyb20gJy4uLy4uL21vZGVscy9maWx0ZXItaXRlbSc7XG5pbXBvcnQgeyBvYmplY3RzQXJlRXF1YWxzIH0gZnJvbSAnLi4vLi4vaGVscGVycy9jb21wYXJlJztcbmltcG9ydCB7IEZpbHRlclBhcmFtcyB9IGZyb20gJy4uLy4uL21vZGVscy9maWx0ZXItcGFyYW1zJztcbmltcG9ydCB7IEZzRmlsdGVyT3ZlcmxheVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9maWx0ZXItb3ZlcmxheS5zZXJ2aWNlJztcbmltcG9ydCB7IEl0ZW1UeXBlIH0gZnJvbSAnLi4vLi4vZW51bXMvaXRlbS10eXBlLmVudW0nO1xuXG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2ZzLWZpbHRlcicsXG4gIHN0eWxlVXJsczogWyAnLi9maWx0ZXIuY29tcG9uZW50LnNjc3MnIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi9maWx0ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBwcm92aWRlcnM6IFtcbiAgICBGc0ZpbHRlck92ZXJsYXlTZXJ2aWNlLFxuICBdXG59KVxuZXhwb3J0IGNsYXNzIEZpbHRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICBwcm90ZWN0ZWQgX2NvbmZpZzogRnNGaWx0ZXJDb25maWcgPSBudWxsO1xuXG4gIEBJbnB1dCgnY29uZmlnJykgc2V0IHNldENvbmZpZyhjb25maWcpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgfVxuXG4gIEBJbnB1dCgnZmlsdGVyJykgc2V0IHNldEZpbHRlcihjb25maWcpIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgfVxuXG4gIEBJbnB1dCgpIHB1YmxpYyBzb3J0VXBkYXRlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG51bGw7XG4gIEBJbnB1dCgpIHB1YmxpYyBzaG93U29ydEJ5OiBhbnkgPSB0cnVlO1xuICBASW5wdXQoKSBwdWJsaWMgc2hvd0ZpbHRlcklucHV0ID0gdHJ1ZTtcblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5dXAnLCBbJyRldmVudCddKVxuICBrZXlFdmVudChldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgIGlmIChldmVudC5jb2RlID09PSAnRXNjYXBlJyAmJiB0aGlzLnNob3dGaWx0ZXJNZW51KSB7XG4gICAgICB0aGlzLmNoYW5nZVZpc2liaWxpdHkoZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxuICB1cGRhdGVXaW5kb3dXaWR0aCgpIHtcbiAgICB0aGlzLndpbmRvd0Rlc2t0b3AgPSB3aW5kb3cuaW5uZXJXaWR0aCA+IDEyMDA7XG4gIH1cblxuICBAVmlld0NoaWxkKCdzZWFyY2hUZXh0SW5wdXQnKVxuICBzZXQgc2VhcmNoVGV4dElucHV0KHZhbHVlKSB7XG4gICAgdGhpcy5fc2VhcmNoVGV4dElucHV0ID0gdmFsdWU7XG4gIH1cblxuICBwdWJsaWMgY2hhbmdlZEZpbHRlcnMgPSBbXTtcbiAgcHVibGljIHNlYXJjaFRleHQgPSAnJztcbiAgcHVibGljIHBlcnNpc3RzID0gbnVsbDtcbiAgcHVibGljIGFjdGl2ZUZpbHRlcnNDb3VudCA9IDA7XG4gIHB1YmxpYyBhY3RpdmVGaWx0ZXJzV2l0aElucHV0Q291bnQgPSAwO1xuICBwdWJsaWMgc2hvd0ZpbHRlck1lbnUgPSBmYWxzZTtcbiAgcHVibGljIG1vZGVsQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgcHVibGljIHdpbmRvd0Rlc2t0b3AgPSBmYWxzZTtcblxuICBwcml2YXRlIF9zZWFyY2hUZXh0SXRlbTogRnNGaWx0ZXJDb25maWdJdGVtO1xuICBwcml2YXRlIF9zZWFyY2hUZXh0SW5wdXQ6IEVsZW1lbnRSZWYgPSBudWxsO1xuICBwcml2YXRlIF9maXJzdE9wZW4gPSB0cnVlO1xuICBwcml2YXRlIF9maWx0ZXJQYXJhbXM6IEZpbHRlclBhcmFtcztcbiAgcHJpdmF0ZSBfc29ydCA9IHt9O1xuICBwcml2YXRlIF9kZXN0cm95JCA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBfc3RvcmU6IEZzU3RvcmUsXG4gICAgcHJpdmF0ZSBfbG9jYXRpb246IExvY2F0aW9uLFxuICAgIHByaXZhdGUgX3JvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICBwcml2YXRlIF9yb3V0ZXI6IFJvdXRlcixcbiAgICBwcml2YXRlIF9hcHBSZWY6IEFwcGxpY2F0aW9uUmVmLFxuICAgIHByaXZhdGUgX2luamVjdG9yOiBJbmplY3RvcixcbiAgICBwcml2YXRlIF9kb2N1bWVudFNjcm9sbFNlcnZpY2U6IEZzRG9jdW1lbnRTY3JvbGxTZXJ2aWNlLFxuICAgIHByaXZhdGUgX2ZpbHRlck92ZXJsYXk6IEZzRmlsdGVyT3ZlcmxheVNlcnZpY2UsXG4gICkge1xuICAgIHRoaXMudXBkYXRlV2luZG93V2lkdGgoKTtcblxuICAgIHRoaXMuX2ZpbHRlck92ZXJsYXkuYXR0YWNoJFxuICAgIC5waXBlKFxuICAgICB0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpXG4gICAgKVxuICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy5zaG93RmlsdGVyTWVudSA9IHRydWU7XG4gICAgfSk7XG5cbiAgICB0aGlzLl9maWx0ZXJPdmVybGF5LmRldGFjaCRcbiAgICAucGlwZShcbiAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JClcbiAgICApXG4gICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZUZpbGxlZENvdW50ZXIoKTtcbiAgICAgIHRoaXMuc2hvd0ZpbHRlck1lbnUgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzZXQgY29uZmlnKGNvbmZpZykge1xuICAgIHRoaXMuX2NvbmZpZyA9IG5ldyBGc0ZpbHRlckNvbmZpZyhjb25maWcpO1xuICAgIHRoaXMuX3Jlc3RvcmVQZXJzaXN0VmFsdWVzKCk7XG4gICAgdGhpcy5jb25maWcuaW5pdEl0ZW1zKGNvbmZpZy5pdGVtcywgdGhpcy5fcm91dGUsIHRoaXMucGVyc2lzdHMpO1xuXG4gICAgdGhpcy5fZmlsdGVyUGFyYW1zID0gbmV3IEZpbHRlclBhcmFtcyh0aGlzLl9yb3V0ZXIsIHRoaXMuX3JvdXRlLCB0aGlzLmNvbmZpZy5pdGVtcyk7XG4gICAgaWYgKHRoaXMuY29uZmlnLnF1ZXJ5UGFyYW0pIHtcbiAgICAgIHRoaXMuX2ZpbHRlclBhcmFtcy51cGRhdGVGcm9tUXVlcnlQYXJhbXModGhpcy5fcm91dGUuc25hcHNob3QucXVlcnlQYXJhbXMpO1xuICAgIH1cblxuICAgIHRoaXMuX3NlYXJjaFRleHRJdGVtID0gdGhpcy5jb25maWcuaXRlbXMuZmluZCgoaXRlbSkgPT4gaXRlbS5pc1R5cGVLZXl3b3JkKTtcbiAgICBpZiAodGhpcy5fc2VhcmNoVGV4dEl0ZW0pIHtcbiAgICAgIHRoaXMuc2VhcmNoVGV4dCA9IHRoaXMuX3NlYXJjaFRleHRJdGVtLm1vZGVsO1xuICAgIH1cblxuICAgIC8vIENvdW50IGFjdGl2ZSBmaWx0ZXJzIGFmdGVyIHJlc3RvcmVcbiAgICB0aGlzLnVwZGF0ZUZpbGxlZENvdW50ZXIoKTtcblxuICAgIGlmICh0aGlzLmNvbmZpZy5wZXJzaXN0KSB7XG4gICAgICB0aGlzLl9zdG9yZVBlcnNpc3RWYWx1ZXMoKTtcbiAgICB9XG5cbiAgICBpZiAoISF0aGlzLmNvbmZpZy5yZWxvYWRXaGVuQ29uZmlnQ2hhbmdlZCkge1xuICAgICAgdGhpcy5jaGFuZ2UoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0IGNvbmZpZygpIHtcbiAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICB9XG5cbiAgcHVibGljIG5nT25Jbml0KCkge1xuXG4gICAgLy8gQXZvaWQgbmdDaGFuZ2VzIGVycm9yXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmZvY3VzKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLl93YXRjaFNlYXJjaElucHV0KCk7XG5cbiAgICBpZiAodGhpcy5zb3J0VXBkYXRlKSB7XG4gICAgICB0aGlzLnNvcnRVcGRhdGVc