@alfresco/adf-content-services
Version:
Alfresco ADF content services
206 lines • 37 kB
JavaScript
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NodesApi, PreferencesApi } from '@alfresco/js-api';
import { inject, Injectable, InjectionToken } from '@angular/core';
import { of, from, ReplaySubject, throwError } from 'rxjs';
import { catchError, concatMap, first, map, switchMap, take, tap } from 'rxjs/operators';
import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { AuthenticationService } from '@alfresco/adf-core';
import * as i0 from "@angular/core";
import * as i1 from "../../services/alfresco-api.service";
import * as i2 from "@alfresco/adf-core";
export const SAVED_SEARCHES_SERVICE_PREFERENCES = new InjectionToken('SAVED_SEARCHES_SERVICE_PREFERENCES');
export class SavedSearchesService {
get nodesApi() {
this._nodesApi = this._nodesApi ?? new NodesApi(this.apiService.getInstance());
return this._nodesApi;
}
get preferencesApi() {
if (this.preferencesService) {
this._preferencesApi = this.preferencesService;
return this._preferencesApi;
}
this._preferencesApi = this._preferencesApi ?? new PreferencesApi(this.apiService.getInstance());
return this._preferencesApi;
}
constructor(apiService, authService) {
this.apiService = apiService;
this.authService = authService;
this.preferencesService = inject(SAVED_SEARCHES_SERVICE_PREFERENCES, { optional: true });
this.savedSearches$ = new ReplaySubject(1);
}
init() {
this.fetchSavedSearches();
}
/**
* Gets a list of saved searches by user.
*
* @returns SavedSearch list containing user saved searches
*/
getSavedSearches() {
const savedSearchesMigrated = localStorage.getItem(this.getLocalStorageKey()) ?? '';
if (savedSearchesMigrated === 'true') {
return from(this.preferencesApi.getPreference('-me-', 'saved-searches')).pipe(map((preference) => JSON.parse(preference.entry.value)), catchError(() => of([])));
}
else {
return this.getSavedSearchesNodeId().pipe(take(1), concatMap(() => {
if (this.savedSearchFileNodeId !== '') {
return this.migrateSavedSearches();
}
else {
return from(this.preferencesApi.getPreference('-me-', 'saved-searches')).pipe(map((preference) => JSON.parse(preference.entry.value)), catchError(() => of([])));
}
}));
}
}
/**
* Saves a new search into state and updates state. If there are less than 5 searches,
* it will be pushed on first place, if more it will be pushed to 6th place.
*
* @param newSaveSearch object { name: string, description: string, encodedUrl: string }
* @returns NodeEntry
*/
saveSearch(newSaveSearch) {
return this.getSavedSearches().pipe(take(1), switchMap((savedSearches) => {
let updatedSavedSearches = [];
if (savedSearches.length < 5) {
updatedSavedSearches = [{ ...newSaveSearch, order: 0 }, ...savedSearches];
}
else {
const firstFiveSearches = savedSearches.slice(0, 5);
const restOfSearches = savedSearches.slice(5);
updatedSavedSearches = [...firstFiveSearches, { ...newSaveSearch, order: 5 }, ...restOfSearches];
}
updatedSavedSearches = updatedSavedSearches.map((search, index) => ({
...search,
order: index
}));
return from(this.preferencesApi.updatePreference('-me-', 'saved-searches', JSON.stringify(updatedSavedSearches))).pipe(map((preference) => JSON.parse(preference.entry.value)), tap(() => this.savedSearches$.next(updatedSavedSearches)));
}), catchError((error) => {
console.error('Error saving new search:', error);
return throwError(() => error);
}));
}
/**
* Replace Save Search with new one and also updates the state.
*
* @param updatedSavedSearch - updated Save Search
* @returns NodeEntry
*/
editSavedSearch(updatedSavedSearch) {
let previousSavedSearches;
return this.savedSearches$.pipe(take(1), map((savedSearches) => {
previousSavedSearches = [...savedSearches];
return savedSearches.map((search) => (search.order === updatedSavedSearch.order ? updatedSavedSearch : search));
}), tap((updatedSearches) => {
this.savedSearches$.next(updatedSearches);
}), switchMap((updatedSearches) => from(this.preferencesApi.updatePreference('-me-', 'saved-searches', JSON.stringify(updatedSearches))).pipe(map((preference) => JSON.parse(preference.entry.value)))), catchError((error) => {
this.savedSearches$.next(previousSavedSearches);
return throwError(() => error);
}));
}
/**
* Deletes Save Search and update state.
*
* @param deletedSavedSearch - Save Search to delete
* @returns NodeEntry
*/
deleteSavedSearch(deletedSavedSearch) {
let previousSavedSearchesOrder;
return this.savedSearches$.pipe(take(1), map((savedSearches) => {
previousSavedSearchesOrder = [...savedSearches];
const updatedSearches = savedSearches.filter((search) => search.order !== deletedSavedSearch.order);
return updatedSearches.map((search, index) => ({
...search,
order: index
}));
}), tap((updatedSearches) => {
this.savedSearches$.next(updatedSearches);
}), switchMap((updatedSearches) => from(this.preferencesApi.updatePreference('-me-', 'saved-searches', JSON.stringify(updatedSearches))).pipe(map((preference) => JSON.parse(preference.entry.value)))), catchError((error) => {
this.savedSearches$.next(previousSavedSearchesOrder);
return throwError(() => error);
}));
}
/**
* Reorders saved search place
*
* @param previousIndex - previous index of saved search
* @param currentIndex - new index of saved search
*/
changeOrder(previousIndex, currentIndex) {
let previousSavedSearchesOrder;
this.savedSearches$
.pipe(take(1), map((savedSearches) => {
previousSavedSearchesOrder = [...savedSearches];
const [movedSearch] = savedSearches.splice(previousIndex, 1);
savedSearches.splice(currentIndex, 0, movedSearch);
return savedSearches.map((search, index) => ({
...search,
order: index
}));
}), tap((savedSearches) => this.savedSearches$.next(savedSearches)), switchMap((updatedSearches) => from(this.preferencesApi.updatePreference('-me-', 'saved-searches', JSON.stringify(updatedSearches))).pipe(map((preference) => JSON.parse(preference.entry.value)))), catchError((error) => {
this.savedSearches$.next(previousSavedSearchesOrder);
return throwError(() => error);
}))
.subscribe();
}
getSavedSearchesNodeId() {
return from(this.nodesApi.getNode('-my-', { relativePath: 'config.json' })).pipe(first(), concatMap((configNode) => {
this.savedSearchFileNodeId = configNode.entry.id;
return configNode.entry.id;
}), catchError((error) => {
const errorStatusCode = JSON.parse(error.message).error.statusCode;
if (errorStatusCode === 404) {
localStorage.setItem(this.getLocalStorageKey(), 'true');
return '';
}
else {
return throwError(() => error);
}
}));
}
async mapFileContentToSavedSearches(blob) {
return blob
.text()
.then((content) => (content ? JSON.parse(content) : []))
.catch(() => []);
}
getLocalStorageKey() {
return `saved-searches-${this.authService.getUsername()}-migrated`;
}
fetchSavedSearches() {
this.getSavedSearches()
.pipe(take(1))
.subscribe((searches) => this.savedSearches$.next(searches));
}
migrateSavedSearches() {
return from(this.nodesApi.getNodeContent(this.savedSearchFileNodeId).then((content) => this.mapFileContentToSavedSearches(content))).pipe(tap((savedSearches) => {
this.preferencesApi.updatePreference('-me-', 'saved-searches', JSON.stringify(savedSearches));
localStorage.setItem(this.getLocalStorageKey(), 'true');
this.nodesApi.deleteNode(this.savedSearchFileNodeId, { permanent: true });
}));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SavedSearchesService, deps: [{ token: i1.AlfrescoApiService }, { token: i2.AuthenticationService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SavedSearchesService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: SavedSearchesService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i1.AlfrescoApiService }, { type: i2.AuthenticationService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2F2ZWQtc2VhcmNoZXMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYi9jb250ZW50LXNlcnZpY2VzL3NyYy9saWIvY29tbW9uL3NlcnZpY2VzL3NhdmVkLXNlYXJjaGVzLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUFFLFFBQVEsRUFBYSxjQUFjLEVBQXVDLE1BQU0sa0JBQWtCLENBQUM7QUFDNUcsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25FLE9BQU8sRUFBYyxFQUFFLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBRXpFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7O0FBTzNELE1BQU0sQ0FBQyxNQUFNLGtDQUFrQyxHQUFHLElBQUksY0FBYyxDQUFxQyxvQ0FBb0MsQ0FBQyxDQUFDO0FBSy9JLE1BQU0sT0FBTyxvQkFBb0I7SUFNN0IsSUFBSSxRQUFRO1FBQ1IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUMvRSxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDMUIsQ0FBQztJQUVELElBQUksY0FBYztRQUNkLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFD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QUUsQ0FBQyxDQUFDO1FBQzlFLENBQUMsQ0FBQyxDQUNMLENBQUM7SUFDTixDQUFDOzhHQTdPUSxvQkFBb0I7a0hBQXBCLG9CQUFvQixjQUZqQixNQUFNOzsyRkFFVCxvQkFBb0I7a0JBSGhDLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IMKpIDIwMDUtMjAyNSBIeWxhbmQgU29mdHdhcmUsIEluYy4gYW5kIGl0cyBhZmZpbGlhdGVzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgeyBOb2Rlc0FwaSwgTm9kZUVudHJ5LCBQcmVmZXJlbmNlc0FwaSwgQ29udGVudEZpZWxkc1F1ZXJ5LCBQcmVmZXJlbmNlRW50cnkgfSBmcm9tICdAYWxmcmVzY28vanMtYXBpJztcbmltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBmcm9tLCBSZXBsYXlTdWJqZWN0LCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBjb25jYXRNYXAsIGZpcnN0LCBtYXAsIHN3aXRjaE1hcCwgdGFrZSwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQWxmcmVzY29BcGlTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvYWxmcmVzY28tYXBpLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2F2ZWRTZWFyY2ggfSBmcm9tICcuLi9pbnRlcmZhY2VzL3NhdmVkLXNlYXJjaC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQXV0aGVudGljYXRpb25TZXJ2aWNlIH0gZnJvbSAnQGFsZnJlc2NvL2FkZi1jb3JlJztcblxuZXhwb3J0IGludGVyZmFjZSBTYXZlZFNlYXJjaGVzUHJlZmVyZW5jZXNBcGlTZXJ2aWNlIHtcbiAgICBnZXRQcmVmZXJlbmNlOiAocGVyc29uSWQ6IHN0cmluZywgcHJlZmVyZW5jZU5hbWU6IHN0cmluZywgb3B0cz86IENvbnRlbnRGaWVsZHNRdWVyeSkgPT4gUHJvbWlzZTxQcmVmZXJlbmNlRW50cnk+IHwgT2JzZXJ2YWJsZTxQcmVmZXJlbmNlRW50cnk+O1xuICAgIHVwZGF0ZVByZWZlcmVuY2U6IChwZXJzb25JZDogc3RyaW5nLCBwcmVmZXJlbmNlTmFtZTogc3RyaW5nLCBwcmVmZXJlbmNlVmFsdWU6IHN0cmluZykgPT4gUHJvbWlzZTxQcmVmZXJlbmNlRW50cnk+IHwgT2JzZXJ2YWJsZTxQcmVmZXJlbmNlRW50cnk+O1xufVxuXG5leHBvcnQgY29uc3QgU0FWRURfU0VBUkNIRVNfU0VSVklDRV9QUkVGRVJFTkNFUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxTYXZlZFNlYXJjaGVzUHJlZmVyZW5jZXNBcGlTZXJ2aWNlPignU0FWRURfU0VBUkNIRVNfU0VSVklDRV9QUkVGRVJFTkNFUycpO1xuXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFNhdmVkU2VhcmNoZXNTZXJ2aWNlIHtcbiAgICBwcml2YXRlIHNhdmVkU2VhcmNoRmlsZU5vZGVJZDogc3RyaW5nO1xuICAgIHByaXZhdGUgX25vZGVzQXBpOiBOb2Rlc0FwaTtcbiAgICBwcml2YXRlIF9wcmVmZXJlbmNlc0FwaTogU2F2ZWRTZWFyY2hlc1ByZWZlcmVuY2VzQXBpU2VydmljZTtcbiAgICBwcml2YXRlIHByZWZlcmVuY2VzU2VydmljZSA9IGluamVjdChTQVZFRF9TRUFSQ0hFU19TRVJWSUNFX1BSRUZFUkVOQ0VTLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG4gICAgZ2V0IG5vZGVzQXBpKCk6IE5vZGVzQXBpIHtcbiAgICAgICAgdGhpcy5fbm9kZXNBcGkgPSB0aGlzLl9ub2Rlc0FwaSA/PyBuZXcgTm9kZXNBcGkodGhpcy5hcGlTZXJ2aWNlLmdldEluc3RhbmNlKCkpO1xuICAgICAgICByZXR1cm4gdGhpcy5fbm9kZXNBcGk7XG4gICAgfVxuXG4gICAgZ2V0IHByZWZlcmVuY2VzQXBpKCk6IFNhdmVkU2VhcmNoZXNQcmVmZXJlbmNlc0FwaVNlcnZpY2Uge1xuICAgICAgICBpZiAodGhpcy5wcmVmZXJlbmNlc1NlcnZpY2UpIHtcbiAgICAgICAgICAgIHRoaXMuX3ByZWZlcmVuY2VzQXBpID0gdGhpcy5wcmVmZXJlbmNlc1NlcnZpY2U7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJlZmVyZW5jZXNBcGk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9wcmVmZXJlbmNlc0FwaSA9IHRoaXMuX3ByZWZlcmVuY2VzQXBpID8/IG5ldyBQcmVmZXJlbmNlc0FwaSh0aGlzLmFwaVNlcnZpY2UuZ2V0SW5zdGFuY2UoKSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcmVmZXJlbmNlc0FwaTtcbiAgICB9XG5cbiAgICByZWFkb25seSBzYXZlZFNlYXJjaGVzJCA9IG5ldyBSZXBsYXlTdWJqZWN0PFNhdmVkU2VhcmNoW10+KDEpO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBhcGlTZXJ2aWNlOiBBbGZyZXNjb0FwaVNlcnZpY2UsIHByaXZhdGUgcmVhZG9ubHkgYXV0aFNlcnZpY2U6IEF1dGhlbnRpY2F0aW9uU2VydmljZSkge31cblxuICAgIGluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZmV0Y2hTYXZlZFNlYXJjaGVzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhIGxpc3Qgb2Ygc2F2ZWQgc2VhcmNoZXMgYnkgdXNlci5cbiAgICAgKlxuICAgICAqIEByZXR1cm5zIFNhdmVkU2VhcmNoIGxpc3QgY29udGFpbmluZyB1c2VyIHNhdmVkIHNlYXJjaGVzXG4gICAgICovXG4gICAgZ2V0U2F2ZWRTZWFyY2hlcygpOiBPYnNlcnZhYmxlPFNhdmVkU2VhcmNoW10+IHtcbiAgICAgICAgY29uc3Qgc2F2ZWRTZWFyY2hlc01pZ3JhdGVkID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5nZXRMb2NhbFN0b3JhZ2VLZXkoKSkgPz8gJyc7XG4gICAgICAgIGlmIChzYXZlZFNlYXJjaGVzTWlncmF0ZWQgPT09ICd0cnVlJykge1xuICAgICAgICAgICAgcmV0dXJuIGZyb20odGhpcy5wcmVmZXJlbmNlc0FwaS5nZXRQcmVmZXJlbmNlKCctbWUtJywgJ3NhdmVkLXNlYXJjaGVzJykpLnBpcGUoXG4gICAgICAgICAgICAgICAgbWFwKChwcmVmZXJlbmNlKSA9PiBKU09OLnBhcnNlKHByZWZlcmVuY2UuZW50cnkudmFsdWUpKSxcbiAgICAgICAgICAgICAgICBjYXRjaEVycm9yKCgpID0+IG9mKFtdKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRTYXZlZFNlYXJjaGVzTm9kZUlkKCkucGlwZShcbiAgICAgICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgICAgIGNvbmNhdE1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNhdmVkU2VhcmNoRmlsZU5vZGVJZCAhPT0gJycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1pZ3JhdGVTYXZlZFNlYXJjaGVzKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZnJvbSh0aGlzLnByZWZlcmVuY2VzQXBpLmdldFByZWZlcmVuY2UoJy1tZS0nLCAnc2F2ZWQtc2VhcmNoZXMnKSkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAoKHByZWZlcmVuY2UpID0+IEpTT04ucGFyc2UocHJlZmVyZW5jZS5lbnRyeS52YWx1ZSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YoW10pKVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2F2ZXMgYSBuZXcgc2VhcmNoIGludG8gc3RhdGUgYW5kIHVwZGF0ZXMgc3RhdGUuIElmIHRoZXJlIGFyZSBsZXNzIHRoYW4gNSBzZWFyY2hlcyxcbiAgICAgKiBpdCB3aWxsIGJlIHB1c2hlZCBvbiBmaXJzdCBwbGFjZSwgaWYgbW9yZSBpdCB3aWxsIGJlIHB1c2hlZCB0byA2dGggcGxhY2UuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbmV3U2F2ZVNlYXJjaCBvYmplY3QgeyBuYW1lOiBzdHJpbmcsIGRlc2NyaXB0aW9uOiBzdHJpbmcsIGVuY29kZWRVcmw6IHN0cmluZyB9XG4gICAgICogQHJldHVybnMgTm9kZUVudHJ5XG4gICAgICovXG4gICAgc2F2ZVNlYXJjaChuZXdTYXZlU2VhcmNoOiBQaWNrPFNhdmVkU2VhcmNoLCAnbmFtZScgfCAnZGVzY3JpcHRpb24nIHwgJ2VuY29kZWRVcmwnPik6IE9ic2VydmFibGU8Tm9kZUVudHJ5PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFNhdmVkU2VhcmNoZXMoKS5waXBlKFxuICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoc2F2ZWRTZWFyY2hlczogU2F2ZWRTZWFyY2hbXSkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCB1cGRhdGVkU2F2ZWRTZWFyY2hlczogU2F2ZWRTZWFyY2hbXSA9IFtdO1xuXG4gICAgICAgICAgICAgICAgaWYgKHNhdmVkU2VhcmNoZXMubGVuZ3RoIDwgNSkge1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVkU2F2ZWRTZWFyY2hlcyA9IFt7IC4uLm5ld1NhdmVTZWFyY2gsIG9yZGVyOiAwIH0sIC4uLnNhdmVkU2VhcmNoZXNdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpcnN0Rml2ZVNlYXJjaGVzID0gc2F2ZWRTZWFyY2hlcy5zbGljZSgwLCA1KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdE9mU2VhcmNoZXMgPSBzYXZlZFNlYXJjaGVzLnNsaWNlKDUpO1xuXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRTYXZlZFNlYXJjaGVzID0gWy4uLmZpcnN0Rml2ZVNlYXJjaGVzLCB7IC4uLm5ld1NhdmVTZWFyY2gsIG9yZGVyOiA1IH0sIC4uLnJlc3RPZlNlYXJjaGVzXTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB1cGRhdGVkU2F2ZWRTZWFyY2hlcyA9IHVwZGF0ZWRTYXZlZFNlYXJjaGVzLm1hcCgoc2VhcmNoLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgLi4uc2VhcmNoLFxuICAgICAgICAgICAgICAgICAgICBvcmRlcjogaW5kZXhcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gZnJvbSh0aGlzLnByZWZlcmVuY2VzQXBpLnVwZGF0ZVByZWZlcmVuY2UoJy1tZS0nLCAnc2F2ZWQtc2VhcmNoZXMnLCBKU09OLnN0cmluZ2lmeSh1cGRhdGVkU2F2ZWRTZWFyY2hlcykpKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICBtYXAoKHByZWZlcmVuY2UpID0+IEpTT04ucGFyc2UocHJlZmVyZW5jZS5lbnRyeS52YWx1ZSkpLFxuICAgICAgICAgICAgICAgICAgICB0YXAoKCkgPT4gdGhpcy5zYXZlZFNlYXJjaGVzJC5uZXh0KHVwZGF0ZWRTYXZlZFNlYXJjaGVzKSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNhdmluZyBuZXcgc2VhcmNoOicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlcGxhY2UgU2F2ZSBTZWFyY2ggd2l0aCBuZXcgb25lIGFuZCBhbHNvIHVwZGF0ZXMgdGhlIHN0YXRlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHVwZGF0ZWRTYXZlZFNlYXJjaCAtIHVwZGF0ZWQgU2F2ZSBTZWFyY2hcbiAgICAgKiBAcmV0dXJucyBOb2RlRW50cnlcbiAgICAgKi9cbiAgICBlZGl0U2F2ZWRTZWFyY2godXBkYXRlZFNhdmVkU2VhcmNoOiBTYXZlZFNlYXJjaCk6IE9ic2VydmFibGU8Tm9kZUVudHJ5PiB7XG4gICAgICAgIGxldCBwcmV2aW91c1NhdmVkU2VhcmNoZXM6IFNhdmVkU2VhcmNoW107XG4gICAgICAgIHJldHVybiB0aGlzLnNhdmVkU2VhcmNoZXMkLnBpcGUoXG4gICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgbWFwKChzYXZlZFNlYXJjaGVzOiBTYXZlZFNlYXJjaFtdKSA9PiB7XG4gICAgICAgICAgICAgICAgcHJldmlvdXNTYXZlZFNlYXJjaGVzID0gWy4uLnNhdmVkU2VhcmNoZXNdO1xuICAgICAgICAgICAgICAgIHJldHVybiBzYXZlZFNlYXJjaGVzLm1hcCgoc2VhcmNoKSA9PiAoc2VhcmNoLm9yZGVyID09PSB1cGRhdGVkU2F2ZWRTZWFyY2gub3JkZXIgPyB1cGRhdGVkU2F2ZWRTZWFyY2ggOiBzZWFyY2gpKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGFwKCh1cGRhdGVkU2VhcmNoZXM6IFNhdmVkU2VhcmNoW10pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNhdmVkU2VhcmNoZXMkLm5leHQodXBkYXRlZFNlYXJjaGVzKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgc3dpdGNoTWFwKCh1cGRhdGVkU2VhcmNoZXM6IFNhdmVkU2VhcmNoW10pID0+XG4gICAgICAgICAgICAgICAgZnJvbSh0aGlzLnByZWZlcmVuY2VzQXBpLnVwZGF0ZVByZWZlcmVuY2UoJy1tZS0nLCAnc2F2ZWQtc2VhcmNoZXMnLCBKU09OLnN0cmluZ2lmeSh1cGRhdGVkU2VhcmNoZXMpKSkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgbWFwKChwcmVmZXJlbmNlKSA9PiBKU09OLnBhcnNlKHByZWZlcmVuY2UuZW50cnkudmFsdWUpKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZWRTZWFyY2hlcyQubmV4dChwcmV2aW91c1NhdmVkU2VhcmNoZXMpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBTYXZlIFNlYXJjaCBhbmQgdXBkYXRlIHN0YXRlLlxuICAgICAqXG4gICAgICogQHBhcmFtIGRlbGV0ZWRTYXZlZFNlYXJjaCAtIFNhdmUgU2VhcmNoIHRvIGRlbGV0ZVxuICAgICAqIEByZXR1cm5zIE5vZGVFbnRyeVxuICAgICAqL1xuICAgIGRlbGV0ZVNhdmVkU2VhcmNoKGRlbGV0ZWRTYXZlZFNlYXJjaDogU2F2ZWRTZWFyY2gpOiBPYnNlcnZhYmxlPE5vZGVFbnRyeT4ge1xuICAgICAgICBsZXQgcHJldmlvdXNTYXZlZFNlYXJjaGVzT3JkZXI6IFNhdmVkU2VhcmNoW107XG4gICAgICAgIHJldHVybiB0aGlzLnNhdmVkU2VhcmNoZXMkLnBpcGUoXG4gICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgbWFwKChzYXZlZFNlYXJjaGVzOiBTYXZlZFNlYXJjaFtdKSA9PiB7XG4gICAgICAgICAgICAgICAgcHJldmlvdXNTYXZlZFNlYXJjaGVzT3JkZXIgPSBbLi4uc2F2ZWRTZWFyY2hlc107XG4gICAgICAgICAgICAgICAgY29uc3QgdXBkYXRlZFNlYXJjaGVzID0gc2F2ZWRTZWFyY2hlcy5maWx0ZXIoKHNlYXJjaCkgPT4gc2VhcmNoLm9yZGVyICE9PSBkZWxldGVkU2F2ZWRTZWFyY2gub3JkZXIpO1xuICAgICAgICAgICAgICAgIHJldHVybiB1cGRhdGVkU2VhcmNoZXMubWFwKChzZWFyY2gsIGluZGV4KSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAuLi5zZWFyY2gsXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyOiBpbmRleFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgdGFwKCh1cGRhdGVkU2VhcmNoZXM6IFNhdmVkU2VhcmNoW10pID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNhdmVkU2VhcmNoZXMkLm5leHQodXBkYXRlZFNlYXJjaGVzKTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgc3dpdGNoTWFwKCh1cGRhdGVkU2VhcmNoZXM6IFNhdmVkU2VhcmNoW10pID0+XG4gICAgICAgICAgICAgICAgZnJvbSh0aGlzLnByZWZlcmVuY2VzQXBpLnVwZGF0ZVByZWZlcmVuY2UoJy1tZS0nLCAnc2F2ZWQtc2VhcmNoZXMnLCBKU09OLnN0cmluZ2lmeSh1cGRhdGVkU2VhcmNoZXMpKSkucGlwZShcbiAgICAgICAgICAgICAgICAgICAgbWFwKChwcmVmZXJlbmNlKSA9PiBKU09OLnBhcnNlKHByZWZlcmVuY2UuZW50cnkudmFsdWUpKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZWRTZWFyY2hlcyQubmV4dChwcmV2aW91c1NhdmVkU2VhcmNoZXNPcmRlcik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gZXJyb3IpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW9yZGVycyBzYXZlZCBzZWFyY2ggcGxhY2VcbiAgICAgKlxuICAgICAqIEBwYXJhbSBwcmV2aW91c0luZGV4IC0gcHJldmlvdXMgaW5kZXggb2Ygc2F2ZWQgc2VhcmNoXG4gICAgICogQHBhcmFtIGN1cnJlbnRJbmRleCAtIG5ldyBpbmRleCBvZiBzYXZlZCBzZWFyY2hcbiAgICAgKi9cbiAgICBjaGFuZ2VPcmRlcihwcmV2aW91c0luZGV4OiBudW1iZXIsIGN1cnJlbnRJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGxldCBwcmV2aW91c1NhdmVkU2VhcmNoZXNPcmRlcjogU2F2ZWRTZWFyY2hbXTtcbiAgICAgICAgdGhpcy5zYXZlZFNlYXJjaGVzJFxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgICAgICBtYXAoKHNhdmVkU2VhcmNoZXM6IFNhdmVkU2VhcmNoW10pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNTYXZlZFNlYXJjaGVzT3JkZXIgPSBbLi4uc2F2ZWRTZWFyY2hlc107XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IFttb3ZlZFNlYXJjaF0gPSBzYXZlZFNlYXJjaGVzLnNwbGljZShwcmV2aW91c0luZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAgICAgc2F2ZWRTZWFyY2hlcy5zcGxpY2UoY3VycmVudEluZGV4LCAwLCBtb3ZlZFNlYXJjaCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzYXZlZFNlYXJjaGVzLm1hcCgoc2VhcmNoLCBpbmRleCkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLnNlYXJjaCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyOiBpbmRleFxuICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgdGFwKChzYXZlZFNlYXJjaGVzOiBTYXZlZFNlYXJjaFtdKSA9PiB0aGlzLnNhdmVkU2VhcmNoZXMkLm5leHQoc2F2ZWRTZWFyY2hlcykpLFxuICAgICAgICAgICAgICAgIHN3aXRjaE1hcCgodXBkYXRlZFNlYXJjaGVzOiBTYXZlZFNlYXJjaFtdKSA9PlxuICAgICAgICAgICAgICAgICAgICBmcm9tKHRoaXMucHJlZmVyZW5jZXNBcGkudXBkYXRlUHJlZmVyZW5jZSgnLW1lLScsICdzYXZlZC1zZWFyY2hlcycsIEpTT04uc3RyaW5naWZ5KHVwZGF0ZWRTZWFyY2hlcykpKS5waXBlKFxuICAgICAgICAgICAgICAgICAgICAgICAgbWFwKChwcmVmZXJlbmNlKSA9PiBKU09OLnBhcnNlKHByZWZlcmVuY2UuZW50cnkudmFsdWUpKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNhdmVkU2VhcmNoZXMkLm5leHQocHJldmlvdXNTYXZlZFNlYXJjaGVzT3JkZXIpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldFNhdmVkU2VhcmNoZXNOb2RlSWQoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICAgICAgcmV0dXJuIGZyb20odGhpcy5ub2Rlc0FwaS5nZXROb2RlKCctbXktJywgeyByZWxhdGl2ZVBhdGg6ICdjb25maWcuanNvbicgfSkpLnBpcGUoXG4gICAgICAgICAgICBmaXJzdCgpLFxuICAgICAgICAgICAgY29uY2F0TWFwKChjb25maWdOb2RlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zYXZlZFNlYXJjaEZpbGVOb2RlSWQgPSBjb25maWdOb2RlLmVudHJ5LmlkO1xuICAgICAgICAgICAgICAgIHJldHVybiBjb25maWdOb2RlLmVudHJ5LmlkO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yU3RhdHVzQ29kZSA9IEpTT04ucGFyc2UoZXJyb3IubWVzc2FnZSkuZXJyb3Iuc3RhdHVzQ29kZTtcbiAgICAgICAgICAgICAgICBpZiAoZXJyb3JTdGF0dXNDb2RlID09PSA0MDQpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0odGhpcy5nZXRMb2NhbFN0b3JhZ2VLZXkoKSwgJ3RydWUnKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgbWFwRmlsZUNvbnRlbnRUb1NhdmVkU2VhcmNoZXMoYmxvYjogQmxvYik6IFByb21pc2U8QXJyYXk8U2F2ZWRTZWFyY2g+PiB7XG4gICAgICAgIHJldHVybiBibG9iXG4gICAgICAgICAgICAudGV4dCgpXG4gICAgICAgICAgICAudGhlbigoY29udGVudCkgPT4gKGNvbnRlbnQgPyBKU09OLnBhcnNlKGNvbnRlbnQpIDogW10pKVxuICAgICAgICAgICAgLmNhdGNoKCgpID0+IFtdKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldExvY2FsU3RvcmFnZUtleSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYHNhdmVkLXNlYXJjaGVzLSR7dGhpcy5hdXRoU2VydmljZS5nZXRVc2VybmFtZSgpfS1taWdyYXRlZGA7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmZXRjaFNhdmVkU2VhcmNoZXMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZ2V0U2F2ZWRTZWFyY2hlcygpXG4gICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoc2VhcmNoZXMpID0+IHRoaXMuc2F2ZWRTZWFyY2hlcyQubmV4dChzZWFyY2hlcykpO1xuICAgIH1cblxuICAgIHByaXZhdGUgbWlncmF0ZVNhdmVkU2VhcmNoZXMoKTogT2JzZXJ2YWJsZTxTYXZlZFNlYXJjaFtdPiB7XG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMubm9kZXNBcGkuZ2V0Tm9kZUNvbnRlbnQodGhpcy5zYXZlZFNlYXJjaEZpbGVOb2RlSWQpLnRoZW4oKGNvbnRlbnQpID0+IHRoaXMubWFwRmlsZUNvbnRlbnRUb1NhdmVkU2VhcmNoZXMoY29udGVudCkpKS5waXBlKFxuICAgICAgICAgICAgdGFwKChzYXZlZFNlYXJjaGVzKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmVmZXJlbmNlc0FwaS51cGRhdGVQcmVmZXJlbmNlKCctbWUtJywgJ3NhdmVkLXNlYXJjaGVzJywgSlNPTi5zdHJpbmdpZnkoc2F2ZWRTZWFyY2hlcykpO1xuICAgICAgICAgICAgICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMuZ2V0TG9jYWxTdG9yYWdlS2V5KCksICd0cnVlJyk7XG4gICAgICAgICAgICAgICAgdGhpcy5ub2Rlc0FwaS5kZWxldGVOb2RlKHRoaXMuc2F2ZWRTZWFyY2hGaWxlTm9kZUlkLCB7IHBlcm1hbmVudDogdHJ1ZSB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxufVxuIl19