@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
323 lines • 41.6 kB
JavaScript
import { DeviceStatusComponent, gettext, GroupFragment, NavigatorNode } from '@c8y/ngx-components';
import { debounce } from 'lodash-es';
import { BehaviorSubject, Subject } from 'rxjs';
import { AssetsNavigatorAction } from './action.enum';
import { LoadMoreNode } from './load-more-node';
export class AssetNode extends NavigatorNode {
static { this.NAME = 'AssetNode'; }
get hasChildren() {
return this.root || this.service.isGroup(this.mo);
}
get isDevice() {
return !!this.mo.c8y_IsDevice;
}
get isDeviceOrProbablyChildDevice() {
return this.isDevice || this.isNeitherDeviceOrGroup;
}
get isNeitherDeviceOrGroup() {
return (!this.service.isGroup(this.mo) &&
!this.service.isDynamicGroup(this.mo) &&
!this.isDevice &&
!this.root);
}
constructor(service, config = {}) {
super(config);
this.service = service;
this.config = config;
this.hideDevices = false;
this.filterQuery$ = new BehaviorSubject('');
this.showChildDevices = false;
/**
* Asset node children (subentries).
*/
this.children = [];
this.nodesFetched = new Subject();
this.root = this.root || false;
this.hideDevices = config.hideDevices ?? this.hideDevices;
this.mo = this.mo || {};
this.path = this.getPath();
this.draggable = !this.service?.moduleConfig?.disableDragAndDrop && !this.root;
this.droppable =
!this.service?.moduleConfig?.disableDragAndDrop && !this.isDeviceOrProbablyChildDevice;
this.routerLinkExact = this.root;
this.updateIcon(false);
this.onUpdateSubscription = this.service
.onUpdate(this)
.subscribe(({ data, method }) => this.refresh(data, method));
this.setLabel();
this.iconComponent = this.isDeviceOrProbablyChildDevice ? DeviceStatusComponent : undefined;
}
getPath() {
if (this.config.path) {
return this.config.path;
}
return this.root
? 'group'
: this.isDeviceOrProbablyChildDevice
? `device/${this.mo.id}`
: `group/${this.mo.id}`;
}
refresh(mo = {}, method = 'GET') {
if (mo?.id === this.mo.id) {
this.mo = mo;
this.setLabel();
}
else if (method === 'DELETE') {
this.parents.forEach((node) => node.refresh());
return;
}
if (this.events) {
this.events.next(AssetsNavigatorAction.REFRESH);
}
}
setLabel() {
if (this.config.label || this.root) {
this.label = this.config.label || gettext('Groups');
this.translateLabel = true;
}
else {
this.label = this.service.label(this.mo);
this.translateLabel = false;
}
}
click(options = {}) {
if (this.isDeviceOrProbablyChildDevice && !this.showChildDevices) {
this.service.preferBreadcrumb(this.parents);
return;
}
this.hookEvents();
this.updateIcon(options.open);
if (options.open) {
this.events.next(AssetsNavigatorAction.FETCH);
}
}
sort() {
this.children.sort((a, b) => {
if (a.priority > b.priority) {
return -1;
}
else if (a.priority < b.priority) {
return 1;
}
else {
return 0;
}
});
}
addManagedObject(mo) {
const { childAdditions } = this.mo;
if (!this.isChildAddition(childAdditions, mo)) {
this.add(this.service.createChildNode(mo, { hideDevices: this.hideDevices }));
}
}
isChildAddition(childAdditions, mo) {
return (childAdditions && childAdditions.references.some(({ managedObject: { id } }) => id === mo.id));
}
destroy() {
this.onUpdateSubscription.unsubscribe();
}
get canDrop() {
const nodeToMove = this.service.draggedData;
if (nodeToMove) {
const shouldGetChildOfItsOwn = !!nodeToMove.find(child => child === this);
const isAlreadyChild = this.children.some(child => child.mo && child.mo.id === nodeToMove.mo.id);
const preventMove = this === nodeToMove || shouldGetChildOfItsOwn || isAlreadyChild;
return this.droppable && !preventMove && this.service.canDropNode(this.root);
}
return this.droppable;
}
dragStart($event) {
super.dragStart($event);
this.service.draggedData = this;
this.service.rootNode.droppable = !this.isDeviceOrProbablyChildDevice;
}
dragEnd($event) {
super.dragEnd($event);
}
async drop($event) {
const nodeToMove = this.service.draggedData;
// TODO remove when asset type node can be used on the root level.
if (this.root && this.isAsset(nodeToMove)) {
this.service.alert.info(gettext('Asset type node cannot become root node.'));
this.draggedHover = false;
this.service.draggedData = undefined;
return;
}
super.drop($event);
if (this.canDrop) {
await this.moveNode(nodeToMove);
}
else {
this.draggedHover = false;
this.service.draggedData = undefined;
}
}
hookEvents() {
if (!this.events) {
this.events = new Subject();
this.events.subscribe(evt => {
if (!this.loading) {
this.handleEvent(evt);
}
});
}
}
toString() {
return AssetNode.NAME;
}
/**
* Checks if the current node has child devices.
*/
hasChildDevices() {
return this.mo && this.mo.c8y_IsDevice && this.mo.childDevices.references.length > 0;
}
fetch() {
return this.root
? this.service.getRootNodes()
: this.service.getGroupItems(this.mo.id, this.hideDevices
? {
query: `$filter=(has(${GroupFragment.groupFragmentType}))$orderby=name`
}
: {});
}
async updateIcon(open) {
this.icon = await this.service.icon(
// if it's root we are going to pass a fake mo to get the same icon as groups
this.root ? { c8y_IsDeviceGroup: {} } : this.mo, open);
}
countChildren() {
return this.children.length;
}
async handleEvent(evt) {
if (!this.countChildren() && evt === AssetsNavigatorAction.FETCH) {
this.loading = true;
this.addNodes(await this.fetch());
this.loading = false;
}
else if (evt === AssetsNavigatorAction.NEXT) {
this.loadMoreNode.loading = true;
this.addNodes(await this.paging.next());
this.loadMoreNode.loading = false;
}
else if (evt === AssetsNavigatorAction.REFRESH) {
this.loading = false;
this.paging = undefined;
this.loadMoreNode = undefined;
this.empty();
this.events.next(AssetsNavigatorAction.FETCH);
}
}
addNodes(res) {
if (res.paging) {
const { currentPage, nextPage, pageSize } = (this.paging = res.paging);
if (currentPage === 1) {
this.empty();
}
const itemsCount = res.data.length;
const moreItemsAvailable = !!nextPage && itemsCount === pageSize;
this.toggleLoadMore(moreItemsAvailable);
}
(res.data || res).map(mo => {
return this.addManagedObject(mo);
});
this.events.next(AssetsNavigatorAction.LOADING_DONE);
this.nodesFetched.next();
}
toggleLoadMore(show) {
if (!this.loadMoreNode && show) {
this.loadMoreNode = new LoadMoreNode();
this.add(this.loadMoreNode);
this.loadMoreNode.click = debounce(() => this.events.next(AssetsNavigatorAction.NEXT), 300, {
leading: true,
trailing: false
});
}
if (this.loadMoreNode) {
this.loadMoreNode.hidden = !show;
}
}
async moveNode(nodeToMove) {
try {
const isCopy = await this.showDropConfirm(nodeToMove);
await this.verifyNodeAccess(nodeToMove);
await this.addMovedNode(nodeToMove);
if (!isCopy) {
await this.removeMovedNode(nodeToMove);
}
this.expand();
}
catch (ex) {
if (ex) {
this.service.alert.addServerFailure(ex);
}
}
finally {
this.draggedHover = false;
this.service.draggedData = undefined;
}
}
async showDropConfirm(nodeToMove) {
this.confirm.title = gettext('Move');
this.confirm.message = gettext('Do you want to move the group?');
const buttons = [
{
label: gettext('Cancel'),
action: () => Promise.reject()
},
{
label: gettext('Move'),
status: 'default',
action: () => Promise.resolve(false)
}
];
if (nodeToMove.isDeviceOrProbablyChildDevice) {
this.confirm.title = gettext('Move or add');
this.confirm.message = gettext('Do you want to move or add the device?');
buttons.push({
label: gettext('Add'),
status: 'primary',
action: () => Promise.resolve(true)
});
}
return this.confirm.show(buttons);
}
async verifyNodeAccess(nodeToMove) {
return this.service.inventory.update({ id: nodeToMove.mo.id });
}
async addMovedNode(nodeToMove) {
let mo;
if (this.root && !this.isAsset(nodeToMove)) {
mo = (await this.service.inventory.update({
id: nodeToMove.mo.id,
type: GroupFragment.groupType
})).data;
this.addManagedObject(mo);
return;
}
mo = (await this.service.inventory.childAssetsAdd(nodeToMove.mo, this.mo)).data;
this.addManagedObject(mo);
}
isAsset(nodeToMove) {
// TODO use isAsset check when https://github.com/Cumulocity-IoT/cumulocity-ui/pull/690 is merged.
// Do not override asset type!
return nodeToMove.mo?.c8y_IsAsset;
}
async removeMovedNode(nodeToMove) {
for (const parent of nodeToMove.parents) {
if (parent.mo && parent.mo.type === GroupFragment.dynamicGroupType) {
break; // smart groups don't need to be changed
}
if (parent.root && !this.isAsset(nodeToMove)) {
await this.service.inventory.update({
id: nodeToMove.mo.id,
type: GroupFragment.subGroupType
});
}
if (!parent.root) {
await this.service.inventory.childAssetsRemove(nodeToMove.mo, parent.mo);
}
parent.remove(nodeToMove);
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXQtbm9kZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2Fzc2V0cy1uYXZpZ2F0b3IvYXNzZXQtbm9kZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBRUwscUJBQXFCLEVBQ3JCLE9BQU8sRUFDUCxhQUFhLEVBQ2IsYUFBYSxFQUVkLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNyQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDOUQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXRELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVoRCxNQUFNLE9BQU8sU0FBVSxTQUFRLGFBQWE7YUFDbkMsU0FBSSxHQUFHLFdBQVcsQUFBZCxDQUFlO0lBWTFCLElBQUksV0FBVztRQUNiLE9BQU8sSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELElBQUksUUFBUTtRQUNWLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxJQUFJLDZCQUE2QjtRQUMvQixPQUFPLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLHNCQUFzQixDQUFDO0lBQ3RELENBQUM7SUFFRCxJQUFJLHNCQUFzQjtRQUN4QixPQUFPLENBQ0wsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQzlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNyQyxDQUFDLElBQUksQ0FBQyxRQUFRO1lBQ2QsQ0FBQyxJ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QUMsQ0FBQztJQUM1QixDQUFDO0lBRU8sT0FBTyxDQUFDLFVBQXFCO1FBQ25DLGtHQUFrRztRQUNsRyw4QkFBOEI7UUFDOUIsT0FBTyxVQUFVLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQztJQUNwQyxDQUFDO0lBRU8sS0FBSyxDQUFDLGVBQWUsQ0FBQyxVQUFxQjtRQUNqRCxLQUFLLE1BQU0sTUFBTSxJQUFJLFVBQVUsQ0FBQyxPQUFzQixFQUFFLENBQUM7WUFDdkQsSUFBSSxNQUFNLENBQUMsRUFBRSxJQUFJLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUNuRSxNQUFNLENBQUMsd0NBQXdDO1lBQ2pELENBQUM7WUFFRCxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7Z0JBQzdDLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO29CQUNsQyxFQUFFLEVBQUUsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFO29CQUNwQixJQUFJLEVBQUUsYUFBYSxDQUFDLFlBQVk7aUJBQ2pDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUNqQixNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzNFLENBQUM7WUFDRCxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUlkZW50aWZpZWQsIFBhZ2luZyB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7XG4gIENsaWNrT3B0aW9ucyxcbiAgRGV2aWNlU3RhdHVzQ29tcG9uZW50LFxuICBnZXR0ZXh0LFxuICBHcm91cEZyYWdtZW50LFxuICBOYXZpZ2F0b3JOb2RlLFxuICBOYXZpZ2F0b3JOb2RlRGF0YVxufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IGRlYm91bmNlIH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBBc3NldHNOYXZpZ2F0b3JBY3Rpb24gfSBmcm9tICcuL2FjdGlvbi5lbnVtJztcbmltcG9ydCB7IEFzc2V0Tm9kZU1vLCBBc3NldE5vZGVTZXJ2aWNlIH0gZnJvbSAnLi9hc3NldC1ub2RlLnNlcnZpY2UnO1xuaW1wb3J0IHsgTG9hZE1vcmVOb2RlIH0gZnJvbSAnLi9sb2FkLW1vcmUtbm9kZSc7XG5cbmV4cG9ydCBjbGFzcyBBc3NldE5vZGUgZXh0ZW5kcyBOYXZpZ2F0b3JOb2RlIHtcbiAgc3RhdGljIE5BTUUgPSAnQXNzZXROb2RlJztcbiAgcm9vdDogYm9vbGVhbjtcbiAgbW86IGFueTtcbiAgaGlkZURldmljZXMgPSBmYWxzZTtcbiAgZmlsdGVyUXVlcnkkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcbiAgc2hvd0NoaWxkRGV2aWNlcyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBBc3NldCBub2RlIGNoaWxkcmVuIChzdWJlbnRyaWVzKS5cbiAgICovXG4gIGNoaWxkcmVuOiBBc3NldE5vZGVbXSA9IFtdO1xuXG4gIGdldCBoYXNDaGlsZHJlbigpIHtcbiAgICByZXR1cm4gdGhpcy5yb290IHx8IHRoaXMuc2VydmljZS5pc0dyb3VwKHRoaXMubW8pO1xuICB9XG5cbiAgZ2V0IGlzRGV2aWNlKCkge1xuICAgIHJldHVybiAhIXRoaXMubW8uYzh5X0lzRGV2aWNlO1xuICB9XG5cbiAgZ2V0IGlzRGV2aWNlT3JQcm9iYWJseUNoaWxkRGV2aWNlKCkge1xuICAgIHJldHVybiB0aGlzLmlzRGV2aWNlIHx8IHRoaXMuaXNOZWl0aGVyRGV2aWNlT3JHcm91cDtcbiAgfVxuXG4gIGdldCBpc05laXRoZXJEZXZpY2VPckdyb3VwKCkge1xuICAgIHJldHVybiAoXG4gICAgICAhdGhpcy5zZXJ2aWNlLmlzR3JvdXAodGhpcy5tbykgJiZcbiAgICAgICF0aGlzLnNlcnZpY2UuaXNEeW5hbWljR3JvdXAodGhpcy5tbykgJiZcbiAgICAgICF0aGlzLmlzRGV2aWNlICYmXG4gICAgICAhdGhpcy5yb290XG4gICAgKTtcbiAgfVxuXG4gIGV2ZW50czogU3ViamVjdDxBc3NldHNOYXZpZ2F0b3JBY3Rpb24+O1xuICBub2Rlc0ZldGNoZWQ6IFN1YmplY3Q8dm9pZD4gPSBuZXcgU3ViamVjdCgpO1xuICBwcm90ZWN0ZWQgcGFnaW5nOiBQYWdpbmc8QXNzZXROb2RlTW8+O1xuICBwcm90ZWN0ZWQgbG9hZE1vcmVOb2RlOiBMb2FkTW9yZU5vZGU7XG4gIHByaXZhdGUgb25VcGRhdGVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgc2VydmljZTogQXNzZXROb2RlU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgY29uZmlnOiBOYXZpZ2F0b3JOb2RlRGF0YSA9IHt9XG4gICkge1xuICAgIHN1cGVyKGNvbmZpZyk7XG5cbiAgICB0aGlzLnJvb3QgPSB0aGlzLnJvb3QgfHwgZmFsc2U7XG4gICAgdGhpcy5oaWRlRGV2aWNlcyA9IGNvbmZpZy5oaWRlRGV2aWNlcyA/PyB0aGlzLmhpZGVEZXZpY2VzO1xuICAgIHRoaXMubW8gPSB0aGlzLm1vIHx8IHt9O1xuICAgIHRoaXMucGF0aCA9IHRoaXMuZ2V0UGF0aCgpO1xuICAgIHRoaXMuZHJhZ2dhYmxlID0gIXRoaXMuc2VydmljZT8ubW9kdWxlQ29uZmlnPy5kaXNhYmxlRHJhZ0FuZERyb3AgJiYgIXRoaXMucm9vdDtcbiAgICB0aGlzLmRyb3BwYWJsZSA9XG4gICAgICAhdGhpcy5zZXJ2aWNlPy5tb2R1bGVDb25maWc/LmRpc2FibGVEcmFnQW5kRHJvcCAmJiAhdGhpcy5pc0RldmljZU9yUHJvYmFibHlDaGlsZERldmljZTtcbiAgICB0aGlzLnJvdXRlckxpbmtFeGFjdCA9IHRoaXMucm9vdDtcbiAgICB0aGlzLnVwZGF0ZUljb24oZmFsc2UpO1xuICAgIHRoaXMub25VcGRhdGVTdWJzY3JpcHRpb24gPSB0aGlzLnNlcnZpY2VcbiAgICAgIC5vblVwZGF0ZSh0aGlzKVxuICAgICAgLnN1YnNjcmliZSgoeyBkYXRhLCBtZXRob2QgfSkgPT4gdGhpcy5yZWZyZXNoKGRhdGEsIG1ldGhvZCkpO1xuICAgIHRoaXMuc2V0TGFiZWwoKTtcbiAgICB0aGlzLmljb25Db21wb25lbnQgPSB0aGlzLmlzRGV2aWNlT3JQcm9iYWJseUNoaWxkRGV2aWNlID8gRGV2aWNlU3RhdHVzQ29tcG9uZW50IDogdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0UGF0aCgpIHtcbiAgICBpZiAodGhpcy5jb25maWcucGF0aCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnBhdGg7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucm9vdFxuICAgICAgPyAnZ3JvdXAnXG4gICAgICA6IHRoaXMuaXNEZXZpY2VPclByb2JhYmx5Q2hpbGREZXZpY2VcbiAgICAgICAgPyBgZGV2aWNlLyR7dGhpcy5tby5pZH1gXG4gICAgICAgIDogYGdyb3VwLyR7dGhpcy5tby5pZH1gO1xuICB9XG5cbiAgcmVmcmVzaChtbzogYW55ID0ge30sIG1ldGhvZCA9ICdHRVQnKSB7XG4gICAgaWYgKG1vPy5pZCA9PT0gdGhpcy5tby5pZCkge1xuICAgICAgdGhpcy5tbyA9IG1vO1xuICAgICAgdGhpcy5zZXRMYWJlbCgpO1xuICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSAnREVMRVRFJykge1xuICAgICAgdGhpcy5wYXJlbnRzLmZvckVhY2goKG5vZGU6IEFzc2V0Tm9kZSkgPT4gbm9kZS5yZWZyZXNoKCkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5ldmVudHMpIHtcbiAgICAgIHRoaXMuZXZlbnRzLm5leHQoQXNzZXRzTmF2aWdhdG9yQWN0aW9uLlJFRlJFU0gpO1xuICAgIH1cbiAgfVxuXG4gIHNldExhYmVsKCkge1xuICAgIGlmICh0aGlzLmNvbmZpZy5sYWJlbCB8fCB0aGlzLnJvb3QpIHtcbiAgICAgIHRoaXMubGFiZWwgPSB0aGlzLmNvbmZpZy5sYWJlbCB8fCBnZXR0ZXh0KCdHcm91cHMnKTtcbiAgICAgIHRoaXMudHJhbnNsYXRlTGFiZWwgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxhYmVsID0gdGhpcy5zZXJ2aWNlLmxhYmVsKHRoaXMubW8pO1xuICAgICAgdGhpcy50cmFuc2xhdGVMYWJlbCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGNsaWNrKG9wdGlvbnM6IENsaWNrT3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKHRoaXMuaXNEZXZpY2VPclByb2JhYmx5Q2hpbGREZXZpY2UgJiYgIXRoaXMuc2hvd0NoaWxkRGV2aWNlcykge1xuICAgICAgdGhpcy5zZXJ2aWNlLnByZWZlckJyZWFkY3J1bWIodGhpcy5wYXJlbnRzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5ob29rRXZlbnRzKCk7XG4gICAgdGhpcy51cGRhdGVJY29uKG9wdGlvbnMub3Blbik7XG4gICAgaWYgKG9wdGlvbnMub3Blbikge1xuICAgICAgdGhpcy5ldmVudHMubmV4dChBc3NldHNOYXZpZ2F0b3JBY3Rpb24uRkVUQ0gpO1xuICAgIH1cbiAgfVxuXG4gIHNvcnQoKSB7XG4gICAgdGhpcy5jaGlsZHJlbi5zb3J0KChhLCBiKSA9PiB7XG4gICAgICBpZiAoYS5wcmlvcml0eSA+IGIucHJpb3JpdHkpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfSBlbHNlIGlmIChhLnByaW9yaXR5IDwgYi5wcmlvcml0eSkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgYWRkTWFuYWdlZE9iamVjdChtbykge1xuICAgIGNvbnN0IHsgY2hpbGRBZGRpdGlvbnMgfSA9IHRoaXMubW87XG4gICAgaWYgKCF0aGlzLmlzQ2hpbGRBZGRpdGlvbihjaGlsZEFkZGl0aW9ucywgbW8pKSB7XG4gICAgICB0aGlzLmFkZCh0aGlzLnNlcnZpY2UuY3JlYXRlQ2hpbGROb2RlKG1vLCB7IGhpZGVEZXZpY2VzOiB0aGlzLmhpZGVEZXZpY2VzIH0pKTtcbiAgICB9XG4gIH1cblxuICBpc0NoaWxkQWRkaXRpb24oY2hpbGRBZGRpdGlvbnMsIG1vKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGNoaWxkQWRkaXRpb25zICYmIGNoaWxkQWRkaXRpb25zLnJlZmVyZW5jZXMuc29tZSgoeyBtYW5hZ2VkT2JqZWN0OiB7IGlkIH0gfSkgPT4gaWQgPT09IG1vLmlkKVxuICAgICk7XG4gIH1cblxuICBkZXN0cm95KCkge1xuICAgIHRoaXMub25VcGRhdGVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIGdldCBjYW5Ecm9wKCkge1xuICAgIGNvbnN0IG5vZGVUb01vdmUgPSB0aGlzLnNlcnZpY2UuZHJhZ2dlZERhdGE7XG4gICAgaWYgKG5vZGVUb01vdmUpIHtcbiAgICAgIGNvbnN0IHNob3VsZEdldENoaWxkT2ZJdHNPd24gPSAhIW5vZGVUb01vdmUuZmluZChjaGlsZCA9PiBjaGlsZCA9PT0gdGhpcyk7XG4gICAgICBjb25zdCBpc0FscmVhZHlDaGlsZCA9ICh0aGlzLmNoaWxkcmVuIGFzIEFzc2V0Tm9kZVtdKS5zb21lKFxuICAgICAgICBjaGlsZCA9PiBjaGlsZC5tbyAmJiBjaGlsZC5tby5pZCA9PT0gbm9kZVRvTW92ZS5tby5pZFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHByZXZlbnRNb3ZlID0gdGhpcyA9PT0gbm9kZVRvTW92ZSB8fCBzaG91bGRHZXRDaGlsZE9mSXRzT3duIHx8IGlzQWxyZWFkeUNoaWxkO1xuICAgICAgcmV0dXJuIHRoaXMuZHJvcHBhYmxlICYmICFwcmV2ZW50TW92ZSAmJiB0aGlzLnNlcnZpY2UuY2FuRHJvcE5vZGUodGhpcy5yb290KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZHJvcHBhYmxlO1xuICB9XG5cbiAgZHJhZ1N0YXJ0KCRldmVudCkge1xuICAgIHN1cGVyLmRyYWdTdGFydCgkZXZlbnQpO1xuICAgIHRoaXMuc2VydmljZS5kcmFnZ2VkRGF0YSA9IHRoaXM7XG4gICAgdGhpcy5zZXJ2aWNlLnJvb3ROb2RlLmRyb3BwYWJsZSA9ICF0aGlzLmlzRGV2aWNlT3JQcm9iYWJseUNoaWxkRGV2aWNlO1xuICB9XG5cbiAgZHJhZ0VuZCgkZXZlbnQpIHtcbiAgICBzdXBlci5kcmFnRW5kKCRldmVudCk7XG4gIH1cblxuICBhc3luYyBkcm9wKCRldmVudCkge1xuICAgIGNvbnN0IG5vZGVUb01vdmUgPSB0aGlzLnNlcnZpY2UuZHJhZ2dlZERhdGE7XG5cbiAgICAvLyBUT0RPIHJlbW92ZSB3aGVuIGFzc2V0IHR5cGUgbm9kZSBjYW4gYmUgdXNlZCBvbiB0aGUgcm9vdCBsZXZlbC5cbiAgICBpZiAodGhpcy5yb290ICYmIHRoaXMuaXNBc3NldChub2RlVG9Nb3ZlKSkge1xuICAgICAgdGhpcy5zZXJ2aWNlLmFsZXJ0LmluZm8oZ2V0dGV4dCgnQXNzZXQgdHlwZSBub2RlIGNhbm5vdCBiZWNvbWUgcm9vdCBub2RlLicpKTtcbiAgICAgIHRoaXMuZHJhZ2dlZEhvdmVyID0gZmFsc2U7XG4gICAgICB0aGlzLnNlcnZpY2UuZHJhZ2dlZERhdGEgPSB1bmRlZmluZWQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc3VwZXIuZHJvcCgkZXZlbnQpO1xuICAgIGlmICh0aGlzLmNhbkRyb3ApIHtcbiAgICAgIGF3YWl0IHRoaXMubW92ZU5vZGUobm9kZVRvTW92ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZHJhZ2dlZEhvdmVyID0gZmFsc2U7XG4gICAgICB0aGlzLnNlcnZpY2UuZHJhZ2dlZERhdGEgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgaG9va0V2ZW50cygpIHtcbiAgICBpZiAoIXRoaXMuZXZlbnRzKSB7XG4gICAgICB0aGlzLmV2ZW50cyA9IG5ldyBTdWJqZWN0KCk7XG4gICAgICB0aGlzLmV2ZW50cy5zdWJzY3JpYmUoZXZ0ID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmxvYWRpbmcpIHtcbiAgICAgICAgICB0aGlzLmhhbmRsZUV2ZW50KGV2dCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiBBc3NldE5vZGUuTkFNRTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgbm9kZSBoYXMgY2hpbGQgZGV2aWNlcy5cbiAgICovXG4gIGhhc0NoaWxkRGV2aWNlcygpIHtcbiAgICByZXR1cm4gdGhpcy5tbyAmJiB0aGlzLm1vLmM4eV9Jc0RldmljZSAmJiB0aGlzLm1vLmNoaWxkRGV2aWNlcy5yZWZlcmVuY2VzLmxlbmd0aCA+IDA7XG4gIH1cblxuICBwcm90ZWN0ZWQgZmV0Y2goKSB7XG4gICAgcmV0dXJuIHRoaXMucm9vdFxuICAgICAgPyB0aGlzLnNlcnZpY2UuZ2V0Um9vdE5vZGVzKClcbiAgICAgIDogdGhpcy5zZXJ2aWNlLmdldEdyb3VwSXRlbXMoXG4gICAgICAgICAgdGhpcy5tby5pZCxcbiAgICAgICAgICB0aGlzLmhpZGVEZXZpY2VzXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBxdWVyeTogYCRmaWx0ZXI9KGhhcygke0dyb3VwRnJhZ21lbnQuZ3JvdXBGcmFnbWVudFR5cGV9KSkkb3JkZXJieT1uYW1lYFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHt9XG4gICAgICAgICk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlSWNvbihvcGVuKSB7XG4gICAgdGhpcy5pY29uID0gYXdhaXQgdGhpcy5zZXJ2aWNlLmljb24oXG4gICAgICAvLyBpZiBpdCdzIHJvb3Qgd2UgYXJlIGdvaW5nIHRvIHBhc3MgYSBmYWtlIG1vIHRvIGdldCB0aGUgc2FtZSBpY29uIGFzIGdyb3Vwc1xuICAgICAgdGhpcy5yb290ID8geyBjOHlfSXNEZXZpY2VHcm91cDoge30gfSA6IHRoaXMubW8sXG4gICAgICBvcGVuXG4gICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjb3VudENoaWxkcmVuKCkge1xuICAgIHJldHVybiB0aGlzLmNoaWxkcmVuLmxlbmd0aDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBoYW5kbGVFdmVudChldnQ6IEFzc2V0c05hdmlnYXRvckFjdGlvbikge1xuICAgIGlmICghdGhpcy5jb3VudENoaWxkcmVuKCkgJiYgZXZ0ID09PSBBc3NldHNOYXZpZ2F0b3JBY3Rpb24uRkVUQ0gpIHtcbiAgICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG4gICAgICB0aGlzLmFkZE5vZGVzKGF3YWl0IHRoaXMuZmV0Y2goKSk7XG4gICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKGV2dCA9PT0gQXNzZXRzTmF2aWdhdG9yQWN0aW9uLk5FWFQpIHtcbiAgICAgIHRoaXMubG9hZE1vcmVOb2RlLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5hZGROb2Rlcyhhd2FpdCB0aGlzLnBhZ2luZy5uZXh0KCkpO1xuICAgICAgdGhpcy5sb2FkTW9yZU5vZGUubG9hZGluZyA9IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoZXZ0ID09PSBBc3NldHNOYXZpZ2F0b3JBY3Rpb24uUkVGUkVTSCkge1xuICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgICB0aGlzLnBhZ2luZyA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMubG9hZE1vcmVOb2RlID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5lbXB0eSgpO1xuICAgICAgdGhpcy5ldmVudHMubmV4dChBc3NldHNOYXZpZ2F0b3JBY3Rpb24uRkVUQ0gpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhZGROb2RlcyhyZXMpIHtcbiAgICBpZiAocmVzLnBhZ2luZykge1xuICAgICAgY29uc3QgeyBjdXJyZW50UGFnZSwgbmV4dFBhZ2UsIHBhZ2VTaXplIH0gPSAodGhpcy5wYWdpbmcgPSByZXMucGFnaW5nKTtcbiAgICAgIGlmIChjdXJyZW50UGFnZSA9PT0gMSkge1xuICAgICAgICB0aGlzLmVtcHR5KCk7XG4gICAgICB9XG4gICAgICBjb25zdCBpdGVtc0NvdW50ID0gcmVzLmRhdGEubGVuZ3RoO1xuICAgICAgY29uc3QgbW9yZUl0ZW1zQXZhaWxhYmxlID0gISFuZXh0UGFnZSAmJiBpdGVtc0NvdW50ID09PSBwYWdlU2l6ZTtcbiAgICAgIHRoaXMudG9nZ2xlTG9hZE1vcmUobW9yZUl0ZW1zQXZhaWxhYmxlKTtcbiAgICB9XG4gICAgKHJlcy5kYXRhIHx8IHJlcykubWFwKG1vID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmFkZE1hbmFnZWRPYmplY3QobW8pO1xuICAgIH0pO1xuICAgIHRoaXMuZXZlbnRzLm5leHQoQXNzZXRzTmF2aWdhdG9yQWN0aW9uLkxPQURJTkdfRE9ORSk7XG4gICAgdGhpcy5ub2Rlc0ZldGNoZWQubmV4dCgpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHRvZ2dsZUxvYWRNb3JlKHNob3c6IGJvb2xlYW4pIHtcbiAgICBpZiAoIXRoaXMubG9hZE1vcmVOb2RlICYmIHNob3cpIHtcbiAgICAgIHRoaXMubG9hZE1vcmVOb2RlID0gbmV3IExvYWRNb3JlTm9kZSgpO1xuICAgICAgdGhpcy5hZGQodGhpcy5sb2FkTW9yZU5vZGUpO1xuICAgICAgdGhpcy5sb2FkTW9yZU5vZGUuY2xpY2sgPSBkZWJvdW5jZSgoKSA9PiB0aGlzLmV2ZW50cy5uZXh0KEFzc2V0c05hdmlnYXRvckFjdGlvbi5ORVhUKSwgMzAwLCB7XG4gICAgICAgIGxlYWRpbmc6IHRydWUsXG4gICAgICAgIHRyYWlsaW5nOiBmYWxzZVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubG9hZE1vcmVOb2RlKSB7XG4gICAgICB0aGlzLmxvYWRNb3JlTm9kZS5oaWRkZW4gPSAhc2hvdztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG1vdmVOb2RlKG5vZGVUb01vdmU6IEFzc2V0Tm9kZSkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBpc0NvcHkgPSBhd2FpdCB0aGlzLnNob3dEcm9wQ29uZmlybShub2RlVG9Nb3ZlKTtcbiAgICAgIGF3YWl0IHRoaXMudmVyaWZ5Tm9kZUFjY2Vzcyhub2RlVG9Nb3ZlKTtcbiAgICAgIGF3YWl0IHRoaXMuYWRkTW92ZWROb2RlKG5vZGVUb01vdmUpO1xuICAgICAgaWYgKCFpc0NvcHkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZW1vdmVNb3ZlZE5vZGUobm9kZVRvTW92ZSk7XG4gICAgICB9XG4gICAgICB0aGlzLmV4cGFuZCgpO1xuICAgIH0gY2F0Y2ggKGV4KSB7XG4gICAgICBpZiAoZXgpIHtcbiAgICAgICAgdGhpcy5zZXJ2aWNlLmFsZXJ0LmFkZFNlcnZlckZhaWx1cmUoZXgpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmRyYWdnZWRIb3ZlciA9IGZhbHNlO1xuICAgICAgdGhpcy5zZXJ2aWNlLmRyYWdnZWREYXRhID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2hvd0Ryb3BDb25maXJtKG5vZGVUb01vdmU6IEFzc2V0Tm9kZSkge1xuICAgIHRoaXMuY29uZmlybS50aXRsZSA9IGdldHRleHQoJ01vdmUnKTtcbiAgICB0aGlzLmNvbmZpcm0ubWVzc2FnZSA9IGdldHRleHQoJ0RvIHlvdSB3YW50IHRvIG1vdmUgdGhlIGdyb3VwPycpO1xuICAgIGNvbnN0IGJ1dHRvbnM6IGFueSA9IFtcbiAgICAgIHtcbiAgICAgICAgbGFiZWw6IGdldHRleHQoJ0NhbmNlbCcpLFxuICAgICAgICBhY3Rpb246ICgpID0+IFByb21pc2UucmVqZWN0KClcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGxhYmVsOiBnZXR0ZXh0KCdNb3ZlJyksXG4gICAgICAgIHN0YXR1czogJ2RlZmF1bHQnLFxuICAgICAgICBhY3Rpb246ICgpID0+IFByb21pc2UucmVzb2x2ZShmYWxzZSlcbiAgICAgIH1cbiAgICBdO1xuICAgIGlmIChub2RlVG9Nb3ZlLmlzRGV2aWNlT3JQcm9iYWJseUNoaWxkRGV2aWNlKSB7XG4gICAgICB0aGlzLmNvbmZpcm0udGl0bGUgPSBnZXR0ZXh0KCdNb3ZlIG9yIGFkZCcpO1xuICAgICAgdGhpcy5jb25maXJtLm1lc3NhZ2UgPSBnZXR0ZXh0KCdEbyB5b3Ugd2FudCB0byBtb3ZlIG9yIGFkZCB0aGUgZGV2aWNlPycpO1xuICAgICAgYnV0dG9ucy5wdXNoKHtcbiAgICAgICAgbGFiZWw6IGdldHRleHQoJ0FkZCcpLFxuICAgICAgICBzdGF0dXM6ICdwcmltYXJ5JyxcbiAgICAgICAgYWN0aW9uOiAoKSA9PiBQcm9taXNlLnJlc29sdmUodHJ1ZSlcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jb25maXJtLnNob3coYnV0dG9ucyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHZlcmlmeU5vZGVBY2Nlc3Mobm9kZVRvTW92ZTogQXNzZXROb2RlKSB7XG4gICAgcmV0dXJuIHRoaXMuc2VydmljZS5pbnZlbnRvcnkudXBkYXRlKHsgaWQ6IG5vZGVUb01vdmUubW8uaWQgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFkZE1vdmVkTm9kZShub2RlVG9Nb3ZlOiBBc3NldE5vZGUpIHtcbiAgICBsZXQgbW86IElJZGVudGlmaWVkO1xuXG4gICAgaWYgKHRoaXMucm9vdCAmJiAhdGhpcy5pc0Fzc2V0KG5vZGVUb01vdmUpKSB7XG4gICAgICBtbyA9IChcbiAgICAgICAgYXdhaXQgdGhpcy5zZXJ2aWNlLmludmVudG9yeS51cGRhdGUoe1xuICAgICAgICAgIGlkOiBub2RlVG9Nb3ZlLm1vLmlkLFxuICAgICAgICAgIHR5cGU6IEdyb3VwRnJhZ21lbnQuZ3JvdXBUeXBlXG4gICAgICAgIH0pXG4gICAgICApLmRhdGE7XG5cbiAgICAgIHRoaXMuYWRkTWFuYWdlZE9iamVjdChtbyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbW8gPSAoYXdhaXQgdGhpcy5zZXJ2aWNlLmludmVudG9yeS5jaGlsZEFzc2V0c0FkZChub2RlVG9Nb3ZlLm1vLCB0aGlzLm1vKSkuZGF0YTtcbiAgICB0aGlzLmFkZE1hbmFnZWRPYmplY3QobW8pO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0Fzc2V0KG5vZGVUb01vdmU6IEFzc2V0Tm9kZSkge1xuICAgIC8vIFRPRE8gdXNlIGlzQXNzZXQgY2hlY2sgd2hlbiBodHRwczovL2dpdGh1Yi5jb20vQ3VtdWxvY2l0eS1Jb1QvY3VtdWxvY2l0eS11aS9wdWxsLzY5MCBpcyBtZXJnZWQuXG4gICAgLy8gRG8gbm90IG92ZXJyaWRlIGFzc2V0IHR5cGUhXG4gICAgcmV0dXJuIG5vZGVUb01vdmUubW8/LmM4eV9Jc0Fzc2V0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZW1vdmVNb3ZlZE5vZGUobm9kZVRvTW92ZTogQXNzZXROb2RlKSB7XG4gICAgZm9yIChjb25zdCBwYXJlbnQgb2Ygbm9kZVRvTW92ZS5wYXJlbnRzIGFzIEFzc2V0Tm9kZVtdKSB7XG4gICAgICBpZiAocGFyZW50Lm1vICYmIHBhcmVudC5tby50eXBlID09PSBHcm91cEZyYWdtZW50LmR5bmFtaWNHcm91cFR5cGUpIHtcbiAgICAgICAgYnJlYWs7IC8vIHNtYXJ0IGdyb3VwcyBkb24ndCBuZWVkIHRvIGJlIGNoYW5nZWRcbiAgICAgIH1cblxuICAgICAgaWYgKHBhcmVudC5yb290ICYmICF0aGlzLmlzQXNzZXQobm9kZVRvTW92ZSkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zZXJ2aWNlLmludmVudG9yeS51cGRhdGUoe1xuICAgICAgICAgIGlkOiBub2RlVG9Nb3ZlLm1vLmlkLFxuICAgICAgICAgIHR5cGU6IEdyb3VwRnJhZ21lbnQuc3ViR3JvdXBUeXBlXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXBhcmVudC5yb290KSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2VydmljZS5pbnZlbnRvcnkuY2hpbGRBc3NldHNSZW1vdmUobm9kZVRvTW92ZS5tbywgcGFyZW50Lm1vKTtcbiAgICAgIH1cbiAgICAgIHBhcmVudC5yZW1vdmUobm9kZVRvTW92ZSk7XG4gICAgfVxuICB9XG59XG4iXX0=