UNPKG

ngx-diagrams

Version:

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.2.0.

434 lines 37.6 kB
/** * @fileoverview added by tsickle * Generated from: lib/services/engine.service.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Injectable, ComponentFactoryResolver, RendererFactory2 } from '@angular/core'; import { DiagramModel } from '../models/diagram.model'; import { DefaultNodeFactory } from '../defaults/factories/default-node.factory'; import { DefaultPortFactory } from '../defaults/factories/default-port.factory'; import { BehaviorSubject } from 'rxjs'; import { take, delay, filter } from 'rxjs/operators'; import { DefaultLinkFactory } from '../defaults/factories/default-link.factory'; import { NgxDiagramsModule } from '../ngx-diagrams.module'; import { DefaultLabelFactory } from '../defaults/factories/default-label.factory'; import * as i0 from "@angular/core"; import * as i1 from "../ngx-diagrams.module"; export class DiagramEngine { /** * @param {?} resolver * @param {?} rendererFactory */ constructor(resolver, rendererFactory) { this.resolver = resolver; this.rendererFactory = rendererFactory; this._renderer = this.rendererFactory.createRenderer(null, null); this.nodeFactories = {}; this.linkFactories = {}; this.portFactories = {}; this.labelFactories = {}; this.canvas$ = new BehaviorSubject(null); } /** * @return {?} */ createDiagram() { this.diagramModel = new DiagramModel(this); return this.diagramModel; } /** * @return {?} */ registerDefaultFactories() { this.registerNodeFactory(new DefaultNodeFactory(this.resolver, this._renderer)); this.registerPortFactory(new DefaultPortFactory(this.resolver, this._renderer)); this.registerLinkFactory(new DefaultLinkFactory(this.resolver, this._renderer)); this.registerLabelFactory(new DefaultLabelFactory(this.resolver, this._renderer)); } //#region Factories // LABELS /** * @param {?} labelFactory * @return {?} */ registerLabelFactory(labelFactory) { this.labelFactories[labelFactory.type] = labelFactory; } /** * @return {?} */ getLabelFactories() { return this.labelFactories; } /** * @param {?} type * @return {?} */ getLabelFactory(type) { if (this.labelFactories[type]) { return this.labelFactories[type]; } throw new Error(`cannot find factory for node of type: [${type}]`); } /** * @param {?} label * @return {?} */ getFactoryForLabel(label) { return this.getLabelFactory(label.getType()); } /** * @param {?} label * @param {?} labelHost * @return {?} */ generateWidgetForLabel(label, labelHost) { /** @type {?} */ const labelFactory = this.getFactoryForLabel(label); if (!labelFactory) { throw new Error(`Cannot find widget factory for node: ${label.getType()}`); } return labelFactory.generateWidget(label, labelHost); } // NODES /** * @param {?} nodeFactory * @return {?} */ registerNodeFactory(nodeFactory) { this.nodeFactories[nodeFactory.type] = nodeFactory; } /** * @return {?} */ getNodeFactories() { return this.nodeFactories; } /** * @param {?} type * @return {?} */ getNodeFactory(type) { if (this.nodeFactories[type]) { return this.nodeFactories[type]; } throw new Error(`cannot find factory for node of type: [${type}]`); } /** * @param {?} node * @return {?} */ getFactoryForNode(node) { return this.getNodeFactory(node.getType()); } /** * @param {?} node * @param {?} nodesHost * @return {?} */ generateWidgetForNode(node, nodesHost) { /** @type {?} */ const nodeFactory = this.getFactoryForNode(node); if (!nodeFactory) { throw new Error(`Cannot find widget factory for node: ${node.getType()}`); } return nodeFactory.generateWidget(this, node, nodesHost); } // PORTS /** * @param {?} factory * @return {?} */ registerPortFactory(factory) { this.portFactories[factory.type] = factory; } /** * @return {?} */ getPortFactories() { return this.portFactories; } /** * @param {?} type * @return {?} */ getPortFactory(type) { if (this.portFactories[type]) { return this.portFactories[type]; } throw new Error(`cannot find factory for port of type: [${type}]`); } /** * @param {?} port * @return {?} */ getFactoryForPort(port) { return this.getPortFactory(port.getType()); } /** * @param {?} port * @param {?} portsHost * @return {?} */ generateWidgetForPort(port, portsHost) { /** @type {?} */ const portFactory = this.getFactoryForPort(port); if (!portFactory) { throw new Error(`Cannot find widget factory for port: ${port.getType()}`); } return portFactory.generateWidget(port, portsHost); } // LINKS /** * @return {?} */ getLinkFactories() { return this.linkFactories; } /** * @param {?} factory * @return {?} */ registerLinkFactory(factory) { this.linkFactories[factory.type] = factory; } /** * @param {?} type * @return {?} */ getLinkFactory(type) { if (this.linkFactories[type]) { return this.linkFactories[type]; } throw new Error(`cannot find factory for link of type: [${type}]`); } /** * @param {?} link * @return {?} */ getFactoryForLink(link) { return this.getLinkFactory(link.getType()); } /** * @param {?} link * @param {?} linksHost * @return {?} */ generateWidgetForLink(link, linksHost) { /** @type {?} */ const linkFactory = this.getFactoryForLink(link); if (!linkFactory) { throw new Error(`Cannot find link factory for link: ${link.getType()}`); } return linkFactory.generateWidget(this, link, linksHost); } //#endregion /** * @param {?} node * @return {?} */ getNodeElement(node) { /** @type {?} */ const selector = this.canvas$.getValue().querySelector(`[data-nodeid="${node.id}"]`); if (selector === null) { throw new Error('Cannot find Node element with node id: [' + node.id + ']'); } return (/** @type {?} */ (selector)); } /** * @param {?} port * @return {?} */ getNodePortElement(port) { /** @type {?} */ const selector = this.canvas$.getValue().querySelector(`[data-nodeid="${port.getParent().id}"] [data-portid="${port.id}"]`); if (selector === null) { throw new Error('Cannot find Node Port element with node id: [' + port.getParent().id + '] and port id: [' + port.id + ']'); } return (/** @type {?} */ (selector)); } /** * @param {?} port * @return {?} */ getPortCenter(port) { /** @type {?} */ const sourceElement = this.getNodePortElement(port); /** @type {?} */ const sourceRect = sourceElement.getBoundingClientRect(); /** @type {?} */ const rel = this.getRelativePoint(sourceRect.left, sourceRect.top); return { x: sourceElement.offsetWidth / 2 + (rel.x - this.diagramModel.getOffsetX()) / (this.diagramModel.getZoomLevel() / 100.0), y: sourceElement.offsetHeight / 2 + (rel.y - this.diagramModel.getOffsetY()) / (this.diagramModel.getZoomLevel() / 100.0) }; } /** * Calculate rectangular coordinates of the port passed in. * @param {?} port * @return {?} */ getPortCoords(port) { /** @type {?} */ const sourceElement = this.getNodePortElement(port); /** @type {?} */ const sourceRect = (/** @type {?} */ (sourceElement.getBoundingClientRect())); /** @type {?} */ const canvasRect = (/** @type {?} */ (this.canvas$.getValue().getBoundingClientRect())); return { x: (sourceRect.x - this.diagramModel.getOffsetX()) / (this.diagramModel.getZoomLevel() / 100.0) - canvasRect.left, y: (sourceRect.y - this.diagramModel.getOffsetY()) / (this.diagramModel.getZoomLevel() / 100.0) - canvasRect.top, width: sourceRect.width, height: sourceRect.height }; } /** * Determine the width and height of the node passed in. * It currently assumes nodes have a rectangular shape, can be overriden for customised shapes. * @param {?} node * @return {?} */ getNodeDimensions(node) { if (!this.canvas$.getValue()) { return { width: 0, height: 0 }; } /** @type {?} */ const nodeElement = this.getNodeElement(node); /** @type {?} */ const nodeRect = nodeElement.getBoundingClientRect(); return { width: nodeRect.width, height: nodeRect.height }; } /** * @param {?} canvas * @return {?} */ setCanvas(canvas) { this.canvas$.next(canvas); } /** * @param {?} event * @return {?} */ getRelativeMousePoint(event) { /** @type {?} */ const point = this.getRelativePoint(event.clientX, event.clientY); return { x: (point.x - this.diagramModel.getOffsetX()) / (this.diagramModel.getZoomLevel() / 100.0), y: (point.y - this.diagramModel.getOffsetY()) / (this.diagramModel.getZoomLevel() / 100.0) }; } /** * @param {?} x * @param {?} y * @return {?} */ getRelativePoint(x, y) { /** @type {?} */ const canvasRect = this.canvas$.getValue().getBoundingClientRect(); return { x: x - canvasRect.left, y: y - canvasRect.top }; } /** * @return {?} */ getDiagramModel() { return this.diagramModel; } /** * @param {?} model * @return {?} */ isModelLocked(model) { if (this.diagramModel.getLocked()) { return true; } return model.getLocked(); } /** * auto arrange the graph * @return {?} */ autoArrange() { } /** * fit the canvas zoom levels to the elements contained. * @param {?=} additionalZoomFactor allow for further zooming out to make sure edges doesn't cut * @return {?} */ zoomToFit(additionalZoomFactor = 0.005) { this.canvas$ .pipe(filter(Boolean), take(1), delay(0)) .subscribe((/** * @param {?} canvas * @return {?} */ (canvas) => { /** @type {?} */ const xFactor = canvas.clientWidth / canvas.scrollWidth; /** @type {?} */ const yFactor = canvas.clientHeight / canvas.scrollHeight; /** @type {?} */ const zoomFactor = xFactor < yFactor ? xFactor : yFactor; this.diagramModel.setZoomLevel(this.diagramModel.getZoomLevel() * (zoomFactor - additionalZoomFactor)); this.diagramModel.setOffset(0, 0); })); } } DiagramEngine.decorators = [ { type: Injectable, args: [{ providedIn: NgxDiagramsModule },] } ]; /** @nocollapse */ DiagramEngine.ctorParameters = () => [ { type: ComponentFactoryResolver }, { type: RendererFactory2 } ]; /** @nocollapse */ DiagramEngine.ngInjectableDef = i0.ɵɵdefineInjectable({ factory: function DiagramEngine_Factory() { return new DiagramEngine(i0.ɵɵinject(i0.ComponentFactoryResolver), i0.ɵɵinject(i0.RendererFactory2)); }, token: DiagramEngine, providedIn: i1.NgxDiagramsModule }); if (false) { /** * @type {?} * @private */ DiagramEngine.prototype._renderer; /** * @type {?} * @private */ DiagramEngine.prototype.nodeFactories; /** * @type {?} * @private */ DiagramEngine.prototype.labelFactories; /** * @type {?} * @private */ DiagramEngine.prototype.linkFactories; /** * @type {?} * @private */ DiagramEngine.prototype.portFactories; /** * @type {?} * @private */ DiagramEngine.prototype.canvas$; /** @type {?} */ DiagramEngine.prototype.diagramModel; /** * @type {?} * @private */ DiagramEngine.prototype.resolver; /** * @type {?} * @private */ DiagramEngine.prototype.rendererFactory; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5naW5lLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtZGlhZ3JhbXMvIiwic291cmNlcyI6WyJsaWIvc2VydmljZXMvZW5naW5lLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLHdCQUF3QixFQUE2QyxnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVsSSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFJaEYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFHaEYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2QyxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUVoRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUczRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQzs7O0FBR2xGLE1BQU0sT0FBTyxhQUFhOzs7OztJQVV6QixZQUFvQixRQUFrQyxFQUFVLGVBQWlDO1FBQTdFLGFBQVEsR0FBUixRQUFRLENBQTBCO1FBQVUsb0JBQWUsR0FBZixlQUFlLENBQWtCO1FBQ2hHLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2pFLElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxj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Q29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsIFZpZXdDb250YWluZXJSZWYsIENvbXBvbmVudFJlZiwgUmVuZGVyZXIyLCBSZW5kZXJlckZhY3RvcnkyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBYnN0cmFjdE5vZGVGYWN0b3J5IH0gZnJvbSAnLi4vZmFjdG9yaWVzL25vZGUuZmFjdG9yeSc7XG5pbXBvcnQgeyBEaWFncmFtTW9kZWwgfSBmcm9tICcuLi9tb2RlbHMvZGlhZ3JhbS5tb2RlbCc7XG5pbXBvcnQgeyBEZWZhdWx0Tm9kZUZhY3RvcnkgfSBmcm9tICcuLi9kZWZhdWx0cy9mYWN0b3JpZXMvZGVmYXVsdC1ub2RlLmZhY3RvcnknO1xuaW1wb3J0IHsgTm9kZU1vZGVsIH0gZnJvbSAnLi4vbW9kZWxzL25vZGUubW9kZWwnO1xuaW1wb3J0IHsgQWJzdHJhY3RMaW5rRmFjdG9yeSB9IGZyb20gJy4uL2ZhY3Rvcmllcy9saW5rLmZhY3RvcnknO1xuaW1wb3J0IHsgQWJzdHJhY3RQb3J0RmFjdG9yeSB9IGZyb20gJy4uL2ZhY3Rvcmllcy9wb3J0LmZhY3RvcnknO1xuaW1wb3J0IHsgRGVmYXVsdFBvcnRGYWN0b3J5IH0gZnJvbSAnLi4vZGVmYXVsdHMvZmFjdG9yaWVzL2RlZmF1bHQtcG9ydC5mYWN0b3J5JztcbmltcG9ydCB7IExpbmtNb2RlbCB9IGZyb20gJy4uL21vZGVscy9saW5rLm1vZGVsJztcbmltcG9ydCB7IFBvcnRNb2RlbCB9IGZyb20gJy4uL21vZGVscy9wb3J0Lm1vZGVsJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFrZSwgZGVsYXksIGZpbHRlciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IERlZmF1bHRMaW5rRmFjdG9yeSB9IGZyb20gJy4uL2RlZmF1bHRzL2ZhY3Rvcmllcy9kZWZhdWx0LWxpbmsuZmFjdG9yeSc7XG5pbXBvcnQgeyBCYXNlRW50aXR5IH0gZnJvbSAnLi4vYmFzZS5lbnRpdHknO1xuaW1wb3J0IHsgTmd4RGlhZ3JhbXNNb2R1bGUgfSBmcm9tICcuLi9uZ3gtZGlhZ3JhbXMubW9kdWxlJztcbmltcG9ydCB7IEFic3RyYWN0TGFiZWxGYWN0b3J5IH0gZnJvbSAnLi4vZmFjdG9yaWVzL2xhYmVsLmZhY3RvcnknO1xuaW1wb3J0IHsgTGFiZWxNb2RlbCB9IGZyb20gJy4uL21vZGVscy9sYWJlbC5tb2RlbCc7XG5pbXBvcnQgeyBEZWZhdWx0TGFiZWxGYWN0b3J5IH0gZnJvbSAnLi4vZGVmYXVsdHMvZmFjdG9yaWVzL2RlZmF1bHQtbGFiZWwuZmFjdG9yeSc7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogTmd4RGlhZ3JhbXNNb2R1bGUgfSlcbmV4cG9ydCBjbGFzcyBEaWFncmFtRW5naW5lIHtcblx0cHJpdmF0ZSBfcmVuZGVyZXI6IFJlbmRlcmVyMjtcblx0cHJpdmF0ZSBub2RlRmFjdG9yaWVzOiB7IFtzOiBzdHJpbmddOiBBYnN0cmFjdE5vZGVGYWN0b3J5IH07XG5cdHByaXZhdGUgbGFiZWxGYWN0b3JpZXM6IHsgW3M6IHN0cmluZ106IEFic3RyYWN0TGFiZWxGYWN0b3J5IH07XG5cdHByaXZhdGUgbGlua0ZhY3RvcmllczogeyBbczogc3RyaW5nXTogQWJzdHJhY3RMaW5rRmFjdG9yeSB9O1xuXHRwcml2YXRlIHBvcnRGYWN0b3JpZXM6IHsgW3M6IHN0cmluZ106IEFic3RyYWN0UG9ydEZhY3RvcnkgfTtcblx0cHJpdmF0ZSBjYW52YXMkOiBCZWhhdmlvclN1YmplY3Q8RWxlbWVudD47XG5cblx0ZGlhZ3JhbU1vZGVsOiBEaWFncmFtTW9kZWw7XG5cblx0Y29uc3RydWN0b3IocHJpdmF0ZSByZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBwcml2YXRlIHJlbmRlcmVyRmFjdG9yeTogUmVuZGVyZXJGYWN0b3J5Mikge1xuXHRcdHRoaXMuX3JlbmRlcmVyID0gdGhpcy5yZW5kZXJlckZhY3RvcnkuY3JlYXRlUmVuZGVyZXIobnVsbCwgbnVsbCk7XG5cdFx0dGhpcy5ub2RlRmFjdG9yaWVzID0ge307XG5cdFx0dGhpcy5saW5rRmFjdG9yaWVzID0ge307XG5cdFx0dGhpcy5wb3J0RmFjdG9yaWVzID0ge307XG5cdFx0dGhpcy5sYWJlbEZhY3RvcmllcyA9IHt9O1xuXHRcdHRoaXMuY2FudmFzJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RWxlbWVudD4obnVsbCk7XG5cdH1cblxuXHRjcmVhdGVEaWFncmFtKCkge1xuXHRcdHRoaXMuZGlhZ3JhbU1vZGVsID0gbmV3IERpYWdyYW1Nb2RlbCh0aGlzKTtcblx0XHRyZXR1cm4gdGhpcy5kaWFncmFtTW9kZWw7XG5cdH1cblxuXHRyZWdpc3RlckRlZmF1bHRGYWN0b3JpZXMoKSB7XG5cdFx0dGhpcy5yZWdpc3Rlck5vZGVGYWN0b3J5KG5ldyBEZWZhdWx0Tm9kZUZhY3RvcnkodGhpcy5yZXNvbHZlciwgdGhpcy5fcmVuZGVyZXIpKTtcblx0XHR0aGlzLnJlZ2lzdGVyUG9ydEZhY3RvcnkobmV3IERlZmF1bHRQb3J0RmFjdG9yeSh0aGlzLnJlc29sdmVyLCB0aGlzLl9yZW5kZXJlcikpO1xuXHRcdHRoaXMucmVnaXN0ZXJMaW5rRmFjdG9yeShuZXcgRGVmYXVsdExpbmtGYWN0b3J5KHRoaXMucmVzb2x2ZXIsIHRoaXMuX3JlbmRlcmVyKSk7XG5cdFx0dGhpcy5yZWdpc3RlckxhYmVsRmFjdG9yeShuZXcgRGVmYXVsdExhYmVsRmFjdG9yeSh0aGlzLnJlc29sdmVyLCB0aGlzLl9yZW5kZXJlcikpO1xuXHR9XG5cblx0Ly8jcmVnaW9uIEZhY3Rvcmllc1xuXHQvLyBMQUJFTFNcblx0cmVnaXN0ZXJMYWJlbEZhY3RvcnkobGFiZWxGYWN0b3J5OiBBYnN0cmFjdExhYmVsRmFjdG9yeSkge1xuXHRcdHRoaXMubGFiZWxGYWN0b3JpZXNbbGFiZWxGYWN0b3J5LnR5cGVdID0gbGFiZWxGYWN0b3J5O1xuXHR9XG5cblx0Z2V0TGFiZWxGYWN0b3JpZXMoKTogeyBbczogc3RyaW5nXTogQWJzdHJhY3RMYWJlbEZhY3RvcnkgfSB7XG5cdFx0cmV0dXJuIHRoaXMubGFiZWxGYWN0b3JpZXM7XG5cdH1cblxuXHRnZXRMYWJlbEZhY3RvcnkodHlwZTogc3RyaW5nKTogQWJzdHJhY3RMYWJlbEZhY3Rvcnkge1xuXHRcdGlmICh0aGlzLmxhYmVsRmFjdG9yaWVzW3R5cGVdKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5sYWJlbEZhY3Rvcmllc1t0eXBlXTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgZmluZCBmYWN0b3J5IGZvciBub2RlIG9mIHR5cGU6IFske3R5cGV9XWApO1xuXHR9XG5cblx0Z2V0RmFjdG9yeUZvckxhYmVsKGxhYmVsOiBMYWJlbE1vZGVsKTogQWJzdHJhY3RMYWJlbEZhY3RvcnkgfCBudWxsIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRMYWJlbEZhY3RvcnkobGFiZWwuZ2V0VHlwZSgpKTtcblx0fVxuXG5cdGdlbmVyYXRlV2lkZ2V0Rm9yTGFiZWwobGFiZWw6IExhYmVsTW9kZWwsIGxhYmVsSG9zdDogVmlld0NvbnRhaW5lclJlZik6IENvbXBvbmVudFJlZjxMYWJlbE1vZGVsPiB8IG51bGwge1xuXHRcdGNvbnN0IGxhYmVsRmFjdG9yeSA9IHRoaXMuZ2V0RmFjdG9yeUZvckxhYmVsKGxhYmVsKTtcblx0XHRpZiAoIWxhYmVsRmFjdG9yeSkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgZmluZCB3aWRnZXQgZmFjdG9yeSBmb3Igbm9kZTogJHtsYWJlbC5nZXRUeXBlKCl9YCk7XG5cdFx0fVxuXHRcdHJldHVybiBsYWJlbEZhY3RvcnkuZ2VuZXJhdGVXaWRnZXQobGFiZWwsIGxhYmVsSG9zdCk7XG5cdH1cblxuXHQvLyBOT0RFU1xuXHRyZWdpc3Rlck5vZGVGYWN0b3J5KG5vZGVGYWN0b3J5OiBBYnN0cmFjdE5vZGVGYWN0b3J5KSB7XG5cdFx0dGhpcy5ub2RlRmFjdG9yaWVzW25vZGVGYWN0b3J5LnR5cGVdID0gbm9kZUZhY3Rvcnk7XG5cdH1cblxuXHRnZXROb2RlRmFjdG9yaWVzKCk6IHsgW3M6IHN0cmluZ106IEFic3RyYWN0Tm9kZUZhY3RvcnkgfSB7XG5cdFx0cmV0dXJuIHRoaXMubm9kZUZhY3Rvcmllcztcblx0fVxuXG5cdGdldE5vZGVGYWN0b3J5KHR5cGU6IHN0cmluZyk6IEFic3RyYWN0Tm9kZUZhY3Rvcnkge1xuXHRcdGlmICh0aGlzLm5vZGVGYWN0b3JpZXNbdHlwZV0pIHtcblx0XHRcdHJldHVybiB0aGlzLm5vZGVGYWN0b3JpZXNbdHlwZV07XG5cdFx0fVxuXHRcdHRocm93IG5ldyBFcnJvcihgY2Fubm90IGZpbmQgZmFjdG9yeSBmb3Igbm9kZSBvZiB0eXBlOiBbJHt0eXBlfV1gKTtcblx0fVxuXG5cdGdldEZhY3RvcnlGb3JOb2RlKG5vZGU6IE5vZGVNb2RlbCk6IEFic3RyYWN0Tm9kZUZhY3RvcnkgfCBudWxsIHtcblx0XHRyZXR1cm4gdGhpcy5nZXROb2RlRmFjdG9yeShub2RlLmdldFR5cGUoKSk7XG5cdH1cblxuXHRnZW5lcmF0ZVdpZGdldEZvck5vZGUobm9kZTogTm9kZU1vZGVsLCBub2Rlc0hvc3Q6IFZpZXdDb250YWluZXJSZWYpOiBDb21wb25lbnRSZWY8Tm9kZU1vZGVsPiB8IG51bGwge1xuXHRcdGNvbnN0IG5vZGVGYWN0b3J5ID0gdGhpcy5nZXRGYWN0b3J5Rm9yTm9kZShub2RlKTtcblx0XHRpZiAoIW5vZGVGYWN0b3J5KSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIHdpZGdldCBmYWN0b3J5IGZvciBub2RlOiAke25vZGUuZ2V0VHlwZSgpfWApO1xuXHRcdH1cblx0XHRyZXR1cm4gbm9kZUZhY3RvcnkuZ2VuZXJhdGVXaWRnZXQodGhpcywgbm9kZSwgbm9kZXNIb3N0KTtcblx0fVxuXG5cdC8vIFBPUlRTXG5cdHJlZ2lzdGVyUG9ydEZhY3RvcnkoZmFjdG9yeTogQWJzdHJhY3RQb3J0RmFjdG9yeSkge1xuXHRcdHRoaXMucG9ydEZhY3Rvcmllc1tmYWN0b3J5LnR5cGVdID0gZmFjdG9yeTtcblx0fVxuXG5cdGdldFBvcnRGYWN0b3JpZXMoKSB7XG5cdFx0cmV0dXJuIHRoaXMucG9ydEZhY3Rvcmllcztcblx0fVxuXG5cdGdldFBvcnRGYWN0b3J5KHR5cGU6IHN0cmluZyk6IEFic3RyYWN0UG9ydEZhY3Rvcnkge1xuXHRcdGlmICh0aGlzLnBvcnRGYWN0b3JpZXNbdHlwZV0pIHtcblx0XHRcdHJldHVybiB0aGlzLnBvcnRGYWN0b3JpZXNbdHlwZV07XG5cdFx0fVxuXHRcdHRocm93IG5ldyBFcnJvcihgY2Fubm90IGZpbmQgZmFjdG9yeSBmb3IgcG9ydCBvZiB0eXBlOiBbJHt0eXBlfV1gKTtcblx0fVxuXG5cdGdldEZhY3RvcnlGb3JQb3J0KHBvcnQ6IFBvcnRNb2RlbCk6IEFic3RyYWN0UG9ydEZhY3RvcnkgfCBudWxsIHtcblx0XHRyZXR1cm4gdGhpcy5nZXRQb3J0RmFjdG9yeShwb3J0LmdldFR5cGUoKSk7XG5cdH1cblxuXHRnZW5lcmF0ZVdpZGdldEZvclBvcnQocG9ydDogUG9ydE1vZGVsLCBwb3J0c0hvc3Q6IFZpZXdDb250YWluZXJSZWYpOiBDb21wb25lbnRSZWY8UG9ydE1vZGVsPiB8IG51bGwge1xuXHRcdGNvbnN0IHBvcnRGYWN0b3J5ID0gdGhpcy5nZXRGYWN0b3J5Rm9yUG9ydChwb3J0KTtcblx0XHRpZiAoIXBvcnRGYWN0b3J5KSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBmaW5kIHdpZGdldCBmYWN0b3J5IGZvciBwb3J0OiAke3BvcnQuZ2V0VHlwZSgpfWApO1xuXHRcdH1cblx0XHRyZXR1cm4gcG9ydEZhY3RvcnkuZ2VuZXJhdGVXaWRnZXQocG9ydCwgcG9ydHNIb3N0KTtcblx0fVxuXG5cdC8vIExJTktTXG5cdGdldExpbmtGYWN0b3JpZXMoKTogeyBbczogc3RyaW5nXTogQWJzdHJhY3RMaW5rRmFjdG9yeSB9IHtcblx0XHRyZXR1cm4gdGhpcy5saW5rRmFjdG9yaWVzO1xuXHR9XG5cblx0cmVnaXN0ZXJMaW5rRmFjdG9yeShmYWN0b3J5OiBBYnN0cmFjdExpbmtGYWN0b3J5KSB7XG5cdFx0dGhpcy5saW5rRmFjdG9yaWVzW2ZhY3RvcnkudHlwZV0gPSBmYWN0b3J5O1xuXHR9XG5cblx0Z2V0TGlua0ZhY3RvcnkodHlwZTogc3RyaW5nKTogQWJzdHJhY3RMaW5rRmFjdG9yeSB7XG5cdFx0aWYgKHRoaXMubGlua0ZhY3Rvcmllc1t0eXBlXSkge1xuXHRcdFx0cmV0dXJuIHRoaXMubGlua0ZhY3Rvcmllc1t0eXBlXTtcblx0XHR9XG5cdFx0dGhyb3cgbmV3IEVycm9yKGBjYW5ub3QgZmluZCBmYWN0b3J5IGZvciBsaW5rIG9mIHR5cGU6IFske3R5cGV9XWApO1xuXHR9XG5cblx0Z2V0RmFjdG9yeUZvckxpbmsobGluazogTGlua01vZGVsKTogQWJzdHJhY3RMaW5rRmFjdG9yeSB8IG51bGwge1xuXHRcdHJldHVybiB0aGlzLmdldExpbmtGYWN0b3J5KGxpbmsuZ2V0VHlwZSgpKTtcblx0fVxuXG5cdGdlbmVyYXRlV2lkZ2V0Rm9yTGluayhsaW5rOiBMaW5rTW9kZWwsIGxpbmtzSG9zdDogVmlld0NvbnRhaW5lclJlZik6IENvbXBvbmVudFJlZjxMaW5rTW9kZWw+IHwgbnVsbCB7XG5cdFx0Y29uc3QgbGlua0ZhY3RvcnkgPSB0aGlzLmdldEZhY3RvcnlGb3JMaW5rKGxpbmspO1xuXHRcdGlmICghbGlua0ZhY3RvcnkpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGZpbmQgbGluayBmYWN0b3J5IGZvciBsaW5rOiAke2xpbmsuZ2V0VHlwZSgpfWApO1xuXHRcdH1cblx0XHRyZXR1cm4gbGlua0ZhY3RvcnkuZ2VuZXJhdGVXaWRnZXQodGhpcywgbGluaywgbGlua3NIb3N0KTtcblx0fVxuXHQvLyNlbmRyZWdpb25cblxuXHRnZXROb2RlRWxlbWVudChub2RlOiBOb2RlTW9kZWwpOiBIVE1MRWxlbWVudCB7XG5cdFx0Y29uc3Qgc2VsZWN0b3IgPSB0aGlzLmNhbnZhcyQuZ2V0VmFsdWUoKS5xdWVyeVNlbGVjdG9yKGBbZGF0YS1ub2RlaWQ9XCIke25vZGUuaWR9XCJdYCk7XG5cdFx0aWYgKHNlbGVjdG9yID09PSBudWxsKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmaW5kIE5vZGUgZWxlbWVudCB3aXRoIG5vZGUgaWQ6IFsnICsgbm9kZS5pZCArICddJyk7XG5cdFx0fVxuXHRcdHJldHVybiBzZWxlY3RvciBhcyBIVE1MRWxlbWVudDtcblx0fVxuXG5cdGdldE5vZGVQb3J0RWxlbWVudChwb3J0OiBQb3J0TW9kZWwpOiBIVE1MRWxlbWVudCB7XG5cdFx0Y29uc3Qgc2VsZWN0b3IgPSB0aGlzLmNhbnZhcyQuZ2V0VmFsdWUoKS5xdWVyeVNlbGVjdG9yKGBbZGF0YS1ub2RlaWQ9XCIke3BvcnQuZ2V0UGFyZW50KCkuaWR9XCJdIFtkYXRhLXBvcnRpZD1cIiR7cG9ydC5pZH1cIl1gKTtcblx0XHRpZiAoc2VsZWN0b3IgPT09IG51bGwpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignQ2Fubm90IGZpbmQgTm9kZSBQb3J0IGVsZW1lbnQgd2l0aCBub2RlIGlkOiBbJyArIHBvcnQuZ2V0UGFyZW50KCkuaWQgKyAnXSBhbmQgcG9ydCBpZDogWycgKyBwb3J0LmlkICsgJ10nKTtcblx0XHR9XG5cdFx0cmV0dXJuIHNlbGVjdG9yIGFzIEhUTUxFbGVtZW50O1xuXHR9XG5cblx0Z2V0UG9ydENlbnRlcihwb3J0OiBQb3J0TW9kZWwpIHtcblx0XHRjb25zdCBzb3VyY2VFbGVtZW50ID0gdGhpcy5nZXROb2RlUG9ydEVsZW1lbnQocG9ydCk7XG5cdFx0Y29uc3Qgc291cmNlUmVjdCA9IHNvdXJjZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0Y29uc3QgcmVsID0gdGhpcy5nZXRSZWxhdGl2ZVBvaW50KHNvdXJjZVJlY3QubGVmdCwgc291cmNlUmVjdC50b3ApO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdHg6IHNvdXJjZUVsZW1lbnQub2Zmc2V0V2lkdGggLyAyICsgKHJlbC54IC0gdGhpcy5kaWFncmFtTW9kZWwuZ2V0T2Zmc2V0WCgpKSAvICh0aGlzLmRpYWdyYW1Nb2RlbC5nZXRab29tTGV2ZWwoKSAvIDEwMC4wKSxcblx0XHRcdHk6IHNvdXJjZUVsZW1lbnQub2Zmc2V0SGVpZ2h0IC8gMiArIChyZWwueSAtIHRoaXMuZGlhZ3JhbU1vZGVsLmdldE9mZnNldFkoKSkgLyAodGhpcy5kaWFncmFtTW9kZWwuZ2V0Wm9vbUxldmVsKCkgLyAxMDAuMClcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIENhbGN1bGF0ZSByZWN0YW5ndWxhciBjb29yZGluYXRlcyBvZiB0aGUgcG9ydCBwYXNzZWQgaW4uXG5cdCAqL1xuXHRnZXRQb3J0Q29vcmRzKFxuXHRcdHBvcnQ6IFBvcnRNb2RlbFxuXHQpOiB7XG5cdFx0eDogbnVtYmVyO1xuXHRcdHk6IG51bWJlcjtcblx0XHR3aWR0aDogbnVtYmVyO1xuXHRcdGhlaWdodDogbnVtYmVyO1xuXHR9IHtcblx0XHRjb25zdCBzb3VyY2VFbGVtZW50ID0gdGhpcy5nZXROb2RlUG9ydEVsZW1lbnQocG9ydCk7XG5cdFx0Y29uc3Qgc291cmNlUmVjdCA9IHNvdXJjZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgYXMgRE9NUmVjdDtcblx0XHRjb25zdCBjYW52YXNSZWN0ID0gdGhpcy5jYW52YXMkLmdldFZhbHVlKCkuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgYXMgQ2xpZW50UmVjdDtcblxuXHRcdHJldHVybiB7XG5cdFx0XHR4OiAoc291cmNlUmVjdC54IC0gdGhpcy5kaWFncmFtTW9kZWwuZ2V0T2Zmc2V0WCgpKSAvICh0aGlzLmRpYWdyYW1Nb2RlbC5nZXRab29tTGV2ZWwoKSAvIDEwMC4wKSAtIGNhbnZhc1JlY3QubGVmdCxcblx0XHRcdHk6IChzb3VyY2VSZWN0LnkgLSB0aGlzLmRpYWdyYW1Nb2RlbC5nZXRPZmZzZXRZKCkpIC8gKHRoaXMuZGlhZ3JhbU1vZGVsLmdldFpvb21MZXZlbCgpIC8gMTAwLjApIC0gY2FudmFzUmVjdC50b3AsXG5cdFx0XHR3aWR0aDogc291cmNlUmVjdC53aWR0aCxcblx0XHRcdGhlaWdodDogc291cmNlUmVjdC5oZWlnaHRcblx0XHR9O1xuXHR9XG5cblx0LyoqXG5cdCAqIERldGVybWluZSB0aGUgd2lkdGggYW5kIGhlaWdodCBvZiB0aGUgbm9kZSBwYXNzZWQgaW4uXG5cdCAqIEl0IGN1cnJlbnRseSBhc3N1bWVzIG5vZGVzIGhhdmUgYSByZWN0YW5ndWxhciBzaGFwZSwgY2FuIGJlIG92ZXJyaWRlbiBmb3IgY3VzdG9taXNlZCBzaGFwZXMuXG5cdCAqL1xuXHRnZXROb2RlRGltZW5zaW9ucyhub2RlOiBOb2RlTW9kZWwpOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0ge1xuXHRcdGlmICghdGhpcy5jYW52YXMkLmdldFZhbHVlKCkpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHdpZHRoOiAwLFxuXHRcdFx0XHRoZWlnaHQ6IDBcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Y29uc3Qgbm9kZUVsZW1lbnQgPSB0aGlzLmdldE5vZGVFbGVtZW50KG5vZGUpO1xuXHRcdGNvbnN0IG5vZGVSZWN0ID0gbm9kZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0d2lkdGg6IG5vZGVSZWN0LndpZHRoLFxuXHRcdFx0aGVpZ2h0OiBub2RlUmVjdC5oZWlnaHRcblx0XHR9O1xuXHR9XG5cblx0c2V0Q2FudmFzKGNhbnZhczogRWxlbWVudCkge1xuXHRcdHRoaXMuY2FudmFzJC5uZXh0KGNhbnZhcyk7XG5cdH1cblxuXHRnZXRSZWxhdGl2ZU1vdXNlUG9pbnQoZXZlbnQ6IE1vdXNlRXZlbnQpOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0ge1xuXHRcdGNvbnN0IHBvaW50ID0gdGhpcy5nZXRSZWxhdGl2ZVBvaW50KGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xuXHRcdHJldHVybiB7XG5cdFx0XHR4OiAocG9pbnQueCAtIHRoaXMuZGlhZ3JhbU1vZGVsLmdldE9mZnNldFgoKSkgLyAodGhpcy5kaWFncmFtTW9kZWwuZ2V0Wm9vbUxldmVsKCkgLyAxMDAuMCksXG5cdFx0XHR5OiAocG9pbnQueSAtIHRoaXMuZGlhZ3JhbU1vZGVsLmdldE9mZnNldFkoKSkgLyAodGhpcy5kaWFncmFtTW9kZWwuZ2V0Wm9vbUxldmVsKCkgLyAxMDAuMClcblx0XHR9O1xuXHR9XG5cblx0Z2V0UmVsYXRpdmVQb2ludCh4OiBudW1iZXIsIHk6IG51bWJlcikge1xuXHRcdGNvbnN0IGNhbnZhc1JlY3QgPSB0aGlzLmNhbnZhcyQuZ2V0VmFsdWUoKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHRyZXR1cm4geyB4OiB4IC0gY2FudmFzUmVjdC5sZWZ0LCB5OiB5IC0gY2FudmFzUmVjdC50b3AgfTtcblx0fVxuXG5cdGdldERpYWdyYW1Nb2RlbCgpIHtcblx0XHRyZXR1cm4gdGhpcy5kaWFncmFtTW9kZWw7XG5cdH1cblxuXHRpc01vZGVsTG9ja2VkKG1vZGVsOiBCYXNlRW50aXR5KSB7XG5cdFx0aWYgKHRoaXMuZGlhZ3JhbU1vZGVsLmdldExvY2tlZCgpKSB7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbW9kZWwuZ2V0TG9ja2VkKCk7XG5cdH1cblxuXHQvKipcblx0ICogYXV0byBhcnJhbmdlIHRoZSBncmFwaFxuXHQgKi9cblx0YXV0b0FycmFuZ2UoKSB7fVxuXG5cdC8qKlxuXHQgKiBmaXQgdGhlIGNhbnZhcyB6b29tIGxldmVscyB0byB0aGUgZWxlbWVudHMgY29udGFpbmVkLlxuXHQgKiBAcGFyYW0gYWRkaXRpb25hbFpvb21GYWN0b3IgYWxsb3cgZm9yIGZ1cnRoZXIgem9vbWluZyBvdXQgdG8gbWFrZSBzdXJlIGVkZ2VzIGRvZXNuJ3QgY3V0XG5cdCAqL1xuXHR6b29tVG9GaXQoYWRkaXRpb25hbFpvb21GYWN0b3I6IG51bWJlciA9IDAuMDA1KSB7XG5cdFx0dGhpcy5jYW52YXMkXG5cdFx0XHQucGlwZShcblx0XHRcdFx0ZmlsdGVyKEJvb2xlYW4pLFxuXHRcdFx0XHR0YWtlKDEpLFxuXHRcdFx0XHRkZWxheSgwKVxuXHRcdFx0KVxuXHRcdFx0LnN1YnNjcmliZSgoY2FudmFzOiBIVE1MRWxlbWVudCkgPT4ge1xuXHRcdFx0XHRjb25zdCB4RmFjdG9yID0gY2FudmFzLmNsaWVudFdpZHRoIC8gY2FudmFzLnNjcm9sbFdpZHRoO1xuXHRcdFx0XHRjb25zdCB5RmFjdG9yID0gY2FudmFzLmNsaWVudEhlaWdodCAvIGNhbnZhcy5zY3JvbGxIZWlnaHQ7XG5cdFx0XHRcdGNvbnN0IHpvb21GYWN0b3IgPSB4RmFjdG9yIDwgeUZhY3RvciA/IHhGYWN0b3IgOiB5RmFjdG9yO1xuXG5cdFx0XHRcdHRoaXMuZGlhZ3JhbU1vZGVsLnNldFpvb21MZXZlbCh0aGlzLmRpYWdyYW1Nb2RlbC5nZXRab29tTGV2ZWwoKSAqICh6b29tRmFjdG9yIC0gYWRkaXRpb25hbFpvb21GYWN0b3IpKTtcblx0XHRcdFx0dGhpcy5kaWFncmFtTW9kZWwuc2V0T2Zmc2V0KDAsIDApO1xuXHRcdFx0fSk7XG5cdH1cbn1cbiJdfQ==