UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

323 lines • 41.6 kB
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=