UNPKG

@spartacus/storefront

Version:

Spartacus Storefront is a package that you can include in your application, which allows you to add default storefront features.

202 lines 24.4 kB
import { Injectable } from '@angular/core'; import { combineLatest, of } from 'rxjs'; import { map, switchMap, tap } from 'rxjs/operators'; import { SearchBoxProductSelectedEvent, SearchBoxSuggestionSelectedEvent, } from './search-box.events'; import * as i0 from "@angular/core"; import * as i1 from "@spartacus/core"; const HAS_SEARCH_RESULT_CLASS = 'has-searchbox-results'; export class SearchBoxComponentService { constructor(searchService, routingService, translationService, winRef, eventService) { this.searchService = searchService; this.routingService = routingService; this.translationService = translationService; this.winRef = winRef; this.eventService = eventService; } /** * Executes the search for products and suggestions, * unless the configuration is setup to not search for * products or suggestions. */ search(query, config) { if (!query || query === '') { this.clearResults(); return; } if (config.minCharactersBeforeRequest && query.length < config.minCharactersBeforeRequest) { return; } if (config.displayProducts) { this.searchService.search(query, { pageSize: config.maxProducts, }); } if (config.displaySuggestions) { this.searchService.searchSuggestions(query, { pageSize: config.maxSuggestions, }); } } /** * Returns an observable with the SearchResults. When there's any * result, the body tag will get a classname, so that specific style * rules can be applied. */ getResults(config) { return combineLatest([ this.getProductResults(config), this.getProductSuggestions(config), this.getSearchMessage(config), ]).pipe(map(([productResults, suggestions, message]) => { return { products: productResults ? productResults.products : null, suggestions, message, }; }), tap((results) => this.toggleBodyClass(HAS_SEARCH_RESULT_CLASS, this.hasResults(results)))); } /** * Clears the searchbox results, so that old values are * no longer emited upon next search. */ clearResults() { this.searchService.clearResults(); this.toggleBodyClass(HAS_SEARCH_RESULT_CLASS, false); } hasBodyClass(className) { return this.winRef.document.body.classList.contains(className); } toggleBodyClass(className, add) { if (add === undefined) { this.winRef.document.body.classList.toggle(className); } else { add ? this.winRef.document.body.classList.add(className) : this.winRef.document.body.classList.remove(className); } } /** * Dispatches a searchbox event for product selected * * @param eventData data for the "SearchBoxProductSelectedEvent" */ dispatchProductSelectedEvent(eventData) { this.eventService.dispatch({ freeText: eventData.freeText, productCode: eventData.productCode, }, SearchBoxProductSelectedEvent); } /** * Dispatches a searchbox event for suggestion selected * * @param eventData data for the "SearchBoxSuggestionSelectedEvent" */ dispatchSuggestionSelectedEvent(eventData) { this.eventService.dispatch({ freeText: eventData.freeText, selectedSuggestion: eventData.selectedSuggestion, searchSuggestions: eventData.searchSuggestions, }, SearchBoxSuggestionSelectedEvent); } /** * For search results model, it returns true when: * * there is any product OR * * the is any search suggestion OR * * there is a message. * * Otherwise it returns false. */ hasResults(results) { return ((!!results.products && results.products.length > 0) || (!!results.suggestions && results.suggestions.length > 0) || !!results.message); } /** * Emits product search results in case when the config property `displayProducts` is true. * Otherwise it emits an empty object. */ getProductResults(config) { if (config.displayProducts) { return this.searchService.getResults(); } else { return of({}); } } /** * Loads suggestions from the backend. In case there's no suggestion * available, we try to get an exact match suggestion. */ getProductSuggestions(config) { if (!config.displaySuggestions) { return of([]); } else { return this.searchService.getSuggestionResults().pipe(map((res) => res.map((suggestion) => suggestion.value)), switchMap((suggestions) => { if (suggestions.length === 0) { return this.getExactSuggestion(config).pipe(map((match) => (match ? [match] : []))); } else { return of(suggestions); } })); } } /** * Whenever there is at least 1 product, we simulate * a suggestion to provide easy access to the search result page */ getExactSuggestion(config) { return this.getProductResults(config).pipe(switchMap((productResult) => { return productResult.products && productResult.products.length > 0 ? this.fetchTranslation('searchBox.help.exactMatch', { term: productResult.freeTextSearch, }) : of(null); })); } /** * Emits a 'no match' message, in case the product search results and search suggestions are empty. * Otherwise it emits null. */ getSearchMessage(config) { return combineLatest([ this.getProductResults(config), this.getProductSuggestions(config), ]).pipe(switchMap(([productResult, suggestions]) => { if (productResult && productResult.products && productResult.products.length === 0 && suggestions && suggestions.length === 0) { return this.fetchTranslation('searchBox.help.noMatch'); } else { return of(null); } })); } /** * Navigates to the search result page with a given query */ launchSearchPage(query) { this.routingService.go({ cxRoute: 'search', params: { query }, }); } fetchTranslation(translationKey, options) { return this.translationService.translate(translationKey, options); } } SearchBoxComponentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: SearchBoxComponentService, deps: [{ token: i1.SearchboxService }, { token: i1.RoutingService }, { token: i1.TranslationService }, { token: i1.WindowRef }, { token: i1.EventService }], target: i0.ɵɵFactoryTarget.Injectable }); SearchBoxComponentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: SearchBoxComponentService, providedIn: 'root' }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.5", ngImport: i0, type: SearchBoxComponentService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: function () { return [{ type: i1.SearchboxService }, { type: i1.RoutingService }, { type: i1.TranslationService }, { type: i1.WindowRef }, { type: i1.EventService }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLWJveC1jb21wb25lbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0b3JlZnJvbnRsaWIvY21zLWNvbXBvbmVudHMvbmF2aWdhdGlvbi9zZWFyY2gtYm94L3NlYXJjaC1ib3gtY29tcG9uZW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQVMzQyxPQUFPLEVBQUUsYUFBYSxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRCxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRCxPQUFPLEVBQ0wsNkJBQTZCLEVBQzdCLGdDQUFnQyxHQUNqQyxNQUFNLHFCQUFxQixDQUFDOzs7QUFHN0IsTUFBTSx1QkFBdUIsR0FBRyx1QkFBdUIsQ0FBQztBQUt4RCxNQUFNLE9BQU8seUJBQXlCO0lBQ3BDLFlBQ1MsYUFBK0IsRUFDNUIsY0FBOEIsRUFDOUIsa0JBQXNDLEVBQ3RDLE1BQWlCLEVBQ2pCLFlBQTBCO1FBSjdCLGtCQUFhLEdBQWIsYUFBYSxDQUFrQjtRQUM1QixtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0QyxXQUFNLEdBQU4sTUFBTSxDQUFXO1FBQ2pCLGlCQUFZLEdBQVosWUFBWSxDQUFjO0lBQ25DLENBQUM7SUFFSjs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLEtBQWEsRUFBRSxNQUF1QjtRQUMzQyxJQUFJLENBQUMsS0FBSyxJQUFJLEtBQUssS0FBSyxFQUFFLEVBQUU7WUFDMUIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLE9BQU87U0FDUjtRQUVELElBQ0UsTUFBTSxDQUFDLDBCQUEwQjtZQUNqQyxLQUFLLENBQUMsTUFBTSxHQUFHLE1B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QkFBZ0IsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO2FBQ3hEO2lCQUFNO2dCQUNMLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ2pCO1FBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNILGdCQUFnQixDQUFDLEtBQWE7UUFDNUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDckIsT0FBTyxFQUFFLFFBQVE7WUFDakIsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFO1NBQ2xCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxnQkFBZ0IsQ0FDdEIsY0FBc0IsRUFDdEIsT0FBYTtRQUViLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDcEUsQ0FBQzs7c0hBdk9VLHlCQUF5QjswSEFBekIseUJBQXlCLGNBRnhCLE1BQU07MkZBRVAseUJBQXlCO2tCQUhyQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEV2ZW50U2VydmljZSxcbiAgUHJvZHVjdFNlYXJjaFBhZ2UsXG4gIFJvdXRpbmdTZXJ2aWNlLFxuICBTZWFyY2hib3hTZXJ2aWNlLFxuICBUcmFuc2xhdGlvblNlcnZpY2UsXG4gIFdpbmRvd1JlZixcbn0gZnJvbSAnQHNwYXJ0YWN1cy9jb3JlJztcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QsIE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtcbiAgU2VhcmNoQm94UHJvZHVjdFNlbGVjdGVkRXZlbnQsXG4gIFNlYXJjaEJveFN1Z2dlc3Rpb25TZWxlY3RlZEV2ZW50LFxufSBmcm9tICcuL3NlYXJjaC1ib3guZXZlbnRzJztcbmltcG9ydCB7IFNlYXJjaEJveENvbmZpZywgU2VhcmNoUmVzdWx0cyB9IGZyb20gJy4vc2VhcmNoLWJveC5tb2RlbCc7XG5cbmNvbnN0IEhBU19TRUFSQ0hfUkVTVUxUX0NMQVNTID0gJ2hhcy1zZWFyY2hib3gtcmVzdWx0cyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBTZWFyY2hCb3hDb21wb25lbnRTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHNlYXJjaFNlcnZpY2U6IFNlYXJjaGJveFNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHJvdXRpbmdTZXJ2aWNlOiBSb3V0aW5nU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgdHJhbnNsYXRpb25TZXJ2aWNlOiBUcmFuc2xhdGlvblNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIHdpblJlZjogV2luZG93UmVmLFxuICAgIHByb3RlY3RlZCBldmVudFNlcnZpY2U6IEV2ZW50U2VydmljZVxuICApIHt9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIHRoZSBzZWFyY2ggZm9yIHByb2R1Y3RzIGFuZCBzdWdnZXN0aW9ucyxcbiAgICogdW5sZXNzIHRoZSBjb25maWd1cmF0aW9uIGlzIHNldHVwIHRvIG5vdCBzZWFyY2ggZm9yXG4gICAqIHByb2R1Y3RzIG9yIHN1Z2dlc3Rpb25zLlxuICAgKi9cbiAgc2VhcmNoKHF1ZXJ5OiBzdHJpbmcsIGNvbmZpZzogU2VhcmNoQm94Q29uZmlnKTogdm9pZCB7XG4gICAgaWYgKCFxdWVyeSB8fCBxdWVyeSA9PT0gJycpIHtcbiAgICAgIHRoaXMuY2xlYXJSZXN1bHRzKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgY29uZmlnLm1pbkNoYXJhY3RlcnNCZWZvcmVSZXF1ZXN0ICYmXG4gICAgICBxdWVyeS5sZW5ndGggPCBjb25maWcubWluQ2hhcmFjdGVyc0JlZm9yZVJlcXVlc3RcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLmRpc3BsYXlQcm9kdWN0cykge1xuICAgICAgdGhpcy5zZWFyY2hTZXJ2aWNlLnNlYXJjaChxdWVyeSwge1xuICAgICAgICBwYWdlU2l6ZTogY29uZmlnLm1heFByb2R1Y3RzLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5kaXNwbGF5U3VnZ2VzdGlvbnMpIHtcbiAgICAgIHRoaXMuc2VhcmNoU2VydmljZS5zZWFyY2hTdWdnZXN0aW9ucyhxdWVyeSwge1xuICAgICAgICBwYWdlU2l6ZTogY29uZmlnLm1heFN1Z2dlc3Rpb25zLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gb2JzZXJ2YWJsZSB3aXRoIHRoZSBTZWFyY2hSZXN1bHRzLiBXaGVuIHRoZXJlJ3MgYW55XG4gICAqIHJlc3VsdCwgdGhlIGJvZHkgdGFnIHdpbGwgZ2V0IGEgY2xhc3NuYW1lLCBzbyB0aGF0IHNwZWNpZmljIHN0eWxlXG4gICAqIHJ1bGVzIGNhbiBiZSBhcHBsaWVkLlxuICAgKi9cbiAgZ2V0UmVzdWx0cyhjb25maWc6IFNlYXJjaEJveENvbmZpZyk6IE9ic2VydmFibGU8U2VhcmNoUmVzdWx0cz4ge1xuICAgIHJldHVybiBjb21iaW5lTGF0ZXN0KFtcbiAgICAgIHRoaXMuZ2V0UHJvZHVjdFJlc3VsdHMoY29uZmlnKSxcbiAgICAgIHRoaXMuZ2V0UHJvZHVjdFN1Z2dlc3Rpb25zKGNvbmZpZyksXG4gICAgICB0aGlzLmdldFNlYXJjaE1lc3NhZ2UoY29uZmlnKSxcbiAgICBdKS5waXBlKFxuICAgICAgbWFwKChbcHJvZHVjdFJlc3VsdHMsIHN1Z2dlc3Rpb25zLCBtZXNzYWdlXSkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHByb2R1Y3RzOiBwcm9kdWN0UmVzdWx0cyA/IHByb2R1Y3RSZXN1bHRzLnByb2R1Y3RzIDogbnVsbCxcbiAgICAgICAgICBzdWdnZXN0aW9ucyxcbiAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgICB0YXAoKHJlc3VsdHMpID0+XG4gICAgICAgIHRoaXMudG9nZ2xlQm9keUNsYXNzKEhBU19TRUFSQ0hfUkVTVUxUX0NMQVNTLCB0aGlzLmhhc1Jlc3VsdHMocmVzdWx0cykpXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgdGhlIHNlYXJjaGJveCByZXN1bHRzLCBzbyB0aGF0IG9sZCB2YWx1ZXMgYXJlXG4gICAqIG5vIGxvbmdlciBlbWl0ZWQgdXBvbiBuZXh0IHNlYXJjaC5cbiAgICovXG4gIGNsZWFyUmVzdWx0cygpIHtcbiAgICB0aGlzLnNlYXJjaFNlcnZpY2UuY2xlYXJSZXN1bHRzKCk7XG4gICAgdGhpcy50b2dnbGVCb2R5Q2xhc3MoSEFTX1NFQVJDSF9SRVNVTFRfQ0xBU1MsIGZhbHNlKTtcbiAgfVxuXG4gIGhhc0JvZHlDbGFzcyhjbGFzc05hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLndpblJlZi5kb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpO1xuICB9XG5cbiAgdG9nZ2xlQm9keUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBhZGQ/OiBib29sZWFuKSB7XG4gICAgaWYgKGFkZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLndpblJlZi5kb2N1bWVudC5ib2R5LmNsYXNzTGlzdC50b2dnbGUoY2xhc3NOYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWRkXG4gICAgICAgID8gdGhpcy53aW5SZWYuZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSlcbiAgICAgICAgOiB0aGlzLndpblJlZi5kb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoY2xhc3NOYW1lKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2hlcyBhIHNlYXJjaGJveCBldmVudCBmb3IgcHJvZHVjdCBzZWxlY3RlZFxuICAgKlxuICAgKiBAcGFyYW0gZXZlbnREYXRhIGRhdGEgZm9yIHRoZSBcIlNlYXJjaEJveFByb2R1Y3RTZWxlY3RlZEV2ZW50XCJcbiAgICovXG4gIGRpc3BhdGNoUHJvZHVjdFNlbGVjdGVkRXZlbnQoZXZlbnREYXRhOiBTZWFyY2hCb3hQcm9kdWN0U2VsZWN0ZWRFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuZXZlbnRTZXJ2aWNlLmRpc3BhdGNoPFNlYXJjaEJveFByb2R1Y3RTZWxlY3RlZEV2ZW50PihcbiAgICAgIHtcbiAgICAgICAgZnJlZVRleHQ6IGV2ZW50RGF0YS5mcmVlVGV4dCxcbiAgICAgICAgcHJvZHVjdENvZGU6IGV2ZW50RGF0YS5wcm9kdWN0Q29kZSxcbiAgICAgIH0sXG4gICAgICBTZWFyY2hCb3hQcm9kdWN0U2VsZWN0ZWRFdmVudFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGlzcGF0Y2hlcyBhIHNlYXJjaGJveCBldmVudCBmb3Igc3VnZ2VzdGlvbiBzZWxlY3RlZFxuICAgKlxuICAgKiBAcGFyYW0gZXZlbnREYXRhIGRhdGEgZm9yIHRoZSBcIlNlYXJjaEJveFN1Z2dlc3Rpb25TZWxlY3RlZEV2ZW50XCJcbiAgICovXG4gIGRpc3BhdGNoU3VnZ2VzdGlvblNlbGVjdGVkRXZlbnQoXG4gICAgZXZlbnREYXRhOiBTZWFyY2hCb3hTdWdnZXN0aW9uU2VsZWN0ZWRFdmVudFxuICApOiB2b2lkIHtcbiAgICB0aGlzLmV2ZW50U2VydmljZS5kaXNwYXRjaDxTZWFyY2hCb3hTdWdnZXN0aW9uU2VsZWN0ZWRFdmVudD4oXG4gICAgICB7XG4gICAgICAgIGZyZWVUZXh0OiBldmVudERhdGEuZnJlZVRleHQsXG4gICAgICAgIHNlbGVjdGVkU3VnZ2VzdGlvbjogZXZlbnREYXRhLnNlbGVjdGVkU3VnZ2VzdGlvbixcbiAgICAgICAgc2VhcmNoU3VnZ2VzdGlvbnM6IGV2ZW50RGF0YS5zZWFyY2hTdWdnZXN0aW9ucyxcbiAgICAgIH0sXG4gICAgICBTZWFyY2hCb3hTdWdnZXN0aW9uU2VsZWN0ZWRFdmVudFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRm9yIHNlYXJjaCByZXN1bHRzIG1vZGVsLCBpdCByZXR1cm5zIHRydWUgd2hlbjpcbiAgICogKiB0aGVyZSBpcyBhbnkgcHJvZHVjdCBPUlxuICAgKiAqIHRoZSBpcyBhbnkgc2VhcmNoIHN1Z2dlc3Rpb24gT1JcbiAgICogKiB0aGVyZSBpcyBhIG1lc3NhZ2UuXG4gICAqXG4gICAqIE90aGVyd2lzZSBpdCByZXR1cm5zIGZhbHNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGhhc1Jlc3VsdHMocmVzdWx0czogU2VhcmNoUmVzdWx0cyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICAoISFyZXN1bHRzLnByb2R1Y3RzICYmIHJlc3VsdHMucHJvZHVjdHMubGVuZ3RoID4gMCkgfHxcbiAgICAgICghIXJlc3VsdHMuc3VnZ2VzdGlvbnMgJiYgcmVzdWx0cy5zdWdnZXN0aW9ucy5sZW5ndGggPiAwKSB8fFxuICAgICAgISFyZXN1bHRzLm1lc3NhZ2VcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIHByb2R1Y3Qgc2VhcmNoIHJlc3VsdHMgaW4gY2FzZSB3aGVuIHRoZSBjb25maWcgcHJvcGVydHkgYGRpc3BsYXlQcm9kdWN0c2AgaXMgdHJ1ZS5cbiAgICogT3RoZXJ3aXNlIGl0IGVtaXRzIGFuIGVtcHR5IG9iamVjdC5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQcm9kdWN0UmVzdWx0cyhcbiAgICBjb25maWc6IFNlYXJjaEJveENvbmZpZ1xuICApOiBPYnNlcnZhYmxlPFByb2R1Y3RTZWFyY2hQYWdlPiB7XG4gICAgaWYgKGNvbmZpZy5kaXNwbGF5UHJvZHVjdHMpIHtcbiAgICAgIHJldHVybiB0aGlzLnNlYXJjaFNlcnZpY2UuZ2V0UmVzdWx0cygpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gb2Yoe30pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyBzdWdnZXN0aW9ucyBmcm9tIHRoZSBiYWNrZW5kLiBJbiBjYXNlIHRoZXJlJ3Mgbm8gc3VnZ2VzdGlvblxuICAgKiBhdmFpbGFibGUsIHdlIHRyeSB0byBnZXQgYW4gZXhhY3QgbWF0Y2ggc3VnZ2VzdGlvbi5cbiAgICovXG4gIHByb3RlY3RlZCBnZXRQcm9kdWN0U3VnZ2VzdGlvbnMoXG4gICAgY29uZmlnOiBTZWFyY2hCb3hDb25maWdcbiAgKTogT2JzZXJ2YWJsZTxzdHJpbmdbXT4ge1xuICAgIGlmICghY29uZmlnLmRpc3BsYXlTdWdnZXN0aW9ucykge1xuICAgICAgcmV0dXJuIG9mKFtdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuc2VhcmNoU2VydmljZS5nZXRTdWdnZXN0aW9uUmVzdWx0cygpLnBpcGUoXG4gICAgICAgIG1hcCgocmVzKSA9PiByZXMubWFwKChzdWdnZXN0aW9uKSA9PiBzdWdnZXN0aW9uLnZhbHVlKSksXG4gICAgICAgIHN3aXRjaE1hcCgoc3VnZ2VzdGlvbnMpID0+IHtcbiAgICAgICAgICBpZiAoc3VnZ2VzdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRFeGFjdFN1Z2dlc3Rpb24oY29uZmlnKS5waXBlKFxuICAgICAgICAgICAgICBtYXAoKG1hdGNoKSA9PiAobWF0Y2ggPyBbbWF0Y2hdIDogW10pKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG9mKHN1Z2dlc3Rpb25zKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBXaGVuZXZlciB0aGVyZSBpcyBhdCBsZWFzdCAxIHByb2R1Y3QsIHdlIHNpbXVsYXRlXG4gICAqIGEgc3VnZ2VzdGlvbiB0byBwcm92aWRlIGVhc3kgYWNjZXNzIHRvIHRoZSBzZWFyY2ggcmVzdWx0IHBhZ2VcbiAgICovXG4gIHByb3RlY3RlZCBnZXRFeGFjdFN1Z2dlc3Rpb24oY29uZmlnOiBTZWFyY2hCb3hDb25maWcpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLmdldFByb2R1Y3RSZXN1bHRzKGNvbmZpZykucGlwZShcbiAgICAgIHN3aXRjaE1hcCgocHJvZHVjdFJlc3VsdCkgPT4ge1xuICAgICAgICByZXR1cm4gcHJvZHVjdFJlc3VsdC5wcm9kdWN0cyAmJiBwcm9kdWN0UmVzdWx0LnByb2R1Y3RzLmxlbmd0aCA+IDBcbiAgICAgICAgICA/IHRoaXMuZmV0Y2hUcmFuc2xhdGlvbignc2VhcmNoQm94LmhlbHAuZXhhY3RNYXRjaCcsIHtcbiAgICAgICAgICAgICAgdGVybTogcHJvZHVjdFJlc3VsdC5mcmVlVGV4dFNlYXJjaCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgOiBvZihudWxsKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0cyBhICdubyBtYXRjaCcgbWVzc2FnZSwgaW4gY2FzZSB0aGUgcHJvZHVjdCBzZWFyY2ggcmVzdWx0cyBhbmQgc2VhcmNoIHN1Z2dlc3Rpb25zIGFyZSBlbXB0eS5cbiAgICogT3RoZXJ3aXNlIGl0IGVtaXRzIG51bGwuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0U2VhcmNoTWVzc2FnZShjb25maWc6IFNlYXJjaEJveENvbmZpZyk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QoW1xuICAgICAgdGhpcy5nZXRQcm9kdWN0UmVzdWx0cyhjb25maWcpLFxuICAgICAgdGhpcy5nZXRQcm9kdWN0U3VnZ2VzdGlvbnMoY29uZmlnKSxcbiAgICBdKS5waXBlKFxuICAgICAgc3dpdGNoTWFwKChbcHJvZHVjdFJlc3VsdCwgc3VnZ2VzdGlvbnNdKSA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBwcm9kdWN0UmVzdWx0ICYmXG4gICAgICAgICAgcHJvZHVjdFJlc3VsdC5wcm9kdWN0cyAmJlxuICAgICAgICAgIHByb2R1Y3RSZXN1bHQucHJvZHVjdHMubGVuZ3RoID09PSAwICYmXG4gICAgICAgICAgc3VnZ2VzdGlvbnMgJiZcbiAgICAgICAgICBzdWdnZXN0aW9ucy5sZW5ndGggPT09IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZmV0Y2hUcmFuc2xhdGlvbignc2VhcmNoQm94LmhlbHAubm9NYXRjaCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIE5hdmlnYXRlcyB0byB0aGUgc2VhcmNoIHJlc3VsdCBwYWdlIHdpdGggYSBnaXZlbiBxdWVyeVxuICAgKi9cbiAgbGF1bmNoU2VhcmNoUGFnZShxdWVyeTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5yb3V0aW5nU2VydmljZS5nbyh7XG4gICAgICBjeFJvdXRlOiAnc2VhcmNoJyxcbiAgICAgIHBhcmFtczogeyBxdWVyeSB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaFRyYW5zbGF0aW9uKFxuICAgIHRyYW5zbGF0aW9uS2V5OiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IGFueVxuICApOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLnRyYW5zbGF0aW9uU2VydmljZS50cmFuc2xhdGUodHJhbnNsYXRpb25LZXksIG9wdGlvbnMpO1xuICB9XG59XG4iXX0=