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
JavaScript
/**
* @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==