tree-ngx
Version:
A highly customizable Angular Tree Component, usable with minimal implementation.
136 lines • 19.3 kB
JavaScript
import { Component, Input, EventEmitter, Output, ContentChild } from '@angular/core';
import { TreeService } from '../service/tree-service';
import { TreeMode } from '../model/tree-mode';
import { timer } from 'rxjs';
import { TreeUtil } from '../util/util';
import * as i0 from "@angular/core";
import * as i1 from "../service/tree-service";
import * as i2 from "../node/node.component";
import * as i3 from "@angular/common";
export class TreeNgxComponent {
constructor(treeService) {
this.treeService = treeService;
this.defaultOptions = {
mode: TreeMode.SingleSelect,
checkboxes: false,
alwaysEmitSelected: false
};
this.options = this.defaultOptions;
this.callbacks = this.treeService.callbacks;
this.filter = '';
this.selectedItems = new EventEmitter();
}
ngOnInit() {
this.subscription = this.treeService.connect().subscribe(it => {
const sub = timer(0).subscribe(() => {
this.selectedItems.emit(it);
sub.unsubscribe();
});
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
ngOnChanges(changes) {
if (changes.filter) {
this.treeService.filterChanged(this.filter.toLowerCase());
}
if (changes.options) {
this.setOptions();
if (this.treeService.nodeItems) {
this.treeService.treeState = this.initTreeStructure(null, this.treeService.nodeItems, this.treeService.options);
this.treeService.clear();
this.treeService.setInitialState();
this.treeService.forceFilterTraverse();
}
}
if (changes.callbacks) {
this.treeService.callbacks = this.callbacks;
}
if (changes.nodeItems) {
this.initialize();
}
}
addNodeById(nodeItem, id) {
const newNodeState = TreeUtil.initState(null, nodeItem, this.options);
this.treeService.addNodeById(newNodeState, id);
}
deleteById(id) {
this.treeService.deleteById(id);
}
editNameById(id, name) {
this.treeService.editNameById(id, name);
}
editItemById(id, item) {
this.treeService.editItemById(id, item);
}
getParentById(id) {
return this.treeService.getParentById(id);
}
expandAll() {
this.treeService.toggleExpanded(true);
}
collapseAll() {
this.treeService.toggleExpanded(false);
}
expandById(id) {
this.treeService.expandById(id);
}
collapseById(id) {
this.treeService.collapseById(id);
}
selectById(id) {
this.treeService.selectById(id);
}
initialize() {
this.setOptions();
this.treeService.callbacks = this.callbacks;
this.treeService.nodeItems = this.nodeItems;
this.treeService.treeState = this.initTreeStructure(null, this.treeService.nodeItems, this.treeService.options);
this.treeService.clear();
this.treeService.setInitialState();
}
initTreeStructure(parent, nodeItems, options) {
let treeStructure = [];
for (let nodeItem of nodeItems) {
const nodeState = TreeUtil.initState(parent, nodeItem, options);
if (nodeItem.children) {
nodeState.children = this.initTreeStructure(nodeState, nodeItem.children, options);
nodeState.filteredChildren = nodeState.children;
}
treeStructure.push(nodeState);
}
return treeStructure;
}
setOptions() {
if (this.options.mode === TreeMode.NoSelect) {
this.treeService.options = { ...this.options, checkboxes: false };
}
else {
this.treeService.options = { ...this.options };
}
}
}
TreeNgxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeNgxComponent, deps: [{ token: i1.TreeService }], target: i0.ɵɵFactoryTarget.Component });
TreeNgxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.2", type: TreeNgxComponent, selector: "tree-ngx", inputs: { options: "options", callbacks: "callbacks", nodeItems: "nodeItems", filter: "filter" }, outputs: { selectedItems: "selectedItems" }, providers: [TreeService], queries: [{ propertyName: "nodeNameTemplate", first: true, predicate: ["nodeNameTemplate"], descendants: true }, { propertyName: "nodeCollapsibleTemplate", first: true, predicate: ["nodeCollapsibleTemplate"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"tree-ngx\">\r\n <node class=\"node-root\" [state]=\"state\" [selectedState]=\"state.selectedState\" [nodeCollapsibleTemplate]=\"nodeCollapsibleTemplate\"\r\n [nodeNameTemplate]=\"nodeNameTemplate\" *ngFor=\"let state of treeService.treeState\"></node>\r\n</div>\r\n", components: [{ type: i2.NodeComponent, selector: "node", inputs: ["state", "selectedState", "nodeNameTemplate", "nodeCollapsibleTemplate"] }], directives: [{ type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.2", ngImport: i0, type: TreeNgxComponent, decorators: [{
type: Component,
args: [{ selector: 'tree-ngx', providers: [TreeService], template: "<div class=\"tree-ngx\">\r\n <node class=\"node-root\" [state]=\"state\" [selectedState]=\"state.selectedState\" [nodeCollapsibleTemplate]=\"nodeCollapsibleTemplate\"\r\n [nodeNameTemplate]=\"nodeNameTemplate\" *ngFor=\"let state of treeService.treeState\"></node>\r\n</div>\r\n" }]
}], ctorParameters: function () { return [{ type: i1.TreeService }]; }, propDecorators: { nodeNameTemplate: [{
type: ContentChild,
args: ['nodeNameTemplate', { static: false }]
}], nodeCollapsibleTemplate: [{
type: ContentChild,
args: ['nodeCollapsibleTemplate', { static: false }]
}], options: [{
type: Input
}], callbacks: [{
type: Input
}], nodeItems: [{
type: Input
}], filter: [{
type: Input
}], selectedItems: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1uZ3guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL3RyZWUtbmd4L3NyYy90cmVlLW5neC90cmVlLW5neC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvdHJlZS1uZ3gvc3JjL3RyZWUtbmd4L3RyZWUtbmd4LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBSVQsS0FBSyxFQUNMLFlBQVksRUFDWixNQUFNLEVBQ04sWUFBWSxFQUdiLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUd0RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFnQixLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHM0MsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGNBQWMsQ0FBQzs7Ozs7QUFPeEMsTUFBTSxPQUFPLGdCQUFnQjtJQWtCM0IsWUFBbUIsV0FBd0I7UUFBeEIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFabkMsbUJBQWMsR0FBZ0I7WUFDcEMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxZQUFZO1lBQzNCLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLGtCQUFrQixFQUFFLEtBQUs7U0FDMUIsQ0FBQztRQUVPLFlBQU8sR0FBZ0IsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUMzQyxjQUFTLEdBQWtCLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDO1FBRXRELFdBQU0sR0FBRyxFQUFFLENBQUM7UUFDWCxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFHbEQsQ0FBQztJQUVELFFBQVE7UUFDTixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUMsU0FB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U0FDL0I7UUFFRCxPQUFPLGFBQWEsQ0FBQztJQUN2QixDQUFDO0lBRU8sVUFBVTtRQUNoQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxRQUFRLEVBQUU7WUFDM0MsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxDQUFDO1NBQ25FO2FBQU07WUFDTCxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQ2hEO0lBQ0gsQ0FBQzs7NkdBcklVLGdCQUFnQjtpR0FBaEIsZ0JBQWdCLGtMQUZoQixDQUFDLFdBQVcsQ0FBQyxzUkN6QjFCLDRSQUlBOzJGRHVCYSxnQkFBZ0I7a0JBTDVCLFNBQVM7K0JBQ0UsVUFBVSxhQUVULENBQUMsV0FBVyxDQUFDO2tHQUc2QixnQkFBZ0I7c0JBQXBFLFlBQVk7dUJBQUMsa0JBQWtCLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO2dCQUNTLHVCQUF1QjtzQkFBbEYsWUFBWTt1QkFBQyx5QkFBeUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBVWpELE9BQU87c0JBQWYsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNJLGFBQWE7c0JBQXRCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCxcclxuICBPbkluaXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9uQ2hhbmdlcyxcclxuICBJbnB1dCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgT3V0cHV0LFxyXG4gIENvbnRlbnRDaGlsZCxcclxuICBUZW1wbGF0ZVJlZixcclxuICBTaW1wbGVDaGFuZ2VzXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IE5vZGVJdGVtIH0gZnJvbSAnLi4vbW9kZWwvbm9kZS1pdGVtJztcclxuaW1wb3J0IHsgVHJlZVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlL3RyZWUtc2VydmljZSc7XHJcbmltcG9ydCB7IFRyZWVPcHRpb25zIH0gZnJvbSAnLi4vbW9kZWwvdHJlZS1vcHRpb25zJztcclxuaW1wb3J0IHsgVHJlZUNhbGxiYWNrcyB9IGZyb20gJy4uL21vZGVsL3RyZWUtY2FsbGJhY2tzJztcclxuaW1wb3J0IHsgVHJlZU1vZGUgfSBmcm9tICcuLi9tb2RlbC90cmVlLW1vZGUnO1xyXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIHRpbWVyIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IE5vZGVTdGF0ZSB9IGZyb20gJy4uL21vZGVsL25vZGUtc3RhdGUnO1xyXG5pbXBvcnQgeyBUcmVlTmd4IH0gZnJvbSAnLi4vbW9kZWwvdHJlZS1uZ3gnO1xyXG5pbXBvcnQgeyBUcmVlVXRpbCB9IGZyb20gJy4uL3V0aWwvdXRpbCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3RyZWUtbmd4JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vdHJlZS1uZ3guY29tcG9uZW50Lmh0bWwnLFxyXG4gIHByb3ZpZGVyczogW1RyZWVTZXJ2aWNlXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVHJlZU5neENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMsIFRyZWVOZ3gge1xyXG4gIEBDb250ZW50Q2hpbGQoJ25vZGVOYW1lVGVtcGxhdGUnLCB7IHN0YXRpYzogZmFsc2UgfSkgbm9kZU5hbWVUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcclxuICBAQ29udGVudENoaWxkKCdub2RlQ29sbGFwc2libGVUZW1wbGF0ZScsIHsgc3RhdGljOiBmYWxzZSB9KSBub2RlQ29sbGFwc2libGVUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcclxuXHJcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuXHJcbiAgcHJpdmF0ZSBkZWZhdWx0T3B0aW9uczogVHJlZU9wdGlvbnMgPSB7XHJcbiAgICBtb2RlOiBUcmVlTW9kZS5TaW5nbGVTZWxlY3QsXHJcbiAgICBjaGVja2JveGVzOiBmYWxzZSxcclxuICAgIGFsd2F5c0VtaXRTZWxlY3RlZDogZmFsc2VcclxuICB9O1xyXG5cclxuICBASW5wdXQoKSBvcHRpb25zOiBUcmVlT3B0aW9ucyA9IHRoaXMuZGVmYXVsdE9wdGlvbnM7XHJcbiAgQElucHV0KCkgY2FsbGJhY2tzOiBUcmVlQ2FsbGJhY2tzID0gdGhpcy50cmVlU2VydmljZS5jYWxsYmFja3M7XHJcbiAgQElucHV0KCkgbm9kZUl0ZW1zOiBOb2RlSXRlbTxhbnk+W107XHJcbiAgQElucHV0KCkgZmlsdGVyID0gJyc7XHJcbiAgQE91dHB1dCgpIHNlbGVjdGVkSXRlbXMgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgY29uc3RydWN0b3IocHVibGljIHRyZWVTZXJ2aWNlOiBUcmVlU2VydmljZSkge1xyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbiA9IHRoaXMudHJlZVNlcnZpY2UuY29ubmVjdCgpLnN1YnNjcmliZShpdCA9PiB7XHJcbiAgICAgIGNvbnN0IHN1YiA9IHRpbWVyKDApLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW1zLmVtaXQoaXQpO1xyXG4gICAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgaWYgKGNoYW5nZXMuZmlsdGVyKSB7XHJcbiAgICAgIHRoaXMudHJlZVNlcnZpY2UuZmlsdGVyQ2hhbmdlZCh0aGlzLmZpbHRlci50b0xvd2VyQ2FzZSgpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY2hhbmdlcy5vcHRpb25zKSB7XHJcbiAgICAgIHRoaXMuc2V0T3B0aW9ucygpO1xyXG4gICAgICBpZiAodGhpcy50cmVlU2VydmljZS5ub2RlSXRlbXMpIHtcclxuICAgICAgICB0aGlzLnRyZWVTZXJ2aWNlLnRyZWVTdGF0ZSA9IHRoaXMuaW5pdFRyZWVTdHJ1Y3R1cmUobnVsbCwgdGhpcy50cmVlU2VydmljZS5ub2RlSXRlbXMsIHRoaXMudHJlZVNlcnZpY2Uub3B0aW9ucyk7XHJcbiAgICAgICAgdGhpcy50cmVlU2VydmljZS5jbGVhcigpO1xyXG4gICAgICAgIHRoaXMudHJlZVNlcnZpY2Uuc2V0SW5pdGlhbFN0YXRlKCk7XHJcbiAgICAgICAgdGhpcy50cmVlU2VydmljZS5mb3JjZUZpbHRlclRyYXZlcnNlKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoY2hhbmdlcy5jYWxsYmFja3MpIHtcclxuICAgICAgdGhpcy50cmVlU2VydmljZS5jYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrcztcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY2hhbmdlcy5ub2RlSXRlbXMpIHtcclxuICAgICAgdGhpcy5pbml0aWFsaXplKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYWRkTm9kZUJ5SWQobm9kZUl0ZW06IE5vZGVJdGVtPGFueT4sIGlkPzogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBjb25zdCBuZXdOb2RlU3RhdGUgPSBUcmVlVXRpbC5pbml0U3RhdGUobnVsbCwgbm9kZUl0ZW0sIHRoaXMub3B0aW9ucyk7XHJcbiAgICB0aGlzLnRyZWVTZXJ2aWNlLmFkZE5vZGVCeUlkKG5ld05vZGVTdGF0ZSwgaWQpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGRlbGV0ZUJ5SWQoaWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy50cmVlU2VydmljZS5kZWxldGVCeUlkKGlkKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBlZGl0TmFtZUJ5SWQoaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0aGlzLnRyZWVTZXJ2aWNlLmVkaXROYW1lQnlJZChpZCwgbmFtZSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZWRpdEl0ZW1CeUlkKGlkOiBzdHJpbmcsIGl0ZW06IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy50cmVlU2VydmljZS5lZGl0SXRlbUJ5SWQoaWQsIGl0ZW0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldFBhcmVudEJ5SWQoaWQ6IHN0cmluZyk6IE5vZGVJdGVtPGFueT4ge1xyXG4gICAgcmV0dXJuIHRoaXMudHJlZVNlcnZpY2UuZ2V0UGFyZW50QnlJZChpZCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZXhwYW5kQWxsKCk6IHZvaWQge1xyXG4gICAgdGhpcy50cmVlU2VydmljZS50b2dnbGVFeHBhbmRlZCh0cnVlKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjb2xsYXBzZUFsbCgpOiB2b2lkIHtcclxuICAgIHRoaXMudHJlZVNlcnZpY2UudG9nZ2xlRXhwYW5kZWQoZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGV4cGFuZEJ5SWQoaWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy50cmVlU2VydmljZS5leHBhbmRCeUlkKGlkKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjb2xsYXBzZUJ5SWQoaWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy50cmVlU2VydmljZS5jb2xsYXBzZUJ5SWQoaWQpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNlbGVjdEJ5SWQoaWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy50cmVlU2VydmljZS5zZWxlY3RCeUlkKGlkKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBpbml0aWFsaXplKCkge1xyXG4gICAgdGhpcy5zZXRPcHRpb25zKCk7XHJcbiAgICB0aGlzLnRyZWVTZXJ2aWNlLmNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzO1xyXG4gICAgdGhpcy50cmVlU2VydmljZS5ub2RlSXRlbXMgPSB0aGlzLm5vZGVJdGVtcztcclxuXHJcbiAgICB0aGlzLnRyZWVTZXJ2aWNlLnRyZWVTdGF0ZSA9IHRoaXMuaW5pdFRyZWVTdHJ1Y3R1cmUobnVsbCwgdGhpcy50cmVlU2VydmljZS5ub2RlSXRlbXMsIHRoaXMudHJlZVNlcnZpY2Uub3B0aW9ucyk7XHJcbiAgICB0aGlzLnRyZWVTZXJ2aWNlLmNsZWFyKCk7XHJcbiAgICB0aGlzLnRyZWVTZXJ2aWNlLnNldEluaXRpYWxTdGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0VHJlZVN0cnVjdHVyZShwYXJlbnQ6IE5vZGVTdGF0ZSwgbm9kZUl0ZW1zOiBOb2RlSXRlbTxhbnk+W10sIG9wdGlvbnM6IFRyZWVPcHRpb25zKSB7XHJcbiAgICBsZXQgdHJlZVN0cnVjdHVyZTogTm9kZVN0YXRlW10gPSBbXTtcclxuXHJcbiAgICBmb3IgKGxldCBub2RlSXRlbSBvZiBub2RlSXRlbXMpIHtcclxuXHJcbiAgICAgIGNvbnN0IG5vZGVTdGF0ZSA9IFRyZWVVdGlsLmluaXRTdGF0ZShwYXJlbnQsIG5vZGVJdGVtLCBvcHRpb25zKTtcclxuXHJcbiAgICAgIGlmIChub2RlSXRlbS5jaGlsZHJlbikge1xyXG4gICAgICAgIG5vZGVTdGF0ZS5jaGlsZHJlbiA9IHRoaXMuaW5pdFRyZWVTdHJ1Y3R1cmUobm9kZVN0YXRlLCBub2RlSXRlbS5jaGlsZHJlbiwgb3B0aW9ucyk7XHJcbiAgICAgICAgbm9kZVN0YXRlLmZpbHRlcmVkQ2hpbGRyZW4gPSBub2RlU3RhdGUuY2hpbGRyZW47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRyZWVTdHJ1Y3R1cmUucHVzaChub2RlU3RhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0cmVlU3RydWN0dXJlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZXRPcHRpb25zKCkge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5tb2RlID09PSBUcmVlTW9kZS5Ob1NlbGVjdCkge1xyXG4gICAgICB0aGlzLnRyZWVTZXJ2aWNlLm9wdGlvbnMgPSB7IC4uLnRoaXMub3B0aW9ucywgY2hlY2tib3hlczogZmFsc2UgfTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMudHJlZVNlcnZpY2Uub3B0aW9ucyA9IHsgLi4udGhpcy5vcHRpb25zIH07XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjxkaXYgY2xhc3M9XCJ0cmVlLW5neFwiPlxyXG4gIDxub2RlIGNsYXNzPVwibm9kZS1yb290XCIgW3N0YXRlXT1cInN0YXRlXCIgW3NlbGVjdGVkU3RhdGVdPVwic3RhdGUuc2VsZWN0ZWRTdGF0ZVwiIFtub2RlQ29sbGFwc2libGVUZW1wbGF0ZV09XCJub2RlQ29sbGFwc2libGVUZW1wbGF0ZVwiXHJcbiAgICBbbm9kZU5hbWVUZW1wbGF0ZV09XCJub2RlTmFtZVRlbXBsYXRlXCIgKm5nRm9yPVwibGV0IHN0YXRlIG9mIHRyZWVTZXJ2aWNlLnRyZWVTdGF0ZVwiPjwvbm9kZT5cclxuPC9kaXY+XHJcbiJdfQ==