@alfresco/adf-content-services
Version:
Alfresco ADF content services
171 lines • 21.4 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 { AlfrescoApiService } from '../../services/alfresco-api.service';
import { AppConfigService, UserPreferencesService } from '@alfresco/adf-core';
import { EventEmitter, Injectable, Output } from '@angular/core';
import { from } from 'rxjs';
import { map, tap } from 'rxjs/operators';
import { TagBody, TagsApi } from '@alfresco/js-api';
import * as i0 from "@angular/core";
import * as i1 from "../../services/alfresco-api.service";
import * as i2 from "@alfresco/adf-core";
export class TagService {
get tagsApi() {
this._tagsApi = this._tagsApi ?? new TagsApi(this.apiService.getInstance());
return this._tagsApi;
}
constructor(apiService, userPreferencesService, appConfigService) {
this.apiService = apiService;
this.userPreferencesService = userPreferencesService;
this.appConfigService = appConfigService;
/** Emitted when tag information is updated. */
this.refresh = new EventEmitter();
}
/**
* Gets a list of tags added to a node.
*
* @param nodeId ID of the target node
* @returns TagPaging object (defined in JS-API) containing the tags
*/
getTagsByNodeId(nodeId) {
return from(this.tagsApi.listTagsForNode(nodeId));
}
/**
* Gets a list of all the tags already defined in the repository.
*
* @param opts Options supported by JS-API
* @param includedCounts True if count field should be included in response object for each tag, false otherwise.
* @returns TagPaging object (defined in JS-API) containing the tags
*/
getAllTheTags(opts, includedCounts) {
return from(this.tagsApi.listTags({
include: includedCounts ? ['count'] : undefined,
...opts
}));
}
/**
* Adds a tag to a node.
*
* @param nodeId ID of the target node
* @param tagName Name of the tag to add
* @returns TagEntry object (defined in JS-API) with details of the new tag
*/
addTag(nodeId, tagName) {
const tagBody = new TagBody();
tagBody.tag = tagName;
return from(this.tagsApi.createTagForNode(nodeId, [tagBody])).pipe(tap((tagEntry) => this.refresh.emit(tagEntry)));
}
/**
* Removes a tag from a node.
*
* @param nodeId ID of the target node
* @param tag Name of the tag to remove
* @returns Null object when the operation completes
*/
removeTag(nodeId, tag) {
return from(this.tagsApi.deleteTagFromNode(nodeId, tag)).pipe(tap(() => this.refresh.emit()));
}
/**
* Creates tags.
*
* @param tags list of tags to create.
* @returns Created tags.
*/
createTags(tags) {
return from(this.tagsApi.createTags(tags)).pipe(tap((tagEntries) => this.refresh.emit(tagEntries)));
}
/**
* Update a tag
*
* @param tagId The identifier of a tag.
* @param tagBody The updated tag.
* @returns Updated tag.
*/
updateTag(tagId, tagBody) {
return from(this.tagsApi.updateTag(tagId, tagBody)).pipe(tap((tagEntry) => this.refresh.emit(tagEntry)));
}
/**
* Find tags which name contains searched name.
*
* @param name Value for name which should be used during searching tags.
* @param sorting Object which configures sorting. OrderBy field specifies field used for sorting, direction specified ascending or descending direction.
* Default sorting is ascending by tag field.
* @param includedCounts True if count field should be included in response object for each tag, false otherwise.
* @param skipCount Specify how many first results should be skipped. Default 0.
* @param maxItems Specify max number of returned tags. Default is specified by UserPreferencesService.
* @returns Found tags which name contains searched name.
*/
searchTags(name, sorting = { orderBy: 'tag', direction: 'asc' }, includedCounts, skipCount = 0, maxItems) {
maxItems = maxItems || this.userPreferencesService.paginationSize;
return this.getAllTheTags({
tag: `*${name}*`,
skipCount,
maxItems,
sorting,
matching: true
}, includedCounts);
}
/**
* Find tag which name matches exactly to passed name.
*
* @param name Value for name which should be used during finding exact tag.
* @returns Found tag which name matches exactly to passed name.
*/
findTagByName(name) {
return this.getAllTheTags({ tag: name }).pipe(map((result) => result.list.entries[0]));
}
/**
* Deletes a tag with tagId.
* This will cause the tag to be removed from all nodes.
* You must have admin rights to delete a tag.
*
* @param tagId of the tag to be deleted
* @returns Null object when the operation completes
*/
deleteTag(tagId) {
return from(this.tagsApi.deleteTag(tagId)).pipe(tap(() => this.refresh.emit()));
}
/**
* Assign tags to node. If tag is new then tag is also created additionally, if tag already exists then it is just assigned.
*
* @param nodeId Id of node to which tags should be assigned.
* @param tags List of tags to create and assign or just assign if they already exist.
* @returns Just linked tags to node or single tag if linked only one tag.
*/
assignTagsToNode(nodeId, tags) {
return from(this.tagsApi.assignTagsToNode(nodeId, tags)).pipe(tap((data) => this.refresh.emit(data)));
}
/**
* Checks if tags plugin is enabled.
*
* @returns boolean true if tags plugin is enabled, false otherwise.
*/
areTagsEnabled() {
return this.appConfigService.get('plugins.tagsEnabled', true);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TagService, deps: [{ token: i1.AlfrescoApiService }, { token: i2.UserPreferencesService }, { token: i2.AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TagService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: TagService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i1.AlfrescoApiService }, { type: i2.UserPreferencesService }, { type: i2.AppConfigService }], propDecorators: { refresh: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL3RhZy9zZXJ2aWNlcy90YWcuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5RSxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDakUsT0FBTyxFQUFFLElBQUksRUFBYyxNQUFNLE1BQU0sQ0FBQztBQUN4QyxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxPQUFPLEVBQXVCLE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDOzs7O0FBS3pFLE1BQU0sT0FBTyxVQUFVO0lBRW5CLElBQUksT0FBTztRQUNQLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDNUUsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3pCLENBQUM7SUFNRCxZQUNZLFVBQThCLEVBQzlCLHNCQUE4QyxFQUM5QyxnQkFBa0M7UUFGbEMsZUFBVSxHQUFWLFVBQVUsQ0FBb0I7UUFDOUIsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3QjtRQUM5QyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBUDlDLCtDQUErQztRQUUvQyxZQUFPLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQU0xQixDQUFDO0lBRUo7Ozs7O09BS0c7SUFDSCxlQUFl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QyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxTQUFTLENBQUMsS0FBYTtRQUNuQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDcEYsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGdCQUFnQixDQUFDLE1BQWMsRUFBRSxJQUFlO1FBQzVDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFHLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsY0FBYztRQUNWLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNsRSxDQUFDOzhHQWhLUSxVQUFVO2tIQUFWLFVBQVUsY0FGUCxNQUFNOzsyRkFFVCxVQUFVO2tCQUh0QixVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQjsySkFVRyxPQUFPO3NCQUROLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgwqkgMjAwNS0yMDI1IEh5bGFuZCBTb2Z0d2FyZSwgSW5jLiBhbmQgaXRzIGFmZmlsaWF0ZXMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbmltcG9ydCB7IEFsZnJlc2NvQXBpU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2FsZnJlc2NvLWFwaS5zZXJ2aWNlJztcbmltcG9ydCB7IEFwcENvbmZpZ1NlcnZpY2UsIFVzZXJQcmVmZXJlbmNlc1NlcnZpY2UgfSBmcm9tICdAYWxmcmVzY28vYWRmLWNvcmUnO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyLCBJbmplY3RhYmxlLCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZyb20sIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVGFnQm9keSwgVGFnRW50cnksIFRhZ1BhZ2luZywgVGFnc0FwaSB9IGZyb20gJ0BhbGZyZXNjby9qcy1hcGknO1xuXG5ASW5qZWN0YWJsZSh7XG4gICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFRhZ1NlcnZpY2Uge1xuICAgIHByaXZhdGUgX3RhZ3NBcGk6IFRhZ3NBcGk7XG4gICAgZ2V0IHRhZ3NBcGkoKTogVGFnc0FwaSB7XG4gICAgICAgIHRoaXMuX3RhZ3NBcGkgPSB0aGlzLl90YWdzQXBpID8/IG5ldyBUYWdzQXBpKHRoaXMuYXBpU2VydmljZS5nZXRJbnN0YW5jZSgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RhZ3NBcGk7XG4gICAgfVxuXG4gICAgLyoqIEVtaXR0ZWQgd2hlbiB0YWcgaW5mb3JtYXRpb24gaXMgdXBkYXRlZC4gKi9cbiAgICBAT3V0cHV0KClcbiAgICByZWZyZXNoID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgYXBpU2VydmljZTogQWxmcmVzY29BcGlTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHVzZXJQcmVmZXJlbmNlc1NlcnZpY2U6IFVzZXJQcmVmZXJlbmNlc1NlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgYXBwQ29uZmlnU2VydmljZTogQXBwQ29uZmlnU2VydmljZVxuICAgICkge31cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSBsaXN0IG9mIHRhZ3MgYWRkZWQgdG8gYSBub2RlLlxuICAgICAqXG4gICAgICogQHBhcmFtIG5vZGVJZCBJRCBvZiB0aGUgdGFyZ2V0IG5vZGVcbiAgICAgKiBAcmV0dXJucyBUYWdQYWdpbmcgb2JqZWN0IChkZWZpbmVkIGluIEpTLUFQSSkgY29udGFpbmluZyB0aGUgdGFnc1xuICAgICAqL1xuICAgIGdldFRhZ3NCeU5vZGVJZChub2RlSWQ6IHN0cmluZyk6IE9ic2VydmFibGU8VGFnUGFnaW5nPiB7XG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMudGFnc0FwaS5saXN0VGFnc0Zvck5vZGUobm9kZUlkKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhIGxpc3Qgb2YgYWxsIHRoZSB0YWdzIGFscmVhZHkgZGVmaW5lZCBpbiB0aGUgcmVwb3NpdG9yeS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBvcHRzIE9wdGlvbnMgc3VwcG9ydGVkIGJ5IEpTLUFQSVxuICAgICAqIEBwYXJhbSBpbmNsdWRlZENvdW50cyBUcnVlIGlmIGNvdW50IGZpZWxkIHNob3VsZCBiZSBpbmNsdWRlZCBpbiByZXNwb25zZSBvYmplY3QgZm9yIGVhY2ggdGFnLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICogQHJldHVybnMgVGFnUGFnaW5nIG9iamVjdCAoZGVmaW5lZCBpbiBKUy1BUEkpIGNvbnRhaW5pbmcgdGhlIHRhZ3NcbiAgICAgKi9cbiAgICBnZXRBbGxUaGVUYWdzKG9wdHM/OiBhbnksIGluY2x1ZGVkQ291bnRzPzogYm9vbGVhbik6IE9ic2VydmFibGU8VGFnUGFnaW5nPiB7XG4gICAgICAgIHJldHVybiBmcm9tKFxuICAgICAgICAgICAgdGhpcy50YWdzQXBpLmxpc3RUYWdzKHtcbiAgICAgICAgICAgICAgICBpbmNsdWRlOiBpbmNsdWRlZENvdW50cyA/IFsnY291bnQnXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAuLi5vcHRzXG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSB0YWcgdG8gYSBub2RlLlxuICAgICAqXG4gICAgICogQHBhcmFtIG5vZGVJZCBJRCBvZiB0aGUgdGFyZ2V0IG5vZGVcbiAgICAgKiBAcGFyYW0gdGFnTmFtZSBOYW1lIG9mIHRoZSB0YWcgdG8gYWRkXG4gICAgICogQHJldHVybnMgVGFnRW50cnkgb2JqZWN0IChkZWZpbmVkIGluIEpTLUFQSSkgd2l0aCBkZXRhaWxzIG9mIHRoZSBuZXcgdGFnXG4gICAgICovXG4gICAgYWRkVGFnKG5vZGVJZDogc3RyaW5nLCB0YWdOYW1lOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFRhZ0VudHJ5PiB7XG4gICAgICAgIGNvbnN0IHRhZ0JvZHkgPSBuZXcgVGFnQm9keSgpO1xuICAgICAgICB0YWdCb2R5LnRhZyA9IHRhZ05hbWU7XG5cbiAgICAgICAgcmV0dXJuIGZyb20odGhpcy50YWdzQXBpLmNyZWF0ZVRhZ0Zvck5vZGUobm9kZUlkLCBbdGFnQm9keV0pKS5waXBlKHRhcCgodGFnRW50cnkpID0+IHRoaXMucmVmcmVzaC5lbWl0KHRhZ0VudHJ5KSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSB0YWcgZnJvbSBhIG5vZGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbm9kZUlkIElEIG9mIHRoZSB0YXJnZXQgbm9kZVxuICAgICAqIEBwYXJhbSB0YWcgTmFtZSBvZiB0aGUgdGFnIHRvIHJlbW92ZVxuICAgICAqIEByZXR1cm5zIE51bGwgb2JqZWN0IHdoZW4gdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXNcbiAgICAgKi9cbiAgICByZW1vdmVUYWcobm9kZUlkOiBzdHJpbmcsIHRhZzogc3RyaW5nKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMudGFnc0FwaS5kZWxldGVUYWdGcm9tTm9kZShub2RlSWQsIHRhZykpLnBpcGUodGFwKCgpID0+IHRoaXMucmVmcmVzaC5lbWl0KCkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIHRhZ3MuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdGFncyBsaXN0IG9mIHRhZ3MgdG8gY3JlYXRlLlxuICAgICAqIEByZXR1cm5zIENyZWF0ZWQgdGFncy5cbiAgICAgKi9cbiAgICBjcmVhdGVUYWdzKHRhZ3M6IFRhZ0JvZHlbXSk6IE9ic2VydmFibGU8VGFnRW50cnlbXT4ge1xuICAgICAgICByZXR1cm4gZnJvbSh0aGlzLnRhZ3NBcGkuY3JlYXRlVGFncyh0YWdzKSkucGlwZSh0YXAoKHRhZ0VudHJpZXMpID0+IHRoaXMucmVmcmVzaC5lbWl0KHRhZ0VudHJpZXMpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlIGEgdGFnXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdGFnSWQgVGhlIGlkZW50aWZpZXIgb2YgYSB0YWcuXG4gICAgICogQHBhcmFtIHRhZ0JvZHkgVGhlIHVwZGF0ZWQgdGFnLlxuICAgICAqIEByZXR1cm5zIFVwZGF0ZWQgdGFnLlxuICAgICAqL1xuICAgIHVwZGF0ZVRhZyh0YWdJZDogc3RyaW5nLCB0YWdCb2R5OiBUYWdCb2R5KTogT2JzZXJ2YWJsZTxUYWdFbnRyeT4ge1xuICAgICAgICByZXR1cm4gZnJvbSh0aGlzLnRhZ3NBcGkudXBkYXRlVGFnKHRhZ0lkLCB0YWdCb2R5KSkucGlwZSh0YXAoKHRhZ0VudHJ5KSA9PiB0aGlzLnJlZnJlc2guZW1pdCh0YWdFbnRyeSkpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaW5kIHRhZ3Mgd2hpY2ggbmFtZSBjb250YWlucyBzZWFyY2hlZCBuYW1lLlxuICAgICAqXG4gICAgICogQHBhcmFtIG5hbWUgVmFsdWUgZm9yIG5hbWUgd2hpY2ggc2hvdWxkIGJlIHVzZWQgZHVyaW5nIHNlYXJjaGluZyB0YWdzLlxuICAgICAqIEBwYXJhbSBzb3J0aW5nIE9iamVjdCB3aGljaCBjb25maWd1cmVzIHNvcnRpbmcuIE9yZGVyQnkgZmllbGQgc3BlY2lmaWVzIGZpZWxkIHVzZWQgZm9yIHNvcnRpbmcsIGRpcmVjdGlvbiBzcGVjaWZpZWQgYXNjZW5kaW5nIG9yIGRlc2NlbmRpbmcgZGlyZWN0aW9uLlxuICAgICAqIERlZmF1bHQgc29ydGluZyBpcyBhc2NlbmRpbmcgYnkgdGFnIGZpZWxkLlxuICAgICAqIEBwYXJhbSBpbmNsdWRlZENvdW50cyBUcnVlIGlmIGNvdW50IGZpZWxkIHNob3VsZCBiZSBpbmNsdWRlZCBpbiByZXNwb25zZSBvYmplY3QgZm9yIGVhY2ggdGFnLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICogQHBhcmFtIHNraXBDb3VudCBTcGVjaWZ5IGhvdyBtYW55IGZpcnN0IHJlc3VsdHMgc2hvdWxkIGJlIHNraXBwZWQuIERlZmF1bHQgMC5cbiAgICAgKiBAcGFyYW0gbWF4SXRlbXMgU3BlY2lmeSBtYXggbnVtYmVyIG9mIHJldHVybmVkIHRhZ3MuIERlZmF1bHQgaXMgc3BlY2lmaWVkIGJ5IFVzZXJQcmVmZXJlbmNlc1NlcnZpY2UuXG4gICAgICogQHJldHVybnMgRm91bmQgdGFncyB3aGljaCBuYW1lIGNvbnRhaW5zIHNlYXJjaGVkIG5hbWUuXG4gICAgICovXG4gICAgc2VhcmNoVGFncyhcbiAgICAgICAgbmFtZTogc3RyaW5nLFxuICAgICAgICBzb3J0aW5nID0geyBvcmRlckJ5OiAndGFnJywgZGlyZWN0aW9uOiAnYXNjJyB9LFxuICAgICAgICBpbmNsdWRlZENvdW50cz86IGJvb2xlYW4sXG4gICAgICAgIHNraXBDb3VudCA9IDAsXG4gICAgICAgIG1heEl0ZW1zPzogbnVtYmVyXG4gICAgKTogT2JzZXJ2YWJsZTxUYWdQYWdpbmc+IHtcbiAgICAgICAgbWF4SXRlbXMgPSBtYXhJdGVtcyB8fCB0aGlzLnVzZXJQcmVmZXJlbmNlc1NlcnZpY2UucGFnaW5hdGlvblNpemU7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEFsbFRoZVRhZ3MoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGFnOiBgKiR7bmFtZX0qYCxcbiAgICAgICAgICAgICAgICBza2lwQ291bnQsXG4gICAgICAgICAgICAgICAgbWF4SXRlbXMsXG4gICAgICAgICAgICAgICAgc29ydGluZyxcbiAgICAgICAgICAgICAgICBtYXRjaGluZzogdHJ1ZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGluY2x1ZGVkQ291bnRzXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmluZCB0YWcgd2hpY2ggbmFtZSBtYXRjaGVzIGV4YWN0bHkgdG8gcGFzc2VkIG5hbWUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbmFtZSBWYWx1ZSBmb3IgbmFtZSB3aGljaCBzaG91bGQgYmUgdXNlZCBkdXJpbmcgZmluZGluZyBleGFjdCB0YWcuXG4gICAgICogQHJldHVybnMgRm91bmQgdGFnIHdoaWNoIG5hbWUgbWF0Y2hlcyBleGFjdGx5IHRvIHBhc3NlZCBuYW1lLlxuICAgICAqL1xuICAgIGZpbmRUYWdCeU5hbWUobmFtZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxUYWdFbnRyeT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRBbGxUaGVUYWdzKHsgdGFnOiBuYW1lIH0pLnBpcGUobWFwKChyZXN1bHQpID0+IHJlc3VsdC5saXN0LmVudHJpZXNbMF0pKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGEgdGFnIHdpdGggdGFnSWQuXG4gICAgICogVGhpcyB3aWxsIGNhdXNlIHRoZSB0YWcgdG8gYmUgcmVtb3ZlZCBmcm9tIGFsbCBub2Rlcy5cbiAgICAgKiBZb3UgbXVzdCBoYXZlIGFkbWluIHJpZ2h0cyB0byBkZWxldGUgYSB0YWcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdGFnSWQgb2YgdGhlIHRhZyB0byBiZSBkZWxldGVkXG4gICAgICogQHJldHVybnMgTnVsbCBvYmplY3Qgd2hlbiB0aGUgb3BlcmF0aW9uIGNvbXBsZXRlc1xuICAgICAqL1xuICAgIGRlbGV0ZVRhZyh0YWdJZDogc3RyaW5nKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMudGFnc0FwaS5kZWxldGVUYWcodGFnSWQpKS5waXBlKHRhcCgoKSA9PiB0aGlzLnJlZnJlc2guZW1pdCgpKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXNzaWduIHRhZ3MgdG8gbm9kZS4gSWYgdGFnIGlzIG5ldyB0aGVuIHRhZyBpcyBhbHNvIGNyZWF0ZWQgYWRkaXRpb25hbGx5LCBpZiB0YWcgYWxyZWFkeSBleGlzdHMgdGhlbiBpdCBpcyBqdXN0IGFzc2lnbmVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIG5vZGVJZCBJZCBvZiBub2RlIHRvIHdoaWNoIHRhZ3Mgc2hvdWxkIGJlIGFzc2lnbmVkLlxuICAgICAqIEBwYXJhbSB0YWdzIExpc3Qgb2YgdGFncyB0byBjcmVhdGUgYW5kIGFzc2lnbiBvciBqdXN0IGFzc2lnbiBpZiB0aGV5IGFscmVhZHkgZXhpc3QuXG4gICAgICogQHJldHVybnMgSnVzdCBsaW5rZWQgdGFncyB0byBub2RlIG9yIHNpbmdsZSB0YWcgaWYgbGlua2VkIG9ubHkgb25lIHRhZy5cbiAgICAgKi9cbiAgICBhc3NpZ25UYWdzVG9Ob2RlKG5vZGVJZDogc3RyaW5nLCB0YWdzOiBUYWdCb2R5W10pOiBPYnNlcnZhYmxlPFRhZ1BhZ2luZyB8IFRhZ0VudHJ5PiB7XG4gICAgICAgIHJldHVybiBmcm9tKHRoaXMudGFnc0FwaS5hc3NpZ25UYWdzVG9Ob2RlKG5vZGVJZCwgdGFncykpLnBpcGUodGFwKChkYXRhKSA9PiB0aGlzLnJlZnJlc2guZW1pdChkYXRhKSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiB0YWdzIHBsdWdpbiBpcyBlbmFibGVkLlxuICAgICAqXG4gICAgICogQHJldHVybnMgYm9vbGVhbiB0cnVlIGlmIHRhZ3MgcGx1Z2luIGlzIGVuYWJsZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICAgKi9cbiAgICBhcmVUYWdzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwQ29uZmlnU2VydmljZS5nZXQoJ3BsdWdpbnMudGFnc0VuYWJsZWQnLCB0cnVlKTtcbiAgICB9XG59XG4iXX0=