UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

242 lines 36.7 kB
import { Component, EventEmitter, Inject, Input, Optional, Output, ViewChild } from '@angular/core'; import { SmartGroupsService } from '@c8y/client'; import { BuiltInActionType, DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, DATA_GRID_CONFIGURATION_STRATEGY, DataGridComponent, FilteringActionType, SearchFilters, UserPreferencesConfigurationStrategy, gettext } from '@c8y/ngx-components'; import { AlarmsDeviceGridColumn, ImeiDeviceGridColumn, ModelDeviceGridColumn, NameDeviceGridColumn, RegistrationDateDeviceGridColumn, SerialNumberDeviceGridColumn, SystemIdDeviceGridColumn } from '@c8y/ngx-components/device-grid'; import { DeleteAssetsModalComponent, SubAssetsService } from '@c8y/ngx-components/sub-assets'; import { BsModalService } from 'ngx-bootstrap/modal'; import { AssetTypeSearchGridColumn } from './columns/asset-type-search-grid-column'; import { SEARCH_CONFIG } from './search-config.model'; import { AssetSearchService } from './search.service'; import * as i0 from "@angular/core"; import * as i1 from "./search.service"; import * as i2 from "ngx-bootstrap/modal"; import * as i3 from "@c8y/client"; import * as i4 from "@c8y/ngx-components/sub-assets"; import * as i5 from "@c8y/ngx-components"; import * as i6 from "@angular/common"; export class SearchGridComponent { set _columns(value) { if (value) { this.columns = value; } else { this.columns = this.assetSearchService.getDefaultColumns(); } } set _pagination(value) { if (value) { this.pagination = value; } } set _actionControls(value) { if (value) { this.actionControls = value; } else { this.actionControls = this.assetSearchService.getDefaultActionControls(); } } set _bulkActionControls(value) { if (value) { this.bulkActionControls = value; } else { this.bulkActionControls = this.assetSearchService.getDefaultBulkActionControls(); } } constructor(assetSearchService, bsModalService, smartGroupsService, subAssetsGridService, moduleConfig) { this.assetSearchService = assetSearchService; this.bsModalService = bsModalService; this.smartGroupsService = smartGroupsService; this.subAssetsGridService = subAssetsGridService; this.moduleConfig = moduleConfig; this.title = ''; this.loadingItemsLabel = gettext('Loading results…'); this.selectable = false; this.onColumnsChange = new EventEmitter(); this.searchText = ''; this.pagination = this.assetSearchService.getDefaultPagination(); this.bulkActionControls = this.assetSearchService.getDefaultBulkActionControls(); this.refresh = new EventEmitter(); this.sizeCount = 0; this.showAdvancedFilters = moduleConfig?.showAdvancedFilters ?? false; this.customPlaceholder = moduleConfig?.placeholder ?? undefined; } getGridConfigContext() { return { key: this.columnsConfigKey || this.assetSearchService.GRID_CONFIG_STORAGE_KEY }; } ngOnInit() { if (!this.filteringName) { this.columns = [ new AssetTypeSearchGridColumn(this.showAdvancedFilters, { sortOrder: 'desc' }, this.assetSearchService, this.customPlaceholder), ...this.assetSearchService.getDefaultColumns() ]; } else { this.columns = [ new AssetTypeSearchGridColumn(this.showAdvancedFilters, { sortOrder: 'desc' }, this.assetSearchService), new NameDeviceGridColumn({ sortOrder: 'asc', filter: { externalFilterQuery: { names: [this.filteringName] } } }), new ModelDeviceGridColumn(), new SerialNumberDeviceGridColumn({ visible: false }), new RegistrationDateDeviceGridColumn({ visible: false }), new SystemIdDeviceGridColumn({ visible: false }), new ImeiDeviceGridColumn({ visible: false }), new AlarmsDeviceGridColumn() ]; } this.serverSideDataCallback = this.onDataSourceModifier.bind(this); this.setActionControls(); } ngAfterViewInit() { this.setInitialFilterForTypeColumn(); } trackByName(_index, column) { return column.name; } async onDataSourceModifier(dataSourceModifier) { const response = await this.assetSearchService.getData(dataSourceModifier.columns, dataSourceModifier.pagination, dataSourceModifier.searchText); const { res, data, paging } = response; if (paging.currentPage === 1) { this.sizeCount = 0; } this.sizeCount += data.length; this.onColumnsChange.emit(dataSourceModifier.columns); return { res, data, paging, filteredSize: this.sizeCount, size: undefined }; } setActionControls() { const actionControls = []; const deleteAction = { type: BuiltInActionType.Delete, callback: (asset) => this.onDeleteAsset(asset, this.parentGroup) }; actionControls.push(deleteAction); if (!this.actionControls) { this.actionControls = actionControls; } } updateFiltering(columnNames, action) { const { type } = action; if (type === FilteringActionType.ResetFilter) { this.dataGrid.clearFilters(); } else { /** * TODO: find better solution. After new changes from DM team, we're running into race condition where * this.dataGrid.updateFiltering is executed before this.configurationStrategy.getConfig$() value is emitted. * Columns setter sets columns after this.dataGrid.updateFiltering executes its logic. Value of this.columns in * dataGrid.updateFiltering is just not yet set. */ setTimeout(() => { this.dataGrid.updateFiltering(columnNames, action, false); }, 500); } } onColumnFilterReset(column) { if (column.name === 'type') { this.assetSearchService.resetAppliedFilters(); } } onDeleteAsset(asset, parentRef) { const initialState = { showWithDeviceUserCheckbox: this.subAssetsGridService.shouldShowWithDeviceUserCheckbox(asset), asset, showWithCascadeCheckbox: !this.smartGroupsService.isSmartGroup(asset) }; const modalRef = this.bsModalService.show(DeleteAssetsModalComponent, { initialState }); modalRef.content.closeSubject.subscribe(async (result) => { if (result) { await this.subAssetsGridService.deleteAsset(asset, parentRef, result); this.refresh.emit(); } }); } setInitialFilterForTypeColumn() { const checkboxes = this.assetSearchService.appliedFilters$.value; // Set filter only when all checkboxes are not selected if (checkboxes[SearchFilters.ONLY_DEVICES] !== checkboxes[SearchFilters.ONLY_GROUPS_AND_ASSETS]) { const externalFilterQuery = { [SearchFilters.ONLY_DEVICES]: checkboxes[SearchFilters.ONLY_DEVICES], [SearchFilters.ONLY_GROUPS_AND_ASSETS]: checkboxes[SearchFilters.ONLY_GROUPS_AND_ASSETS] }; this.updateFiltering(['type'], { type: FilteringActionType.ApplyFilter, payload: { filteringModifier: { externalFilterQuery } } }); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchGridComponent, deps: [{ token: i1.AssetSearchService }, { token: i2.BsModalService }, { token: i3.SmartGroupsService }, { token: i4.SubAssetsService }, { token: SEARCH_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SearchGridComponent, selector: "c8y-search-grid", inputs: { parentGroup: ["parent-group", "parentGroup"], title: "title", loadingItemsLabel: "loadingItemsLabel", _columns: ["columns", "_columns"], _pagination: ["pagination", "_pagination"], _actionControls: ["actionControls", "_actionControls"], selectable: "selectable", _bulkActionControls: ["bulkActionControls", "_bulkActionControls"], searchText: "searchText", filteringName: "filteringName", columnsConfigKey: "columnsConfigKey" }, outputs: { onColumnsChange: "onColumnsChange" }, providers: [ { provide: DATA_GRID_CONFIGURATION_STRATEGY, useClass: UserPreferencesConfigurationStrategy }, { provide: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, useExisting: SearchGridComponent } ], viewQueries: [{ propertyName: "dataGrid", first: true, predicate: DataGridComponent, descendants: true, static: true }], ngImport: i0, template: "<div class=\"card--grid--fullpage border-top border-bottom\">\n <c8y-data-grid\n [title]=\"'Search results' | translate\"\n [loadingItemsLabel]=\"loadingItemsLabel\"\n [columns]=\"columns\"\n [pagination]=\"pagination\"\n [actionControls]=\"actionControls\"\n [selectable]=\"selectable\"\n [bulkActionControls]=\"bulkActionControls\"\n [serverSideDataCallback]=\"serverSideDataCallback\"\n [infiniteScroll]=\"'auto'\"\n [showSearch]=\"true\"\n [searchText]=\"searchText\"\n [refresh]=\"refresh\"\n (onColumnFilterReset)=\"onColumnFilterReset($event)\"\n >\n <ng-container *ngFor=\"let column of columns; trackBy: trackByName\">\n <c8y-column [name]=\"column.name\"></c8y-column>\n </ng-container>\n\n <c8y-ui-empty-state\n [icon]=\"'search'\"\n [title]=\"'No results to display.' | translate\"\n [subtitle]=\"'Refine your search terms or check your spelling.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </c8y-data-grid>\n</div>", dependencies: [{ kind: "component", type: i5.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.ColumnDirective, selector: "c8y-column", inputs: ["name"] }, { kind: "component", type: i5.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "pipe", type: i5.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SearchGridComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-search-grid', providers: [ { provide: DATA_GRID_CONFIGURATION_STRATEGY, useClass: UserPreferencesConfigurationStrategy }, { provide: DATA_GRID_CONFIGURATION_CONTEXT_PROVIDER, useExisting: SearchGridComponent } ], template: "<div class=\"card--grid--fullpage border-top border-bottom\">\n <c8y-data-grid\n [title]=\"'Search results' | translate\"\n [loadingItemsLabel]=\"loadingItemsLabel\"\n [columns]=\"columns\"\n [pagination]=\"pagination\"\n [actionControls]=\"actionControls\"\n [selectable]=\"selectable\"\n [bulkActionControls]=\"bulkActionControls\"\n [serverSideDataCallback]=\"serverSideDataCallback\"\n [infiniteScroll]=\"'auto'\"\n [showSearch]=\"true\"\n [searchText]=\"searchText\"\n [refresh]=\"refresh\"\n (onColumnFilterReset)=\"onColumnFilterReset($event)\"\n >\n <ng-container *ngFor=\"let column of columns; trackBy: trackByName\">\n <c8y-column [name]=\"column.name\"></c8y-column>\n </ng-container>\n\n <c8y-ui-empty-state\n [icon]=\"'search'\"\n [title]=\"'No results to display.' | translate\"\n [subtitle]=\"'Refine your search terms or check your spelling.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </c8y-data-grid>\n</div>" }] }], ctorParameters: () => [{ type: i1.AssetSearchService }, { type: i2.BsModalService }, { type: i3.SmartGroupsService }, { type: i4.SubAssetsService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [SEARCH_CONFIG] }] }], propDecorators: { parentGroup: [{ type: Input, args: ['parent-group'] }], title: [{ type: Input }], loadingItemsLabel: [{ type: Input }], _columns: [{ type: Input, args: ['columns'] }], _pagination: [{ type: Input, args: ['pagination'] }], _actionControls: [{ type: Input, args: ['actionControls'] }], selectable: [{ type: Input }], _bulkActionControls: [{ type: Input, args: ['bulkActionControls'] }], onColumnsChange: [{ type: Output }], searchText: [{ type: Input }], filteringName: [{ type: Input }], columnsConfigKey: [{ type: Input }], dataGrid: [{ type: ViewChild, args: [DataGridComponent, { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLWdyaWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc2VhcmNoL3NlYXJjaC1ncmlkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uL3NlYXJjaC9zZWFyY2gtZ3JpZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3BHLE9BQU8sRUFBa0Isa0JBQWtCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDakUsT0FBTyxFQUVMLGlCQUFpQixFQUdqQix3Q0FBd0MsRUFDeEMsZ0NBQWdDLEVBQ2hDLGlCQUFpQixFQUVqQixtQkFBbUIsRUFLbkIsYUFBYSxFQUViLG9DQUFvQyxFQUVwQyxPQUFPLEVBQ1IsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLG9CQUFvQixFQUNwQixxQkFBcUIsRUFDckIsb0JBQW9CLEVBQ3BCLGdDQUFnQyxFQUNoQyw0QkFBNEIsRUFDNUIsd0JBQXdCLEVBQ3pCLE1BQU0saUNBQWlDLENBQUM7QUFDekMsT0FBTyxFQUNMLDBCQUEwQixFQUUxQixnQkFBZ0IsRUFDakIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDcEYsT0FBTyxFQUFFLGFBQWEsRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQzs7Ozs7Ozs7QUFnQnRELE1BQU0sT0FBTyxtQkFBbUI7SUFJOUIsSUFBc0IsUUFBUSxDQUFDLEtBQWU7UUFDNUMsSUFBSSxLQUFLLEVBQUUs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Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNnQixRQUFRO3NCQUE3QixLQUFLO3VCQUFDLFNBQVM7Z0JBT1MsV0FBVztzQkFBbkMsS0FBSzt1QkFBQyxZQUFZO2dCQUtVLGVBQWU7c0JBQTNDLEtBQUs7dUJBQUMsZ0JBQWdCO2dCQU9kLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQzJCLG1CQUFtQjtzQkFBbkQsS0FBSzt1QkFBQyxvQkFBb0I7Z0JBT2pCLGVBQWU7c0JBQXhCLE1BQU07Z0JBR1AsVUFBVTtzQkFEVCxLQUFLO2dCQUlOLGFBQWE7c0JBRFosS0FBSztnQkFJRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBWU4sUUFBUTtzQkFEUCxTQUFTO3VCQUFDLGlCQUFpQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbmplY3QsIElucHV0LCBPcHRpb25hbCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElNYW5hZ2VkT2JqZWN0LCBTbWFydEdyb3Vwc1NlcnZpY2UgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQge1xuICBBY3Rpb25Db250cm9sLFxuICBCdWlsdEluQWN0aW9uVHlwZSxcbiAgQnVsa0FjdGlvbkNvbnRyb2wsXG4gIENvbHVtbixcbiAgREFUQV9HUklEX0NPTkZJR1VSQVRJT05fQ09OVEVYVF9QUk9WSURFUixcbiAgREFUQV9HUklEX0NPTkZJR1VSQVRJT05fU1RSQVRFR1ksXG4gIERhdGFHcmlkQ29tcG9uZW50LFxuICBEYXRhU291cmNlTW9kaWZpZXIsXG4gIEZpbHRlcmluZ0FjdGlvblR5cGUsXG4gIEZpbHRlcmluZ01vZGlmaWVyLFxuICBHcmlkQ29uZmlnQ29udGV4dFByb3ZpZGVyLFxuICBQYWdpbmF0aW9uLFxuICBSb3csXG4gIFNlYXJjaEZpbHRlcnMsXG4gIFNlcnZlclNpZGVEYXRhUmVzdWx0LFxuICBVc2VyUHJlZmVyZW5jZXNDb25maWd1cmF0aW9uU3RyYXRlZ3ksXG4gIFVzZXJQcmVmZXJlbmNlc0dyaWRDb25maWdDb250ZXh0LFxuICBnZXR0ZXh0XG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHtcbiAgQWxhcm1zRGV2aWNlR3JpZENvbHVtbixcbiAgSW1laURldmljZUdyaWRDb2x1bW4sXG4gIE1vZGVsRGV2aWNlR3JpZENvbHVtbixcbiAgTmFtZURldmljZUdyaWRDb2x1bW4sXG4gIFJlZ2lzdHJhdGlvbkRhdGVEZXZpY2VHcmlkQ29sdW1uLFxuICBTZXJpYWxOdW1iZXJEZXZpY2VHcmlkQ29sdW1uLFxuICBTeXN0ZW1JZERldmljZUdyaWRDb2x1bW5cbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9kZXZpY2UtZ3JpZCc7XG5pbXBvcnQge1xuICBEZWxldGVBc3NldHNNb2RhbENvbXBvbmVudCxcbiAgRGVsZXRlTW9kYWxDaGVja2JveGVzLFxuICBTdWJBc3NldHNTZXJ2aWNlXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvc3ViLWFzc2V0cyc7XG5pbXBvcnQgeyBCc01vZGFsU2VydmljZSB9IGZyb20gJ25neC1ib290c3RyYXAvbW9kYWwnO1xuaW1wb3J0IHsgQXNzZXRUeXBlU2VhcmNoR3JpZENvbHVtbiB9IGZyb20gJy4vY29sdW1ucy9hc3NldC10eXBlLXNlYXJjaC1ncmlkLWNvbHVtbic7XG5pbXBvcnQgeyBTRUFSQ0hfQ09ORklHLCBTZWFyY2hDb25maWcgfSBmcm9tICcuL3NlYXJjaC1jb25maWcubW9kZWwnO1xuaW1wb3J0IHsgQXNzZXRTZWFyY2hTZXJ2aWNlIH0gZnJvbSAnLi9zZWFyY2guc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS1zZWFyY2gtZ3JpZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9zZWFyY2gtZ3JpZC5jb21wb25lbnQuaHRtbCcsXG4gIHByb3ZpZGVyczogW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IERBVEFfR1JJRF9DT05GSUdVUkFUSU9OX1NUUkFURUdZLFxuICAgICAgdXNlQ2xhc3M6IFVzZXJQcmVmZXJlbmNlc0NvbmZpZ3VyYXRpb25TdHJhdGVneVxuICAgIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogREFUQV9HUklEX0NPTkZJR1VSQVRJT05fQ09OVEVYVF9QUk9WSURFUixcbiAgICAgIHVzZUV4aXN0aW5nOiBTZWFyY2hHcmlkQ29tcG9uZW50XG4gICAgfVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIFNlYXJjaEdyaWRDb21wb25lbnQgaW1wbGVtZW50cyBHcmlkQ29uZmlnQ29udGV4dFByb3ZpZGVyIHtcbiAgQElucHV0KCdwYXJlbnQtZ3JvdXAnKSBwYXJlbnRHcm91cDogSU1hbmFnZWRPYmplY3Q7XG4gIEBJbnB1dCgpIHRpdGxlID0gJyc7XG4gIEBJbnB1dCgpIGxvYWRpbmdJdGVtc0xhYmVsOiBzdHJpbmcgPSBnZXR0ZXh0KCdMb2FkaW5nIHJlc3VsdHPigKYnKTtcbiAgQElucHV0KCdjb2x1bW5zJykgc2V0IF9jb2x1bW5zKHZhbHVlOiBDb2x1bW5bXSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5jb2x1bW5zID0gdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29sdW1ucyA9IHRoaXMuYXNzZXRTZWFyY2hTZXJ2aWNlLmdldERlZmF1bHRDb2x1bW5zKCk7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgncGFnaW5hdGlvbicpIHNldCBfcGFnaW5hdGlvbih2YWx1ZTogUGFnaW5hdGlvbikge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5wYWdpbmF0aW9uID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgnYWN0aW9uQ29udHJvbHMnKSBzZXQgX2FjdGlvbkNvbnRyb2xzKHZhbHVlOiBBY3Rpb25Db250cm9sW10pIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuYWN0aW9uQ29udHJvbHMgPSB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hY3Rpb25Db250cm9scyA9IHRoaXMuYXNzZXRTZWFyY2hTZXJ2aWNlLmdldERlZmF1bHRBY3Rpb25Db250cm9scygpO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKSBzZWxlY3RhYmxlID0gZmFsc2U7XG4gIEBJbnB1dCgnYnVsa0FjdGlvbkNvbnRyb2xzJykgc2V0IF9idWxrQWN0aW9uQ29udHJvbHModmFsdWU6IEJ1bGtBY3Rpb25Db250cm9sW10pIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuYnVsa0FjdGlvbkNvbnRyb2xzID0gdmFsdWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnVsa0FjdGlvbkNvbnRyb2xzID0gdGhpcy5hc3NldFNlYXJjaFNlcnZpY2UuZ2V0RGVmYXVsdEJ1bGtBY3Rpb25Db250cm9scygpO1xuICAgIH1cbiAgfVxuICBAT3V0cHV0KCkgb25Db2x1bW5zQ2hhbmdlOiBFdmVudEVtaXR0ZXI8Q29sdW1uW10+ID0gbmV3IEV2ZW50RW1pdHRlcjxDb2x1bW5bXT4oKTtcblxuICBASW5wdXQoKVxuICBzZWFyY2hUZXh0ID0gJyc7XG5cbiAgQElucHV0KClcbiAgZmlsdGVyaW5nTmFtZTogc3RyaW5nO1xuXG4gIC8qKiBUaGUgbmFtZSBvZiB0aGUga2V5IHdoZXJlIGNvbHVtbnMgY29uZmlndXJhdGlvbiB3aWxsIGJlIHN0b3JlZC4gKi9cbiAgQElucHV0KCkgY29sdW1uc0NvbmZpZ0tleTogc3RyaW5nO1xuXG4gIGNvbHVtbnM6IENvbHVtbltdO1xuICBwYWdpbmF0aW9uOiBQYWdpbmF0aW9uID0gdGhpcy5hc3NldFNlYXJjaFNlcnZpY2UuZ2V0RGVmYXVsdFBhZ2luYXRpb24oKTtcbiAgYWN0aW9uQ29udHJvbHM6IEFjdGlvbkNvbnRyb2xbXTtcbiAgYnVsa0FjdGlvbkNvbnRyb2xzOiBCdWxrQWN0aW9uQ29udHJvbFtdID0gdGhpcy5hc3NldFNlYXJjaFNlcnZpY2UuZ2V0RGVmYXVsdEJ1bGtBY3Rpb25Db250cm9scygpO1xuICBzaG93QWR2YW5jZWRGaWx0ZXJzOiBib29sZWFuO1xuICBjdXN0b21QbGFjZWhvbGRlcjogc3RyaW5nO1xuICBzZXJ2ZXJTaWRlRGF0YUNhbGxiYWNrOiBhbnk7XG4gIHJlZnJlc2g6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBWaWV3Q2hpbGQoRGF0YUdyaWRDb21wb25lbnQsIHsgc3RhdGljOiB0cnVlIH0pXG4gIGRhdGFHcmlkOiBEYXRhR3JpZENvbXBvbmVudDtcblxuICBwcml2YXRlIHNpemVDb3VudCA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGFzc2V0U2VhcmNoU2VydmljZTogQXNzZXRTZWFyY2hTZXJ2aWNlLFxuICAgIHByaXZhdGUgYnNNb2RhbFNlcnZpY2U6IEJzTW9kYWxTZXJ2aWNlLFxuICAgIHByaXZhdGUgc21hcnRHcm91cHNTZXJ2aWNlOiBTbWFydEdyb3Vwc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBzdWJBc3NldHNHcmlkU2VydmljZTogU3ViQXNzZXRzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNFQVJDSF9DT05GSUcpIHB1YmxpYyBtb2R1bGVDb25maWc6IFNlYXJjaENvbmZpZ1xuICApIHtcbiAgICB0aGlzLnNob3dBZHZhbmNlZEZpbHRlcnMgPSBtb2R1bGVDb25maWc/LnNob3dBZHZhbmNlZEZpbHRlcnMgPz8gZmFsc2U7XG4gICAgdGhpcy5jdXN0b21QbGFjZWhvbGRlciA9IG1vZHVsZUNvbmZpZz8ucGxhY2Vob2xkZXIgPz8gdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0R3JpZENvbmZpZ0NvbnRleHQoKTogVXNlclByZWZlcmVuY2VzR3JpZENvbmZpZ0NvbnRleHQge1xuICAgIHJldHVybiB7IGtleTogdGhpcy5jb2x1bW5zQ29uZmlnS2V5IHx8IHRoaXMuYXNzZXRTZWFyY2hTZXJ2aWNlLkdSSURfQ09ORklHX1NUT1JBR0VfS0VZIH07XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZmlsdGVyaW5nTmFtZSkge1xuICAgICAgdGhpcy5jb2x1bW5zID0gW1xuICAgICAgICBuZXcgQXNzZXRUeXBlU2VhcmNoR3JpZENvbHVtbihcbiAgICAgICAgICB0aGlzLnNob3dBZHZhbmNlZEZpbHRlcnMsXG4gICAgICAgICAgeyBzb3J0T3JkZXI6ICdkZXNjJyB9LFxuICAgICAgICAgIHRoaXMuYXNzZXRTZWFyY2hTZXJ2aWNlLFxuICAgICAgICAgIHRoaXMuY3VzdG9tUGxhY2Vob2xkZXJcbiAgICAgICAgKSxcbiAgICAgICAgLi4udGhpcy5hc3NldFNlYXJjaFNlcnZpY2UuZ2V0RGVmYXVsdENvbHVtbnMoKVxuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb2x1bW5zID0gW1xuICAgICAgICBuZXcgQXNzZXRUeXBlU2VhcmNoR3JpZENvbHVtbihcbiAgICAgICAgICB0aGlzLnNob3dBZHZhbmNlZEZpbHRlcnMsXG4gICAgICAgICAgeyBzb3J0T3JkZXI6ICdkZXNjJyB9LFxuICAgICAgICAgIHRoaXMuYXNzZXRTZWFyY2hTZXJ2aWNlXG4gICAgICAgICksXG4gICAgICAgIG5ldyBOYW1lRGV2aWNlR3JpZENvbHVtbih7XG4gICAgICAgICAgc29ydE9yZGVyOiAnYXNjJyxcbiAgICAgICAgICBmaWx0ZXI6IHsgZXh0ZXJuYWxGaWx0ZXJRdWVyeTogeyBuYW1lczogW3RoaXMuZmlsdGVyaW5nTmFtZV0gfSB9XG4gICAgICAgIH0pLFxuICAgICAgICBuZXcgTW9kZWxEZXZpY2VHcmlkQ29sdW1uKCksXG4gICAgICAgIG5ldyBTZXJpYWxOdW1iZXJEZXZpY2VHcmlkQ29sdW1uKHsgdmlzaWJsZTogZmFsc2UgfSksXG4gICAgICAgIG5ldyBSZWdpc3RyYXRpb25EYXRlRGV2aWNlR3JpZENvbHVtbih7IHZpc2libGU6IGZhbHNlIH0pLFxuICAgICAgICBuZXcgU3lzdGVtSWREZXZpY2VHcmlkQ29sdW1uKHsgdmlzaWJsZTogZmFsc2UgfSksXG4gICAgICAgIG5ldyBJbWVpRGV2aWNlR3JpZENvbHVtbih7IHZpc2libGU6IGZhbHNlIH0pLFxuICAgICAgICBuZXcgQWxhcm1zRGV2aWNlR3JpZENvbHVtbigpXG4gICAgICBdO1xuICAgIH1cbiAgICB0aGlzLnNlcnZlclNpZGVEYXRhQ2FsbGJhY2sgPSB0aGlzLm9uRGF0YVNvdXJjZU1vZGlmaWVyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5zZXRBY3Rpb25Db250cm9scygpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuc2V0SW5pdGlhbEZpbHRlckZvclR5cGVDb2x1bW4oKTtcbiAgfVxuXG4gIHRyYWNrQnlOYW1lKF9pbmRleCwgY29sdW1uOiBDb2x1bW4pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb2x1bW4ubmFtZTtcbiAgfVxuXG4gIGFzeW5jIG9uRGF0YVNvdXJjZU1vZGlmaWVyKFxuICAgIGRhdGFTb3VyY2VNb2RpZmllcjogRGF0YVNvdXJjZU1vZGlmaWVyXG4gICk6IFByb21pc2U8U2VydmVyU2lkZURhdGFSZXN1bHQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuYXNzZXRTZWFyY2hTZXJ2aWNlLmdldERhdGEoXG4gICAgICBkYXRhU291cmNlTW9kaWZpZXIuY29sdW1ucyxcbiAgICAgIGRhdGFTb3VyY2VNb2RpZmllci5wYWdpbmF0aW9uLFxuICAgICAgZGF0YVNvdXJjZU1vZGlmaWVyLnNlYXJjaFRleHRcbiAgICApO1xuICAgIGNvbnN0IHsgcmVzLCBkYXRhLCBwYWdpbmcgfSA9IHJlc3BvbnNlO1xuXG4gICAgaWYgKHBhZ2luZy5jdXJyZW50UGFnZSA9PT0gMSkge1xuICAgICAgdGhpcy5zaXplQ291bnQgPSAwO1xuICAgIH1cbiAgICB0aGlzLnNpemVDb3VudCArPSBkYXRhLmxlbmd0aDtcbiAgICB0aGlzLm9uQ29sdW1uc0NoYW5nZS5lbWl0KGRhdGFTb3VyY2VNb2RpZmllci5jb2x1bW5zKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZXMsXG4gICAgICBkYXRhLFxuICAgICAgcGFnaW5nLFxuICAgICAgZmlsdGVyZWRTaXplOiB0aGlzLnNpemVDb3VudCxcbiAgICAgIHNpemU6IHVuZGVmaW5lZFxuICAgIH07XG4gIH1cblxuICBzZXRBY3Rpb25Db250cm9scygpIHtcbiAgICBjb25zdCBhY3Rpb25Db250cm9sczogQWN0aW9uQ29udHJvbFtdID0gW107XG4gICAgY29uc3QgZGVsZXRlQWN0aW9uOiBBY3Rpb25Db250cm9sID0ge1xuICAgICAgdHlwZTogQnVpbHRJbkFjdGlvblR5cGUuRGVsZXRlLFxuICAgICAgY2FsbGJhY2s6IChhc3NldDogUm93KSA9PiB0aGlzLm9uRGVsZXRlQXNzZXQoYXNzZXQgYXMgSU1hbmFnZWRPYmplY3QsIHRoaXMucGFyZW50R3JvdXApXG4gICAgfTtcbiAgICBhY3Rpb25Db250cm9scy5wdXNoKGRlbGV0ZUFjdGlvbik7XG4gICAgaWYgKCF0aGlzLmFjdGlvbkNvbnRyb2xzKSB7XG4gICAgICB0aGlzLmFjdGlvbkNvbnRyb2xzID0gYWN0aW9uQ29udHJvbHM7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlRmlsdGVyaW5nKFxuICAgIGNvbHVtbk5hbWVzOiBzdHJpbmdbXSxcbiAgICBhY3Rpb246IHtcbiAgICAgIHR5cGU6IEZpbHRlcmluZ0FjdGlvblR5cGU7XG4gICAgICBwYXlsb2FkPzogeyBmaWx0ZXJpbmdNb2RpZmllcjogRmlsdGVyaW5nTW9kaWZpZXIgfTtcbiAgICB9XG4gICkge1xuICAgIGNvbnN0IHsgdHlwZSB9ID0gYWN0aW9uO1xuICAgIGlmICh0eXBlID09PSBGaWx0ZXJpbmdBY3Rpb25UeXBlLlJlc2V0RmlsdGVyKSB7XG4gICAgICB0aGlzLmRhdGFHcmlkLmNsZWFyRmlsdGVycygpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvKipcbiAgICAgICAqIFRPRE86IGZpbmQgYmV0dGVyIHNvbHV0aW9uLiBBZnRlciBuZXcgY2hhbmdlcyBmcm9tIERNIHRlYW0sIHdlJ3JlIHJ1bm5pbmcgaW50byByYWNlIGNvbmRpdGlvbiB3aGVyZVxuICAgICAgICogdGhpcy5kYXRhR3JpZC51cGRhdGVGaWx0ZXJpbmcgaXMgZXhlY3V0ZWQgYmVmb3JlIHRoaXMuY29uZmlndXJhdGlvblN0cmF0ZWd5LmdldENvbmZpZyQoKSB2YWx1ZSBpcyBlbWl0dGVkLlxuICAgICAgICogQ29sdW1ucyBzZXR0ZXIgc2V0cyBjb2x1bW5zIGFmdGVyIHRoaXMuZGF0YUdyaWQudXBkYXRlRmlsdGVyaW5nIGV4ZWN1dGVzIGl0cyBsb2dpYy4gVmFsdWUgb2YgdGhpcy5jb2x1bW5zIGluXG4gICAgICAgKiBkYXRhR3JpZC51cGRhdGVGaWx0ZXJpbmcgaXMganVzdCBub3QgeWV0IHNldC5cbiAgICAgICAqL1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YUdyaWQudXBkYXRlRmlsdGVyaW5nKGNvbHVtbk5hbWVzLCBhY3Rpb24sIGZhbHNlKTtcbiAgICAgIH0sIDUwMCk7XG4gICAgfVxuICB9XG5cbiAgb25Db2x1bW5GaWx0ZXJSZXNldChjb2x1bW46IENvbHVtbikge1xuICAgIGlmIChjb2x1bW4ubmFtZSA9PT0gJ3R5cGUnKSB7XG4gICAgICB0aGlzLmFzc2V0U2VhcmNoU2VydmljZS5yZXNldEFwcGxpZWRGaWx0ZXJzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbkRlbGV0ZUFzc2V0KGFzc2V0LCBwYXJlbnRSZWYpIHtcbiAgICBjb25zdCBpbml0aWFsU3RhdGUgPSB7XG4gICAgICBzaG93V2l0aERldmljZVVzZXJDaGVja2JveDogdGhpcy5zdWJBc3NldHNHcmlkU2VydmljZS5zaG91bGRTaG93V2l0aERldmljZVVzZXJDaGVja2JveChhc3NldCksXG4gICAgICBhc3NldCxcbiAgICAgIHNob3dXaXRoQ2FzY2FkZUNoZWNrYm94OiAhdGhpcy5zbWFydEdyb3Vwc1NlcnZpY2UuaXNTbWFydEdyb3VwKGFzc2V0KVxuICAgIH07XG5cbiAgICBjb25zdCBtb2RhbFJlZiA9IHRoaXMuYnNNb2RhbFNlcnZpY2Uuc2hvdyhEZWxldGVBc3NldHNNb2RhbENvbXBvbmVudCwgeyBpbml0aWFsU3RhdGUgfSk7XG5cbiAgICBtb2RhbFJlZi5jb250ZW50LmNsb3NlU3ViamVjdC5zdWJzY3JpYmUoYXN5bmMgKHJlc3VsdDogRGVsZXRlTW9kYWxDaGVja2JveGVzKSA9PiB7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc3ViQXNzZXRzR3JpZFNlcnZpY2UuZGVsZXRlQXNzZXQoYXNzZXQsIHBhcmVudFJlZiwgcmVzdWx0KTtcbiAgICAgICAgdGhpcy5yZWZyZXNoLmVtaXQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0SW5pdGlhbEZpbHRlckZvclR5cGVDb2x1bW4oKSB7XG4gICAgY29uc3QgY2hlY2tib3hlcyA9IHRoaXMuYXNzZXRTZWFyY2hTZXJ2aWNlLmFwcGxpZWRGaWx0ZXJzJC52YWx1ZTtcbiAgICAvLyBTZXQgZmlsdGVyIG9ubHkgd2hlbiBhbGwgY2hlY2tib3hlcyBhcmUgbm90IHNlbGVjdGVkXG4gICAgaWYgKFxuICAgICAgY2hlY2tib3hlc1tTZWFyY2hGaWx0ZXJzLk9OTFlfREVWSUNFU10gIT09IGNoZWNrYm94ZXNbU2VhcmNoRmlsdGVycy5PTkxZX0dST1VQU19BTkRfQVNTRVRTXVxuICAgICkge1xuICAgICAgY29uc3QgZXh0ZXJuYWxGaWx0ZXJRdWVyeSA9IHtcbiAgICAgICAgW1NlYXJjaEZpbHRlcnMuT05MWV9ERVZJQ0VTXTogY2hlY2tib3hlc1tTZWFyY2hGaWx0ZXJzLk9OTFlfREVWSUNFU10sXG4gICAgICAgIFtTZWFyY2hGaWx0ZXJzLk9OTFlfR1JPVVBTX0FORF9BU1NFVFNdOiBjaGVja2JveGVzW1NlYXJjaEZpbHRlcnMuT05MWV9HUk9VUFNfQU5EX0FTU0VUU11cbiAgICAgIH07XG4gICAgICB0aGlzLnVwZGF0ZUZpbHRlcmluZyhbJ3R5cGUnXSwge1xuICAgICAgICB0eXBlOiBGaWx0ZXJpbmdBY3Rpb25UeXBlLkFwcGx5RmlsdGVyLFxuICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgZmlsdGVyaW5nTW9kaWZpZXI6IHtcbiAgICAgICAgICAgIGV4dGVybmFsRmlsdGVyUXVlcnlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNhcmQtLWdyaWQtLWZ1bGxwYWdlIGJvcmRlci10b3AgYm9yZGVyLWJvdHRvbVwiPlxuICA8Yzh5LWRhdGEtZ3JpZFxuICAgIFt0aXRsZV09XCInU2VhcmNoIHJlc3VsdHMnIHwgdHJhbnNsYXRlXCJcbiAgICBbbG9hZGluZ0l0ZW1zTGFiZWxdPVwibG9hZGluZ0l0ZW1zTGFiZWxcIlxuICAgIFtjb2x1bW5zXT1cImNvbHVtbnNcIlxuICAgIFtwYWdpbmF0aW9uXT1cInBhZ2luYXRpb25cIlxuICAgIFthY3Rpb25Db250cm9sc109XCJhY3Rpb25Db250cm9sc1wiXG4gICAgW3NlbGVjdGFibGVdPVwic2VsZWN0YWJsZVwiXG4gICAgW2J1bGtBY3Rpb25Db250cm9sc109XCJidWxrQWN0aW9uQ29udHJvbHNcIlxuICAgIFtzZXJ2ZXJTaWRlRGF0YUNhbGxiYWNrXT1cInNlcnZlclNpZGVEYXRhQ2FsbGJhY2tcIlxuICAgIFtpbmZpbml0ZVNjcm9sbF09XCInYXV0bydcIlxuICAgIFtzaG93U2VhcmNoXT1cInRydWVcIlxuICAgIFtzZWFyY2hUZXh0XT1cInNlYXJjaFRleHRcIlxuICAgIFtyZWZyZXNoXT1cInJlZnJlc2hcIlxuICAgIChvbkNvbHVtbkZpbHRlclJlc2V0KT1cIm9uQ29sdW1uRmlsdGVyUmVzZXQoJGV2ZW50KVwiXG4gID5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgY29sdW1uczsgdHJhY2tCeTogdHJhY2tCeU5hbWVcIj5cbiAgICAgIDxjOHktY29sdW1uIFtuYW1lXT1cImNvbHVtbi5uYW1lXCI+PC9jOHktY29sdW1uPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPGM4eS11aS1lbXB0eS1zdGF0ZVxuICAgICAgW2ljb25dPVwiJ3NlYXJjaCdcIlxuICAgICAgW3RpdGxlXT1cIidObyByZXN1bHRzIHRvIGRpc3BsYXkuJyB8IHRyYW5zbGF0ZVwiXG4gICAgICBbc3VidGl0bGVdPVwiJ1JlZmluZSB5b3VyIHNlYXJjaCB0ZXJtcyBvciBjaGVjayB5b3VyIHNwZWxsaW5nLicgfCB0cmFuc2xhdGVcIlxuICAgICAgW2hvcml6b250YWxdPVwidHJ1ZVwiXG4gICAgPjwvYzh5LXVpLWVtcHR5LXN0YXRlPlxuICA8L2M4eS1kYXRhLWdyaWQ+XG48L2Rpdj4iXX0=