@vendasta/store
Version:
Components and data for Store
184 lines • 34.2 kB
JavaScript
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, startWith, filter, take, skip } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
import { Filters, FilterSection, TabbedFilterField, CheckboxFilterField, FilterService, } from '@vendasta/uikit';
import { ProductAnalyticsService } from '@vendasta/product-analytics';
import { LMI_CATEGORIES } from '../lmi-categories';
import { Categories, ShoppingCartItemType } from '@vendasta/marketplace-packages';
import * as i0 from "@angular/core";
import * as i1 from "@vendasta/uikit";
import * as i2 from "@vendasta/product-analytics";
import * as i3 from "@ngx-translate/core";
import * as i4 from "../store.component";
import * as i5 from "@angular/common";
export const STOREFRONT_FILTER_NAME = 'Store Filters';
export class StorefrontComponent {
constructor(filterService, snowplowService, translateService) {
this.filterService = filterService;
this.snowplowService = snowplowService;
this.translateService = translateService;
this.useCustomCase = false;
this.showFilters = true;
this.initialFilteredStoreItems = null;
this.showAllPrices = false;
this.filtersDisabled = false;
this.categorySelected = new EventEmitter();
this.productSelected = new EventEmitter();
this.getDataForCategory = new EventEmitter();
this.categories$$ = new BehaviorSubject([]);
this.packagesMap$$ = new BehaviorSubject(new Map());
this.searchTerm$$ = new BehaviorSubject('');
this.selectedCateoryId$$ = new BehaviorSubject('');
this.filterByInitialStoreItemIds$$ = new BehaviorSubject(false);
}
set categories(value) {
this.categories$$.next(value || []);
}
set categoryIdToStoreItemListMap(value) {
this.packagesMap$$.next(value || new Map());
}
ngOnInit() {
this.filterByInitialStoreItemIds$$.next(!!this.initialFilteredStoreItems && !!this.initialFilteredStoreItems.storeItemIds
? this.initialFilteredStoreItems.storeItemIds.length > 0
: false);
const lmiCategoryCheckboxList = LMI_CATEGORIES.map((category) => {
return new CheckboxFilterField({
name: this.translateService.instant(category.i18nKey),
id: category.categoryId,
value: false,
condition: (item) => {
let lmiCategories = [];
if (item.lmiCategories) {
lmiCategories = item.lmiCategories.map((cat) => {
return Categories[cat].toLowerCase();
});
}
return lmiCategories.indexOf(category.categoryId) > -1;
},
});
});
const lmiCategoryFilterSection = new FilterSection({
title: 'FRONTEND.STORE.STOREFRONT_FILTERS.LMI_CATEGORY',
type: 'or',
fields: lmiCategoryCheckboxList,
});
this.lmiCategoryFilter = new Filters(STOREFRONT_FILTER_NAME, [lmiCategoryFilterSection]);
const packageIdsCheckbox = new CheckboxFilterField({
name: !!this.initialFilteredStoreItems ? this.initialFilteredStoreItems.filterName : '',
id: 'package_id_checkbox',
value: !!this.initialFilteredStoreItems && !!this.initialFilteredStoreItems.storeItemIds
? this.initialFilteredStoreItems.storeItemIds.length > 0
: false,
});
const packageIdsFilterSection = new FilterSection({
title: 'Store item IDs',
type: 'and',
fields: [packageIdsCheckbox],
});
packageIdsFilterSection.hideSelectors = true;
this.filters$ = this.categories$$.pipe(map((categories) => {
const tabbedFilterField = new TabbedFilterField({
name: '',
value: null,
id: 'categorytab',
options: categories,
});
const filters = new Filters('FRONTEND.STORE.STOREFRONT_FILTERS.TITLE', [
new FilterSection({
title: 'FRONTEND.STORE.STOREFRONT_FILTERS.CATEGORIES',
type: 'or',
fields: [tabbedFilterField],
}),
lmiCategoryFilterSection,
packageIdsFilterSection,
]);
filters.id = STOREFRONT_FILTER_NAME.toLowerCase().replace(' ', '_');
return this.showFilters ? filters : null;
}));
this.filterService.setFilters(this.lmiCategoryFilter);
this.searchTermSubscription = this.searchTerm$$
.asObservable()
.pipe(debounceTime(300), distinctUntilChanged(), skip(1))
.subscribe((searchTerm) => this.snowplowService.trackClick('store', 'search-input', searchTerm));
const selectedLMIFilters$ = this.filterService.filters.fieldValuesObservable.pipe(startWith([]), map(() => {
return this.lmiCategoryFilter.fields.filter((item) => item.value);
}));
this.showLMIFilter$ = selectedLMIFilters$.pipe(filter((selectedLMIFilters) => !!selectedLMIFilters), take(1), map((selectedLMIFilters) => selectedLMIFilters.length > 0));
this.filteredItems$ = combineLatest([
this.packagesMap$$,
this.searchTerm$$,
this.selectedCateoryId$$,
selectedLMIFilters$,
this.filterByInitialStoreItemIds$$,
]).pipe(map(([packages, searchTerm, selectedCategoryId, selectedLMIFilters, filterByInitialStoreItemIds]) => {
let storeItems = [];
if (packages.size) {
storeItems = selectedCategoryId
? packages.get(selectedCategoryId)
: packages.get(Array.from(packages.keys())[0]);
}
storeItems = storeItems ? this.lmiCategoryFilter.applyFilters(storeItems) : [];
if (filterByInitialStoreItemIds) {
storeItems = storeItems.filter((storeItem) => this.initialFilteredStoreItems.storeItemIds.includes(storeItem.id));
}
return searchTerm
? storeItems.filter((item) => item?.name?.toLowerCase().indexOf(searchTerm.toLowerCase()) !== -1)
: storeItems;
}));
}
ngOnDestroy() {
this.searchTermSubscription.unsubscribe();
}
onSearchTermChanged(term) {
this.searchTerm$$.next(term);
}
onFieldValueChanged(filterField) {
this.snowplowService.trackClick('store', 'tab-filter', filterField.value.id);
if (filterField.id === 'package_id_checkbox') {
this.filterByInitialStoreItemIds$$.next(filterField.value);
return;
}
if (!(filterField instanceof TabbedFilterField)) {
return;
}
this.selectedCateoryId$$.next(filterField.value.id);
this.categorySelected.emit(filterField.value);
const currentStoreItemsForSelectCategory = this.packagesMap$$.getValue().get(filterField.value.id);
if (!(currentStoreItemsForSelectCategory && currentStoreItemsForSelectCategory.length)) {
this.getDataForCategory.emit(filterField.value);
}
}
storeItemClicked(item) {
const label = item.type === ShoppingCartItemType.SHOPPING_CART_ITEM_TYPE_PRODUCT ? 'view-app' : 'view-package';
this.snowplowService.trackClick('store', label, item.id);
this.productSelected.emit({ id: item.id, type: item.type });
}
}
StorefrontComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: StorefrontComponent, deps: [{ token: i1.FilterService }, { token: i2.ProductAnalyticsService }, { token: i3.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
StorefrontComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.2", type: StorefrontComponent, selector: "app-storefront", inputs: { categories: "categories", categoryIdToStoreItemListMap: "categoryIdToStoreItemListMap", useCustomCase: "useCustomCase", showFilters: "showFilters", initialFilteredStoreItems: "initialFilteredStoreItems", showAllPrices: "showAllPrices", filtersDisabled: "filtersDisabled" }, outputs: { categorySelected: "categorySelected", productSelected: "productSelected", getDataForCategory: "getDataForCategory" }, ngImport: i0, template: "<va-filter-container\n [filters]=\"filters$ | async\"\n (searchTermChanged)=\"onSearchTermChanged($event)\"\n (fieldValueChanged)=\"onFieldValueChanged($event)\"\n [theme]=\"'plain'\"\n [filterIsOpen]=\"showLMIFilter$ | async\"\n [useCustomCase]=\"useCustomCase\"\n [filtersDisabled]=\"filtersDisabled\"\n>\n <app-store\n [items]=\"filteredItems$ | async\"\n [searchable]=\"false\"\n (itemClicked)=\"storeItemClicked($event)\"\n [showAllPrices]=\"showAllPrices\"\n content\n ></app-store>\n</va-filter-container>\n", styles: [".public-store-container{padding:20px}app-store{margin-top:20px;display:block}:host ::ng-deep .filter-wrapper:not(.hide)+.content-container{padding-left:20px}::ng-deep .toolbar ::ng-deep div.table-controls-row .filter-button.disabled{display:none}@media only screen and (device-width: 375px) and (-webkit-device-pixel-ratio: 2){::ng-deep va-filter-tabbed{width:280px}::ng-deep .filter-container .toolbar.toolbar{background:none}}@media only screen and (device-width: 414px) and (-webkit-device-pixel-ratio: 3){::ng-deep va-filter-tabbed{width:280px}::ng-deep .filter-container .toolbar.toolbar{background:none}}\n"], components: [{ type: i1.FilterContainerComponent, selector: "va-filter-container", inputs: ["showFilterSharing", "searchable", "toolbarText", "showToolbar", "searchDisabled", "filtersDisabled", "filterIsOpen", "filters", "savedFilters", "theme", "useCustomCase", "enabledSaveSearchTerm", "contextKey"], outputs: ["searchTermChanged", "fieldValueChanged", "savedFilterSelected", "removeSavedFilter", "saveCurrentFilter", "exportFilterDialog", "importFilterDialog"] }, { type: i4.StoreComponent, selector: "app-store", inputs: ["items", "showAllPrices", "searchable"], outputs: ["itemClicked"] }], pipes: { "async": i5.AsyncPipe } });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.2", ngImport: i0, type: StorefrontComponent, decorators: [{
type: Component,
args: [{ selector: 'app-storefront', template: "<va-filter-container\n [filters]=\"filters$ | async\"\n (searchTermChanged)=\"onSearchTermChanged($event)\"\n (fieldValueChanged)=\"onFieldValueChanged($event)\"\n [theme]=\"'plain'\"\n [filterIsOpen]=\"showLMIFilter$ | async\"\n [useCustomCase]=\"useCustomCase\"\n [filtersDisabled]=\"filtersDisabled\"\n>\n <app-store\n [items]=\"filteredItems$ | async\"\n [searchable]=\"false\"\n (itemClicked)=\"storeItemClicked($event)\"\n [showAllPrices]=\"showAllPrices\"\n content\n ></app-store>\n</va-filter-container>\n", styles: [".public-store-container{padding:20px}app-store{margin-top:20px;display:block}:host ::ng-deep .filter-wrapper:not(.hide)+.content-container{padding-left:20px}::ng-deep .toolbar ::ng-deep div.table-controls-row .filter-button.disabled{display:none}@media only screen and (device-width: 375px) and (-webkit-device-pixel-ratio: 2){::ng-deep va-filter-tabbed{width:280px}::ng-deep .filter-container .toolbar.toolbar{background:none}}@media only screen and (device-width: 414px) and (-webkit-device-pixel-ratio: 3){::ng-deep va-filter-tabbed{width:280px}::ng-deep .filter-container .toolbar.toolbar{background:none}}\n"] }]
}], ctorParameters: function () { return [{ type: i1.FilterService }, { type: i2.ProductAnalyticsService }, { type: i3.TranslateService }]; }, propDecorators: { categories: [{
type: Input
}], categoryIdToStoreItemListMap: [{
type: Input
}], useCustomCase: [{
type: Input
}], showFilters: [{
type: Input
}], initialFilteredStoreItems: [{
type: Input
}], showAllPrices: [{
type: Input
}], filtersDisabled: [{
type: Input
}], categorySelected: [{
type: Output
}], productSelected: [{
type: Output
}], getDataForCategory: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmVmcm9udC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL3N0b3JlL3NyYy9saWIvc3RvcmVmcm9udC9zdG9yZWZyb250LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvc3RvcmUvc3JjL2xpYi9zdG9yZWZyb250L3N0b3JlZnJvbnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUMxRixPQUFPLEVBQUUsZUFBZSxFQUFjLGFBQWEsRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDaEYsT0FBTyxFQUFFLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEcsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFdkQsT0FBTyxFQUNMLE9BQU8sRUFDUCxhQUFhLEVBQ2IsaUJBQWlCLEVBQ2pCLG1CQUFtQixFQUNuQixhQUFhLEdBRWQsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUV0RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLFVBQVUsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7Ozs7O0FBRWxGLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLGVBQWUsQ0FBQztBQWtCdEQsTUFBTSxPQUFPLG1CQUFtQjtJQWtDOUIsWUFDVSxhQUE0QixFQUM1QixlQUF3QyxFQUN4QyxnQkFBa0M7UUFGbEMsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIs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QUksa0NBQWtDLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDdEYsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBMkIsQ0FBQyxDQUFDO1NBQ3ZFO0lBQ0gsQ0FBQztJQUVNLGdCQUFnQixDQUFDLElBQWU7UUFDckMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksS0FBSyxvQkFBb0IsQ0FBQywrQkFBK0IsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUM7UUFDL0csSUFBSSxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDOUQsQ0FBQzs7Z0hBaE1VLG1CQUFtQjtvR0FBbkIsbUJBQW1CLG1kQ3BDaEMsNGhCQWlCQTsyRkRtQmEsbUJBQW1CO2tCQUwvQixTQUFTOytCQUNFLGdCQUFnQjt5S0FNdEIsVUFBVTtzQkFEYixLQUFLO2dCQU1GLDRCQUE0QjtzQkFEL0IsS0FBSztnQkFLRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0cseUJBQXlCO3NCQUFqQyxLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDSSxnQkFBZ0I7c0JBQXpCLE1BQU07Z0JBQ0csZUFBZTtzQkFBeEIsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgY29tYmluZUxhdGVzdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIHN0YXJ0V2l0aCwgZmlsdGVyLCB0YWtlLCBza2lwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuXG5pbXBvcnQge1xuICBGaWx0ZXJzLFxuICBGaWx0ZXJTZWN0aW9uLFxuICBUYWJiZWRGaWx0ZXJGaWVsZCxcbiAgQ2hlY2tib3hGaWx0ZXJGaWVsZCxcbiAgRmlsdGVyU2VydmljZSxcbiAgRmlsdGVyRmllbGQsXG59IGZyb20gJ0B2ZW5kYXN0YS91aWtpdCc7XG5pbXBvcnQgeyBQcm9kdWN0QW5hbHl0aWNzU2VydmljZSB9IGZyb20gJ0B2ZW5kYXN0YS9wcm9kdWN0LWFuYWx5dGljcyc7XG5pbXBvcnQgeyBTdG9yZUl0ZW0sIENhdGVnb3J5VG9JdGVtTGlzdE1hcCB9IGZyb20gJy4uL3N0b3JlLWl0ZW0nO1xuaW1wb3J0IHsgTE1JX0NBVEVHT1JJRVMgfSBmcm9tICcuLi9sbWktY2F0ZWdvcmllcyc7XG5pbXBvcnQgeyBDYXRlZ29yaWVzLCBTaG9wcGluZ0NhcnRJdGVtVHlwZSB9IGZyb20gJ0B2ZW5kYXN0YS9tYXJrZXRwbGFjZS1wYWNrYWdlcyc7XG5cbmV4cG9ydCBjb25zdCBTVE9SRUZST05UX0ZJTFRFUl9OQU1FID0gJ1N0b3JlIEZpbHRlcnMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0b3JlZnJvbnRDYXRlZ29yeSB7XG4gIGlkOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgcGFja2FnZUlkczogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5pdGlhbEZpbHRlcmVkU3RvcmVJdGVtcyB7XG4gIHN0b3JlSXRlbUlkczogc3RyaW5nW107XG4gIGZpbHRlck5hbWU6IHN0cmluZztcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLXN0b3JlZnJvbnQnLFxuICB0ZW1wbGF0ZVVybDogJy4vc3RvcmVmcm9udC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3N0b3JlZnJvbnQuY29tcG9uZW50LnNjc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgU3RvcmVmcm9udENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KClcbiAgc2V0IGNhdGVnb3JpZXModmFsdWU6IFN0b3JlZnJvbnRDYXRlZ29yeVtdKSB7XG4gICAgdGhpcy5jYXRlZ29yaWVzJCQubmV4dCh2YWx1ZSB8fCBbXSk7XG4gIH1cblxuICBASW5wdXQoKVxuICBzZXQgY2F0ZWdvcnlJZFRvU3RvcmVJdGVtTGlzdE1hcCh2YWx1ZTogQ2F0ZWdvcnlUb0l0ZW1MaXN0TWFwKSB7XG4gICAgdGhpcy5wYWNrYWdlc01hcCQkLm5leHQodmFsdWUgfHwgbmV3IE1hcDxzdHJpbmcsIFN0b3JlSXRlbVtdPigpKTtcbiAgfVxuXG4gIEBJbnB1dCgpIHVzZUN1c3RvbUNhc2UgPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd0ZpbHRlcnMgPSB0cnVlO1xuICBASW5wdXQoKSBpbml0aWFsRmlsdGVyZWRTdG9yZUl0ZW1zOiBJbml0aWFsRmlsdGVyZWRTdG9yZUl0ZW1zID0gbnVsbDtcbiAgQElucHV0KCkgc2hvd0FsbFByaWNlcyA9IGZhbHNlO1xuICBASW5wdXQoKSBmaWx0ZXJzRGlzYWJsZWQgPSBmYWxzZTtcbiAgQE91dHB1dCgpIGNhdGVnb3J5U2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPFN0b3JlZnJvbnRDYXRlZ29yeT4oKTtcbiAgQE91dHB1dCgpIHByb2R1Y3RTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8eyBpZDogc3RyaW5nOyB0eXBlOiBTaG9wcGluZ0NhcnRJdGVtVHlwZSB9PigpO1xuICBAT3V0cHV0KCkgZ2V0RGF0YUZvckNhdGVnb3J5ID0gbmV3IEV2ZW50RW1pdHRlcjxTdG9yZWZyb250Q2F0ZWdvcnk+KCk7XG5cbiAgcHJpdmF0ZSBjYXRlZ29yaWVzJCQ6IEJlaGF2aW9yU3ViamVjdDxTdG9yZWZyb250Q2F0ZWdvcnlbXT4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFN0b3JlZnJvbnRDYXRlZ29yeVtdPihbXSk7XG4gIHByaXZhdGUgcGFja2FnZXNNYXAkJDogQmVoYXZpb3JTdWJqZWN0PENhdGVnb3J5VG9JdGVtTGlzdE1hcD4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENhdGVnb3J5VG9JdGVtTGlzdE1hcD4oXG4gICAgbmV3IE1hcDxzdHJpbmcsIFN0b3JlSXRlbVtdPigpLFxuICApO1xuICBwcml2YXRlIHNlYXJjaFRlcm0kJDogQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJycpO1xuICBwcml2YXRlIHNlbGVjdGVkQ2F0ZW9yeUlkJCQ6IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcbiAgcHJpdmF0ZSBsbWlDYXRlZ29yeUZpbHRlcjogRmlsdGVycztcbiAgZmlsdGVycyQ6IE9ic2VydmFibGU8RmlsdGVycz47XG4gIGZpbHRlcmVkSXRlbXMkOiBPYnNlcnZhYmxlPFN0b3JlSXRlbVtdPjtcbiAgc2VhcmNoVGVybVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBzaG93TE1JRmlsdGVyJDogT2JzZXJ2YWJsZTxib29sZWFuPjtcblxuICBwcml2YXRlIGZpbHRlckJ5SW5pdGlhbFN0b3JlSXRlbUlkcyQkOiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGZpbHRlclNlcnZpY2U6IEZpbHRlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBzbm93cGxvd1NlcnZpY2U6IFByb2R1Y3RBbmFseXRpY3NTZXJ2aWNlLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSxcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyQnlJbml0aWFsU3RvcmVJdGVtSWRzJCQubmV4dChcbiAgICAgICEhdGhpcy5pbml0aWFsRmlsdGVyZWRTdG9yZUl0ZW1zICYmICEhdGhpcy5pbml0aWFsRmlsdGVyZWRTdG9yZUl0ZW1zLnN0b3JlSXRlbUlkc1xuICAgICAgICA/IHRoaXMuaW5pdGlhbEZpbHRlcmVkU3RvcmVJdGVtcy5zdG9yZUl0ZW1JZHMubGVuZ3RoID4gMFxuICAgICAgICA6IGZhbHNlLFxuICAgICk7XG5cbiAgICBjb25zdCBsbWlDYXRlZ29yeUNoZWNrYm94TGlzdCA9IExNSV9DQVRFR09SSUVTLm1hcCgoY2F0ZWdvcnkpID0+IHtcbiAgICAgIHJldHVybiBuZXcgQ2hlY2tib3hGaWx0ZXJGaWVsZCh7XG4gICAgICAgIG5hbWU6IHRoaXMudHJhbnNsYXRlU2VydmljZS5pbnN0YW50KGNhdGVnb3J5LmkxOG5LZXkpLFxuICAgICAgICBpZDogY2F0ZWdvcnkuY2F0ZWdvcnlJZCxcbiAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICBjb25kaXRpb246IChpdGVtOiB7IGxtaUNhdGVnb3JpZXM6IHN0cmluZ1tdIH0pOiBib29sZWFuID0+IHtcbiAgICAgICAgICBsZXQgbG1pQ2F0ZWdvcmllczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgICBpZiAoaXRlbS5sbWlDYXRlZ29yaWVzKSB7XG4gICAgICAgICAgICBsbWlDYXRlZ29yaWVzID0gaXRlbS5sbWlDYXRlZ29yaWVzLm1hcCgoY2F0KSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBDYXRlZ29yaWVzW2NhdF0udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbG1pQ2F0ZWdvcmllcy5pbmRleE9mKGNhdGVnb3J5LmNhdGVnb3J5SWQpID4gLTE7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGxtaUNhdGVnb3J5RmlsdGVyU2VjdGlvbiA9IG5ldyBGaWx0ZXJTZWN0aW9uKHtcbiAgICAgIHRpdGxlOiAnRlJPTlRFTkQuU1RPUkUuU1RPUkVGUk9OVF9GSUxURVJTLkxNSV9DQVRFR09SWScsXG4gICAgICB0eXBlOiAnb3InLFxuICAgICAgZmllbGRzOiBsbWlDYXRlZ29yeUNoZWNrYm94TGlzdCxcbiAgICB9KTtcblxuICAgIHRoaXMubG1pQ2F0ZWdvcnlGaWx0ZXIgPSBuZXcgRmlsdGVycyhTVE9SRUZST05UX0ZJTFRFUl9OQU1FLCBbbG1pQ2F0ZWdvcnlGaWx0ZXJTZWN0aW9uXSk7XG5cbiAgICBjb25zdCBwYWNrYWdlSWRzQ2hlY2tib3ggPSBuZXcgQ2hlY2tib3hGaWx0ZXJGaWVsZCh7XG4gICAgICBuYW1lOiAhIXRoaXMuaW5pdGlhbEZpbHRlcmVkU3RvcmVJdGVtcyA/IHRoaXMuaW5pdGlhbEZpbHRlcmVkU3RvcmVJdGVtcy5maWx0ZXJOYW1lIDogJycsXG4gICAgICBpZDogJ3BhY2thZ2VfaWRfY2hlY2tib3gnLFxuICAgICAgdmFsdWU6XG4gICAgICAgICEhdGhpcy5pbml0aWFsRmlsdGVyZWRTdG9yZUl0ZW1zICYmICEhdGhpcy5pbml0aWFsRmlsdGVyZWRTdG9yZUl0ZW1zLnN0b3JlSXRlbUlkc1xuICAgICAgICAgID8gdGhpcy5pbml0aWFsRmlsdGVyZWRTdG9yZUl0ZW1zLnN0b3JlSXRlbUlkcy5sZW5ndGggPiAwXG4gICAgICAgICAgOiBmYWxzZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHBhY2thZ2VJZHNGaWx0ZXJTZWN0aW9uID0gbmV3IEZpbHRlclNlY3Rpb24oe1xuICAgICAgdGl0bGU6ICdTdG9yZSBpdGVtIElEcycsIC8vIFNob3VsZG4ndCBiZSBzZWVuXG4gICAgICB0eXBlOiAnYW5kJyxcbiAgICAgIGZpZWxkczogW3BhY2thZ2VJZHNDaGVja2JveF0sXG4gICAgfSk7XG4gICAgcGFja2FnZUlkc0ZpbHRlclNlY3Rpb24uaGlkZVNlbGVjdG9ycyA9IHRydWU7XG5cbiAgICB0aGlzLmZpbHRlcnMkID0gdGhpcy5jYXRlZ29yaWVzJCQucGlwZShcbiAgICAgIG1hcCgoY2F0ZWdvcmllcykgPT4ge1xuICAgICAgICBjb25zdCB0YWJiZWRGaWx0ZXJGaWVsZCA9IG5ldyBUYWJiZWRGaWx0ZXJGaWVsZCh7XG4gICAgICAgICAgbmFtZTogJycsXG4gICAgICAgICAgdmFsdWU6IG51bGwsXG4gICAgICAgICAgaWQ6ICdjYXRlZ29yeXRhYicsXG4gICAgICAgICAgb3B0aW9uczogY2F0ZWdvcmllcyxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgZmlsdGVycyA9IG5ldyBGaWx0ZXJzKCdGUk9OVEVORC5TVE9SRS5TVE9SRUZST05UX0ZJTFRFUlMuVElUTEUnLCBbXG4gICAgICAgICAgbmV3IEZpbHRlclNlY3Rpb24oe1xuICAgICAgICAgICAgdGl0bGU6ICdGUk9OVEVORC5TVE9SRS5TVE9SRUZST05UX0ZJTFRFUlMuQ0FURUdPUklFUycsXG4gICAgICAgICAgICB0eXBlOiAnb3InLFxuICAgICAgICAgICAgZmllbGRzOiBbdGFiYmVkRmlsdGVyRmllbGRdLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGxtaUNhdGVnb3J5RmlsdGVyU2VjdGlvbixcbiAgICAgICAgICBwYWNrYWdlSWRzRmlsdGVyU2VjdGlvbixcbiAgICAgICAgXSk7XG4gICAgICAgIGZpbHRlcnMuaWQgPSBTVE9SRUZST05UX0ZJTFRFUl9OQU1FLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgnICcsICdfJyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuc2hvd0ZpbHRlcnMgPyBmaWx0ZXJzIDogbnVsbDtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLmZpbHRlclNlcnZpY2Uuc2V0RmlsdGVycyh0aGlzLmxtaUNhdGVnb3J5RmlsdGVyKTtcblxuICAgIHRoaXMuc2VhcmNoVGVybVN1YnNjcmlwdGlvbiA9IHRoaXMuc2VhcmNoVGVybSQkXG4gICAgICAuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKGRlYm91bmNlVGltZSgzMDApLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLCBza2lwKDEpKVxuICAgICAgLnN1YnNjcmliZSgoc2VhcmNoVGVybSkgPT4gdGhpcy5zbm93cGxvd1NlcnZpY2UudHJhY2tDbGljaygnc3RvcmUnLCAnc2VhcmNoLWlucHV0Jywgc2VhcmNoVGVybSkpO1xuXG4gICAgY29uc3Qgc2VsZWN0ZWRMTUlGaWx0ZXJzJCA9IHRoaXMuZmlsdGVyU2VydmljZS5maWx0ZXJzLmZpZWxkVmFsdWVzT2JzZXJ2YWJsZS5waXBlKFxuICAgICAgc3RhcnRXaXRoKFtdKSxcbiAgICAgIG1hcCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmxtaUNhdGVnb3J5RmlsdGVyLmZpZWxkcy5maWx0ZXIoKGl0ZW06IENoZWNrYm94RmlsdGVyRmllbGQpID0+IGl0ZW0udmFsdWUpO1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIHRoaXMuc2hvd0xNSUZpbHRlciQgPSBzZWxlY3RlZExNSUZpbHRlcnMkLnBpcGUoXG4gICAgICBmaWx0ZXIoKHNlbGVjdGVkTE1JRmlsdGVycykgPT4gISFzZWxlY3RlZExNSUZpbHRlcnMpLFxuICAgICAgdGFrZSgxKSxcbiAgICAgIG1hcCgoc2VsZWN0ZWRMTUlGaWx0ZXJzKSA9PiBzZWxlY3RlZExNSUZpbHRlcnMubGVuZ3RoID4gMCksXG4gICAgKTtcblxuICAgIHRoaXMuZmlsdGVyZWRJdGVtcyQgPSBjb21iaW5lTGF0ZXN0KFtcbiAgICAgIHRoaXMucGFja2FnZXNNYXAkJCxcbiAgICAgIHRoaXMuc2VhcmNoVGVybSQkLFxuICAgICAgdGhpcy5zZWxlY3RlZENhdGVvcnlJZCQkLFxuICAgICAgc2VsZWN0ZWRMTUlGaWx0ZXJzJCxcbiAgICAgIHRoaXMuZmlsdGVyQnlJbml0aWFsU3RvcmVJdGVtSWRzJCQsXG4gICAgXSkucGlwZShcbiAgICAgIG1hcCgoW3BhY2thZ2VzLCBzZWFyY2hUZXJtLCBzZWxlY3RlZENhdGVnb3J5SWQsIHNlbGVjdGVkTE1JRmlsdGVycywgZmlsdGVyQnlJbml0aWFsU3RvcmVJdGVtSWRzXSkgPT4ge1xuICAgICAgICBsZXQgc3RvcmVJdGVtczogU3RvcmVJdGVtW10gPSBbXTtcbiAgICAgICAgaWYgKHBhY2thZ2VzLnNpemUpIHtcbiAgICAgICAgICBzdG9yZUl0ZW1zID0gc2VsZWN0ZWRDYXRlZ29yeUlkXG4gICAgICAgICAgICA/IHBhY2thZ2VzLmdldChzZWxlY3RlZENhdGVnb3J5SWQpXG4gICAgICAgICAgICA6IHBhY2thZ2VzLmdldChBcnJheS5mcm9tKHBhY2thZ2VzLmtleXMoKSlbMF0pO1xuICAgICAgICB9XG4gICAgICAgIHN0b3JlSXRlbXMgPSBzdG9yZUl0ZW1zID8gdGhpcy5sbWlDYXRlZ29yeUZpbHRlci5hcHBseUZpbHRlcnMoc3RvcmVJdGVtcykgOiBbXTtcblxuICAgICAgICBpZiAoZmlsdGVyQnlJbml0aWFsU3RvcmVJdGVtSWRzKSB7XG4gICAgICAgICAgc3RvcmVJdGVtcyA9IHN0b3JlSXRlbXMuZmlsdGVyKChzdG9yZUl0ZW0pID0+XG4gICAgICAgICAgICB0aGlzLmluaXRpYWxGaWx0ZXJlZFN0b3JlSXRlbXMuc3RvcmVJdGVtSWRzLmluY2x1ZGVzKHN0b3JlSXRlbS5pZCksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzZWFyY2hUZXJtXG4gICAgICAgICAgPyBzdG9yZUl0ZW1zLmZpbHRlcigoaXRlbSkgPT4gaXRlbT8ubmFtZT8udG9Mb3dlckNhc2UoKS5pbmRleE9mKHNlYXJjaFRlcm0udG9Mb3dlckNhc2UoKSkgIT09IC0xKVxuICAgICAgICAgIDogc3RvcmVJdGVtcztcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnNlYXJjaFRlcm1TdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHB1YmxpYyBvblNlYXJjaFRlcm1DaGFuZ2VkKHRlcm06IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2VhcmNoVGVybSQkLm5leHQodGVybSk7XG4gIH1cblxuICBwdWJsaWMgb25GaWVsZFZhbHVlQ2hhbmdlZChmaWx0ZXJGaWVsZDogRmlsdGVyRmllbGQ8YW55Pik6IHZvaWQge1xuICAgIHRoaXMuc25vd3Bsb3dTZXJ2aWNlLnRyYWNrQ2xpY2soJ3N0b3JlJywgJ3RhYi1maWx0ZXInLCBmaWx0ZXJGaWVsZC52YWx1ZS5pZCk7XG4gICAgaWYgKGZpbHRlckZpZWxkLmlkID09PSAncGFja2FnZV9pZF9jaGVja2JveCcpIHtcbiAgICAgIHRoaXMuZmlsdGVyQnlJbml0aWFsU3RvcmVJdGVtSWRzJCQubmV4dChmaWx0ZXJGaWVsZC52YWx1ZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghKGZpbHRlckZpZWxkIGluc3RhbmNlb2YgVGFiYmVkRmlsdGVyRmllbGQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RlZENhdGVvcnlJZCQkLm5leHQoZmlsdGVyRmllbGQudmFsdWUuaWQpO1xuICAgIHRoaXMuY2F0ZWdvcnlTZWxlY3RlZC5lbWl0KGZpbHRlckZpZWxkLnZhbHVlIGFzIFN0b3JlZnJvbnRDYXRlZ29yeSk7XG5cbiAgICBjb25zdCBjdXJyZW50U3RvcmVJdGVtc0ZvclNlbGVjdENhdGVnb3J5ID0gdGhpcy5wYWNrYWdlc01hcCQkLmdldFZhbHVlKCkuZ2V0KGZpbHRlckZpZWxkLnZhbHVlLmlkKTtcbiAgICBpZiAoIShjdXJyZW50U3RvcmVJdGVtc0ZvclNlbGVjdENhdGVnb3J5ICYmIGN1cnJlbnRTdG9yZUl0ZW1zRm9yU2VsZWN0Q2F0ZWdvcnkubGVuZ3RoKSkge1xuICAgICAgdGhpcy5nZXREYXRhRm9yQ2F0ZWdvcnkuZW1pdChmaWx0ZXJGaWVsZC52YWx1ZSBhcyBTdG9yZWZyb250Q2F0ZWdvcnkpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBzdG9yZUl0ZW1DbGlja2VkKGl0ZW06IFN0b3JlSXRlbSk6IHZvaWQge1xuICAgIGNvbnN0IGxhYmVsID0gaXRlbS50eXBlID09PSBTaG9wcGluZ0NhcnRJdGVtVHlwZS5TSE9QUElOR19DQVJUX0lURU1fVFlQRV9QUk9EVUNUID8gJ3ZpZXctYXBwJyA6ICd2aWV3LXBhY2thZ2UnO1xuICAgIHRoaXMuc25vd3Bsb3dTZXJ2aWNlLnRyYWNrQ2xpY2soJ3N0b3JlJywgbGFiZWwsIGl0ZW0uaWQpO1xuICAgIHRoaXMucHJvZHVjdFNlbGVjdGVkLmVtaXQoeyBpZDogaXRlbS5pZCwgdHlwZTogaXRlbS50eXBlIH0pO1xuICB9XG59XG4iLCI8dmEtZmlsdGVyLWNvbnRhaW5lclxuICBbZmlsdGVyc109XCJmaWx0ZXJzJCB8IGFzeW5jXCJcbiAgKHNlYXJjaFRlcm1DaGFuZ2VkKT1cIm9uU2VhcmNoVGVybUNoYW5nZWQoJGV2ZW50KVwiXG4gIChmaWVsZFZhbHVlQ2hhbmdlZCk9XCJvbkZpZWxkVmFsdWVDaGFuZ2VkKCRldmVudClcIlxuICBbdGhlbWVdPVwiJ3BsYWluJ1wiXG4gIFtmaWx0ZXJJc09wZW5dPVwic2hvd0xNSUZpbHRlciQgfCBhc3luY1wiXG4gIFt1c2VDdXN0b21DYXNlXT1cInVzZUN1c3RvbUNhc2VcIlxuICBbZmlsdGVyc0Rpc2FibGVkXT1cImZpbHRlcnNEaXNhYmxlZFwiXG4+XG4gIDxhcHAtc3RvcmVcbiAgICBbaXRlbXNdPVwiZmlsdGVyZWRJdGVtcyQgfCBhc3luY1wiXG4gICAgW3NlYXJjaGFibGVdPVwiZmFsc2VcIlxuICAgIChpdGVtQ2xpY2tlZCk9XCJzdG9yZUl0ZW1DbGlja2VkKCRldmVudClcIlxuICAgIFtzaG93QWxsUHJpY2VzXT1cInNob3dBbGxQcmljZXNcIlxuICAgIGNvbnRlbnRcbiAgPjwvYXBwLXN0b3JlPlxuPC92YS1maWx0ZXItY29udGFpbmVyPlxuIl19