gojs-angular
Advanced tools
Comparing version 1.0.17 to 2.0.0
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('gojs')) : | ||
typeof define === 'function' && define.amd ? define('gojs-angular', ['exports', '@angular/core', 'gojs'], factory) : | ||
(global = global || self, factory(global['gojs-angular'] = {}, global.ng.core, global.go)); | ||
}(this, (function (exports, core, go) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('gojs'), require('immer')) : | ||
typeof define === 'function' && define.amd ? define('gojs-angular', ['exports', '@angular/core', 'gojs', 'immer'], factory) : | ||
(global = global || self, factory(global['gojs-angular'] = {}, global.ng.core, global.go, global.produce)); | ||
}(this, (function (exports, core, go, produce) { 'use strict'; | ||
produce = produce && Object.prototype.hasOwnProperty.call(produce, 'default') ? produce['default'] : produce; | ||
/** | ||
* @fileoverview added by tsickle | ||
* Generated from: lib/diagram.component.ts | ||
* Generated from: lib/ng-diagram-helper.ts | ||
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc | ||
*/ | ||
var DiagramComponent = /** @class */ (function () { | ||
/** | ||
* An interface to allow methods defined below to accept Palette or Diagram Components, | ||
* without requiring DiagramComponent or PaletteComponent directly in this file | ||
* (that would create a circular dependency) | ||
* @record | ||
*/ | ||
function IDiagramOrPaletteComponent() { } | ||
if (false) { | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.modelChange; | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.zone; | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.nodeDataArray; | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.linkDataArray; | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.modelData; | ||
} | ||
/** | ||
* Defines some shared helper static functions, used in Diagram / Palette / Overview Components | ||
*/ | ||
var NgDiagramHelper = /** @class */ (function () { | ||
function NgDiagramHelper() { | ||
} | ||
/** | ||
* @param {?} _kvdiffers | ||
* Ensures mousemove event listeners on a diagram's canvas are run outside NgZone. | ||
* This way, change detection isn't triggered on each mousemove, improving performance. | ||
* If some state-alteration must happen on a mousemove event inside the diagram, use zone.run() to make sure the event triggers angular change detection. | ||
* Used by DiagramComponent, PaletteComponent, and OverviewComponent in their ngAfterViewInit lifecycle hooks | ||
* @param {?} diagram | ||
* @param {?} zone | ||
*/ | ||
function DiagramComponent(_kvdiffers, zone) { | ||
this._kvdiffers = _kvdiffers; | ||
this.zone = zone; | ||
// Link data for diagram | ||
this.linkDataArray = null; // optional | ||
// optional | ||
// Model data for diagram | ||
this.modelData = null; // optional | ||
// model changed listener function for diagram | ||
this.modelChangedListener = null; | ||
this.skipsDiagramUpdate = false; | ||
// event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
this.modelChange = new core.EventEmitter(); | ||
this.diagram = null; | ||
// differs used to check if there have been changed to the array @Inputs | ||
// without them, changes to the input arrays won't register in ngOnChanges, | ||
// since the array reference itself may be the same | ||
this._ndaDiffer = this._kvdiffers.find([]).create(); | ||
this._ldaDiffer = this._kvdiffers.find([]).create(); | ||
this._mdaDiffer = this._kvdiffers.find([]).create(); | ||
} | ||
/** | ||
* Initializes diagram / model after view init | ||
* @return {?} | ||
*/ | ||
DiagramComponent.prototype.ngAfterViewInit = function () { | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone = function (diagram, zone) { | ||
var _this = this; | ||
this.diagram = this.initDiagram(); | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the diagram, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.diagram.addEventListener = ( /** | ||
diagram.addEventListener = ( /** | ||
* @param {?} DOMElement | ||
@@ -59,3 +60,3 @@ * @param {?} name | ||
if (name === 'mousemove') { | ||
_this.zone.runOutsideAngular(( /** | ||
zone.runOutsideAngular(( /** | ||
* @return {?} | ||
@@ -65,3 +66,3 @@ */function () { return superAddEventListener.call(_this, DOMElement, name, listener, capture); })); | ||
else { | ||
_this.zone.run(( /** | ||
zone.run(( /** | ||
* @return {?} | ||
@@ -73,15 +74,17 @@ */function () { | ||
}); | ||
// assign the Diagram's div, which (among many other things) will attach a bunch of listeners to the canvas, | ||
// using the overridden addEventListener function above | ||
/** @type {?} */ | ||
var divRef = this.diagramDiv.nativeElement; | ||
if (divRef === null) | ||
return; | ||
this.diagram.div = divRef; | ||
// initialize the Diagram's model | ||
this.diagram.delayInitialization(( /** | ||
}; | ||
/** | ||
* Initialize a given diagram's model with given node / link / model data | ||
* @param {?} diagram | ||
* @param {?} nodeDataArray | ||
* @param {?} linkDataArray | ||
* @param {?} modelData | ||
* @return {?} | ||
*/ | ||
NgDiagramHelper.initializeModel = function (diagram, nodeDataArray, linkDataArray, modelData) { | ||
diagram.delayInitialization(( /** | ||
* @return {?} | ||
*/function () { | ||
/** @type {?} */ | ||
var model = _this.diagram.model; | ||
var model = diagram.model; | ||
model.commit(( /** | ||
@@ -91,20 +94,34 @@ * @param {?} m | ||
*/function (m) { | ||
m.mergeNodeDataArray(m.cloneDeep(_this.nodeDataArray)); | ||
if (_this.linkDataArray && m instanceof go.GraphLinksModel) { | ||
m.mergeLinkDataArray(m.cloneDeep(_this.linkDataArray)); | ||
m.mergeNodeDataArray(m.cloneDeep(nodeDataArray)); | ||
if (linkDataArray && m instanceof go.GraphLinksModel) { | ||
m.mergeLinkDataArray(m.cloneDeep(linkDataArray)); | ||
} | ||
if (_this.modelData) { | ||
m.assignAllDataProperties(m.modelData, _this.modelData); | ||
if (modelData) { | ||
m.assignAllDataProperties(m.modelData, modelData); | ||
} | ||
_this.diagram.layoutDiagram(true); | ||
}), null); | ||
})); | ||
// initializer listener | ||
this.modelChangedListener = ( /** | ||
}; | ||
/** | ||
* Initialize the model changed listener for the Palette / Diagram of a given compoennt; ensure it runs inside the component's ngZone. | ||
* Those changes will be emitted through a the component's modelChange EventEmitter. | ||
* @param {?} component | ||
* @return {?} | ||
*/ | ||
NgDiagramHelper.initializeModelChangedListener = function (component) { | ||
/** @type {?} */ | ||
var diagram = null; | ||
if (!(component.hasOwnProperty("diagram")) && !(component.hasOwnProperty("palette"))) | ||
return; | ||
if (component.hasOwnProperty("diagram")) | ||
diagram = component["diagram"]; | ||
if (component.hasOwnProperty("palette")) | ||
diagram = component["palette"]; | ||
component.modelChangedListener = ( /** | ||
* @param {?} e | ||
* @return {?} | ||
*/function (e) { | ||
if (e.isTransactionFinished && _this.diagram && _this.diagram.model && !_this.diagram.model.isReadOnly) { | ||
if (e.isTransactionFinished && diagram && diagram.model && !diagram.model.isReadOnly) { | ||
// this must be done within a NgZone.run block, so changes are detected in the parent component | ||
_this.zone.run(( /** | ||
component.zone.run(( /** | ||
* @return {?} | ||
@@ -114,200 +131,114 @@ */function () { | ||
var dataChanges = ( /** @type {?} */(e.model)).toIncrementalData(e); | ||
_this.modelChange.emit(dataChanges); | ||
component.modelChange.emit(dataChanges); | ||
})); | ||
} | ||
}); | ||
this.diagram.addModelChangedListener(this.modelChangedListener); | ||
}; // end ngAfterViewInit | ||
// end ngAfterViewInit | ||
diagram.addModelChangedListener(component.modelChangedListener); | ||
}; | ||
/** | ||
* Merges changes from app data into GoJS model data, | ||
* making sure only actual changes (and not falsely flagged no-ops on array / obj data props) are logged | ||
* @param {?} component an instance of DiagramComponent or PaletteComponent | ||
* @param {?} kvchanges The kvchanges object produced by either a node or link Angular differ object | ||
* @param {?} str "n" for node data changes, "l" for link data changes | ||
* | ||
* Merge the app-level node / link / model data of a supplied Diagram|Palette Component with its underlying Diagram|Palette model data | ||
* @param {?} component | ||
* @return {?} | ||
*/ | ||
DiagramComponent.mergeChanges = function (component, kvchanges, str) { | ||
// helper function | ||
NgDiagramHelper.mergeAppDataWithModel = function (component) { | ||
/** @type {?} */ | ||
var diagram = null; | ||
if (component.hasOwnProperty("diagram")) | ||
diagram = component["diagram"]; | ||
if (component.hasOwnProperty("palette")) | ||
diagram = component["palette"]; | ||
// don't need model change listener while performing known data updates | ||
/** @type {?} */ | ||
var mcl = component instanceof DiagramComponent ? component.modelChangedListener : null; | ||
if (mcl !== null) | ||
diagram.model.removeChangedListener(mcl); | ||
diagram.model.startTransaction('update data'); | ||
// update modelData first, in case bindings on nodes / links depend on model data | ||
diagram.model.assignAllDataProperties(diagram.model.modelData, component.modelData); | ||
// merge node / link data | ||
diagram.model.mergeNodeDataArray(component.nodeDataArray); | ||
if (component.linkDataArray && diagram.model instanceof go.GraphLinksModel) { | ||
diagram.model.mergeLinkDataArray(component.linkDataArray); | ||
} | ||
diagram.model.commitTransaction('update data'); | ||
// reset the model change listener | ||
if (mcl !== null) | ||
diagram.model.addChangedListener(mcl); | ||
}; | ||
return NgDiagramHelper; | ||
}()); | ||
/** | ||
* @fileoverview added by tsickle | ||
* Generated from: lib/diagram.component.ts | ||
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc | ||
*/ | ||
var DiagramComponent = /** @class */ (function () { | ||
/** | ||
* @param {?} zone | ||
*/ | ||
function DiagramComponent(zone) { | ||
this.zone = zone; | ||
/** | ||
* @param {?} obj1 | ||
* @param {?} obj2 | ||
* @return {?} | ||
* Link data for diagram. Optional. | ||
*/ | ||
function compareObjs(obj1, obj2) { | ||
if (!obj1 || !obj2) | ||
return false; | ||
// Loop through properties in object 1 | ||
for (var p in obj1) { | ||
// Check property exists on both objects | ||
if (obj1.hasOwnProperty(p) !== obj2.hasOwnProperty(p)) | ||
return false; | ||
switch (typeof (obj1[p])) { | ||
// Deep compare objects | ||
case 'object': | ||
if (!compareObjs(obj1[p], obj2[p])) | ||
return false; | ||
break; | ||
// Compare values | ||
default: | ||
if (obj1[p] !== obj2[p]) | ||
return false; | ||
} | ||
} | ||
// Check object 2 for any extra properties | ||
for (var p in obj2) { | ||
if (typeof (obj1[p]) === 'undefined') | ||
return false; | ||
} | ||
return true; | ||
this.linkDataArray = null; | ||
/** | ||
* Model data for diagram. Optional. | ||
*/ | ||
this.modelData = null; | ||
/** | ||
* Model changed listener function for diagram | ||
*/ | ||
this.modelChangedListener = null; | ||
/** | ||
* Whether or not to skip merging app data with GoJS model data (set to true if update is coming from GoJS, false if coming from app-level, usually) | ||
*/ | ||
this.skipsDiagramUpdate = false; | ||
/** | ||
* Event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
*/ | ||
this.modelChange = new core.EventEmitter(); | ||
/** | ||
* The Diagram itself | ||
*/ | ||
this.diagram = null; | ||
} | ||
/** | ||
* Initializes diagram / model after view init | ||
* @return {?} | ||
*/ | ||
DiagramComponent.prototype.ngAfterViewInit = function () { | ||
if (!this.diagramDiv) { | ||
throw new Error("diagramDiv is not defined"); | ||
} | ||
this.diagram = this.initDiagram(); | ||
if (!(this.diagram instanceof go.Diagram)) { | ||
throw new Error("initDiagram function did not return a go.Diagram"); | ||
} | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.diagram, this.zone); | ||
// assign the Diagram's div, which (among many other things) will attach a bunch of listeners to the canvas, | ||
// using the overridden addEventListener function defined in makeMouseMoveRunOutsideAngularZone | ||
/** @type {?} */ | ||
var dia = component instanceof DiagramComponent ? component.diagram : component.palette; | ||
if (!dia || !dia.model) | ||
var divRef = this.diagramDiv.nativeElement; | ||
if (divRef === null) | ||
return; | ||
if (kvchanges) { | ||
// handle added nodes / links | ||
kvchanges.forEachAddedItem(( /** | ||
* @param {?} r | ||
* @return {?} | ||
*/function (r) { | ||
switch (str) { | ||
case "n": { | ||
dia.model.addNodeData(r.currentValue); | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
var m = ( /** @type {?} */(dia.model)); | ||
m.addLinkData(r.currentValue); | ||
break; | ||
} | ||
} | ||
})); | ||
// handle removed nodes / links | ||
kvchanges.forEachRemovedItem(( /** | ||
* @param {?} r | ||
* @return {?} | ||
*/function (r) { | ||
switch (str) { | ||
case "n": { | ||
/** @type {?} */ | ||
var m = dia.model; | ||
/** @type {?} */ | ||
var keyPropName_1 = m.nodeKeyProperty.toString(); | ||
/** @type {?} */ | ||
var node = dia.findNodeForKey(r.previousValue[keyPropName_1]); | ||
if (node) { | ||
dia.remove(node); | ||
} | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
var m = ( /** @type {?} */(dia.model)); | ||
/** @type {?} */ | ||
var keyPropName = m.linkKeyProperty.toString(); | ||
/** @type {?} */ | ||
var link = dia.findLinkForKey(r.previousValue[keyPropName]); | ||
if (link) { | ||
dia.remove(link); | ||
} | ||
break; | ||
} | ||
} | ||
})); | ||
// handle changed data for nodes / links | ||
kvchanges.forEachChangedItem(( /** | ||
* @param {?} r | ||
* @return {?} | ||
*/function (r) { | ||
// ensure "changes" to array / object / enumerable data properties are legit | ||
/** @type {?} */ | ||
var sameVals = compareObjs(r.currentValue, r.previousValue); | ||
// update proper data object for node or link | ||
if (!sameVals) { | ||
switch (str) { | ||
case "n": { | ||
/** @type {?} */ | ||
var m = dia.model; | ||
/** @type {?} */ | ||
var keyPropName_2 = m.nodeKeyProperty.toString(); | ||
/** @type {?} */ | ||
var node = dia.findNodeForKey(r.previousValue[keyPropName_2]); | ||
if (node) { | ||
// if the entry was replaced with null or undefined, just remove the entry altogther | ||
// this is still pretty bad practice -- instead, users should remove entries in their node / link / model data, not set them to null | ||
if (!r.currentValue) { | ||
dia.remove(node); | ||
} | ||
else { | ||
dia.model.assignAllDataProperties(node.data, r.currentValue); | ||
} | ||
} | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
var m = ( /** @type {?} */(dia.model)); | ||
/** @type {?} */ | ||
var keyPropName = m.linkKeyProperty.toString(); | ||
/** @type {?} */ | ||
var link = dia.findLinkForKey(r.previousValue[keyPropName]); | ||
if (link) { | ||
// if the entry was replaced with null or undefined, just remove the entry altogther | ||
// this is still pretty bad practice -- instead, users should remove entries in their node / link / model data, not set them to null | ||
if (!r.currentValue) { | ||
dia.remove(link); | ||
} | ||
else { | ||
dia.model.assignAllDataProperties(link.data, r.currentValue); | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
})); | ||
} | ||
}; | ||
this.diagram.div = divRef; | ||
// initialize the diagram model with the provided node / link / model data | ||
NgDiagramHelper.initializeModel(this.diagram, this.nodeDataArray, this.linkDataArray, this.modelData); | ||
// initializer model listener | ||
NgDiagramHelper.initializeModelChangedListener(this); | ||
}; // end ngAfterViewInit | ||
// end ngAfterViewInit | ||
/** | ||
* Always be checking if array Input data has changed (node and link data arrays) | ||
* If a change has occured on an \@Input property, merge the app-level changes with GoJS | ||
* @return {?} | ||
*/ | ||
DiagramComponent.prototype.ngDoCheck = function () { | ||
if (!this.diagram) | ||
DiagramComponent.prototype.ngOnChanges = function () { | ||
if (!this.diagram || !this.diagram.model || this.skipsDiagramUpdate) | ||
return; | ||
if (!this.diagram.model) | ||
return; | ||
// these need to be run each check, even if no merging happens | ||
// otherwise, they will detect all diffs that happened since last time skipsDiagram was false, | ||
// such as remove ops that happened in GoJS when skipsDiagram = true, | ||
// and then realllllly bad stuff happens (deleting random nodes, updating the wrong Parts) | ||
// Angular differs are a lot of fun | ||
/** @type {?} */ | ||
var nodeDiffs = this._ndaDiffer.diff(this.nodeDataArray); | ||
/** @type {?} */ | ||
var linkDiffs = this._ldaDiffer.diff(this.linkDataArray); | ||
/** @type {?} */ | ||
var modelDiffs = this._mdaDiffer.diff(this.modelData); | ||
if (!nodeDiffs && !linkDiffs && !modelDiffs) | ||
return; | ||
if (this.skipsDiagramUpdate) | ||
return; | ||
// don't need model change listener while performing known data updates | ||
if (this.modelChangedListener !== null) | ||
this.diagram.model.removeChangedListener(this.modelChangedListener); | ||
this.diagram.model.startTransaction('update data'); | ||
// update modelData first, in case bindings on nodes / links depend on model data | ||
this.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); | ||
// merge node / link data | ||
DiagramComponent.mergeChanges(this, nodeDiffs, "n"); | ||
DiagramComponent.mergeChanges(this, linkDiffs, "l"); | ||
this.diagram.model.commitTransaction('update data'); | ||
// reset the model change listener | ||
if (this.modelChangedListener !== null) | ||
this.diagram.model.addChangedListener(this.modelChangedListener); | ||
}; // end ngDoCheck | ||
// end ngDoCheck | ||
NgDiagramHelper.mergeAppDataWithModel(this); | ||
}; // end ngOnChanges | ||
// end ngOnChanges | ||
/** | ||
@@ -329,3 +260,2 @@ * @return {?} | ||
DiagramComponent.ctorParameters = function () { return [ | ||
{ type: core.KeyValueDiffers }, | ||
{ type: core.NgZone } | ||
@@ -350,40 +280,47 @@ ]; }; | ||
DiagramComponent.prototype.initDiagram; | ||
/** @type {?} */ | ||
/** | ||
* Node data for diagram | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.nodeDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Link data for diagram. Optional. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.linkDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Model data for diagram. Optional. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.modelData; | ||
/** @type {?} */ | ||
/** | ||
* Diagram div class name. Use this name to style your diagram in CSS. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
/** | ||
* Model changed listener function for diagram | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.modelChangedListener; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.skipsDiagramUpdate; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.modelChange; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.diagramDiv; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.diagram; | ||
/** | ||
* Whether or not to skip merging app data with GoJS model data (set to true if update is coming from GoJS, false if coming from app-level, usually) | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._ndaDiffer; | ||
DiagramComponent.prototype.skipsDiagramUpdate; | ||
/** | ||
* Event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._ldaDiffer; | ||
DiagramComponent.prototype.modelChange; | ||
/** | ||
* The DIV element holding the Diagram | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._mdaDiffer; | ||
DiagramComponent.prototype.diagramDiv; | ||
/** | ||
* The Diagram itself | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._kvdiffers; | ||
DiagramComponent.prototype.diagram; | ||
/** @type {?} */ | ||
@@ -400,27 +337,23 @@ DiagramComponent.prototype.zone; | ||
/** | ||
* @param {?} _kvdiffers | ||
* @param {?} zone | ||
*/ | ||
function PaletteComponent(_kvdiffers, zone) { | ||
this._kvdiffers = _kvdiffers; | ||
function PaletteComponent(zone) { | ||
this.zone = zone; | ||
// Link data for palette. Optional | ||
/** | ||
* Link data for palette. Optional. | ||
*/ | ||
this.linkDataArray = null; | ||
// Model data for palette. Optional | ||
/** | ||
* Model data for palette. Optional. | ||
*/ | ||
this.modelData = null; | ||
this.skipsPaletteUpdate = false; | ||
// model changed listener function for palette | ||
this.modelChangedListener = null; | ||
// event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
/** | ||
* Event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
*/ | ||
this.modelChange = new core.EventEmitter(); | ||
// The Palette itself | ||
/** | ||
* The Palette itself | ||
*/ | ||
this.palette = null; | ||
// differs used to check if there have been changed to the array @Inputs | ||
// without them, changes to the input arrays won't register in ngOnChanges, | ||
// since the array reference itself may be the same | ||
this._ndaDiffer = this._kvdiffers.find([]).create(); | ||
this._ldaDiffer = this._kvdiffers.find([]).create(); | ||
this._mdaDiffer = this._kvdiffers.find([]).create(); | ||
} // end constructor | ||
// end constructor | ||
} | ||
/** | ||
@@ -431,32 +364,11 @@ * Initialize Palette after view init | ||
PaletteComponent.prototype.ngAfterViewInit = function () { | ||
var _this = this; | ||
if (!this.paletteDiv) | ||
return; | ||
if (!this.paletteDiv) { | ||
throw new Error("paletteDiv is not defined"); | ||
} | ||
this.palette = this.initPalette(); | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the palette, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.palette.addEventListener = ( /** | ||
* @param {?} DOMElement | ||
* @param {?} name | ||
* @param {?} listener | ||
* @param {?} capture | ||
* @return {?} | ||
*/function (DOMElement, name, listener, capture) { | ||
/** @type {?} */ | ||
var superAddEventListener = go.Diagram.prototype.addEventListener; | ||
if (name === 'mousemove') { | ||
_this.zone.runOutsideAngular(( /** | ||
* @return {?} | ||
*/function () { return superAddEventListener.call(_this, DOMElement, name, listener, capture); })); | ||
} | ||
else { | ||
_this.zone.run(( /** | ||
* @return {?} | ||
*/function () { | ||
superAddEventListener.call(_this, DOMElement, name, listener, capture); | ||
})); | ||
} | ||
}); | ||
if (!(this.palette instanceof go.Palette)) { | ||
throw new Error("initPalette function did not return a go.Palette"); | ||
} | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.palette, this.zone); | ||
// assign the Palette's div, which (among many other things) will attach a bunch of listeners to the canvas, | ||
@@ -466,80 +378,18 @@ // using the overridden addEventListener function above | ||
var divRef = this.paletteDiv.nativeElement; | ||
if (divRef == null) | ||
return; | ||
this.palette.div = divRef; | ||
// initialize palette model | ||
this.palette.delayInitialization(( /** | ||
* @return {?} | ||
*/function () { | ||
/** @type {?} */ | ||
var model = _this.palette.model; | ||
model.commit(( /** | ||
* @param {?} m | ||
* @return {?} | ||
*/function (m) { | ||
m.mergeNodeDataArray(m.cloneDeep(_this.nodeDataArray)); | ||
if (_this.linkDataArray && m instanceof go.GraphLinksModel) { | ||
m.mergeLinkDataArray(m.cloneDeep(_this.linkDataArray)); | ||
} | ||
if (_this.modelData) { | ||
m.assignAllDataProperties(m.modelData, _this.modelData); | ||
} | ||
_this.palette.layoutDiagram(true); | ||
}), null); | ||
})); | ||
// initializer listener | ||
this.modelChangedListener = ( /** | ||
* @param {?} e | ||
* @return {?} | ||
*/function (e) { | ||
if (e.isTransactionFinished && _this.palette && _this.palette.model && !_this.palette.model.isReadOnly) { | ||
// this must be done within a NgZone.run block, so changes are detected in the parent component | ||
_this.zone.run(( /** | ||
* @return {?} | ||
*/function () { | ||
/** @type {?} */ | ||
var dataChanges = ( /** @type {?} */(e.model)).toIncrementalData(e); | ||
_this.modelChange.emit(dataChanges); | ||
})); | ||
} | ||
}); | ||
this.palette.addModelChangedListener(this.modelChangedListener); | ||
}; // end ngAfterViewInit | ||
// end ngAfterViewInit | ||
NgDiagramHelper.initializeModel(this.palette, this.nodeDataArray, this.linkDataArray, this.modelData); | ||
}; | ||
/** | ||
* Always be checking if array Input data has changed (node and link data arrays) | ||
* If a change has occured on an \@Input property, merge the app-level changes with GoJS | ||
* @return {?} | ||
*/ | ||
PaletteComponent.prototype.ngDoCheck = function () { | ||
if (!this.palette) | ||
PaletteComponent.prototype.ngOnChanges = function () { | ||
if (!this.palette || !this.palette.model) | ||
return; | ||
if (!this.palette.model) | ||
return; | ||
// these need to be run each check, even if no merging happens | ||
// otherwise, they will detect all diffs that happened since last time skipsPaletteUpdate was false, | ||
// such as remove ops that happened in GoJS when skipsPaletteUpdate = true, | ||
// and then realllllly bad stuff happens (deleting random nodes, updating the wrong Parts) | ||
// Angular differs are a lot of fun | ||
/** @type {?} */ | ||
var nodeDiffs = this._ndaDiffer.diff(this.nodeDataArray); | ||
/** @type {?} */ | ||
var linkDiffs = this._ldaDiffer.diff(this.linkDataArray); | ||
/** @type {?} */ | ||
var modelDiffs = this._mdaDiffer.diff(this.modelData); | ||
if (!nodeDiffs && !linkDiffs && !modelDiffs) | ||
return; | ||
if (this.skipsPaletteUpdate) | ||
return; | ||
// don't need model change listener while performing known data updates | ||
if (this.modelChangedListener !== null) | ||
this.palette.model.removeChangedListener(this.modelChangedListener); | ||
this.palette.model.startTransaction('update data'); | ||
// update modelData first, in case bindings on nodes / links depend on model data | ||
this.palette.model.assignAllDataProperties(this.palette.model.modelData, this.modelData); | ||
DiagramComponent.mergeChanges(this, nodeDiffs, "n"); | ||
DiagramComponent.mergeChanges(this, linkDiffs, "l"); | ||
this.palette.model.commitTransaction('update data'); | ||
// reset the model change listener | ||
if (this.modelChangedListener !== null) | ||
this.palette.model.addChangedListener(this.modelChangedListener); | ||
}; // end ngDoCheck | ||
// end ngDoCheck | ||
NgDiagramHelper.mergeAppDataWithModel(this); | ||
}; // end ngOnChanges | ||
// end ngOnChanges | ||
/** | ||
@@ -561,3 +411,2 @@ * @return {?} | ||
PaletteComponent.ctorParameters = function () { return [ | ||
{ type: core.KeyValueDiffers }, | ||
{ type: core.NgZone } | ||
@@ -571,3 +420,2 @@ ]; }; | ||
divClassName: [{ type: core.Input }], | ||
skipsPaletteUpdate: [{ type: core.Input }], | ||
modelChange: [{ type: core.Output }], | ||
@@ -583,40 +431,37 @@ paletteDiv: [{ type: core.ViewChild, args: ['ngPalette', { static: true },] }] | ||
PaletteComponent.prototype.initPalette; | ||
/** @type {?} */ | ||
/** | ||
* Node data for palette | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.nodeDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Link data for palette. Optional. | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.linkDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Model data for palette. Optional. | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.modelData; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.skipsPaletteUpdate; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.modelChangedListener; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.modelChange; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.paletteDiv; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.palette; | ||
/** | ||
* Palette div class name. Use this name to style your palette in CSS | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._ndaDiffer; | ||
PaletteComponent.prototype.divClassName; | ||
/** | ||
* Event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._ldaDiffer; | ||
PaletteComponent.prototype.modelChange; | ||
/** | ||
* The DIV element holding the Palette | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._mdaDiffer; | ||
PaletteComponent.prototype.paletteDiv; | ||
/** | ||
* The Palette itself | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._kvdiffers; | ||
PaletteComponent.prototype.palette; | ||
/** @type {?} */ | ||
@@ -637,5 +482,9 @@ PaletteComponent.prototype.zone; | ||
this.zone = zone; | ||
// The Diagram to observe with the Overview | ||
/** | ||
* The Diagram to observe with the Overview | ||
*/ | ||
this.observedDiagram = null; | ||
// The Overview itself | ||
/** | ||
* The Overview itself | ||
*/ | ||
this.overview = null; | ||
@@ -648,7 +497,10 @@ } | ||
OverviewComponent.prototype.ngAfterViewInit = function () { | ||
var _this = this; | ||
if (!this.overviewDiv) | ||
return; | ||
if (!this.overviewDiv) { | ||
throw new Error("overviewDiv is not defined"); | ||
} | ||
if (this.initOverview) { | ||
this.overview = this.initOverview(); | ||
if (!(this.overview instanceof go.Overview)) { | ||
throw new Error("initOverview function did not return a go.Overview"); | ||
} | ||
} | ||
@@ -659,28 +511,4 @@ else { | ||
} | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the overview, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.overview.addEventListener = ( /** | ||
* @param {?} DOMElement | ||
* @param {?} name | ||
* @param {?} listener | ||
* @param {?} capture | ||
* @return {?} | ||
*/function (DOMElement, name, listener, capture) { | ||
/** @type {?} */ | ||
var superAddEventListener = go.Diagram.prototype.addEventListener; | ||
if (name === 'mousemove') { | ||
_this.zone.runOutsideAngular(( /** | ||
* @return {?} | ||
*/function () { return superAddEventListener.call(_this, DOMElement, name, listener, capture); })); | ||
} | ||
else { | ||
_this.zone.run(( /** | ||
* @return {?} | ||
*/function () { | ||
superAddEventListener.call(_this, DOMElement, name, listener, capture); | ||
})); | ||
} | ||
}); | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.overview, this.zone); | ||
this.overview.div = this.overviewDiv.nativeElement; | ||
@@ -725,11 +553,23 @@ }; | ||
if (false) { | ||
/** @type {?} */ | ||
/** | ||
* The function used to initialize and return the Overview | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.initOverview; | ||
/** @type {?} */ | ||
/** | ||
* The div class name that holds the Overview. Use this name to style your Overview in CSS. | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
/** | ||
* The Diagram to observe with the Overview | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.observedDiagram; | ||
/** @type {?} */ | ||
OverviewComponent.prototype.overviewDiv; | ||
/** @type {?} */ | ||
/** | ||
* The Overview itself | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.overview; | ||
@@ -763,51 +603,58 @@ /** @type {?} */ | ||
var modifiedNodesMap = new go.Map(); | ||
// account for modified node data | ||
if (changes.modifiedNodeData) { | ||
changes.modifiedNodeData.forEach(( /** | ||
* @param {?} nd | ||
* @return {?} | ||
*/function (nd) { | ||
// Get the value of the node key property checking wether is a function or a string | ||
/** @type {?} */ | ||
var key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
modifiedNodesMap.set(key, nd); | ||
for (var i = 0; i < nodeData.length; i++) { | ||
// nodeData is immutable, modify it using the immer package's "produce" function (creates new array) | ||
/** @type {?} */ | ||
var newNodeDataArray = produce(nodeData, ( /** | ||
* @param {?} draft | ||
* @return {?} | ||
*/function (draft) { | ||
// account for modified node data | ||
if (changes.modifiedNodeData) { | ||
changes.modifiedNodeData.forEach(( /** | ||
* @param {?} nd | ||
* @return {?} | ||
*/function (nd) { | ||
// Get the value of the node key property checking wether is a function or a string | ||
/** @type {?} */ | ||
var ndEntry = nodeData[i]; | ||
var key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
modifiedNodesMap.set(key, nd); | ||
for (var i = 0; i < nodeData.length; i++) { | ||
/** @type {?} */ | ||
var ndEntry = nodeData[i]; | ||
/** @type {?} */ | ||
var keyNdEntry = model ? model.getKeyForNodeData(ndEntry) : ndEntry['key']; | ||
if (keyNdEntry === key) { | ||
draft[i] = nd; | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted node data | ||
if (changes.insertedNodeKeys) { | ||
changes.insertedNodeKeys.forEach(( /** | ||
* @param {?} key | ||
* @return {?} | ||
*/function (key) { | ||
/** @type {?} */ | ||
var keyNdEntry = model ? model.getKeyForNodeData(ndEntry) : ndEntry['key']; | ||
if (keyNdEntry === key) { | ||
nodeData[i] = nd; | ||
var nd = modifiedNodesMap.get(key); | ||
if (nd) { | ||
draft.push(nd); | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted node data | ||
if (changes.insertedNodeKeys) { | ||
changes.insertedNodeKeys.forEach(( /** | ||
* @param {?} key | ||
* @return {?} | ||
*/function (key) { | ||
/** @type {?} */ | ||
var nd = modifiedNodesMap.get(key); | ||
if (nd) { | ||
nodeData.push(nd); | ||
} | ||
})); | ||
} | ||
// account for removed node data | ||
if (changes.removedNodeKeys) { | ||
nodeData = nodeData.filter(( /** | ||
* @param {?} nd | ||
* @return {?} | ||
*/function (nd) { | ||
/** @type {?} */ | ||
var key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
if (changes.removedNodeKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
return nodeData; | ||
})); | ||
} | ||
// account for removed node data | ||
if (changes.removedNodeKeys) { | ||
return draft.filter(( /** | ||
* @param {?} nd | ||
* @return {?} | ||
*/function (nd) { | ||
/** @type {?} */ | ||
var key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
if (changes.removedNodeKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
return newNodeDataArray; | ||
}; | ||
@@ -829,50 +676,59 @@ /** | ||
var modifiedLinksMap = new go.Map(); | ||
// account for modified link data | ||
if (changes.modifiedLinkData) { | ||
changes.modifiedLinkData.forEach(( /** | ||
* @param {?} ld | ||
* @return {?} | ||
*/function (ld) { | ||
// Get the value of the link key | ||
/** @type {?} */ | ||
var key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
modifiedLinksMap.set(key, ld); | ||
for (var i = 0; i < linkData.length; i++) { | ||
// linkData is immutable, modify it using the immer package's "produce" function (creates new array) | ||
linkData = produce(linkData, ( /** | ||
* @param {?} draft | ||
* @return {?} | ||
*/function (/** | ||
* @param {?} draft | ||
* @return {?} | ||
*/ draft) { | ||
// account for modified link data | ||
if (changes.modifiedLinkData) { | ||
changes.modifiedLinkData.forEach(( /** | ||
* @param {?} ld | ||
* @return {?} | ||
*/function (ld) { | ||
// Get the value of the link key | ||
/** @type {?} */ | ||
var ldEntry = linkData[i]; | ||
var key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
modifiedLinksMap.set(key, ld); | ||
for (var i = 0; i < linkData.length; i++) { | ||
/** @type {?} */ | ||
var ldEntry = linkData[i]; | ||
/** @type {?} */ | ||
var keyLdEntry = model ? model.getKeyForLinkData(ldEntry) : ldEntry['key']; | ||
if (keyLdEntry === key) { | ||
draft[i] = ld; | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted link data | ||
if (changes.insertedLinkKeys) { | ||
changes.insertedLinkKeys.forEach(( /** | ||
* @param {?} key | ||
* @return {?} | ||
*/function (key) { | ||
/** @type {?} */ | ||
var keyLdEntry = model ? model.getKeyForLinkData(ldEntry) : ldEntry['key']; | ||
if (keyLdEntry === key) { | ||
linkData[i] = ld; | ||
var nd = modifiedLinksMap.get(key); | ||
if (nd) { | ||
draft.push(nd); | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted link data | ||
if (changes.insertedLinkKeys) { | ||
changes.insertedLinkKeys.forEach(( /** | ||
* @param {?} key | ||
* @return {?} | ||
*/function (key) { | ||
/** @type {?} */ | ||
var nd = modifiedLinksMap.get(key); | ||
if (nd) { | ||
linkData.push(nd); | ||
} | ||
})); | ||
} | ||
// account for removed link data | ||
if (changes.removedLinkKeys) { | ||
linkData = linkData.filter(( /** | ||
* @param {?} ld | ||
* @return {?} | ||
*/function (ld) { | ||
/** @type {?} */ | ||
var key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
if (changes.removedLinkKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
} | ||
// account for removed link data | ||
if (changes.removedLinkKeys) { | ||
return draft.filter(( /** | ||
* @param {?} ld | ||
* @return {?} | ||
*/function (ld) { | ||
/** @type {?} */ | ||
var key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
if (changes.removedLinkKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
return linkData; | ||
@@ -900,4 +756,2 @@ }; | ||
]; | ||
/** @nocollapse */ | ||
DataSyncService.ctorParameters = function () { return []; }; | ||
@@ -904,0 +758,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("gojs")):"function"==typeof define&&define.amd?define("gojs-angular",["exports","@angular/core","gojs"],t):t((e=e||self)["gojs-angular"]={},e.ng.core,e.go)}(this,(function(e,t,a){"use strict";var i=function(){function e(e,a){this._kvdiffers=e,this.zone=a,this.linkDataArray=null,this.modelData=null,this.modelChangedListener=null,this.skipsDiagramUpdate=!1,this.modelChange=new t.EventEmitter,this.diagram=null,this._ndaDiffer=this._kvdiffers.find([]).create(),this._ldaDiffer=this._kvdiffers.find([]).create(),this._mdaDiffer=this._kvdiffers.find([]).create()}return e.prototype.ngAfterViewInit=function(){var e=this;this.diagram=this.initDiagram(),this.diagram.addEventListener=function(t,i,r,n){var o=a.Diagram.prototype.addEventListener;"mousemove"===i?e.zone.runOutsideAngular((function(){return o.call(e,t,i,r,n)})):e.zone.run((function(){o.call(e,t,i,r,n)}))};var t=this.diagramDiv.nativeElement;null!==t&&(this.diagram.div=t,this.diagram.delayInitialization((function(){e.diagram.model.commit((function(t){t.mergeNodeDataArray(t.cloneDeep(e.nodeDataArray)),e.linkDataArray&&t instanceof a.GraphLinksModel&&t.mergeLinkDataArray(t.cloneDeep(e.linkDataArray)),e.modelData&&t.assignAllDataProperties(t.modelData,e.modelData),e.diagram.layoutDiagram(!0)}),null)})),this.modelChangedListener=function(t){t.isTransactionFinished&&e.diagram&&e.diagram.model&&!e.diagram.model.isReadOnly&&e.zone.run((function(){var a=t.model.toIncrementalData(t);e.modelChange.emit(a)}))},this.diagram.addModelChangedListener(this.modelChangedListener))},e.mergeChanges=function(t,a,i){var r=t instanceof e?t.diagram:t.palette;r&&r.model&&a&&(a.forEachAddedItem((function(e){switch(i){case"n":r.model.addNodeData(e.currentValue);break;case"l":r.model.addLinkData(e.currentValue)}})),a.forEachRemovedItem((function(e){switch(i){case"n":var t=r.model.nodeKeyProperty.toString(),a=r.findNodeForKey(e.previousValue[t]);a&&r.remove(a);break;case"l":var n=r.model.linkKeyProperty.toString(),o=r.findLinkForKey(e.previousValue[n]);o&&r.remove(o)}})),a.forEachChangedItem((function(e){if(!function e(t,a){if(!t||!a)return!1;for(var i in t){if(t.hasOwnProperty(i)!==a.hasOwnProperty(i))return!1;switch(typeof t[i]){case"object":if(!e(t[i],a[i]))return!1;break;default:if(t[i]!==a[i])return!1}}for(var i in a)if(void 0===t[i])return!1;return!0}(e.currentValue,e.previousValue))switch(i){case"n":var t=r.model.nodeKeyProperty.toString(),a=r.findNodeForKey(e.previousValue[t]);a&&(e.currentValue?r.model.assignAllDataProperties(a.data,e.currentValue):r.remove(a));break;case"l":var n=r.model.linkKeyProperty.toString(),o=r.findLinkForKey(e.previousValue[n]);o&&(e.currentValue?r.model.assignAllDataProperties(o.data,e.currentValue):r.remove(o))}})))},e.prototype.ngDoCheck=function(){if(this.diagram&&this.diagram.model){var t=this._ndaDiffer.diff(this.nodeDataArray),a=this._ldaDiffer.diff(this.linkDataArray),i=this._mdaDiffer.diff(this.modelData);(t||a||i)&&(this.skipsDiagramUpdate||(null!==this.modelChangedListener&&this.diagram.model.removeChangedListener(this.modelChangedListener),this.diagram.model.startTransaction("update data"),this.diagram.model.assignAllDataProperties(this.diagram.model.modelData,this.modelData),e.mergeChanges(this,t,"n"),e.mergeChanges(this,a,"l"),this.diagram.model.commitTransaction("update data"),null!==this.modelChangedListener&&this.diagram.model.addChangedListener(this.modelChangedListener)))}},e.prototype.ngOnDestroy=function(){this.diagram.div=null},e}();i.decorators=[{type:t.Component,args:[{selector:"gojs-diagram",template:"<div #ngDiagram [className]=divClassName></div>"}]}],i.ctorParameters=function(){return[{type:t.KeyValueDiffers},{type:t.NgZone}]},i.propDecorators={initDiagram:[{type:t.Input}],nodeDataArray:[{type:t.Input}],linkDataArray:[{type:t.Input}],modelData:[{type:t.Input}],divClassName:[{type:t.Input}],skipsDiagramUpdate:[{type:t.Input}],modelChange:[{type:t.Output}],diagramDiv:[{type:t.ViewChild,args:["ngDiagram",{static:!0}]}]};var r=function(){function e(e,a){this._kvdiffers=e,this.zone=a,this.linkDataArray=null,this.modelData=null,this.skipsPaletteUpdate=!1,this.modelChangedListener=null,this.modelChange=new t.EventEmitter,this.palette=null,this._ndaDiffer=this._kvdiffers.find([]).create(),this._ldaDiffer=this._kvdiffers.find([]).create(),this._mdaDiffer=this._kvdiffers.find([]).create()}return e.prototype.ngAfterViewInit=function(){var e=this;if(this.paletteDiv){this.palette=this.initPalette(),this.palette.addEventListener=function(t,i,r,n){var o=a.Diagram.prototype.addEventListener;"mousemove"===i?e.zone.runOutsideAngular((function(){return o.call(e,t,i,r,n)})):e.zone.run((function(){o.call(e,t,i,r,n)}))};var t=this.paletteDiv.nativeElement;this.palette.div=t,this.palette.delayInitialization((function(){e.palette.model.commit((function(t){t.mergeNodeDataArray(t.cloneDeep(e.nodeDataArray)),e.linkDataArray&&t instanceof a.GraphLinksModel&&t.mergeLinkDataArray(t.cloneDeep(e.linkDataArray)),e.modelData&&t.assignAllDataProperties(t.modelData,e.modelData),e.palette.layoutDiagram(!0)}),null)})),this.modelChangedListener=function(t){t.isTransactionFinished&&e.palette&&e.palette.model&&!e.palette.model.isReadOnly&&e.zone.run((function(){var a=t.model.toIncrementalData(t);e.modelChange.emit(a)}))},this.palette.addModelChangedListener(this.modelChangedListener)}},e.prototype.ngDoCheck=function(){if(this.palette&&this.palette.model){var e=this._ndaDiffer.diff(this.nodeDataArray),t=this._ldaDiffer.diff(this.linkDataArray),a=this._mdaDiffer.diff(this.modelData);(e||t||a)&&(this.skipsPaletteUpdate||(null!==this.modelChangedListener&&this.palette.model.removeChangedListener(this.modelChangedListener),this.palette.model.startTransaction("update data"),this.palette.model.assignAllDataProperties(this.palette.model.modelData,this.modelData),i.mergeChanges(this,e,"n"),i.mergeChanges(this,t,"l"),this.palette.model.commitTransaction("update data"),null!==this.modelChangedListener&&this.palette.model.addChangedListener(this.modelChangedListener)))}},e.prototype.ngOnDestroy=function(){this.palette.div=null},e}();r.decorators=[{type:t.Component,args:[{selector:"gojs-palette",template:"<div #ngPalette [className]=divClassName></div>"}]}],r.ctorParameters=function(){return[{type:t.KeyValueDiffers},{type:t.NgZone}]},r.propDecorators={initPalette:[{type:t.Input}],nodeDataArray:[{type:t.Input}],linkDataArray:[{type:t.Input}],modelData:[{type:t.Input}],divClassName:[{type:t.Input}],skipsPaletteUpdate:[{type:t.Input}],modelChange:[{type:t.Output}],paletteDiv:[{type:t.ViewChild,args:["ngPalette",{static:!0}]}]};var n=function(){function e(e){this.zone=e,this.observedDiagram=null,this.overview=null}return e.prototype.ngAfterViewInit=function(){var e=this;this.overviewDiv&&(this.initOverview?this.overview=this.initOverview():(this.overview=new a.Overview,this.overview.contentAlignment=a.Spot.Center),this.overview.addEventListener=function(t,i,r,n){var o=a.Diagram.prototype.addEventListener;"mousemove"===i?e.zone.runOutsideAngular((function(){return o.call(e,t,i,r,n)})):e.zone.run((function(){o.call(e,t,i,r,n)}))},this.overview.div=this.overviewDiv.nativeElement)},e.prototype.ngOnChanges=function(e){this.overview&&e&&e.observedDiagram&&e.observedDiagram.currentValue!==e.observedDiagram.previousValue&&(this.overview.observed=e.observedDiagram.currentValue)},e.prototype.ngOnDestroy=function(){this.overview.div=null},e}();n.decorators=[{type:t.Component,args:[{selector:"gojs-overview",template:"<div #ngOverview [className]=divClassName></div>"}]}],n.ctorParameters=function(){return[{type:t.NgZone}]},n.propDecorators={initOverview:[{type:t.Input}],divClassName:[{type:t.Input}],observedDiagram:[{type:t.Input}],overviewDiv:[{type:t.ViewChild,args:["ngOverview",{static:!0}]}]};var o=function(){function e(){}return e.syncNodeData=function(e,t,i){if(!e)return t;if(!e.modifiedNodeData&&!e.insertedNodeKeys&&!e.removedNodeKeys)return t;var r=new a.Map;return e.modifiedNodeData&&e.modifiedNodeData.forEach((function(e){var a=i?i.getKeyForNodeData(e):e.key;r.set(a,e);for(var n=0;n<t.length;n++){var o=t[n];(i?i.getKeyForNodeData(o):o.key)===a&&(t[n]=e)}})),e.insertedNodeKeys&&e.insertedNodeKeys.forEach((function(e){var a=r.get(e);a&&t.push(a)})),e.removedNodeKeys&&(t=t.filter((function(t){var a=i?i.getKeyForNodeData(t):t.key;return!e.removedNodeKeys.includes(a)}))),t},e.syncLinkData=function(e,t,i){if(!e)return t;if(!e.modifiedLinkData&&!e.insertedLinkKeys&&!e.removedLinkKeys)return t;var r=new a.Map;return e.modifiedLinkData&&e.modifiedLinkData.forEach((function(e){var a=i?i.getKeyForLinkData(e):e.key;r.set(a,e);for(var n=0;n<t.length;n++){var o=t[n];(i?i.getKeyForLinkData(o):o.key)===a&&(t[n]=e)}})),e.insertedLinkKeys&&e.insertedLinkKeys.forEach((function(e){var a=r.get(e);a&&t.push(a)})),e.removedLinkKeys&&(t=t.filter((function(t){var a=i?i.getKeyForLinkData(t):t.key;return!e.removedLinkKeys.includes(a)}))),t},e.syncModelData=function(e,t){return e&&e.modelData?e.modelData?e.modelData:void 0:t},e}();o.decorators=[{type:t.Injectable}],o.ctorParameters=function(){return[]};var s=function(){};s.decorators=[{type:t.NgModule,args:[{declarations:[i,n,r],imports:[],providers:[o],exports:[i,n,r]}]}],e.DataSyncService=o,e.DiagramComponent=i,e.GojsAngularModule=s,e.OverviewComponent=n,e.PaletteComponent=r,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("gojs"),require("immer")):"function"==typeof define&&define.amd?define("gojs-angular",["exports","@angular/core","gojs","immer"],t):t((e=e||self)["gojs-angular"]={},e.ng.core,e.go,e.produce)}(this,(function(e,t,i,a){"use strict";a=a&&Object.prototype.hasOwnProperty.call(a,"default")?a.default:a;var n=function(){function e(){}return e.makeMouseMoveRunOutsideAngularZone=function(e,t){var a=this;e.addEventListener=function(e,n,r,o){var s=i.Diagram.prototype.addEventListener;"mousemove"===n?t.runOutsideAngular((function(){return s.call(a,e,n,r,o)})):t.run((function(){s.call(a,e,n,r,o)}))}},e.initializeModel=function(e,t,a,n){e.delayInitialization((function(){e.model.commit((function(e){e.mergeNodeDataArray(e.cloneDeep(t)),a&&e instanceof i.GraphLinksModel&&e.mergeLinkDataArray(e.cloneDeep(a)),n&&e.assignAllDataProperties(e.modelData,n)}),null)}))},e.initializeModelChangedListener=function(e){var t=null;(e.hasOwnProperty("diagram")||e.hasOwnProperty("palette"))&&(e.hasOwnProperty("diagram")&&(t=e.diagram),e.hasOwnProperty("palette")&&(t=e.palette),e.modelChangedListener=function(i){i.isTransactionFinished&&t&&t.model&&!t.model.isReadOnly&&e.zone.run((function(){var t=i.model.toIncrementalData(i);e.modelChange.emit(t)}))},t.addModelChangedListener(e.modelChangedListener))},e.mergeAppDataWithModel=function(e){var t=null;e.hasOwnProperty("diagram")&&(t=e.diagram),e.hasOwnProperty("palette")&&(t=e.palette);var a=e instanceof r?e.modelChangedListener:null;null!==a&&t.model.removeChangedListener(a),t.model.startTransaction("update data"),t.model.assignAllDataProperties(t.model.modelData,e.modelData),t.model.mergeNodeDataArray(e.nodeDataArray),e.linkDataArray&&t.model instanceof i.GraphLinksModel&&t.model.mergeLinkDataArray(e.linkDataArray),t.model.commitTransaction("update data"),null!==a&&t.model.addChangedListener(a)},e}(),r=function(){function e(e){this.zone=e,this.linkDataArray=null,this.modelData=null,this.modelChangedListener=null,this.skipsDiagramUpdate=!1,this.modelChange=new t.EventEmitter,this.diagram=null}return e.prototype.ngAfterViewInit=function(){if(!this.diagramDiv)throw new Error("diagramDiv is not defined");if(this.diagram=this.initDiagram(),!(this.diagram instanceof i.Diagram))throw new Error("initDiagram function did not return a go.Diagram");n.makeMouseMoveRunOutsideAngularZone(this.diagram,this.zone);var e=this.diagramDiv.nativeElement;null!==e&&(this.diagram.div=e,n.initializeModel(this.diagram,this.nodeDataArray,this.linkDataArray,this.modelData),n.initializeModelChangedListener(this))},e.prototype.ngOnChanges=function(){this.diagram&&this.diagram.model&&!this.skipsDiagramUpdate&&n.mergeAppDataWithModel(this)},e.prototype.ngOnDestroy=function(){this.diagram.div=null},e}();r.decorators=[{type:t.Component,args:[{selector:"gojs-diagram",template:"<div #ngDiagram [className]=divClassName></div>"}]}],r.ctorParameters=function(){return[{type:t.NgZone}]},r.propDecorators={initDiagram:[{type:t.Input}],nodeDataArray:[{type:t.Input}],linkDataArray:[{type:t.Input}],modelData:[{type:t.Input}],divClassName:[{type:t.Input}],skipsDiagramUpdate:[{type:t.Input}],modelChange:[{type:t.Output}],diagramDiv:[{type:t.ViewChild,args:["ngDiagram",{static:!0}]}]};var o=function(){function e(e){this.zone=e,this.linkDataArray=null,this.modelData=null,this.modelChange=new t.EventEmitter,this.palette=null}return e.prototype.ngAfterViewInit=function(){if(!this.paletteDiv)throw new Error("paletteDiv is not defined");if(this.palette=this.initPalette(),!(this.palette instanceof i.Palette))throw new Error("initPalette function did not return a go.Palette");n.makeMouseMoveRunOutsideAngularZone(this.palette,this.zone);var e=this.paletteDiv.nativeElement;null!=e&&(this.palette.div=e,n.initializeModel(this.palette,this.nodeDataArray,this.linkDataArray,this.modelData))},e.prototype.ngOnChanges=function(){this.palette&&this.palette.model&&n.mergeAppDataWithModel(this)},e.prototype.ngOnDestroy=function(){this.palette.div=null},e}();o.decorators=[{type:t.Component,args:[{selector:"gojs-palette",template:"<div #ngPalette [className]=divClassName></div>"}]}],o.ctorParameters=function(){return[{type:t.NgZone}]},o.propDecorators={initPalette:[{type:t.Input}],nodeDataArray:[{type:t.Input}],linkDataArray:[{type:t.Input}],modelData:[{type:t.Input}],divClassName:[{type:t.Input}],modelChange:[{type:t.Output}],paletteDiv:[{type:t.ViewChild,args:["ngPalette",{static:!0}]}]};var s=function(){function e(e){this.zone=e,this.observedDiagram=null,this.overview=null}return e.prototype.ngAfterViewInit=function(){if(!this.overviewDiv)throw new Error("overviewDiv is not defined");if(this.initOverview){if(this.overview=this.initOverview(),!(this.overview instanceof i.Overview))throw new Error("initOverview function did not return a go.Overview")}else this.overview=new i.Overview,this.overview.contentAlignment=i.Spot.Center;n.makeMouseMoveRunOutsideAngularZone(this.overview,this.zone),this.overview.div=this.overviewDiv.nativeElement},e.prototype.ngOnChanges=function(e){this.overview&&e&&e.observedDiagram&&e.observedDiagram.currentValue!==e.observedDiagram.previousValue&&(this.overview.observed=e.observedDiagram.currentValue)},e.prototype.ngOnDestroy=function(){this.overview.div=null},e}();s.decorators=[{type:t.Component,args:[{selector:"gojs-overview",template:"<div #ngOverview [className]=divClassName></div>"}]}],s.ctorParameters=function(){return[{type:t.NgZone}]},s.propDecorators={initOverview:[{type:t.Input}],divClassName:[{type:t.Input}],observedDiagram:[{type:t.Input}],overviewDiv:[{type:t.ViewChild,args:["ngOverview",{static:!0}]}]};var d=function(){function e(){}return e.syncNodeData=function(e,t,n){if(!e)return t;if(!e.modifiedNodeData&&!e.insertedNodeKeys&&!e.removedNodeKeys)return t;var r=new i.Map;return a(t,(function(i){if(e.modifiedNodeData&&e.modifiedNodeData.forEach((function(e){var a=n?n.getKeyForNodeData(e):e.key;r.set(a,e);for(var o=0;o<t.length;o++){var s=t[o];(n?n.getKeyForNodeData(s):s.key)===a&&(i[o]=e)}})),e.insertedNodeKeys&&e.insertedNodeKeys.forEach((function(e){var t=r.get(e);t&&i.push(t)})),e.removedNodeKeys)return i.filter((function(t){var i=n?n.getKeyForNodeData(t):t.key;return!e.removedNodeKeys.includes(i)}))}))},e.syncLinkData=function(e,t,n){if(!e)return t;if(!e.modifiedLinkData&&!e.insertedLinkKeys&&!e.removedLinkKeys)return t;var r=new i.Map;return t=a(t,(function(i){if(e.modifiedLinkData&&e.modifiedLinkData.forEach((function(e){var a=n?n.getKeyForLinkData(e):e.key;r.set(a,e);for(var o=0;o<t.length;o++){var s=t[o];(n?n.getKeyForLinkData(s):s.key)===a&&(i[o]=e)}})),e.insertedLinkKeys&&e.insertedLinkKeys.forEach((function(e){var t=r.get(e);t&&i.push(t)})),e.removedLinkKeys)return i.filter((function(t){var i=n?n.getKeyForLinkData(t):t.key;return!e.removedLinkKeys.includes(i)}))}))},e.syncModelData=function(e,t){return e&&e.modelData?e.modelData?e.modelData:void 0:t},e}();d.decorators=[{type:t.Injectable}];var l=function(){};l.decorators=[{type:t.NgModule,args:[{declarations:[r,s,o],imports:[],providers:[d],exports:[r,s,o]}]}],e.DataSyncService=d,e.DiagramComponent=r,e.GojsAngularModule=l,e.OverviewComponent=s,e.PaletteComponent=o,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
//# sourceMappingURL=gojs-angular.umd.min.js.map |
@@ -8,4 +8,4 @@ /** | ||
import * as go from 'gojs'; | ||
import produce from "immer"; | ||
export class DataSyncService { | ||
constructor() { } | ||
/** | ||
@@ -26,54 +26,62 @@ * Sync a node data array with a set of changes | ||
const modifiedNodesMap = new go.Map(); | ||
// account for modified node data | ||
if (changes.modifiedNodeData) { | ||
changes.modifiedNodeData.forEach((/** | ||
* @param {?} nd | ||
* @return {?} | ||
*/ | ||
(nd) => { | ||
// Get the value of the node key property checking wether is a function or a string | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
modifiedNodesMap.set(key, nd); | ||
for (let i = 0; i < nodeData.length; i++) { | ||
// nodeData is immutable, modify it using the immer package's "produce" function (creates new array) | ||
/** @type {?} */ | ||
var newNodeDataArray = produce(nodeData, (/** | ||
* @param {?} draft | ||
* @return {?} | ||
*/ | ||
(draft) => { | ||
// account for modified node data | ||
if (changes.modifiedNodeData) { | ||
changes.modifiedNodeData.forEach((/** | ||
* @param {?} nd | ||
* @return {?} | ||
*/ | ||
(nd) => { | ||
// Get the value of the node key property checking wether is a function or a string | ||
/** @type {?} */ | ||
const ndEntry = nodeData[i]; | ||
const key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
modifiedNodesMap.set(key, nd); | ||
for (let i = 0; i < nodeData.length; i++) { | ||
/** @type {?} */ | ||
const ndEntry = nodeData[i]; | ||
/** @type {?} */ | ||
const keyNdEntry = model ? model.getKeyForNodeData(ndEntry) : ndEntry['key']; | ||
if (keyNdEntry === key) { | ||
draft[i] = nd; | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted node data | ||
if (changes.insertedNodeKeys) { | ||
changes.insertedNodeKeys.forEach((/** | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
(key) => { | ||
/** @type {?} */ | ||
const keyNdEntry = model ? model.getKeyForNodeData(ndEntry) : ndEntry['key']; | ||
if (keyNdEntry === key) { | ||
nodeData[i] = nd; | ||
const nd = modifiedNodesMap.get(key); | ||
if (nd) { | ||
draft.push(nd); | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted node data | ||
if (changes.insertedNodeKeys) { | ||
changes.insertedNodeKeys.forEach((/** | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
(key) => { | ||
/** @type {?} */ | ||
const nd = modifiedNodesMap.get(key); | ||
if (nd) { | ||
nodeData.push(nd); | ||
} | ||
})); | ||
} | ||
// account for removed node data | ||
if (changes.removedNodeKeys) { | ||
nodeData = nodeData.filter((/** | ||
* @param {?} nd | ||
* @return {?} | ||
*/ | ||
(nd) => { | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
if (changes.removedNodeKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
return nodeData; | ||
})); | ||
} | ||
// account for removed node data | ||
if (changes.removedNodeKeys) { | ||
return draft.filter((/** | ||
* @param {?} nd | ||
* @return {?} | ||
*/ | ||
(nd) => { | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
if (changes.removedNodeKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
return newNodeDataArray; | ||
} | ||
@@ -95,53 +103,60 @@ /** | ||
const modifiedLinksMap = new go.Map(); | ||
// account for modified link data | ||
if (changes.modifiedLinkData) { | ||
changes.modifiedLinkData.forEach((/** | ||
* @param {?} ld | ||
* @return {?} | ||
*/ | ||
(ld) => { | ||
// Get the value of the link key | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
modifiedLinksMap.set(key, ld); | ||
for (let i = 0; i < linkData.length; i++) { | ||
// linkData is immutable, modify it using the immer package's "produce" function (creates new array) | ||
linkData = produce(linkData, (/** | ||
* @param {?} draft | ||
* @return {?} | ||
*/ | ||
draft => { | ||
// account for modified link data | ||
if (changes.modifiedLinkData) { | ||
changes.modifiedLinkData.forEach((/** | ||
* @param {?} ld | ||
* @return {?} | ||
*/ | ||
(ld) => { | ||
// Get the value of the link key | ||
/** @type {?} */ | ||
const ldEntry = linkData[i]; | ||
const key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
modifiedLinksMap.set(key, ld); | ||
for (let i = 0; i < linkData.length; i++) { | ||
/** @type {?} */ | ||
const ldEntry = linkData[i]; | ||
/** @type {?} */ | ||
const keyLdEntry = model ? model.getKeyForLinkData(ldEntry) : ldEntry['key']; | ||
if (keyLdEntry === key) { | ||
draft[i] = ld; | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted link data | ||
if (changes.insertedLinkKeys) { | ||
changes.insertedLinkKeys.forEach((/** | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
(key) => { | ||
/** @type {?} */ | ||
const keyLdEntry = model ? model.getKeyForLinkData(ldEntry) : ldEntry['key']; | ||
if (keyLdEntry === key) { | ||
linkData[i] = ld; | ||
const nd = modifiedLinksMap.get(key); | ||
if (nd) { | ||
draft.push(nd); | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted link data | ||
if (changes.insertedLinkKeys) { | ||
changes.insertedLinkKeys.forEach((/** | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
(key) => { | ||
/** @type {?} */ | ||
const nd = modifiedLinksMap.get(key); | ||
if (nd) { | ||
linkData.push(nd); | ||
} | ||
})); | ||
} | ||
// account for removed link data | ||
if (changes.removedLinkKeys) { | ||
linkData = linkData.filter((/** | ||
* @param {?} ld | ||
* @return {?} | ||
*/ | ||
(ld) => { | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
if (changes.removedLinkKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
} | ||
// account for removed link data | ||
if (changes.removedLinkKeys) { | ||
return draft.filter((/** | ||
* @param {?} ld | ||
* @return {?} | ||
*/ | ||
(ld) => { | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
if (changes.removedLinkKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
return linkData; | ||
@@ -168,4 +183,2 @@ } | ||
]; | ||
/** @nocollapse */ | ||
DataSyncService.ctorParameters = () => []; | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1zeW5jLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nb2pzLWFuZ3VsYXIvc3JjL2xpYi9kYXRhLXN5bmMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFHM0IsTUFBTSxPQUFPLGVBQWU7SUFFMUIsZ0JBQWdCLENBQUM7Ozs7Ozs7O0lBU1YsTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUEyQixFQUFFLFFBQThCLEVBQUUsS0FBZ0I7UUFDdEcsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUM5QixJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWU7WUFBRSxPQUFPLFFBQVEsQ0FBQzs7O2NBR2xHLGdCQUFnQixHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsRUFBeUI7UUFFNUQsaUNBQWlDO1FBQ2pDLElBQUksT0FBTyxDQUFDLGdCQUFnQixFQUFFO1lBQzVCLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPOzs7O1lBQUMsQ0FBQyxFQUFpQixFQUFFLEVBQUU7OztzQkFFL0MsR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO2dCQUMzRCxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM5QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTs7MEJBQ2xDLE9BQU8sR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDOzswQkFDckIsVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO29CQUM1RSxJQUFJLFVBQVUsS0FBSyxHQUFHLEVBQUU7d0JBQ3RCLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7cUJBQ2xCO2lCQUNGO1lBQ0gsQ0FBQyxFQUFDLENBQUM7U0FDSjtRQUVELGlDQUFpQztRQUNqQyxJQUFJLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRTtZQUM1QixPQUFPLENBQUMsZ0JBQWdCLENBQUMsT0FBTzs7OztZQUFDLENBQUMsR0FBVyxFQUFFLEVBQUU7O3NCQUN6QyxFQUFFLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztnQkFDcEMsSUFBSSxFQUFFLEVBQUU7b0JBQ04sUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDbkI7WUFDSCxDQUFDLEVBQUMsQ0FBQztTQUNKO1FBRUQsZ0NBQWdDO1FBQ2hDLElBQUksT0FBTyxDQUFDLGVBQWUsRUFBRTtZQUMzQixRQUFRLEdBQUcsUUFBUSxDQUFDLE1BQU07Ozs7WUFBQyxDQUFDLEVBQWlCLEVBQUUsRUFBRTs7c0JBQ3pDLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztnQkFDM0QsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtvQkFDekMsT0FBTyxLQUFLLENBQUM7aUJBQ2Q7Z0JBQUMsT0FBTyxJQUFJLENBQUM7WUFDaEIsQ0FBQyxFQUFDLENBQUM7U0FDSjtRQUVELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Ozs7Ozs7O0lBU00sTUFBTSxDQUFDLFlBQVksQ0FBQyxPQUEyQixFQUFFLFFBQThCLEVBQUUsS0FBMEI7UUFDaEgsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUM5QixJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLGVBQWU7WUFBRSxPQUFPLFFBQVEsQ0FBQzs7O2NBR2xHLGdCQUFnQixHQUFHLElBQUksRUFBRSxDQUFDLEdBQUcsRUFBeUI7UUFFNUQsaUNBQWlDO1FBQ2pDLElBQUksT0FBTyxDQUFDLGdCQUFnQixFQUFFO1lBQzVCLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPOzs7O1lBQUMsQ0FBQyxFQUFpQixFQUFFLEVBQUU7OztzQkFFL0MsR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDO2dCQUMzRCxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUU5QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTs7MEJBQ2xDLE9BQU8sR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDOzswQkFDckIsVUFBVSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO29CQUM1RSxJQUFJLFVBQVUsS0FBSyxHQUFHLEVBQUU7d0JBQ3RCLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7cUJBQ2xCO2lCQUNGO1lBQ0gsQ0FBQyxFQUFDLENBQUM7U0FDSjtRQUVELGlDQUFpQztRQUNqQyxJQUFJLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRTtZQUM1QixPQUFPLENBQUMsZ0JBQWdCLENBQUMsT0FBTzs7OztZQUFDLENBQUMsR0FBVyxFQUFFLEVBQUU7O3NCQUN6QyxFQUFFLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztnQkFDcEMsSUFBSSxFQUFFLEVBQUU7b0JBQ04sUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDbkI7WUFDSCxDQUFDLEVBQUMsQ0FBQztTQUNKO1FBRUQsZ0NBQWdDO1FBQ2hDLElBQUksT0FBTyxDQUFDLGVBQWUsRUFBRTtZQUMzQixRQUFRLEdBQUcsUUFBUSxDQUFDLE1BQU07Ozs7WUFBQyxDQUFDLEVBQWlCLEVBQUUsRUFBRTs7c0JBQ3pDLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztnQkFDM0QsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtvQkFDekMsT0FBTyxLQUFLLENBQUM7aUJBQ2Q7Z0JBQUMsT0FBTyxJQUFJLENBQUM7WUFDaEIsQ0FBQyxFQUFDLENBQUM7U0FDSjtRQUVELE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Ozs7Ozs7SUFRTSxNQUFNLENBQUMsYUFBYSxDQUFDLE9BQTJCLEVBQUUsU0FBd0I7UUFDL0UsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUMvQixJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVM7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUN6QyxJQUFJLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDckIsT0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDO1NBQzFCO0lBQ0gsQ0FBQzs7O1lBNUhGLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIGdvIGZyb20gJ2dvanMnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgRGF0YVN5bmNTZXJ2aWNlIHtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7IH1cclxuXHJcbiAgLyoqXHJcbiAgICogU3luYyBhIG5vZGUgZGF0YSBhcnJheSB3aXRoIGEgc2V0IG9mIGNoYW5nZXNcclxuICAgKiBAcGFyYW0gY2hhbmdlcyBUaGUgc2V0IG9mIGNoYW5nZXMgdG8gdGhlIEdvSlMgbW9kZWxcclxuICAgKiBAcGFyYW0gbm9kZURhdGEgVGhlIG5vZGUgZGF0YSBhcnJheSB0byBtZXJnZSB0aGVzZSBjaGFuZ2VzIHdpdGhcclxuICAgKiBAcGFyYW0gbW9kZWwgUmVxdWlyZWQgaWYgeW91IGhhdmUgZGVmaW5lZCB5b3VyIG1vZGVsLm5vZGVLZXlQcm9wZXJ0eSB0byBiZSBzb21ldGhpbmcgb3RoZXIgdGhhbiAna2V5J1xyXG4gICAqIEByZXR1cm5zIEEgbm9kZSBkYXRhIGFycmF5LCBtZXJnZWQgd2l0aCB0aGUgY2hhbmdlc1xyXG4gICAqL1xyXG4gIHB1YmxpYyBzdGF0aWMgc3luY05vZGVEYXRhKGNoYW5nZXM6IGdvLkluY3JlbWVudGFsRGF0YSwgbm9kZURhdGE6IEFycmF5PGdvLk9iamVjdERhdGE+LCBtb2RlbD86IGdvLk1vZGVsKSB7XHJcbiAgICBpZiAoIWNoYW5nZXMpIHJldHVybiBub2RlRGF0YTtcclxuICAgIGlmICghY2hhbmdlcy5tb2RpZmllZE5vZGVEYXRhICYmICFjaGFuZ2VzLmluc2VydGVkTm9kZUtleXMgJiYgIWNoYW5nZXMucmVtb3ZlZE5vZGVLZXlzKSByZXR1cm4gbm9kZURhdGE7XHJcblxyXG4gICAgLy8gbWFpbnRhaW4gYSBtYXAgb2YgbW9kaWZpZWQgbm9kZXMgZm9yIGZhc3QgbG9va3VwIGR1cmluZyBpbnNlcnRpb25cclxuICAgIGNvbnN0IG1vZGlmaWVkTm9kZXNNYXAgPSBuZXcgZ28uTWFwPGdvLktleSwgZ28uT2JqZWN0RGF0YT4oKTtcclxuXHJcbiAgICAvLyBhY2NvdW50IGZvciBtb2RpZmllZCBub2RlIGRhdGFcclxuICAgIGlmIChjaGFuZ2VzLm1vZGlmaWVkTm9kZURhdGEpIHtcclxuICAgICAgY2hhbmdlcy5tb2RpZmllZE5vZGVEYXRhLmZvckVhY2goKG5kOiBnby5PYmplY3REYXRhKSA9PiB7XHJcbiAgICAgICAgLy8gR2V0IHRoZSB2YWx1ZSBvZiB0aGUgbm9kZSBrZXkgcHJvcGVydHkgY2hlY2tpbmcgd2V0aGVyIGlzIGEgZnVuY3Rpb24gb3IgYSBzdHJpbmdcclxuICAgICAgICBjb25zdCBrZXkgPSBtb2RlbCA/IG1vZGVsLmdldEtleUZvck5vZGVEYXRhKG5kKSA6IG5kWydrZXknXTtcclxuICAgICAgICBtb2RpZmllZE5vZGVzTWFwLnNldChrZXksIG5kKTtcclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVEYXRhLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICBjb25zdCBuZEVudHJ5ID0gbm9kZURhdGFbaV07XHJcbiAgICAgICAgICBjb25zdCBrZXlOZEVudHJ5ID0gbW9kZWwgPyBtb2RlbC5nZXRLZXlGb3JOb2RlRGF0YShuZEVudHJ5KSA6IG5kRW50cnlbJ2tleSddO1xyXG4gICAgICAgICAgaWYgKGtleU5kRW50cnkgPT09IGtleSkge1xyXG4gICAgICAgICAgICBub2RlRGF0YVtpXSA9IG5kO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYWNjb3VudCBmb3IgaW5zZXJ0ZWQgbm9kZSBkYXRhXHJcbiAgICBpZiAoY2hhbmdlcy5pbnNlcnRlZE5vZGVLZXlzKSB7XHJcbiAgICAgIGNoYW5nZXMuaW5zZXJ0ZWROb2RlS2V5cy5mb3JFYWNoKChrZXk6IGdvLktleSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IG5kID0gbW9kaWZpZWROb2Rlc01hcC5nZXQoa2V5KTtcclxuICAgICAgICBpZiAobmQpIHtcclxuICAgICAgICAgIG5vZGVEYXRhLnB1c2gobmQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYWNjb3VudCBmb3IgcmVtb3ZlZCBub2RlIGRhdGFcclxuICAgIGlmIChjaGFuZ2VzLnJlbW92ZWROb2RlS2V5cykge1xyXG4gICAgICBub2RlRGF0YSA9IG5vZGVEYXRhLmZpbHRlcigobmQ6IGdvLk9iamVjdERhdGEpID0+IHtcclxuICAgICAgICBjb25zdCBrZXkgPSBtb2RlbCA/IG1vZGVsLmdldEtleUZvck5vZGVEYXRhKG5kKSA6IG5kWydrZXknXTtcclxuICAgICAgICBpZiAoY2hhbmdlcy5yZW1vdmVkTm9kZUtleXMuaW5jbHVkZXMoa2V5KSkge1xyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH0gcmV0dXJuIHRydWU7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBub2RlRGF0YTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN5bmMgYSBsaW5rIGRhdGEgYXJyYXkgd2l0aCBhIHNldCBvZiBjaGFuZ2VzXHJcbiAgICogQHBhcmFtIGNoYW5nZXMgVGhlIHNldCBvZiBjaGFuZ2VzIHRvIHRoZSBHb0pTIG1vZGVsXHJcbiAgICogQHBhcmFtIGxpbmtEYXRhIFRoZSBsaW5rIGRhdGEgYXJyYXkgdG8gbWVyZ2UgdGhlc2UgY2hhbmdlcyB3aXRoXHJcbiAgICogQHBhcmFtIG1vZGVsIFJlcXVpcmVkIGlmIHlvdSBoYXZlIGRlZmluZWQgeW91ciBtb2RlbC5saW5rS2V5UHJvcGVydHkgdG8gYmUgc29tZXRoaW5nIG90aGVyIHRoYW4gJ2tleSdcclxuICAgKiBAcmV0dXJucyBBIGxpbmsgZGF0YSBhcnJheSwgbWVyZ2VkIHdpdGggdGhlIGNoYW5nZXNcclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIHN5bmNMaW5rRGF0YShjaGFuZ2VzOiBnby5JbmNyZW1lbnRhbERhdGEsIGxpbmtEYXRhOiBBcnJheTxnby5PYmplY3REYXRhPiwgbW9kZWw/OiBnby5HcmFwaExpbmtzTW9kZWwpIHtcclxuICAgIGlmICghY2hhbmdlcykgcmV0dXJuIGxpbmtEYXRhO1xyXG4gICAgaWYgKCFjaGFuZ2VzLm1vZGlmaWVkTGlua0RhdGEgJiYgIWNoYW5nZXMuaW5zZXJ0ZWRMaW5rS2V5cyAmJiAhY2hhbmdlcy5yZW1vdmVkTGlua0tleXMpIHJldHVybiBsaW5rRGF0YTtcclxuXHJcbiAgICAvLyBtYWludGFpbiBhIG1hcCBvZiBtb2RpZmllZCBub2RlcyBmb3IgZmFzdCBsb29rdXAgZHVyaW5nIGluc2VydGlvblxyXG4gICAgY29uc3QgbW9kaWZpZWRMaW5rc01hcCA9IG5ldyBnby5NYXA8Z28uS2V5LCBnby5PYmplY3REYXRhPigpO1xyXG5cclxuICAgIC8vIGFjY291bnQgZm9yIG1vZGlmaWVkIGxpbmsgZGF0YVxyXG4gICAgaWYgKGNoYW5nZXMubW9kaWZpZWRMaW5rRGF0YSkge1xyXG4gICAgICBjaGFuZ2VzLm1vZGlmaWVkTGlua0RhdGEuZm9yRWFjaCgobGQ6IGdvLk9iamVjdERhdGEpID0+IHtcclxuICAgICAgICAvLyBHZXQgdGhlIHZhbHVlIG9mIHRoZSBsaW5rIGtleVxyXG4gICAgICAgIGNvbnN0IGtleSA9IG1vZGVsID8gbW9kZWwuZ2V0S2V5Rm9yTGlua0RhdGEobGQpIDogbGRbJ2tleSddO1xyXG4gICAgICAgIG1vZGlmaWVkTGlua3NNYXAuc2V0KGtleSwgbGQpO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmtEYXRhLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICBjb25zdCBsZEVudHJ5ID0gbGlua0RhdGFbaV07XHJcbiAgICAgICAgICBjb25zdCBrZXlMZEVudHJ5ID0gbW9kZWwgPyBtb2RlbC5nZXRLZXlGb3JMaW5rRGF0YShsZEVudHJ5KSA6IGxkRW50cnlbJ2tleSddO1xyXG4gICAgICAgICAgaWYgKGtleUxkRW50cnkgPT09IGtleSkge1xyXG4gICAgICAgICAgICBsaW5rRGF0YVtpXSA9IGxkO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYWNjb3VudCBmb3IgaW5zZXJ0ZWQgbGluayBkYXRhXHJcbiAgICBpZiAoY2hhbmdlcy5pbnNlcnRlZExpbmtLZXlzKSB7XHJcbiAgICAgIGNoYW5nZXMuaW5zZXJ0ZWRMaW5rS2V5cy5mb3JFYWNoKChrZXk6IGdvLktleSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IG5kID0gbW9kaWZpZWRMaW5rc01hcC5nZXQoa2V5KTtcclxuICAgICAgICBpZiAobmQpIHtcclxuICAgICAgICAgIGxpbmtEYXRhLnB1c2gobmQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gYWNjb3VudCBmb3IgcmVtb3ZlZCBsaW5rIGRhdGFcclxuICAgIGlmIChjaGFuZ2VzLnJlbW92ZWRMaW5rS2V5cykge1xyXG4gICAgICBsaW5rRGF0YSA9IGxpbmtEYXRhLmZpbHRlcigobGQ6IGdvLk9iamVjdERhdGEpID0+IHtcclxuICAgICAgICBjb25zdCBrZXkgPSBtb2RlbCA/IG1vZGVsLmdldEtleUZvckxpbmtEYXRhKGxkKSA6IGxkWydrZXknXTtcclxuICAgICAgICBpZiAoY2hhbmdlcy5yZW1vdmVkTGlua0tleXMuaW5jbHVkZXMoa2V5KSkge1xyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH0gcmV0dXJuIHRydWU7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBsaW5rRGF0YTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN5bmMgbW9kZWxEYXRhIHdpdGggYSBzZXQgb2YgY2hhbmdlc1xyXG4gICAqIEBwYXJhbSBjaGFuZ2VzIFRoZSBzZXQgb2YgY2hhbmdlcyB0byB0aGUgR29KUyBtb2RlbFxyXG4gICAqIEBwYXJhbSBtb2RlbERhdGEgVGhlIG1vZGVsRGF0YSB0byBtZXJnZSB0aGVzZSBjaGFuZ2VzIHdpdGhcclxuICAgKiBAcmV0dXJucyBBIG1vZGVsRGF0YSBvYmplY3QsIG1lcmdlZCB3aXRoIHRoZSBjaGFuZ2VzXHJcbiAgICovXHJcbiAgcHVibGljIHN0YXRpYyBzeW5jTW9kZWxEYXRhKGNoYW5nZXM6IGdvLkluY3JlbWVudGFsRGF0YSwgbW9kZWxEYXRhOiBnby5PYmplY3REYXRhKSB7XHJcbiAgICBpZiAoIWNoYW5nZXMpIHJldHVybiBtb2RlbERhdGE7XHJcbiAgICBpZiAoIWNoYW5nZXMubW9kZWxEYXRhKSByZXR1cm4gbW9kZWxEYXRhO1xyXG4gICAgaWYgKGNoYW5nZXMubW9kZWxEYXRhKSB7XHJcbiAgICAgIHJldHVybiBjaGFuZ2VzLm1vZGVsRGF0YTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxufVxyXG4iXX0= | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1zeW5jLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nb2pzLWFuZ3VsYXIvc3JjL2xpYi9kYXRhLXN5bmMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0IsT0FBTyxPQUFPLE1BQU0sT0FBTyxDQUFDO0FBRzVCLE1BQU0sT0FBTyxlQUFlOzs7Ozs7OztJQVNuQixNQUFNLENBQUMsWUFBWSxDQUFDLE9BQTJCLEVBQUUsUUFBOEIsRUFBRSxLQUFnQjtRQUN0RyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU8sUUFBUSxDQUFDO1FBQzlCLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZTtZQUFFLE9BQU8sUUFBUSxDQUFDOzs7Y0FHbEcsZ0JBQWdCLEdBQUcsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUF5Qjs7O1lBR3hELGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxRQUFROzs7O1FBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNqRCxpQ0FBaUM7WUFDakMsSUFBSSxPQUFPLENBQUMsZ0JBQWdCLEVBQUU7Z0JBQzVCLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPOzs7O2dCQUFDLENBQUMsRUFBaUIsRUFBRSxFQUFFOzs7MEJBRS9DLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQztvQkFDM0QsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztvQkFDOUIsS0FBSyxJQUFJLENBQUMs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T0FBTyxPQUFPLENBQUMsU0FBUyxDQUFDO1NBQzFCO0lBQ0gsQ0FBQzs7O1lBaklGLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIGdvIGZyb20gJ2dvanMnO1xyXG5pbXBvcnQgcHJvZHVjZSBmcm9tIFwiaW1tZXJcIjtcclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIERhdGFTeW5jU2VydmljZSB7XHJcblxyXG4gIC8qKlxyXG4gICAqIFN5bmMgYSBub2RlIGRhdGEgYXJyYXkgd2l0aCBhIHNldCBvZiBjaGFuZ2VzXHJcbiAgICogQHBhcmFtIGNoYW5nZXMgVGhlIHNldCBvZiBjaGFuZ2VzIHRvIHRoZSBHb0pTIG1vZGVsXHJcbiAgICogQHBhcmFtIG5vZGVEYXRhIFRoZSBub2RlIGRhdGEgYXJyYXkgdG8gbWVyZ2UgdGhlc2UgY2hhbmdlcyB3aXRoXHJcbiAgICogQHBhcmFtIG1vZGVsIFJlcXVpcmVkIGlmIHlvdSBoYXZlIGRlZmluZWQgeW91ciBtb2RlbC5ub2RlS2V5UHJvcGVydHkgdG8gYmUgc29tZXRoaW5nIG90aGVyIHRoYW4gJ2tleSdcclxuICAgKiBAcmV0dXJucyBBIG5vZGUgZGF0YSBhcnJheSwgbWVyZ2VkIHdpdGggdGhlIGNoYW5nZXNcclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIHN5bmNOb2RlRGF0YShjaGFuZ2VzOiBnby5JbmNyZW1lbnRhbERhdGEsIG5vZGVEYXRhOiBBcnJheTxnby5PYmplY3REYXRhPiwgbW9kZWw/OiBnby5Nb2RlbCkge1xyXG4gICAgaWYgKCFjaGFuZ2VzKSByZXR1cm4gbm9kZURhdGE7XHJcbiAgICBpZiAoIWNoYW5nZXMubW9kaWZpZWROb2RlRGF0YSAmJiAhY2hhbmdlcy5pbnNlcnRlZE5vZGVLZXlzICYmICFjaGFuZ2VzLnJlbW92ZWROb2RlS2V5cykgcmV0dXJuIG5vZGVEYXRhO1xyXG5cclxuICAgIC8vIG1haW50YWluIGEgbWFwIG9mIG1vZGlmaWVkIG5vZGVzIGZvciBmYXN0IGxvb2t1cCBkdXJpbmcgaW5zZXJ0aW9uXHJcbiAgICBjb25zdCBtb2RpZmllZE5vZGVzTWFwID0gbmV3IGdvLk1hcDxnby5LZXksIGdvLk9iamVjdERhdGE+KCk7XHJcblxyXG4gICAgLy8gbm9kZURhdGEgaXMgaW1tdXRhYmxlLCBtb2RpZnkgaXQgdXNpbmcgdGhlIGltbWVyIHBhY2thZ2UncyBcInByb2R1Y2VcIiBmdW5jdGlvbiAoY3JlYXRlcyBuZXcgYXJyYXkpXHJcbiAgICB2YXIgbmV3Tm9kZURhdGFBcnJheSA9IHByb2R1Y2Uobm9kZURhdGEsIChkcmFmdCkgPT4ge1xyXG4gICAgICAvLyBhY2NvdW50IGZvciBtb2RpZmllZCBub2RlIGRhdGFcclxuICAgICAgaWYgKGNoYW5nZXMubW9kaWZpZWROb2RlRGF0YSkge1xyXG4gICAgICAgIGNoYW5nZXMubW9kaWZpZWROb2RlRGF0YS5mb3JFYWNoKChuZDogZ28uT2JqZWN0RGF0YSkgPT4ge1xyXG4gICAgICAgICAgLy8gR2V0IHRoZSB2YWx1ZSBvZiB0aGUgbm9kZSBrZXkgcHJvcGVydHkgY2hlY2tpbmcgd2V0aGVyIGlzIGEgZnVuY3Rpb24gb3IgYSBzdHJpbmdcclxuICAgICAgICAgIGNvbnN0IGtleSA9IG1vZGVsID8gbW9kZWwuZ2V0S2V5Rm9yTm9kZURhdGEobmQpIDogbmRbJ2tleSddO1xyXG4gICAgICAgICAgbW9kaWZpZWROb2Rlc01hcC5zZXQoa2V5LCBuZCk7XHJcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGVEYXRhLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5kRW50cnkgPSBub2RlRGF0YVtpXTtcclxuICAgICAgICAgICAgY29uc3Qga2V5TmRFbnRyeSA9IG1vZGVsID8gbW9kZWwuZ2V0S2V5Rm9yTm9kZURhdGEobmRFbnRyeSkgOiBuZEVudHJ5WydrZXknXTtcclxuICAgICAgICAgICAgaWYgKGtleU5kRW50cnkgPT09IGtleSkge1xyXG4gICAgICAgICAgICAgIGRyYWZ0W2ldID0gbmQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gYWNjb3VudCBmb3IgaW5zZXJ0ZWQgbm9kZSBkYXRhXHJcbiAgICAgIGlmIChjaGFuZ2VzLmluc2VydGVkTm9kZUtleXMpIHtcclxuICAgICAgICBjaGFuZ2VzLmluc2VydGVkTm9kZUtleXMuZm9yRWFjaCgoa2V5OiBnby5LZXkpID0+IHtcclxuICAgICAgICAgIGNvbnN0IG5kID0gbW9kaWZpZWROb2Rlc01hcC5nZXQoa2V5KTtcclxuICAgICAgICAgIGlmIChuZCkge1xyXG4gICAgICAgICAgICBkcmFmdC5wdXNoKG5kKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gYWNjb3VudCBmb3IgcmVtb3ZlZCBub2RlIGRhdGFcclxuICAgICAgaWYgKGNoYW5nZXMucmVtb3ZlZE5vZGVLZXlzKSB7XHJcbiAgICAgICAgcmV0dXJuIGRyYWZ0LmZpbHRlcigobmQ6IGdvLk9iamVjdERhdGEpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGtleSA9IG1vZGVsID8gbW9kZWwuZ2V0S2V5Rm9yTm9kZURhdGEobmQpIDogbmRbJ2tleSddO1xyXG4gICAgICAgICAgaWYgKGNoYW5nZXMucmVtb3ZlZE5vZGVLZXlzLmluY2x1ZGVzKGtleSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgfSBcclxuICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gbmV3Tm9kZURhdGFBcnJheTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN5bmMgYSBsaW5rIGRhdGEgYXJyYXkgd2l0aCBhIHNldCBvZiBjaGFuZ2VzXHJcbiAgICogQHBhcmFtIGNoYW5nZXMgVGhlIHNldCBvZiBjaGFuZ2VzIHRvIHRoZSBHb0pTIG1vZGVsXHJcbiAgICogQHBhcmFtIGxpbmtEYXRhIFRoZSBsaW5rIGRhdGEgYXJyYXkgdG8gbWVyZ2UgdGhlc2UgY2hhbmdlcyB3aXRoXHJcbiAgICogQHBhcmFtIG1vZGVsIFJlcXVpcmVkIGlmIHlvdSBoYXZlIGRlZmluZWQgeW91ciBtb2RlbC5saW5rS2V5UHJvcGVydHkgdG8gYmUgc29tZXRoaW5nIG90aGVyIHRoYW4gJ2tleSdcclxuICAgKiBAcmV0dXJucyBBIGxpbmsgZGF0YSBhcnJheSwgbWVyZ2VkIHdpdGggdGhlIGNoYW5nZXNcclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIHN5bmNMaW5rRGF0YShjaGFuZ2VzOiBnby5JbmNyZW1lbnRhbERhdGEsIGxpbmtEYXRhOiBBcnJheTxnby5PYmplY3REYXRhPiwgbW9kZWw/OiBnby5HcmFwaExpbmtzTW9kZWwpIHtcclxuICAgIGlmICghY2hhbmdlcykgcmV0dXJuIGxpbmtEYXRhO1xyXG4gICAgaWYgKCFjaGFuZ2VzLm1vZGlmaWVkTGlua0RhdGEgJiYgIWNoYW5nZXMuaW5zZXJ0ZWRMaW5rS2V5cyAmJiAhY2hhbmdlcy5yZW1vdmVkTGlua0tleXMpIHJldHVybiBsaW5rRGF0YTtcclxuXHJcbiAgICAvLyBtYWludGFpbiBhIG1hcCBvZiBtb2RpZmllZCBub2RlcyBmb3IgZmFzdCBsb29rdXAgZHVyaW5nIGluc2VydGlvblxyXG4gICAgY29uc3QgbW9kaWZpZWRMaW5rc01hcCA9IG5ldyBnby5NYXA8Z28uS2V5LCBnby5PYmplY3REYXRhPigpO1xyXG5cclxuICAgIC8vIGxpbmtEYXRhIGlzIGltbXV0YWJsZSwgbW9kaWZ5IGl0IHVzaW5nIHRoZSBpbW1lciBwYWNrYWdlJ3MgXCJwcm9kdWNlXCIgZnVuY3Rpb24gKGNyZWF0ZXMgbmV3IGFycmF5KVxyXG4gICAgbGlua0RhdGEgPSBwcm9kdWNlKGxpbmtEYXRhLCBkcmFmdCA9PiB7XHJcbiAgICAgIC8vIGFjY291bnQgZm9yIG1vZGlmaWVkIGxpbmsgZGF0YVxyXG4gICAgICBpZiAoY2hhbmdlcy5tb2RpZmllZExpbmtEYXRhKSB7XHJcbiAgICAgICAgY2hhbmdlcy5tb2RpZmllZExpbmtEYXRhLmZvckVhY2goKGxkOiBnby5PYmplY3REYXRhKSA9PiB7XHJcbiAgICAgICAgICAvLyBHZXQgdGhlIHZhbHVlIG9mIHRoZSBsaW5rIGtleVxyXG4gICAgICAgICAgY29uc3Qga2V5ID0gbW9kZWwgPyBtb2RlbC5nZXRLZXlGb3JMaW5rRGF0YShsZCkgOiBsZFsna2V5J107XHJcbiAgICAgICAgICBtb2RpZmllZExpbmtzTWFwLnNldChrZXksIGxkKTtcclxuXHJcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmtEYXRhLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGxkRW50cnkgPSBsaW5rRGF0YVtpXTtcclxuICAgICAgICAgICAgY29uc3Qga2V5TGRFbnRyeSA9IG1vZGVsID8gbW9kZWwuZ2V0S2V5Rm9yTGlua0RhdGEobGRFbnRyeSkgOiBsZEVudHJ5WydrZXknXTtcclxuICAgICAgICAgICAgaWYgKGtleUxkRW50cnkgPT09IGtleSkge1xyXG4gICAgICAgICAgICAgIGRyYWZ0W2ldID0gbGQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gYWNjb3VudCBmb3IgaW5zZXJ0ZWQgbGluayBkYXRhXHJcbiAgICAgIGlmIChjaGFuZ2VzLmluc2VydGVkTGlua0tleXMpIHtcclxuICAgICAgICBjaGFuZ2VzLmluc2VydGVkTGlua0tleXMuZm9yRWFjaCgoa2V5OiBnby5LZXkpID0+IHtcclxuICAgICAgICAgIGNvbnN0IG5kID0gbW9kaWZpZWRMaW5rc01hcC5nZXQoa2V5KTtcclxuICAgICAgICAgIGlmIChuZCkge1xyXG4gICAgICAgICAgICBkcmFmdC5wdXNoKG5kKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gYWNjb3VudCBmb3IgcmVtb3ZlZCBsaW5rIGRhdGFcclxuICAgICAgaWYgKGNoYW5nZXMucmVtb3ZlZExpbmtLZXlzKSB7XHJcbiAgICAgICAgcmV0dXJuIGRyYWZ0LmZpbHRlcigobGQ6IGdvLk9iamVjdERhdGEpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGtleSA9IG1vZGVsID8gbW9kZWwuZ2V0S2V5Rm9yTGlua0RhdGEobGQpIDogbGRbJ2tleSddO1xyXG4gICAgICAgICAgaWYgKGNoYW5nZXMucmVtb3ZlZExpbmtLZXlzLmluY2x1ZGVzKGtleSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgfSByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIGxpbmtEYXRhO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU3luYyBtb2RlbERhdGEgd2l0aCBhIHNldCBvZiBjaGFuZ2VzXHJcbiAgICogQHBhcmFtIGNoYW5nZXMgVGhlIHNldCBvZiBjaGFuZ2VzIHRvIHRoZSBHb0pTIG1vZGVsXHJcbiAgICogQHBhcmFtIG1vZGVsRGF0YSBUaGUgbW9kZWxEYXRhIHRvIG1lcmdlIHRoZXNlIGNoYW5nZXMgd2l0aFxyXG4gICAqIEByZXR1cm5zIEEgbW9kZWxEYXRhIG9iamVjdCwgbWVyZ2VkIHdpdGggdGhlIGNoYW5nZXNcclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIHN5bmNNb2RlbERhdGEoY2hhbmdlczogZ28uSW5jcmVtZW50YWxEYXRhLCBtb2RlbERhdGE6IGdvLk9iamVjdERhdGEpIHtcclxuICAgIGlmICghY2hhbmdlcykgcmV0dXJuIG1vZGVsRGF0YTtcclxuICAgIGlmICghY2hhbmdlcy5tb2RlbERhdGEpIHJldHVybiBtb2RlbERhdGE7XHJcbiAgICBpZiAoY2hhbmdlcy5tb2RlbERhdGEpIHtcclxuICAgICAgcmV0dXJuIGNoYW5nZXMubW9kZWxEYXRhO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG59XHJcbiJdfQ== |
@@ -6,29 +6,35 @@ /** | ||
*/ | ||
import { Component, ElementRef, EventEmitter, Input, KeyValueDiffers, NgZone, Output, ViewChild } from '@angular/core'; | ||
import { Component, ElementRef, EventEmitter, Input, NgZone, Output, ViewChild } from '@angular/core'; | ||
import * as go from 'gojs'; | ||
import { NgDiagramHelper } from './ng-diagram-helper'; | ||
export class DiagramComponent { | ||
/** | ||
* @param {?} _kvdiffers | ||
* @param {?} zone | ||
*/ | ||
constructor(_kvdiffers, zone) { | ||
this._kvdiffers = _kvdiffers; | ||
constructor(zone) { | ||
this.zone = zone; | ||
// Link data for diagram | ||
this.linkDataArray = null; // optional | ||
// optional | ||
// Model data for diagram | ||
this.modelData = null; // optional | ||
// model changed listener function for diagram | ||
/** | ||
* Link data for diagram. Optional. | ||
*/ | ||
this.linkDataArray = null; | ||
/** | ||
* Model data for diagram. Optional. | ||
*/ | ||
this.modelData = null; | ||
/** | ||
* Model changed listener function for diagram | ||
*/ | ||
this.modelChangedListener = null; | ||
/** | ||
* Whether or not to skip merging app data with GoJS model data (set to true if update is coming from GoJS, false if coming from app-level, usually) | ||
*/ | ||
this.skipsDiagramUpdate = false; | ||
// event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
/** | ||
* Event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
*/ | ||
this.modelChange = new EventEmitter(); | ||
/** | ||
* The Diagram itself | ||
*/ | ||
this.diagram = null; | ||
// differs used to check if there have been changed to the array @Inputs | ||
// without them, changes to the input arrays won't register in ngOnChanges, | ||
// since the array reference itself may be the same | ||
this._ndaDiffer = this._kvdiffers.find([]).create(); | ||
this._ldaDiffer = this._kvdiffers.find([]).create(); | ||
this._mdaDiffer = this._kvdiffers.find([]).create(); | ||
} | ||
@@ -40,34 +46,13 @@ /** | ||
ngAfterViewInit() { | ||
if (!this.diagramDiv) { | ||
throw new Error("diagramDiv is not defined"); | ||
} | ||
this.diagram = this.initDiagram(); | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the diagram, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.diagram.addEventListener = (/** | ||
* @param {?} DOMElement | ||
* @param {?} name | ||
* @param {?} listener | ||
* @param {?} capture | ||
* @return {?} | ||
*/ | ||
(DOMElement, name, listener, capture) => { | ||
/** @type {?} */ | ||
const superAddEventListener = go.Diagram.prototype.addEventListener; | ||
if (name === 'mousemove') { | ||
this.zone.runOutsideAngular((/** | ||
* @return {?} | ||
*/ | ||
() => superAddEventListener.call(this, DOMElement, name, listener, capture))); | ||
} | ||
else { | ||
this.zone.run((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
superAddEventListener.call(this, DOMElement, name, listener, capture); | ||
})); | ||
} | ||
}); | ||
if (!(this.diagram instanceof go.Diagram)) { | ||
throw new Error("initDiagram function did not return a go.Diagram"); | ||
} | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.diagram, this.zone); | ||
// assign the Diagram's div, which (among many other things) will attach a bunch of listeners to the canvas, | ||
// using the overridden addEventListener function above | ||
// using the overridden addEventListener function defined in makeMouseMoveRunOutsideAngularZone | ||
/** @type {?} */ | ||
@@ -78,242 +63,21 @@ const divRef = this.diagramDiv.nativeElement; | ||
this.diagram.div = divRef; | ||
// initialize the Diagram's model | ||
this.diagram.delayInitialization((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
/** @type {?} */ | ||
const model = this.diagram.model; | ||
model.commit((/** | ||
* @param {?} m | ||
* @return {?} | ||
*/ | ||
(m) => { | ||
m.mergeNodeDataArray(m.cloneDeep(this.nodeDataArray)); | ||
if (this.linkDataArray && m instanceof go.GraphLinksModel) { | ||
m.mergeLinkDataArray(m.cloneDeep(this.linkDataArray)); | ||
} | ||
if (this.modelData) { | ||
m.assignAllDataProperties(m.modelData, this.modelData); | ||
} | ||
this.diagram.layoutDiagram(true); | ||
}), null); | ||
})); | ||
// initializer listener | ||
this.modelChangedListener = (/** | ||
* @param {?} e | ||
* @return {?} | ||
*/ | ||
(e) => { | ||
if (e.isTransactionFinished && this.diagram && this.diagram.model && !this.diagram.model.isReadOnly) { | ||
// this must be done within a NgZone.run block, so changes are detected in the parent component | ||
this.zone.run((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
/** @type {?} */ | ||
const dataChanges = (/** @type {?} */ (e.model)).toIncrementalData(e); | ||
this.modelChange.emit(dataChanges); | ||
})); | ||
} | ||
}); | ||
this.diagram.addModelChangedListener(this.modelChangedListener); | ||
// initialize the diagram model with the provided node / link / model data | ||
NgDiagramHelper.initializeModel(this.diagram, this.nodeDataArray, this.linkDataArray, this.modelData); | ||
// initializer model listener | ||
NgDiagramHelper.initializeModelChangedListener(this); | ||
} // end ngAfterViewInit | ||
// end ngAfterViewInit | ||
/** | ||
* Merges changes from app data into GoJS model data, | ||
* making sure only actual changes (and not falsely flagged no-ops on array / obj data props) are logged | ||
* @param {?} component an instance of DiagramComponent or PaletteComponent | ||
* @param {?} kvchanges The kvchanges object produced by either a node or link Angular differ object | ||
* @param {?} str "n" for node data changes, "l" for link data changes | ||
* | ||
* If a change has occured on an \@Input property, merge the app-level changes with GoJS | ||
* @return {?} | ||
*/ | ||
static mergeChanges(component, kvchanges, str) { | ||
// helper function | ||
/** | ||
* @param {?} obj1 | ||
* @param {?} obj2 | ||
* @return {?} | ||
*/ | ||
function compareObjs(obj1, obj2) { | ||
if (!obj1 || !obj2) | ||
return false; | ||
// Loop through properties in object 1 | ||
for (const p in obj1) { | ||
// Check property exists on both objects | ||
if (obj1.hasOwnProperty(p) !== obj2.hasOwnProperty(p)) | ||
return false; | ||
switch (typeof (obj1[p])) { | ||
// Deep compare objects | ||
case 'object': | ||
if (!compareObjs(obj1[p], obj2[p])) | ||
return false; | ||
break; | ||
// Compare values | ||
default: | ||
if (obj1[p] !== obj2[p]) | ||
return false; | ||
} | ||
} | ||
// Check object 2 for any extra properties | ||
for (const p in obj2) { | ||
if (typeof (obj1[p]) === 'undefined') | ||
return false; | ||
} | ||
return true; | ||
} | ||
/** @type {?} */ | ||
var dia = component instanceof DiagramComponent ? component.diagram : component.palette; | ||
if (!dia || !dia.model) | ||
ngOnChanges() { | ||
if (!this.diagram || !this.diagram.model || this.skipsDiagramUpdate) | ||
return; | ||
if (kvchanges) { | ||
// handle added nodes / links | ||
kvchanges.forEachAddedItem((/** | ||
* @param {?} r | ||
* @return {?} | ||
*/ | ||
(r) => { | ||
switch (str) { | ||
case "n": { | ||
dia.model.addNodeData(r.currentValue); | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
var m = (/** @type {?} */ (dia.model)); | ||
m.addLinkData(r.currentValue); | ||
break; | ||
} | ||
} | ||
})); | ||
// handle removed nodes / links | ||
kvchanges.forEachRemovedItem((/** | ||
* @param {?} r | ||
* @return {?} | ||
*/ | ||
(r) => { | ||
switch (str) { | ||
case "n": { | ||
/** @type {?} */ | ||
let m = dia.model; | ||
/** @type {?} */ | ||
let keyPropName = m.nodeKeyProperty.toString(); | ||
/** @type {?} */ | ||
var node = dia.findNodeForKey(r.previousValue[keyPropName]); | ||
if (node) { | ||
dia.remove(node); | ||
} | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
let m = (/** @type {?} */ (dia.model)); | ||
/** @type {?} */ | ||
var keyPropName = m.linkKeyProperty.toString(); | ||
/** @type {?} */ | ||
var link = dia.findLinkForKey(r.previousValue[keyPropName]); | ||
if (link) { | ||
dia.remove(link); | ||
} | ||
break; | ||
} | ||
} | ||
})); | ||
// handle changed data for nodes / links | ||
kvchanges.forEachChangedItem((/** | ||
* @param {?} r | ||
* @return {?} | ||
*/ | ||
(r) => { | ||
// ensure "changes" to array / object / enumerable data properties are legit | ||
/** @type {?} */ | ||
const sameVals = compareObjs(r.currentValue, r.previousValue); | ||
// update proper data object for node or link | ||
if (!sameVals) { | ||
switch (str) { | ||
case "n": { | ||
/** @type {?} */ | ||
let m = dia.model; | ||
/** @type {?} */ | ||
let keyPropName = m.nodeKeyProperty.toString(); | ||
/** @type {?} */ | ||
var node = dia.findNodeForKey(r.previousValue[keyPropName]); | ||
if (node) { | ||
// if the entry was replaced with null or undefined, just remove the entry altogther | ||
// this is still pretty bad practice -- instead, users should remove entries in their node / link / model data, not set them to null | ||
if (!r.currentValue) { | ||
dia.remove(node); | ||
} | ||
else { | ||
dia.model.assignAllDataProperties(node.data, r.currentValue); | ||
} | ||
} | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
let m = (/** @type {?} */ (dia.model)); | ||
/** @type {?} */ | ||
var keyPropName = m.linkKeyProperty.toString(); | ||
/** @type {?} */ | ||
var link = dia.findLinkForKey(r.previousValue[keyPropName]); | ||
if (link) { | ||
// if the entry was replaced with null or undefined, just remove the entry altogther | ||
// this is still pretty bad practice -- instead, users should remove entries in their node / link / model data, not set them to null | ||
if (!r.currentValue) { | ||
dia.remove(link); | ||
} | ||
else { | ||
dia.model.assignAllDataProperties(link.data, r.currentValue); | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
})); | ||
} | ||
} | ||
NgDiagramHelper.mergeAppDataWithModel(this); | ||
} // end ngOnChanges | ||
// end ngOnChanges | ||
/** | ||
* Always be checking if array Input data has changed (node and link data arrays) | ||
* @return {?} | ||
*/ | ||
ngDoCheck() { | ||
if (!this.diagram) | ||
return; | ||
if (!this.diagram.model) | ||
return; | ||
// these need to be run each check, even if no merging happens | ||
// otherwise, they will detect all diffs that happened since last time skipsDiagram was false, | ||
// such as remove ops that happened in GoJS when skipsDiagram = true, | ||
// and then realllllly bad stuff happens (deleting random nodes, updating the wrong Parts) | ||
// Angular differs are a lot of fun | ||
/** @type {?} */ | ||
var nodeDiffs = this._ndaDiffer.diff(this.nodeDataArray); | ||
/** @type {?} */ | ||
var linkDiffs = this._ldaDiffer.diff(this.linkDataArray); | ||
/** @type {?} */ | ||
var modelDiffs = this._mdaDiffer.diff(this.modelData); | ||
if (!nodeDiffs && !linkDiffs && !modelDiffs) | ||
return; | ||
if (this.skipsDiagramUpdate) | ||
return; | ||
// don't need model change listener while performing known data updates | ||
if (this.modelChangedListener !== null) | ||
this.diagram.model.removeChangedListener(this.modelChangedListener); | ||
this.diagram.model.startTransaction('update data'); | ||
// update modelData first, in case bindings on nodes / links depend on model data | ||
this.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); | ||
// merge node / link data | ||
DiagramComponent.mergeChanges(this, nodeDiffs, "n"); | ||
DiagramComponent.mergeChanges(this, linkDiffs, "l"); | ||
this.diagram.model.commitTransaction('update data'); | ||
// reset the model change listener | ||
if (this.modelChangedListener !== null) | ||
this.diagram.model.addChangedListener(this.modelChangedListener); | ||
} // end ngDoCheck | ||
// end ngDoCheck | ||
/** | ||
* @return {?} | ||
*/ | ||
ngOnDestroy() { | ||
@@ -331,3 +95,2 @@ this.diagram.div = null; // removes event listeners | ||
DiagramComponent.ctorParameters = () => [ | ||
{ type: KeyValueDiffers }, | ||
{ type: NgZone } | ||
@@ -352,43 +115,50 @@ ]; | ||
DiagramComponent.prototype.initDiagram; | ||
/** @type {?} */ | ||
/** | ||
* Node data for diagram | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.nodeDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Link data for diagram. Optional. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.linkDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Model data for diagram. Optional. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.modelData; | ||
/** @type {?} */ | ||
/** | ||
* Diagram div class name. Use this name to style your diagram in CSS. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
/** | ||
* Model changed listener function for diagram | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.modelChangedListener; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.skipsDiagramUpdate; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.modelChange; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.diagramDiv; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.diagram; | ||
/** | ||
* Whether or not to skip merging app data with GoJS model data (set to true if update is coming from GoJS, false if coming from app-level, usually) | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._ndaDiffer; | ||
DiagramComponent.prototype.skipsDiagramUpdate; | ||
/** | ||
* Event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._ldaDiffer; | ||
DiagramComponent.prototype.modelChange; | ||
/** | ||
* The DIV element holding the Diagram | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._mdaDiffer; | ||
DiagramComponent.prototype.diagramDiv; | ||
/** | ||
* The Diagram itself | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._kvdiffers; | ||
DiagramComponent.prototype.diagram; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.zone; | ||
} | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhZ3JhbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nb2pzLWFuZ3VsYXIvc3JjL2xpYi9kaWFncmFtLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWtCLGVBQWUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBd0IsTUFBTSxlQUFlLENBQUM7QUFDN0osT0FBTyxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFNM0IsTUFBTSxPQUFPLGdCQUFnQjs7Ozs7SUFxQzNCLFlBQW9CLFVBQTJCLEVBQVMsSUFBWTtRQUFoRCxlQUFVLEdBQVYsVUFBVSxDQUFpQjtRQUFTLFNBQUksR0FBSixJQUFJLENBQVE7O1FBekJwRCxrQkFBYSxHQUF5QixJQUFJLENBQUMsQ0FBQyxXQUFXOzs7UUFHdkQsY0FBUyxHQUFrQixJQUFJLENBQUMsQ0FBQyxXQUFXOztRQU1yRCx5QkFBb0IsR0FBd0MsSUFBSSxDQUFDO1FBRXhELHVCQUFrQixHQUFZLEtBQUssQ0FBQzs7UUFHbkMsZ0JBQVcsR0FBcUMsSUFBSSxZQUFZLEVBQXNCLENBQUM7UUFHakcsWUFBTyxHQUFlLElBQUksQ0FBQztRQVNoQyx3RUFBd0U7UUFDeEUsMkVBQTJFO1FBQzNFLG1EQUFtRDtRQUNuRCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3BELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFcEQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMs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MEJBR0wsTUFBTTt5QkFFTixTQUFTLFNBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTs7Ozs7Ozs7SUF0QnhDLHVDQUE4Qzs7SUFHOUMseUNBQW9EOztJQUdwRCx5Q0FBMkQ7O0lBRzNELHFDQUFnRDs7SUFHaEQsd0NBQXFDOztJQUdyQyxnREFBd0U7O0lBRXhFLDhDQUFvRDs7SUFHcEQsdUNBQXdHOztJQUV4RyxzQ0FBd0U7O0lBQ3hFLG1DQUFrQzs7Ozs7SUFHbEMsc0NBQWdEOzs7OztJQUNoRCxzQ0FBZ0Q7Ozs7O0lBRWhELHNDQUFnRDs7Ozs7SUFFcEMsc0NBQW1DOztJQUFFLGdDQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgS2V5VmFsdWVEaWZmZXIsIEtleVZhbHVlRGlmZmVycywgTmdab25lLCBPdXRwdXQsIFZpZXdDaGlsZCwgS2V5VmFsdWVDaGFuZ2VSZWNvcmQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgZ28gZnJvbSAnZ29qcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2dvanMtZGlhZ3JhbScsXHJcbiAgdGVtcGxhdGU6ICc8ZGl2ICNuZ0RpYWdyYW0gW2NsYXNzTmFtZV09ZGl2Q2xhc3NOYW1lPjwvZGl2PidcclxufSlcclxuZXhwb3J0IGNsYXNzIERpYWdyYW1Db21wb25lbnQge1xyXG5cclxuICAvKipcclxuICAgKiBEaWFncmFtIGluaXRpYWxpemF0aW9uIGZ1bmN0aW9uLiBSZXR1cm5zIGEgZ28uRGlhZ3JhbS5cclxuICAgKiBEbyBub3QgaW5pdGlhbGl6ZSBtb2RlbCBkYXRhIGluIHRoaXMgZnVuY3Rpb24uXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIGluaXREaWFncmFtOiAoKSA9PiBnby5EaWFncmFtO1xyXG5cclxuICAvLyBOb2RlIGRhdGEgZm9yIGRpYWdyYW1cclxuICBASW5wdXQoKSBwdWJsaWMgbm9kZURhdGFBcnJheTogQXJyYXk8Z28uT2JqZWN0RGF0YT47XHJcblxyXG4gIC8vIExpbmsgZGF0YSBmb3IgZGlhZ3JhbVxyXG4gIEBJbnB1dCgpIHB1YmxpYyBsaW5rRGF0YUFycmF5OiBBcnJheTxnby5PYmplY3REYXRhPiA9IG51bGw7IC8vIG9wdGlvbmFsXHJcblxyXG4gIC8vIE1vZGVsIGRhdGEgZm9yIGRpYWdyYW1cclxuICBASW5wdXQoKSBwdWJsaWMgbW9kZWxEYXRhOiBnby5PYmplY3REYXRhID0gbnVsbDsgLy8gb3B0aW9uYWxcclxuXHJcbiAgLy8gRGlhZ3JhbSBkaXYgY2xhc3MgbmFtZS4gVXNlIHRoaXMgbmFtZSB0byBzdHlsZSB5b3VyIGRpYWdyYW0gaW4gQ1NTXHJcbiAgQElucHV0KCkgcHVibGljIGRpdkNsYXNzTmFtZTogc3RyaW5nO1xyXG5cclxuICAvLyBtb2RlbCBjaGFuZ2VkIGxpc3RlbmVyIGZ1bmN0aW9uIGZvciBkaWFncmFtXHJcbiAgcHVibGljIG1vZGVsQ2hhbmdlZExpc3RlbmVyOiAoZTogZ28uQ2hhbmdlZEV2ZW50KSA9PiB2b2lkIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIEBJbnB1dCgpIHB1YmxpYyBza2lwc0RpYWdyYW1VcGRhdGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLy8gZXZlbnQgZW1pdHRlciAtLSBmaXJlcyB3aGVuIGRpYWdyYW0gbW9kZWwgY2hhbmdlcy4gQ2FwdHVyZSB0aGlzIGVtaXR0ZWQgZXZlbnQgaW4gcGFyZW50IGNvbXBvbmVudFxyXG4gIEBPdXRwdXQoKSBwdWJsaWMgbW9kZWxDaGFuZ2U6IEV2ZW50RW1pdHRlcjxnby5JbmNyZW1lbnRhbERhdGE+ID0gbmV3IEV2ZW50RW1pdHRlcjxnby5JbmNyZW1lbnRhbERhdGE+KCk7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ25nRGlhZ3JhbScsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyBkaWFncmFtRGl2OiBFbGVtZW50UmVmO1xyXG4gIHB1YmxpYyBkaWFncmFtOiBnby5EaWFncmFtID0gbnVsbDtcclxuXHJcbiAgLy8gZGlmZmVycyBmb3IgYXJyYXkgaW5wdXRzIChub2RlIC8gbGluayBkYXRhIGFycmF5cylcclxuICBwcml2YXRlIF9uZGFEaWZmZXI6IEtleVZhbHVlRGlmZmVyPHN0cmluZywgYW55PjtcclxuICBwcml2YXRlIF9sZGFEaWZmZXI6IEtleVZhbHVlRGlmZmVyPHN0cmluZywgYW55PjtcclxuXHJcbiAgcHJpdmF0ZSBfbWRhRGlmZmVyOiBLZXlWYWx1ZURpZmZlcjxzdHJpbmcsIGFueT47XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2t2ZGlmZmVyczogS2V5VmFsdWVEaWZmZXJzLCBwdWJsaWMgem9uZTogTmdab25lKSB7XHJcbiAgICAvLyBkaWZmZXJzIHVzZWQgdG8gY2hlY2sgaWYgdGhlcmUgaGF2ZSBiZWVuIGNoYW5nZWQgdG8gdGhlIGFycmF5IEBJbnB1dHNcclxuICAgIC8vIHdpdGhvdXQgdGhlbSwgY2hhbmdlcyB0byB0aGUgaW5wdXQgYXJyYXlzIHdvbid0IHJlZ2lzdGVyIGluIG5nT25DaGFuZ2VzLFxyXG4gICAgLy8gc2luY2UgdGhlIGFycmF5IHJlZmVyZW5jZSBpdHNlbGYgbWF5IGJlIHRoZSBzYW1lXHJcbiAgICB0aGlzLl9uZGFEaWZmZXIgPSB0aGlzLl9rdmRpZmZlcnMuZmluZChbXSkuY3JlYXRlKCk7XHJcbiAgICB0aGlzLl9sZGFEaWZmZXIgPSB0aGlzLl9rdmRpZmZlcnMuZmluZChbXSkuY3JlYXRlKCk7XHJcblxyXG4gICAgdGhpcy5fbWRhRGlmZmVyID0gdGhpcy5fa3ZkaWZmZXJzLmZpbmQoW10pLmNyZWF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZXMgZGlhZ3JhbSAvIG1vZGVsIGFmdGVyIHZpZXcgaW5pdFxyXG4gICAqL1xyXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICB0aGlzLmRpYWdyYW0gPSB0aGlzLmluaXREaWFncmFtKCk7XHJcblxyXG4gICAgLy8gVGhpcyBiaXQgb2YgY29kZSBtYWtlcyBzdXJlIHRoZSBtb3VzZW1vdmUgZXZlbnQgbGlzdGVuZXJzIG9uIHRoZSBjYW52YXMgYXJlIHJ1biBvdXRzaWRlIE5nWm9uZVxyXG4gICAgLy8gVGhpcyBtYWtlcyBpdCBzbyBjaGFuZ2UgZGV0ZWN0aW9uIGlzbid0IHRyaWdnZXJlZCBldmVyeSB0aW1lIHRoZSBtb3VzZSBpcyBtb3ZlZCBpbnNpZGUgdGhlIGNhbnZhcywgZ3JlYXRseSBpbXByb3ZpbmcgcGVyZm9ybWFuY2VcclxuICAgIC8vIElmIHNvbWUgc3RhdGUtYWx0ZXJpbmcgYmVoYXZpb3IgbXVzdCBoYXBwZW4gb24gYSBtb3VzZW1vdmUgZXZlbnQgaW5zaWRlIHRoZSBkaWFncmFtLFxyXG4gICAgLy8geW91IHdpbGwgaGF2ZSB0byB1c2luZyB6b25lLnJ1bigpIHRvIG1ha2Ugc3VyZSB0aGF0IGV2ZW50IHRyaWdnZXJzIGFuZ3VsYXIgY2hhbmdlIGRldGVjdGlvblxyXG4gICAgdGhpcy5kaWFncmFtLmFkZEV2ZW50TGlzdGVuZXIgPSAoRE9NRWxlbWVudDogRWxlbWVudCB8IFdpbmRvdyB8IERvY3VtZW50LCBuYW1lOiBzdHJpbmcsIGxpc3RlbmVyOiBhbnksIGNhcHR1cmU6IGJvb2xlYW4pID0+IHtcclxuICAgICAgY29uc3Qgc3VwZXJBZGRFdmVudExpc3RlbmVyID0gZ28uRGlhZ3JhbS5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lcjtcclxuICAgICAgaWYgKG5hbWUgPT09ICdtb3VzZW1vdmUnKSB7XHJcbiAgICAgICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHN1cGVyQWRkRXZlbnRMaXN0ZW5lci5jYWxsKHRoaXMsIERPTUVsZW1lbnQsIG5hbWUsIGxpc3RlbmVyLCBjYXB0dXJlKSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICBzdXBlckFkZEV2ZW50TGlzdGVuZXIuY2FsbCh0aGlzLCBET01FbGVtZW50LCBuYW1lLCBsaXN0ZW5lciwgY2FwdHVyZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLy8gYXNzaWduIHRoZSBEaWFncmFtJ3MgZGl2LCB3aGljaCAoYW1vbmcgbWFueSBvdGhlciB0aGluZ3MpIHdpbGwgYXR0YWNoIGEgYnVuY2ggb2YgbGlzdGVuZXJzIHRvIHRoZSBjYW52YXMsXHJcbiAgICAvLyB1c2luZyB0aGUgb3ZlcnJpZGRlbiBhZGRFdmVudExpc3RlbmVyIGZ1bmN0aW9uIGFib3ZlXHJcbiAgICBjb25zdCBkaXZSZWYgPSB0aGlzLmRpYWdyYW1EaXYubmF0aXZlRWxlbWVudDtcclxuICAgIGlmIChkaXZSZWYgPT09IG51bGwpIHJldHVybjtcclxuICAgIHRoaXMuZGlhZ3JhbS5kaXYgPSBkaXZSZWY7XHJcblxyXG4gICAgLy8gaW5pdGlhbGl6ZSB0aGUgRGlhZ3JhbSdzIG1vZGVsXHJcbiAgICB0aGlzLmRpYWdyYW0uZGVsYXlJbml0aWFsaXphdGlvbigoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vZGVsID0gdGhpcy5kaWFncmFtLm1vZGVsO1xyXG4gICAgICBtb2RlbC5jb21taXQoKG06IGdvLk1vZGVsKSA9PiB7XHJcbiAgICAgICAgbS5tZXJnZU5vZGVEYXRhQXJyYXkobS5jbG9uZURlZXAodGhpcy5ub2RlRGF0YUFycmF5KSk7XHJcbiAgICAgICAgaWYgKHRoaXMubGlua0RhdGFBcnJheSAmJiBtIGluc3RhbmNlb2YgZ28uR3JhcGhMaW5rc01vZGVsKSB7XHJcbiAgICAgICAgICBtLm1lcmdlTGlua0RhdGFBcnJheShtLmNsb25lRGVlcCh0aGlzLmxpbmtEYXRhQXJyYXkpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMubW9kZWxEYXRhKSB7XHJcbiAgICAgICAgICBtLmFzc2lnbkFsbERhdGFQcm9wZXJ0aWVzKG0ubW9kZWxEYXRhLCB0aGlzLm1vZGVsRGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZGlhZ3JhbS5sYXlvdXREaWFncmFtKHRydWUpO1xyXG4gICAgICB9LCBudWxsKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIGluaXRpYWxpemVyIGxpc3RlbmVyXHJcbiAgICB0aGlzLm1vZGVsQ2hhbmdlZExpc3RlbmVyID0gKGU6IGdvLkNoYW5nZWRFdmVudCkgPT4ge1xyXG4gICAgICBpZiAoZS5pc1RyYW5zYWN0aW9uRmluaXNoZWQgJiYgdGhpcy5kaWFncmFtICYmIHRoaXMuZGlhZ3JhbS5tb2RlbCAmJiAhdGhpcy5kaWFncmFtLm1vZGVsLmlzUmVhZE9ubHkpIHtcclxuICAgICAgICAvLyB0aGlzIG11c3QgYmUgZG9uZSB3aXRoaW4gYSBOZ1pvbmUucnVuIGJsb2NrLCBzbyBjaGFuZ2VzIGFyZSBkZXRlY3RlZCBpbiB0aGUgcGFyZW50IGNvbXBvbmVudFxyXG4gICAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZGF0YUNoYW5nZXMgPSBlLm1vZGVsIS50b0luY3JlbWVudGFsRGF0YShlKTtcclxuICAgICAgICAgIHRoaXMubW9kZWxDaGFuZ2UuZW1pdChkYXRhQ2hhbmdlcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgICB0aGlzLmRpYWdyYW0uYWRkTW9kZWxDaGFuZ2VkTGlzdGVuZXIodGhpcy5tb2RlbENoYW5nZWRMaXN0ZW5lcik7XHJcblxyXG5cclxuICB9IC8vIGVuZCBuZ0FmdGVyVmlld0luaXRcclxuXHJcbiAgLyoqXHJcbiAgICogTWVyZ2VzIGNoYW5nZXMgZnJvbSBhcHAgZGF0YSBpbnRvIEdvSlMgbW9kZWwgZGF0YSwgXHJcbiAgICogbWFraW5nIHN1cmUgb25seSBhY3R1YWwgY2hhbmdlcyAoYW5kIG5vdCBmYWxzZWx5IGZsYWdnZWQgbm8tb3BzIG9uIGFycmF5IC8gb2JqIGRhdGEgcHJvcHMpIGFyZSBsb2dnZWRcclxuICAgKiBAcGFyYW0gY29tcG9uZW50IGFuIGluc3RhbmNlIG9mIERpYWdyYW1Db21wb25lbnQgb3IgUGFsZXR0ZUNvbXBvbmVudFxyXG4gICAqIEBwYXJhbSBrdmNoYW5nZXMgVGhlIGt2Y2hhbmdlcyBvYmplY3QgcHJvZHVjZWQgYnkgZWl0aGVyIGEgbm9kZSBvciBsaW5rIEFuZ3VsYXIgZGlmZmVyIG9iamVjdFxyXG4gICAqIEBwYXJhbSBzdHIgXCJuXCIgZm9yIG5vZGUgZGF0YSBjaGFuZ2VzLCBcImxcIiBmb3IgbGluayBkYXRhIGNoYW5nZXNcclxuICAgKiAgKi8gXHJcbiAgcHVibGljIHN0YXRpYyBtZXJnZUNoYW5nZXMoY29tcG9uZW50LCBrdmNoYW5nZXMsIHN0cik6IGJvb2xlYW4ge1xyXG5cclxuICAgIC8vIGhlbHBlciBmdW5jdGlvblxyXG4gICAgZnVuY3Rpb24gY29tcGFyZU9ianMob2JqMSwgb2JqMikge1xyXG5cclxuICAgICAgaWYgKCFvYmoxIHx8ICFvYmoyKSByZXR1cm4gZmFsc2U7XHJcblxyXG4gICAgICAvLyBMb29wIHRocm91Z2ggcHJvcGVydGllcyBpbiBvYmplY3QgMVxyXG4gICAgICBmb3IgKGNvbnN0IHAgaW4gb2JqMSkge1xyXG4gICAgICAgIC8vIENoZWNrIHByb3BlcnR5IGV4aXN0cyBvbiBib3RoIG9iamVjdHNcclxuICAgICAgICBpZiAob2JqMS5oYXNPd25Qcm9wZXJ0eShwKSAhPT0gb2JqMi5oYXNPd25Qcm9wZXJ0eShwKSkgcmV0dXJuIGZhbHNlO1xyXG5cclxuICAgICAgICBzd2l0Y2ggKHR5cGVvZiAob2JqMVtwXSkpIHtcclxuICAgICAgICAgIC8vIERlZXAgY29tcGFyZSBvYmplY3RzXHJcbiAgICAgICAgICBjYXNlICdvYmplY3QnOlxyXG4gICAgICAgICAgICBpZiAoIWNvbXBhcmVPYmpzKG9iajFbcF0sIG9iajJbcF0pKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgLy8gQ29tcGFyZSB2YWx1ZXNcclxuICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgIGlmIChvYmoxW3BdICE9PSBvYmoyW3BdKSByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBDaGVjayBvYmplY3QgMiBmb3IgYW55IGV4dHJhIHByb3BlcnRpZXNcclxuICAgICAgZm9yIChjb25zdCBwIGluIG9iajIpIHtcclxuICAgICAgICBpZiAodHlwZW9mIChvYmoxW3BdKSA9PT0gJ3VuZGVmaW5lZCcpIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZGlhID0gY29tcG9uZW50IGluc3RhbmNlb2YgRGlhZ3JhbUNvbXBvbmVudCA/IGNvbXBvbmVudC5kaWFncmFtIDogY29tcG9uZW50LnBhbGV0dGU7XHJcblxyXG4gICAgaWYgKCFkaWEgfHwgIWRpYS5tb2RlbCkgcmV0dXJuO1xyXG5cclxuICAgIGlmIChrdmNoYW5nZXMpIHtcclxuXHJcbiAgICAgIC8vIGhhbmRsZSBhZGRlZCBub2RlcyAvIGxpbmtzXHJcbiAgICAgIGt2Y2hhbmdlcy5mb3JFYWNoQWRkZWRJdGVtKChyOiBLZXlWYWx1ZUNoYW5nZVJlY29yZDxzdHJpbmcsIGFueT4pID0+IHtcclxuICAgICAgICBzd2l0Y2ggKHN0cikge1xyXG4gICAgICAgICAgY2FzZSBcIm5cIjoge1xyXG4gICAgICAgICAgICBkaWEubW9kZWwuYWRkTm9kZURhdGEoci5jdXJyZW50VmFsdWUpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGNhc2UgXCJsXCI6IHtcclxuICAgICAgICAgICAgdmFyIG0gPSA8Z28uR3JhcGhMaW5rc01vZGVsPmRpYS5tb2RlbDtcclxuICAgICAgICAgICAgbS5hZGRMaW5rRGF0YShyLmN1cnJlbnRWYWx1ZSk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBoYW5kbGUgcmVtb3ZlZCBub2RlcyAvIGxpbmtzXHJcbiAgICAgIGt2Y2hhbmdlcy5mb3JFYWNoUmVtb3ZlZEl0ZW0oKHI6IEtleVZhbHVlQ2hhbmdlUmVjb3JkPHN0cmluZywgYW55PikgPT4ge1xyXG4gICAgICAgIHN3aXRjaCAoc3RyKSB7XHJcbiAgICAgICAgICBjYXNlIFwiblwiOiB7XHJcbiAgICAgICAgICAgIGxldCBtID0gZGlhLm1vZGVsO1xyXG4gICAgICAgICAgICBsZXQga2V5UHJvcE5hbWUgPSBtLm5vZGVLZXlQcm9wZXJ0eS50b1N0cmluZygpO1xyXG4gICAgICAgICAgICB2YXIgbm9kZSA9IGRpYS5maW5kTm9kZUZvcktleShyLnByZXZpb3VzVmFsdWVba2V5UHJvcE5hbWVdKTtcclxuICAgICAgICAgICAgaWYgKG5vZGUpIHtcclxuICAgICAgICAgICAgICBkaWEucmVtb3ZlKG5vZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgY2FzZSBcImxcIjoge1xyXG4gICAgICAgICAgICBsZXQgbSA9IDxnby5HcmFwaExpbmtzTW9kZWw+ZGlhLm1vZGVsO1xyXG4gICAgICAgICAgICB2YXIga2V5UHJvcE5hbWUgPSBtLmxpbmtLZXlQcm9wZXJ0eS50b1N0cmluZygpO1xyXG4gICAgICAgICAgICB2YXIgbGluayA9IGRpYS5maW5kTGlua0ZvcktleShyLnByZXZpb3VzVmFsdWVba2V5UHJvcE5hbWVdKTtcclxuICAgICAgICAgICAgaWYgKGxpbmspIHtcclxuICAgICAgICAgICAgICBkaWEucmVtb3ZlKGxpbmspO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBoYW5kbGUgY2hhbmdlZCBkYXRhIGZvciBub2RlcyAvIGxpbmtzXHJcbiAgICAgIGt2Y2hhbmdlcy5mb3JFYWNoQ2hhbmdlZEl0ZW0oKHI6IEtleVZhbHVlQ2hhbmdlUmVjb3JkPHN0cmluZywgYW55PikgPT4ge1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIGVuc3VyZSBcImNoYW5nZXNcIiB0byBhcnJheSAvIG9iamVjdCAvIGVudW1lcmFibGUgZGF0YSBwcm9wZXJ0aWVzIGFyZSBsZWdpdFxyXG4gICAgICAgIGNvbnN0IHNhbWVWYWxzID0gY29tcGFyZU9ianMoci5jdXJyZW50VmFsdWUsIHIucHJldmlvdXNWYWx1ZSk7XHJcblxyXG4gICAgICAgIC8vIHVwZGF0ZSBwcm9wZXIgZGF0YSBvYmplY3QgZm9yIG5vZGUgb3IgbGlua1xyXG4gICAgICAgIGlmICghc2FtZVZhbHMpIHtcclxuICAgICAgICAgIHN3aXRjaCAoc3RyKSB7XHJcbiAgICAgICAgICAgIGNhc2UgXCJuXCI6IHtcclxuICAgICAgICAgICAgICBsZXQgbSA9IGRpYS5tb2RlbDtcclxuICAgICAgICAgICAgICBsZXQga2V5UHJvcE5hbWUgPSBtLm5vZGVLZXlQcm9wZXJ0eS50b1N0cmluZygpO1xyXG4gICAgICAgICAgICAgIHZhciBub2RlID0gZGlhLmZpbmROb2RlRm9yS2V5KHIucHJldmlvdXNWYWx1ZVtrZXlQcm9wTmFtZV0pO1xyXG4gICAgICAgICAgICAgIGlmIChub2RlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgZW50cnkgd2FzIHJlcGxhY2VkIHdpdGggbnVsbCBvciB1bmRlZmluZWQsIGp1c3QgcmVtb3ZlIHRoZSBlbnRyeSBhbHRvZ3RoZXJcclxuICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgc3RpbGwgcHJldHR5IGJhZCBwcmFjdGljZSAtLSBpbnN0ZWFkLCB1c2VycyBzaG91bGQgcmVtb3ZlIGVudHJpZXMgaW4gdGhlaXIgbm9kZSAvIGxpbmsgLyBtb2RlbCBkYXRhLCBub3Qgc2V0IHRoZW0gdG8gbnVsbFxyXG4gICAgICAgICAgICAgICAgaWYgKCFyLmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICBkaWEucmVtb3ZlKG5vZGUpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgZGlhLm1vZGVsLmFzc2lnbkFsbERhdGFQcm9wZXJ0aWVzKG5vZGUuZGF0YSwgci5jdXJyZW50VmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYXNlIFwibFwiOiB7XHJcbiAgICAgICAgICAgICAgbGV0IG0gPSA8Z28uR3JhcGhMaW5rc01vZGVsPmRpYS5tb2RlbDtcclxuICAgICAgICAgICAgICB2YXIga2V5UHJvcE5hbWUgPSBtLmxpbmtLZXlQcm9wZXJ0eS50b1N0cmluZygpO1xyXG4gICAgICAgICAgICAgIHZhciBsaW5rID0gZGlhLmZpbmRMaW5rRm9yS2V5KHIucHJldmlvdXNWYWx1ZVtrZXlQcm9wTmFtZV0pO1xyXG4gICAgICAgICAgICAgIGlmIChsaW5rKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgZW50cnkgd2FzIHJlcGxhY2VkIHdpdGggbnVsbCBvciB1bmRlZmluZWQsIGp1c3QgcmVtb3ZlIHRoZSBlbnRyeSBhbHRvZ3RoZXJcclxuICAgICAgICAgICAgICAgIC8vIHRoaXMgaXMgc3RpbGwgcHJldHR5IGJhZCBwcmFjdGljZSAtLSBpbnN0ZWFkLCB1c2VycyBzaG91bGQgcmVtb3ZlIGVudHJpZXMgaW4gdGhlaXIgbm9kZSAvIGxpbmsgLyBtb2RlbCBkYXRhLCBub3Qgc2V0IHRoZW0gdG8gbnVsbFxyXG4gICAgICAgICAgICAgICAgaWYgKCFyLmN1cnJlbnRWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICBkaWEucmVtb3ZlKGxpbmspO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgZGlhLm1vZGVsLmFzc2lnbkFsbERhdGFQcm9wZXJ0aWVzKGxpbmsuZGF0YSwgci5jdXJyZW50VmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFsd2F5cyBiZSBjaGVja2luZyBpZiBhcnJheSBJbnB1dCBkYXRhIGhhcyBjaGFuZ2VkIChub2RlIGFuZCBsaW5rIGRhdGEgYXJyYXlzKVxyXG4gICAqL1xyXG4gIHB1YmxpYyBuZ0RvQ2hlY2soKSB7XHJcblxyXG4gICAgaWYgKCF0aGlzLmRpYWdyYW0pIHJldHVybjtcclxuICAgIGlmICghdGhpcy5kaWFncmFtLm1vZGVsKSByZXR1cm47XHJcblxyXG4gICAgLy8gdGhlc2UgbmVlZCB0byBiZSBydW4gZWFjaCBjaGVjaywgZXZlbiBpZiBubyBtZXJnaW5nIGhhcHBlbnNcclxuICAgIC8vIG90aGVyd2lzZSwgdGhleSB3aWxsIGRldGVjdCBhbGwgZGlmZnMgdGhhdCBoYXBwZW5lZCBzaW5jZSBsYXN0IHRpbWUgc2tpcHNEaWFncmFtIHdhcyBmYWxzZSxcclxuICAgIC8vIHN1Y2ggYXMgcmVtb3ZlIG9wcyB0aGF0IGhhcHBlbmVkIGluIEdvSlMgd2hlbiBza2lwc0RpYWdyYW0gPSB0cnVlLCBcclxuICAgIC8vIGFuZCB0aGVuIHJlYWxsbGxsbHkgYmFkIHN0dWZmIGhhcHBlbnMgKGRlbGV0aW5nIHJhbmRvbSBub2RlcywgdXBkYXRpbmcgdGhlIHdyb25nIFBhcnRzKVxyXG4gICAgLy8gQW5ndWxhciBkaWZmZXJzIGFyZSBhIGxvdCBvZiBmdW5cclxuICAgIHZhciBub2RlRGlmZnMgPSB0aGlzLl9uZGFEaWZmZXIuZGlmZih0aGlzLm5vZGVEYXRhQXJyYXkpO1xyXG4gICAgdmFyIGxpbmtEaWZmcyA9IHRoaXMuX2xkYURpZmZlci5kaWZmKHRoaXMubGlua0RhdGFBcnJheSk7XHJcblxyXG4gICAgdmFyIG1vZGVsRGlmZnMgPSB0aGlzLl9tZGFEaWZmZXIuZGlmZih0aGlzLm1vZGVsRGF0YSk7XHJcblxyXG4gICAgaWYgKCFub2RlRGlmZnMgJiYgIWxpbmtEaWZmcyAmJiAhbW9kZWxEaWZmcykgcmV0dXJuO1xyXG5cclxuICAgIGlmICh0aGlzLnNraXBzRGlhZ3JhbVVwZGF0ZSkgcmV0dXJuO1xyXG5cclxuICAgIC8vIGRvbid0IG5lZWQgbW9kZWwgY2hhbmdlIGxpc3RlbmVyIHdoaWxlIHBlcmZvcm1pbmcga25vd24gZGF0YSB1cGRhdGVzXHJcbiAgICBpZiAodGhpcy5tb2RlbENoYW5nZWRMaXN0ZW5lciAhPT0gbnVsbCkgdGhpcy5kaWFncmFtLm1vZGVsLnJlbW92ZUNoYW5nZWRMaXN0ZW5lcih0aGlzLm1vZGVsQ2hhbmdlZExpc3RlbmVyKTtcclxuXHJcbiAgICB0aGlzLmRpYWdyYW0ubW9kZWwuc3RhcnRUcmFuc2FjdGlvbigndXBkYXRlIGRhdGEnKTtcclxuICAgIC8vIHVwZGF0ZSBtb2RlbERhdGEgZmlyc3QsIGluIGNhc2UgYmluZGluZ3Mgb24gbm9kZXMgLyBsaW5rcyBkZXBlbmQgb24gbW9kZWwgZGF0YVxyXG4gICAgdGhpcy5kaWFncmFtLm1vZGVsLmFzc2lnbkFsbERhdGFQcm9wZXJ0aWVzKHRoaXMuZGlhZ3JhbS5tb2RlbC5tb2RlbERhdGEsIHRoaXMubW9kZWxEYXRhKTtcclxuICAgIC8vIG1lcmdlIG5vZGUgLyBsaW5rIGRhdGFcclxuICAgIERpYWdyYW1Db21wb25lbnQubWVyZ2VDaGFuZ2VzKHRoaXMsIG5vZGVEaWZmcywgXCJuXCIpO1xyXG4gICAgRGlhZ3JhbUNvbXBvbmVudC5tZXJnZUNoYW5nZXModGhpcywgbGlua0RpZmZzLCBcImxcIik7XHJcbiAgICB0aGlzLmRpYWdyYW0ubW9kZWwuY29tbWl0VHJhbnNhY3Rpb24oJ3VwZGF0ZSBkYXRhJyk7XHJcblxyXG4gICAgLy8gcmVzZXQgdGhlIG1vZGVsIGNoYW5nZSBsaXN0ZW5lclxyXG4gICAgaWYgKHRoaXMubW9kZWxDaGFuZ2VkTGlzdGVuZXIgIT09IG51bGwpIHRoaXMuZGlhZ3JhbS5tb2RlbC5hZGRDaGFuZ2VkTGlzdGVuZXIodGhpcy5tb2RlbENoYW5nZWRMaXN0ZW5lcik7XHJcblxyXG4gIH0gLy8gZW5kIG5nRG9DaGVja1xyXG5cclxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLmRpYWdyYW0uZGl2ID0gbnVsbDsgLy8gcmVtb3ZlcyBldmVudCBsaXN0ZW5lcnNcclxuICB9XHJcbn1cclxuIl19 | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhZ3JhbS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nb2pzLWFuZ3VsYXIvc3JjL2xpYi9kaWFncmFtLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEcsT0FBTyxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0IsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBTXRELE1BQU0sT0FBTyxnQkFBZ0I7Ozs7SUEwQjNCLFlBQW1CLElBQVk7UUFBWixTQUFJLEdBQUosSUFBSSxDQUFROzs7O1FBaEJmLGtCQUFhLEdBQXlCLElBQUksQ0FBQzs7OztRQUUzQyxjQUFTLEdBQWtCLElBQUksQ0FBQzs7OztRQUl6Qyx5QkFBb0IsR0FBMEMsSUFBSSxDQUFDOzs7O1FBRTFELHVCQUFrQixHQUFZLEtBQUssQ0FBQzs7OztRQUVuQyxnQkFBVyxHQUFxQyxJQUFJLFlBQVksRUFBc0IsQ0FBQzs7OztRQUlqRyxZQUFPLEdBQWUsSUFBSSxDQUFDO0lBRUUsQ0FBQzs7Ozs7SUFLOUIsZUFBZTtRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7U0FDOUM7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxZQUFZLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUN6QyxNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7U0FDckU7UUFFRCxnRUFBZ0U7UUFDaEUsZUFBZSxDQUFDLGtDQUFrQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDOzs7O2NBSXRFLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWE7UUFDNUMsSUFBSSxNQUFNLEtBQUssSUFBSTtZQUFFLE9BQU87UUFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDO1FBRTFCLDBFQUEwRTtRQUMxRSxlQUFlLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0Ryw2QkFBNkI7UUFDN0IsZUFBZSxDQUFDLDhCQUE4QixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3ZELENBQUMsQ0FBQyxzQkFBc0I7Ozs7OztJQUtqQixXQUFXO1FBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLGtCQUFrQjtZQUFFLE9BQU87UUFDNUUsZUFBZSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlDLENBQUMsQ0FBQyxrQkFBa0I7Ozs7O0lBRWIsV0FBVztRQUNoQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsQ0FBQywwQkFBMEI7SUFDckQsQ0FBQzs7O1lBckVGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsY0FBYztnQkFDeEIsUUFBUSxFQUFFLGlEQUFpRDthQUM1RDs7OztZQVBvRCxNQUFNOzs7MEJBY3hELEtBQUs7NEJBRUwsS0FBSzs0QkFFTCxLQUFLO3dCQUVMLEtBQUs7MkJBRUwsS0FBSztpQ0FJTCxLQUFLOzBCQUVMLE1BQU07eUJBRU4sU0FBUyxTQUFDLFdBQVcsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Ozs7Ozs7O0lBaEJ4Qyx1Q0FBOEM7Ozs7O0lBRTlDLHlDQUFvRDs7Ozs7SUFFcEQseUNBQTJEOzs7OztJQUUzRCxxQ0FBZ0Q7Ozs7O0lBRWhELHdDQUFxQzs7Ozs7SUFFckMsZ0RBQTBFOzs7OztJQUUxRSw4Q0FBb0Q7Ozs7O0lBRXBELHVDQUF3Rzs7Ozs7SUFFeEcsc0NBQXdFOzs7OztJQUV4RSxtQ0FBa0M7O0lBRXRCLGdDQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgTmdab25lLCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgKiBhcyBnbyBmcm9tICdnb2pzJztcclxuaW1wb3J0IHsgTmdEaWFncmFtSGVscGVyIH0gZnJvbSAnLi9uZy1kaWFncmFtLWhlbHBlcic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2dvanMtZGlhZ3JhbScsXHJcbiAgdGVtcGxhdGU6ICc8ZGl2ICNuZ0RpYWdyYW0gW2NsYXNzTmFtZV09ZGl2Q2xhc3NOYW1lPjwvZGl2PidcclxufSlcclxuZXhwb3J0IGNsYXNzIERpYWdyYW1Db21wb25lbnQge1xyXG5cclxuICAvKipcclxuICAgKiBEaWFncmFtIGluaXRpYWxpemF0aW9uIGZ1bmN0aW9uLiBSZXR1cm5zIGEgZ28uRGlhZ3JhbS5cclxuICAgKiBEbyBub3QgaW5pdGlhbGl6ZSBtb2RlbCBkYXRhIGluIHRoaXMgZnVuY3Rpb24uXHJcbiAgICovXHJcbiAgQElucHV0KCkgcHVibGljIGluaXREaWFncmFtOiAoKSA9PiBnby5EaWFncmFtO1xyXG4gIC8qKiAgTm9kZSBkYXRhIGZvciBkaWFncmFtICovXHJcbiAgQElucHV0KCkgcHVibGljIG5vZGVEYXRhQXJyYXk6IEFycmF5PGdvLk9iamVjdERhdGE+O1xyXG4gIC8qKiAgTGluayBkYXRhIGZvciBkaWFncmFtLiBPcHRpb25hbC4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgbGlua0RhdGFBcnJheTogQXJyYXk8Z28uT2JqZWN0RGF0YT4gPSBudWxsO1xyXG4gIC8qKiBNb2RlbCBkYXRhIGZvciBkaWFncmFtLiBPcHRpb25hbC4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgbW9kZWxEYXRhOiBnby5PYmplY3REYXRhID0gbnVsbDsgXHJcbiAgLyoqIERpYWdyYW0gZGl2IGNsYXNzIG5hbWUuIFVzZSB0aGlzIG5hbWUgdG8gc3R5bGUgeW91ciBkaWFncmFtIGluIENTUy4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZGl2Q2xhc3NOYW1lOiBzdHJpbmc7XHJcbiAgLyoqIE1vZGVsIGNoYW5nZWQgbGlzdGVuZXIgZnVuY3Rpb24gZm9yIGRpYWdyYW0gKi9cclxuICBwdWJsaWMgbW9kZWxDaGFuZ2VkTGlzdGVuZXI6ICgoZTogZ28uQ2hhbmdlZEV2ZW50KSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xyXG4gIC8qKiBXaGV0aGVyIG9yIG5vdCB0byBza2lwIG1lcmdpbmcgYXBwIGRhdGEgd2l0aCBHb0pTIG1vZGVsIGRhdGEgKHNldCB0byB0cnVlIGlmIHVwZGF0ZSBpcyBjb21pbmcgZnJvbSBHb0pTLCBmYWxzZSBpZiBjb21pbmcgZnJvbSBhcHAtbGV2ZWwsIHVzdWFsbHkpICovXHJcbiAgQElucHV0KCkgcHVibGljIHNraXBzRGlhZ3JhbVVwZGF0ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIC8qKiBFdmVudCBlbWl0dGVyIC0tIGZpcmVzIHdoZW4gZGlhZ3JhbSBtb2RlbCBjaGFuZ2VzLiBDYXB0dXJlIHRoaXMgZW1pdHRlZCBldmVudCBpbiBwYXJlbnQgY29tcG9uZW50ICovXHJcbiAgQE91dHB1dCgpIHB1YmxpYyBtb2RlbENoYW5nZTogRXZlbnRFbWl0dGVyPGdvLkluY3JlbWVudGFsRGF0YT4gPSBuZXcgRXZlbnRFbWl0dGVyPGdvLkluY3JlbWVudGFsRGF0YT4oKTtcclxuICAvKiogVGhlIERJViBlbGVtZW50IGhvbGRpbmcgdGhlIERpYWdyYW0gKi9cclxuICBAVmlld0NoaWxkKCduZ0RpYWdyYW0nLCB7IHN0YXRpYzogdHJ1ZSB9KSBwdWJsaWMgZGlhZ3JhbURpdjogRWxlbWVudFJlZjtcclxuICAvKiogVGhlIERpYWdyYW0gaXRzZWxmICovXHJcbiAgcHVibGljIGRpYWdyYW06IGdvLkRpYWdyYW0gPSBudWxsO1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgem9uZTogTmdab25lKSB7ICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIGRpYWdyYW0gLyBtb2RlbCBhZnRlciB2aWV3IGluaXRcclxuICAgKi9cclxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgaWYgKCF0aGlzLmRpYWdyYW1EaXYpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZGlhZ3JhbURpdiBpcyBub3QgZGVmaW5lZFwiKTtcclxuICAgIH1cclxuICAgIHRoaXMuZGlhZ3JhbSA9IHRoaXMuaW5pdERpYWdyYW0oKTtcclxuICAgIGlmICghKHRoaXMuZGlhZ3JhbSBpbnN0YW5jZW9mIGdvLkRpYWdyYW0pKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImluaXREaWFncmFtIGZ1bmN0aW9uIGRpZCBub3QgcmV0dXJuIGEgZ28uRGlhZ3JhbVwiKTtcclxuICAgIH0gXHJcblxyXG4gICAgLy8gcmVkdWNlcyBjaGFuZ2UgZGV0ZWN0aW9uIG9uIG1vdXNlIG1vdmVzLCBib29zdGluZyBwZXJmb3JtYW5jZVxyXG4gICAgTmdEaWFncmFtSGVscGVyLm1ha2VNb3VzZU1vdmVSdW5PdXRzaWRlQW5ndWxhclpvbmUodGhpcy5kaWFncmFtLCB0aGlzLnpvbmUpO1xyXG5cclxuICAgIC8vIGFzc2lnbiB0aGUgRGlhZ3JhbSdzIGRpdiwgd2hpY2ggKGFtb25nIG1hbnkgb3RoZXIgdGhpbmdzKSB3aWxsIGF0dGFjaCBhIGJ1bmNoIG9mIGxpc3RlbmVycyB0byB0aGUgY2FudmFzLFxyXG4gICAgLy8gdXNpbmcgdGhlIG92ZXJyaWRkZW4gYWRkRXZlbnRMaXN0ZW5lciBmdW5jdGlvbiBkZWZpbmVkIGluIG1ha2VNb3VzZU1vdmVSdW5PdXRzaWRlQW5ndWxhclpvbmVcclxuICAgIGNvbnN0IGRpdlJlZiA9IHRoaXMuZGlhZ3JhbURpdi5uYXRpdmVFbGVtZW50O1xyXG4gICAgaWYgKGRpdlJlZiA9PT0gbnVsbCkgcmV0dXJuO1xyXG4gICAgdGhpcy5kaWFncmFtLmRpdiA9IGRpdlJlZjtcclxuXHJcbiAgICAvLyBpbml0aWFsaXplIHRoZSBkaWFncmFtIG1vZGVsIHdpdGggdGhlIHByb3ZpZGVkIG5vZGUgLyBsaW5rIC8gbW9kZWwgZGF0YVxyXG4gICAgTmdEaWFncmFtSGVscGVyLmluaXRpYWxpemVNb2RlbCh0aGlzLmRpYWdyYW0sIHRoaXMubm9kZURhdGFBcnJheSwgdGhpcy5saW5rRGF0YUFycmF5LCB0aGlzLm1vZGVsRGF0YSk7XHJcbiAgICAvLyBpbml0aWFsaXplciBtb2RlbCBsaXN0ZW5lclxyXG4gICAgTmdEaWFncmFtSGVscGVyLmluaXRpYWxpemVNb2RlbENoYW5nZWRMaXN0ZW5lcih0aGlzKTtcclxuICB9IC8vIGVuZCBuZ0FmdGVyVmlld0luaXRcclxuXHJcbiAgLyoqXHJcbiAgICogSWYgYSBjaGFuZ2UgaGFzIG9jY3VyZWQgb24gYW4gQElucHV0IHByb3BlcnR5LCBtZXJnZSB0aGUgYXBwLWxldmVsIGNoYW5nZXMgd2l0aCBHb0pTXHJcbiAgICovXHJcbiAgcHVibGljIG5nT25DaGFuZ2VzKCkge1xyXG4gICAgaWYgKCF0aGlzLmRpYWdyYW0gfHwgIXRoaXMuZGlhZ3JhbS5tb2RlbCB8fCB0aGlzLnNraXBzRGlhZ3JhbVVwZGF0ZSkgcmV0dXJuO1xyXG4gICAgTmdEaWFncmFtSGVscGVyLm1lcmdlQXBwRGF0YVdpdGhNb2RlbCh0aGlzKTtcclxuICB9IC8vIGVuZCBuZ09uQ2hhbmdlc1xyXG5cclxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLmRpYWdyYW0uZGl2ID0gbnVsbDsgLy8gcmVtb3ZlcyBldmVudCBsaXN0ZW5lcnNcclxuICB9XHJcblxyXG59XHJcbiJdfQ== |
@@ -8,2 +8,3 @@ /** | ||
import * as go from 'gojs'; | ||
import { NgDiagramHelper } from "./ng-diagram-helper"; | ||
export class OverviewComponent { | ||
@@ -15,5 +16,9 @@ /** | ||
this.zone = zone; | ||
// The Diagram to observe with the Overview | ||
/** | ||
* The Diagram to observe with the Overview | ||
*/ | ||
this.observedDiagram = null; | ||
// The Overview itself | ||
/** | ||
* The Overview itself | ||
*/ | ||
this.overview = null; | ||
@@ -26,6 +31,10 @@ } | ||
ngAfterViewInit() { | ||
if (!this.overviewDiv) | ||
return; | ||
if (!this.overviewDiv) { | ||
throw new Error("overviewDiv is not defined"); | ||
} | ||
if (this.initOverview) { | ||
this.overview = this.initOverview(); | ||
if (!(this.overview instanceof go.Overview)) { | ||
throw new Error("initOverview function did not return a go.Overview"); | ||
} | ||
} | ||
@@ -36,31 +45,4 @@ else { | ||
} | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the overview, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.overview.addEventListener = (/** | ||
* @param {?} DOMElement | ||
* @param {?} name | ||
* @param {?} listener | ||
* @param {?} capture | ||
* @return {?} | ||
*/ | ||
(DOMElement, name, listener, capture) => { | ||
/** @type {?} */ | ||
const superAddEventListener = go.Diagram.prototype.addEventListener; | ||
if (name === 'mousemove') { | ||
this.zone.runOutsideAngular((/** | ||
* @return {?} | ||
*/ | ||
() => superAddEventListener.call(this, DOMElement, name, listener, capture))); | ||
} | ||
else { | ||
this.zone.run((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
superAddEventListener.call(this, DOMElement, name, listener, capture); | ||
})); | ||
} | ||
}); | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.overview, this.zone); | ||
this.overview.div = this.overviewDiv.nativeElement; | ||
@@ -104,11 +86,23 @@ } | ||
if (false) { | ||
/** @type {?} */ | ||
/** | ||
* The function used to initialize and return the Overview | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.initOverview; | ||
/** @type {?} */ | ||
/** | ||
* The div class name that holds the Overview. Use this name to style your Overview in CSS. | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
/** | ||
* The Diagram to observe with the Overview | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.observedDiagram; | ||
/** @type {?} */ | ||
OverviewComponent.prototype.overviewDiv; | ||
/** @type {?} */ | ||
/** | ||
* The Overview itself | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.overview; | ||
@@ -118,2 +112,2 @@ /** @type {?} */ | ||
} | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcnZpZXcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZ29qcy1hbmd1bGFyL3NyYy9saWIvb3ZlcnZpZXcuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBaUIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9GLE9BQU8sS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBTTNCLE1BQU0sT0FBTyxpQkFBaUI7Ozs7SUFnQjVCLFlBQW1CLElBQVk7UUFBWixTQUFJLEdBQUosSUFBSSxDQUFROztRQVBmLG9CQUFlLEdBQWUsSUFBSSxDQUFDOztRQUs1QyxhQUFRLEdBQXVCLElBQUksQ0FBQztJQUVSLENBQUM7Ozs7O0lBSzdCLGVBQWU7UUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTztRQUM5QixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDckIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7U0FDckM7YUFBTTtZQUNMLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztTQUNqRDtRQUVELGlHQUFpRztRQUNqRyxtSUFBbUk7UUFDbkksd0ZBQXdGO1FBQ3hGLDhGQUE4RjtRQUM5RixJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQjs7Ozs7OztRQUFHLENBQUMsVUFBdUMsRUFBRSxJQUFZLEVBQUUsUUFBYSxFQUFFLE9BQWdCLEVBQUUsRUFBRTs7a0JBQ3BILHFCQUFxQixHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLGdCQUFnQjtZQUNuRSxJQUFJLElBQUksS0FBSyxXQUFXLEVBQUU7Z0JBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCOzs7Z0JBQUMsR0FBRyxFQUFFLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsRUFBQyxDQUFDO2FBQzFHO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRzs7O2dCQUFDLEdBQUcsRUFBRTtvQkFDakIscUJBQXFCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDeEUsQ0FBQyxFQUFDLENBQUM7YUFDSjtRQUNILENBQUMsQ0FBQSxDQUFDO1FBRUYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUM7SUFDckQsQ0FBQzs7Ozs7O0lBTU0sV0FBVyxDQUFDLE9BQXNCO1FBQ3ZDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDM0IsSUFBSSxPQUFPLElBQUksT0FBTyxDQUFDLGVBQWUsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLFlBQVksS0FBSyxPQUFPLENBQUMsZUFBZSxDQUFDLGFBQWEsRUFBRTtZQUN4SCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQztTQUMvRDtJQUNILENBQUM7Ozs7SUFFTSxXQUFXO1FBQ2hCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLDBCQUEwQjtJQUN0RCxDQUFDOzs7WUFqRUYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxlQUFlO2dCQUN6QixRQUFRLEVBQUUsa0RBQWtEO2FBQzdEOzs7O1lBTnNDLE1BQU07OzsyQkFVMUMsS0FBSzsyQkFHTCxLQUFLOzhCQUdMLEtBQUs7MEJBRUwsU0FBUyxTQUFDLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Ozs7SUFSekMseUNBQWdEOztJQUdoRCx5Q0FBcUM7O0lBR3JDLDRDQUFtRDs7SUFFbkQsd0NBQTBFOztJQUcxRSxxQ0FBMkM7O0lBRS9CLGlDQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE5nWm9uZSwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIGdvIGZyb20gJ2dvanMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdnb2pzLW92ZXJ2aWV3JyxcclxuICB0ZW1wbGF0ZTogJzxkaXYgI25nT3ZlcnZpZXcgW2NsYXNzTmFtZV09ZGl2Q2xhc3NOYW1lPjwvZGl2PidcclxufSlcclxuZXhwb3J0IGNsYXNzIE92ZXJ2aWV3Q29tcG9uZW50IHtcclxuXHJcbiAgLy8gVGhlIGZ1bmN0aW9uIHVzZWQgdG8gaW5pdGlhbGl6ZSB0aGUgT3ZlcnZpZXdcclxuICBASW5wdXQoKSBwdWJsaWMgaW5pdE92ZXJ2aWV3OiAoKSA9PiBnby5PdmVydmlldztcclxuXHJcbiAgLy8gT3ZlcnZpZXcgZGl2IGNsYXNzIG5hbWUuIFVzZSB0aGlzIG5hbWUgdG8gc3R5bGUgeW91ciBPdmVydmlldyBpbiBDU1NcclxuICBASW5wdXQoKSBwdWJsaWMgZGl2Q2xhc3NOYW1lOiBzdHJpbmc7XHJcblxyXG4gIC8vIFRoZSBEaWFncmFtIHRvIG9ic2VydmUgd2l0aCB0aGUgT3ZlcnZpZXdcclxuICBASW5wdXQoKSBwdWJsaWMgb2JzZXJ2ZWREaWFncmFtOiBnby5EaWFncmFtID0gbnVsbDtcclxuXHJcbiAgQFZpZXdDaGlsZCgnbmdPdmVydmlldycsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyBvdmVydmlld0RpdjogRWxlbWVudFJlZjtcclxuXHJcbiAgLy8gVGhlIE92ZXJ2aWV3IGl0c2VsZlxyXG4gIHB1YmxpYyBvdmVydmlldzogZ28uT3ZlcnZpZXcgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IocHVibGljIHpvbmU6IE5nWm9uZSkgeyB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemUgdGhlIG92ZXJ2aWV3XHJcbiAgICovXHJcbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGlmICghdGhpcy5vdmVydmlld0RpdikgcmV0dXJuO1xyXG4gICAgaWYgKHRoaXMuaW5pdE92ZXJ2aWV3KSB7XHJcbiAgICAgIHRoaXMub3ZlcnZpZXcgPSB0aGlzLmluaXRPdmVydmlldygpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5vdmVydmlldyA9IG5ldyBnby5PdmVydmlldygpO1xyXG4gICAgICB0aGlzLm92ZXJ2aWV3LmNvbnRlbnRBbGlnbm1lbnQgPSBnby5TcG90LkNlbnRlcjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBUaGlzIGJpdCBvZiBjb2RlIG1ha2VzIHN1cmUgdGhlIG1vdXNlbW92ZSBldmVudCBsaXN0ZW5lcnMgb24gdGhlIGNhbnZhcyBhcmUgcnVuIG91dHNpZGUgTmdab25lXHJcbiAgICAvLyBUaGlzIG1ha2VzIGl0IHNvIGNoYW5nZSBkZXRlY3Rpb24gaXNuJ3QgdHJpZ2dlcmVkIGV2ZXJ5IHRpbWUgdGhlIG1vdXNlIGlzIG1vdmVkIGluc2lkZSB0aGUgY2FudmFzLCBncmVhdGx5IGltcHJvdmluZyBwZXJmb3JtYW5jZVxyXG4gICAgLy8gSWYgc29tZSBzdGF0ZS1hbHRlcmluZyBiZWhhdmlvciBtdXN0IGhhcHBlbiBvbiBhIG1vdXNlbW92ZSBldmVudCBpbnNpZGUgdGhlIG92ZXJ2aWV3LFxyXG4gICAgLy8geW91IHdpbGwgaGF2ZSB0byB1c2luZyB6b25lLnJ1bigpIHRvIG1ha2Ugc3VyZSB0aGF0IGV2ZW50IHRyaWdnZXJzIGFuZ3VsYXIgY2hhbmdlIGRldGVjdGlvblxyXG4gICAgdGhpcy5vdmVydmlldy5hZGRFdmVudExpc3RlbmVyID0gKERPTUVsZW1lbnQ6IEVsZW1lbnQgfCBXaW5kb3cgfCBEb2N1bWVudCwgbmFtZTogc3RyaW5nLCBsaXN0ZW5lcjogYW55LCBjYXB0dXJlOiBib29sZWFuKSA9PiB7XHJcbiAgICAgIGNvbnN0IHN1cGVyQWRkRXZlbnRMaXN0ZW5lciA9IGdvLkRpYWdyYW0ucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXI7XHJcbiAgICAgIGlmIChuYW1lID09PSAnbW91c2Vtb3ZlJykge1xyXG4gICAgICAgIHRoaXMuem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBzdXBlckFkZEV2ZW50TGlzdGVuZXIuY2FsbCh0aGlzLCBET01FbGVtZW50LCBuYW1lLCBsaXN0ZW5lciwgY2FwdHVyZSkpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xyXG4gICAgICAgICAgc3VwZXJBZGRFdmVudExpc3RlbmVyLmNhbGwodGhpcywgRE9NRWxlbWVudCwgbmFtZSwgbGlzdGVuZXIsIGNhcHR1cmUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMub3ZlcnZpZXcuZGl2ID0gdGhpcy5vdmVydmlld0Rpdi5uYXRpdmVFbGVtZW50O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT25seSB1cGRhdGUgd2hlbiB0aGUgb2JzZXJ2ZWQgZGlhZ3JhbSBjaGFuZ2VzXHJcbiAgICogQHBhcmFtIGNoYW5nZXNcclxuICAgKi9cclxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgaWYgKCF0aGlzLm92ZXJ2aWV3KSByZXR1cm47XHJcbiAgICBpZiAoY2hhbmdlcyAmJiBjaGFuZ2VzLm9ic2VydmVkRGlhZ3JhbSAmJiBjaGFuZ2VzLm9ic2VydmVkRGlhZ3JhbS5jdXJyZW50VmFsdWUgIT09IGNoYW5nZXMub2JzZXJ2ZWREaWFncmFtLnByZXZpb3VzVmFsdWUpIHtcclxuICAgICAgdGhpcy5vdmVydmlldy5vYnNlcnZlZCA9IGNoYW5nZXMub2JzZXJ2ZWREaWFncmFtLmN1cnJlbnRWYWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMub3ZlcnZpZXcuZGl2ID0gbnVsbDsgLy8gcmVtb3ZlcyBldmVudCBsaXN0ZW5lcnNcclxuICB9XHJcblxyXG59XHJcbiJdfQ== | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcnZpZXcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvZ29qcy1hbmd1bGFyL3NyYy9saWIvb3ZlcnZpZXcuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBaUIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9GLE9BQU8sS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQU10RCxNQUFNLE9BQU8saUJBQWlCOzs7O0lBYzVCLFlBQW1CLElBQVk7UUFBWixTQUFJLEdBQUosSUFBSSxDQUFROzs7O1FBUGYsb0JBQWUsR0FBZSxJQUFJLENBQUM7Ozs7UUFLNUMsYUFBUSxHQUF1QixJQUFJLENBQUM7SUFFUixDQUFDOzs7OztJQUs3QixlQUFlO1FBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQztTQUMvQztRQUNELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNyQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxZQUFZLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFDM0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO2FBQ3ZFO1NBQ0Y7YUFBTTtZQUNMLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztTQUNqRDtRQUVELGdFQUFnRTtRQUNoRSxlQUFlLENBQUMsa0NBQWtDLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUM7SUFDckQsQ0FBQzs7Ozs7O0lBTU0sV0FBVyxDQUFDLE9BQXNCO1FBQ3ZDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU87UUFDM0IsSUFBSSxPQUFPLElBQUksT0FBTyxDQUFDLGVBQWUsSUFBSSxPQUFPLENBQUMsZUFBZSxDQUFDLFlBQVksS0FBSyxPQUFPLENBQUMsZUFBZSxDQUFDLGFBQWEsRUFBRTtZQUN4SCxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQztTQUMvRDtJQUNILENBQUM7Ozs7SUFFTSxXQUFXO1FBQ2hCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLDBCQUEwQjtJQUN0RCxDQUFDOzs7WUF4REYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxlQUFlO2dCQUN6QixRQUFRLEVBQUUsa0RBQWtEO2FBQzdEOzs7O1lBUHNDLE1BQU07OzsyQkFXMUMsS0FBSzsyQkFFTCxLQUFLOzhCQUVMLEtBQUs7MEJBRUwsU0FBUyxTQUFDLFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Ozs7Ozs7SUFOekMseUNBQWdEOzs7OztJQUVoRCx5Q0FBcUM7Ozs7O0lBRXJDLDRDQUFtRDs7SUFFbkQsd0NBQTBFOzs7OztJQUcxRSxxQ0FBMkM7O0lBRS9CLGlDQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE5nWm9uZSwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCAqIGFzIGdvIGZyb20gJ2dvanMnO1xyXG5pbXBvcnQgeyBOZ0RpYWdyYW1IZWxwZXIgfSBmcm9tIFwiLi9uZy1kaWFncmFtLWhlbHBlclwiO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdnb2pzLW92ZXJ2aWV3JyxcclxuICB0ZW1wbGF0ZTogJzxkaXYgI25nT3ZlcnZpZXcgW2NsYXNzTmFtZV09ZGl2Q2xhc3NOYW1lPjwvZGl2PidcclxufSlcclxuZXhwb3J0IGNsYXNzIE92ZXJ2aWV3Q29tcG9uZW50IHtcclxuXHJcbiAgLyoqIFRoZSBmdW5jdGlvbiB1c2VkIHRvIGluaXRpYWxpemUgYW5kIHJldHVybiB0aGUgT3ZlcnZpZXcgKi8gXHJcbiAgQElucHV0KCkgcHVibGljIGluaXRPdmVydmlldzogKCkgPT4gZ28uT3ZlcnZpZXc7XHJcbiAgLyoqIFRoZSBkaXYgY2xhc3MgbmFtZSB0aGF0IGhvbGRzIHRoZSBPdmVydmlldy4gVXNlIHRoaXMgbmFtZSB0byBzdHlsZSB5b3VyIE92ZXJ2aWV3IGluIENTUy4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZGl2Q2xhc3NOYW1lOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBEaWFncmFtIHRvIG9ic2VydmUgd2l0aCB0aGUgT3ZlcnZpZXcgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgb2JzZXJ2ZWREaWFncmFtOiBnby5EaWFncmFtID0gbnVsbDtcclxuXHJcbiAgQFZpZXdDaGlsZCgnbmdPdmVydmlldycsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyBvdmVydmlld0RpdjogRWxlbWVudFJlZjtcclxuXHJcbiAgLyoqIFRoZSBPdmVydmlldyBpdHNlbGYgICovXHJcbiAgcHVibGljIG92ZXJ2aWV3OiBnby5PdmVydmlldyB8IG51bGwgPSBudWxsO1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgem9uZTogTmdab25lKSB7IH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZSB0aGUgb3ZlcnZpZXdcclxuICAgKi9cclxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgaWYgKCF0aGlzLm92ZXJ2aWV3RGl2KSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIm92ZXJ2aWV3RGl2IGlzIG5vdCBkZWZpbmVkXCIpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuaW5pdE92ZXJ2aWV3KSB7XHJcbiAgICAgIHRoaXMub3ZlcnZpZXcgPSB0aGlzLmluaXRPdmVydmlldygpO1xyXG4gICAgICBpZiAoISh0aGlzLm92ZXJ2aWV3IGluc3RhbmNlb2YgZ28uT3ZlcnZpZXcpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaW5pdE92ZXJ2aWV3IGZ1bmN0aW9uIGRpZCBub3QgcmV0dXJuIGEgZ28uT3ZlcnZpZXdcIik7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMub3ZlcnZpZXcgPSBuZXcgZ28uT3ZlcnZpZXcoKTtcclxuICAgICAgdGhpcy5vdmVydmlldy5jb250ZW50QWxpZ25tZW50ID0gZ28uU3BvdC5DZW50ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmVkdWNlcyBjaGFuZ2UgZGV0ZWN0aW9uIG9uIG1vdXNlIG1vdmVzLCBib29zdGluZyBwZXJmb3JtYW5jZVxyXG4gICAgTmdEaWFncmFtSGVscGVyLm1ha2VNb3VzZU1vdmVSdW5PdXRzaWRlQW5ndWxhclpvbmUodGhpcy5vdmVydmlldywgdGhpcy56b25lKTtcclxuXHJcbiAgICB0aGlzLm92ZXJ2aWV3LmRpdiA9IHRoaXMub3ZlcnZpZXdEaXYubmF0aXZlRWxlbWVudDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE9ubHkgdXBkYXRlIHdoZW4gdGhlIG9ic2VydmVkIGRpYWdyYW0gY2hhbmdlc1xyXG4gICAqIEBwYXJhbSBjaGFuZ2VzXHJcbiAgICovXHJcbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIGlmICghdGhpcy5vdmVydmlldykgcmV0dXJuO1xyXG4gICAgaWYgKGNoYW5nZXMgJiYgY2hhbmdlcy5vYnNlcnZlZERpYWdyYW0gJiYgY2hhbmdlcy5vYnNlcnZlZERpYWdyYW0uY3VycmVudFZhbHVlICE9PSBjaGFuZ2VzLm9ic2VydmVkRGlhZ3JhbS5wcmV2aW91c1ZhbHVlKSB7XHJcbiAgICAgIHRoaXMub3ZlcnZpZXcub2JzZXJ2ZWQgPSBjaGFuZ2VzLm9ic2VydmVkRGlhZ3JhbS5jdXJyZW50VmFsdWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLm92ZXJ2aWV3LmRpdiA9IG51bGw7IC8vIHJlbW92ZXMgZXZlbnQgbGlzdGVuZXJzXHJcbiAgfVxyXG5cclxufVxyXG4iXX0= |
@@ -6,32 +6,28 @@ /** | ||
*/ | ||
import { Component, ElementRef, EventEmitter, Input, KeyValueDiffers, NgZone, Output, ViewChild } from '@angular/core'; | ||
import { Component, ElementRef, EventEmitter, Input, NgZone, Output, ViewChild } from '@angular/core'; | ||
import * as go from 'gojs'; | ||
import { DiagramComponent } from './diagram.component'; | ||
import { NgDiagramHelper } from './ng-diagram-helper'; | ||
export class PaletteComponent { | ||
/** | ||
* @param {?} _kvdiffers | ||
* @param {?} zone | ||
*/ | ||
constructor(_kvdiffers, zone) { | ||
this._kvdiffers = _kvdiffers; | ||
constructor(zone) { | ||
this.zone = zone; | ||
// Link data for palette. Optional | ||
/** | ||
* Link data for palette. Optional. | ||
*/ | ||
this.linkDataArray = null; | ||
// Model data for palette. Optional | ||
/** | ||
* Model data for palette. Optional. | ||
*/ | ||
this.modelData = null; | ||
this.skipsPaletteUpdate = false; | ||
// model changed listener function for palette | ||
this.modelChangedListener = null; | ||
// event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
/** | ||
* Event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
*/ | ||
this.modelChange = new EventEmitter(); | ||
// The Palette itself | ||
/** | ||
* The Palette itself | ||
*/ | ||
this.palette = null; | ||
// differs used to check if there have been changed to the array @Inputs | ||
// without them, changes to the input arrays won't register in ngOnChanges, | ||
// since the array reference itself may be the same | ||
this._ndaDiffer = this._kvdiffers.find([]).create(); | ||
this._ldaDiffer = this._kvdiffers.find([]).create(); | ||
this._mdaDiffer = this._kvdiffers.find([]).create(); | ||
} // end constructor | ||
// end constructor | ||
} | ||
/** | ||
@@ -42,34 +38,11 @@ * Initialize Palette after view init | ||
ngAfterViewInit() { | ||
if (!this.paletteDiv) | ||
return; | ||
if (!this.paletteDiv) { | ||
throw new Error("paletteDiv is not defined"); | ||
} | ||
this.palette = this.initPalette(); | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the palette, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.palette.addEventListener = (/** | ||
* @param {?} DOMElement | ||
* @param {?} name | ||
* @param {?} listener | ||
* @param {?} capture | ||
* @return {?} | ||
*/ | ||
(DOMElement, name, listener, capture) => { | ||
/** @type {?} */ | ||
const superAddEventListener = go.Diagram.prototype.addEventListener; | ||
if (name === 'mousemove') { | ||
this.zone.runOutsideAngular((/** | ||
* @return {?} | ||
*/ | ||
() => superAddEventListener.call(this, DOMElement, name, listener, capture))); | ||
} | ||
else { | ||
this.zone.run((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
superAddEventListener.call(this, DOMElement, name, listener, capture); | ||
})); | ||
} | ||
}); | ||
if (!(this.palette instanceof go.Palette)) { | ||
throw new Error("initPalette function did not return a go.Palette"); | ||
} | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.palette, this.zone); | ||
// assign the Palette's div, which (among many other things) will attach a bunch of listeners to the canvas, | ||
@@ -79,84 +52,18 @@ // using the overridden addEventListener function above | ||
const divRef = this.paletteDiv.nativeElement; | ||
if (divRef == null) | ||
return; | ||
this.palette.div = divRef; | ||
// initialize palette model | ||
this.palette.delayInitialization((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
/** @type {?} */ | ||
const model = this.palette.model; | ||
model.commit((/** | ||
* @param {?} m | ||
* @return {?} | ||
*/ | ||
(m) => { | ||
m.mergeNodeDataArray(m.cloneDeep(this.nodeDataArray)); | ||
if (this.linkDataArray && m instanceof go.GraphLinksModel) { | ||
m.mergeLinkDataArray(m.cloneDeep(this.linkDataArray)); | ||
} | ||
if (this.modelData) { | ||
m.assignAllDataProperties(m.modelData, this.modelData); | ||
} | ||
this.palette.layoutDiagram(true); | ||
}), null); | ||
})); | ||
// initializer listener | ||
this.modelChangedListener = (/** | ||
* @param {?} e | ||
* @return {?} | ||
*/ | ||
(e) => { | ||
if (e.isTransactionFinished && this.palette && this.palette.model && !this.palette.model.isReadOnly) { | ||
// this must be done within a NgZone.run block, so changes are detected in the parent component | ||
this.zone.run((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
/** @type {?} */ | ||
const dataChanges = (/** @type {?} */ (e.model)).toIncrementalData(e); | ||
this.modelChange.emit(dataChanges); | ||
})); | ||
} | ||
}); | ||
this.palette.addModelChangedListener(this.modelChangedListener); | ||
} // end ngAfterViewInit | ||
// end ngAfterViewInit | ||
NgDiagramHelper.initializeModel(this.palette, this.nodeDataArray, this.linkDataArray, this.modelData); | ||
} | ||
/** | ||
* Always be checking if array Input data has changed (node and link data arrays) | ||
* If a change has occured on an \@Input property, merge the app-level changes with GoJS | ||
* @return {?} | ||
*/ | ||
ngDoCheck() { | ||
if (!this.palette) | ||
ngOnChanges() { | ||
if (!this.palette || !this.palette.model) | ||
return; | ||
if (!this.palette.model) | ||
return; | ||
// these need to be run each check, even if no merging happens | ||
// otherwise, they will detect all diffs that happened since last time skipsPaletteUpdate was false, | ||
// such as remove ops that happened in GoJS when skipsPaletteUpdate = true, | ||
// and then realllllly bad stuff happens (deleting random nodes, updating the wrong Parts) | ||
// Angular differs are a lot of fun | ||
/** @type {?} */ | ||
var nodeDiffs = this._ndaDiffer.diff(this.nodeDataArray); | ||
/** @type {?} */ | ||
var linkDiffs = this._ldaDiffer.diff(this.linkDataArray); | ||
/** @type {?} */ | ||
var modelDiffs = this._mdaDiffer.diff(this.modelData); | ||
if (!nodeDiffs && !linkDiffs && !modelDiffs) | ||
return; | ||
if (this.skipsPaletteUpdate) | ||
return; | ||
// don't need model change listener while performing known data updates | ||
if (this.modelChangedListener !== null) | ||
this.palette.model.removeChangedListener(this.modelChangedListener); | ||
this.palette.model.startTransaction('update data'); | ||
// update modelData first, in case bindings on nodes / links depend on model data | ||
this.palette.model.assignAllDataProperties(this.palette.model.modelData, this.modelData); | ||
DiagramComponent.mergeChanges(this, nodeDiffs, "n"); | ||
DiagramComponent.mergeChanges(this, linkDiffs, "l"); | ||
this.palette.model.commitTransaction('update data'); | ||
// reset the model change listener | ||
if (this.modelChangedListener !== null) | ||
this.palette.model.addChangedListener(this.modelChangedListener); | ||
} // end ngDoCheck | ||
// end ngDoCheck | ||
NgDiagramHelper.mergeAppDataWithModel(this); | ||
} // end ngOnChanges | ||
// end ngOnChanges | ||
/** | ||
@@ -177,3 +84,2 @@ * @return {?} | ||
PaletteComponent.ctorParameters = () => [ | ||
{ type: KeyValueDiffers }, | ||
{ type: NgZone } | ||
@@ -187,3 +93,2 @@ ]; | ||
divClassName: [{ type: Input }], | ||
skipsPaletteUpdate: [{ type: Input }], | ||
modelChange: [{ type: Output }], | ||
@@ -199,43 +104,40 @@ paletteDiv: [{ type: ViewChild, args: ['ngPalette', { static: true },] }] | ||
PaletteComponent.prototype.initPalette; | ||
/** @type {?} */ | ||
/** | ||
* Node data for palette | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.nodeDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Link data for palette. Optional. | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.linkDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Model data for palette. Optional. | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.modelData; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.skipsPaletteUpdate; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.modelChangedListener; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.modelChange; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.paletteDiv; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.palette; | ||
/** | ||
* Palette div class name. Use this name to style your palette in CSS | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._ndaDiffer; | ||
PaletteComponent.prototype.divClassName; | ||
/** | ||
* Event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._ldaDiffer; | ||
PaletteComponent.prototype.modelChange; | ||
/** | ||
* The DIV element holding the Palette | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._mdaDiffer; | ||
PaletteComponent.prototype.paletteDiv; | ||
/** | ||
* The Palette itself | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._kvdiffers; | ||
PaletteComponent.prototype.palette; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.zone; | ||
} | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFsZXR0ZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nb2pzLWFuZ3VsYXIvc3JjL2xpYi9wYWxldHRlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQWtCLGVBQWUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2SSxPQUFPLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUt2RCxNQUFNLE9BQU8sZ0JBQWdCOzs7OztJQXVDM0IsWUFBb0IsVUFBMkIsRUFBUyxJQUFZO1FBQWhELGVBQVUsR0FBVixVQUFVLENBQWlCO1FBQVMsU0FBSSxHQUFKLElBQUksQ0FBUTs7UUEzQnBELGtCQUFhLEdBQXlCLElBQUksQ0FBQzs7UUFHM0MsY0FBUyxHQUFrQixJQUFJLENBQUM7UUFLaEMsdUJBQWtCLEdBQVksS0FBSyxDQUFDOztRQUc3Qyx5QkFBb0IsR0FBd0MsSUFBSSxDQUFDOztRQUd2RCxnQkFBVyxHQUFxQyxJQUFJLFlBQVksRUFBc0IsQ0FBQzs7UUFLakcsWUFBTyxHQUFzQixJQUFJLENBQUM7UUFTdkMsd0VBQXdFO1FBQ3hFLDJFQUEyRTtRQUMzRSxtREFBbUQ7UUFDbkQsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNwRCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRXBELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUs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ciwgSW5wdXQsIEtleVZhbHVlRGlmZmVyLCBLZXlWYWx1ZURpZmZlcnMsIE5nWm9uZSwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0ICogYXMgZ28gZnJvbSAnZ29qcyc7XHJcbmltcG9ydCB7IERpYWdyYW1Db21wb25lbnQgfSBmcm9tICcuL2RpYWdyYW0uY29tcG9uZW50JztcclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdnb2pzLXBhbGV0dGUnLFxyXG4gIHRlbXBsYXRlOiAnPGRpdiAjbmdQYWxldHRlIFtjbGFzc05hbWVdPWRpdkNsYXNzTmFtZT48L2Rpdj4nXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQYWxldHRlQ29tcG9uZW50IHtcclxuXHJcbiAgLyoqXHJcbiAgICogUGFsZXR0ZSBpbml0aWFsaXphdGlvbiBmdW5jdGlvbi4gUmV0dXJucyBhIGdvLlBhbGV0dGUuXHJcbiAgICogRG8gbm90IGluaXRpYWxpemUgbW9kZWwgZGF0YSBpbiB0aGlzIGZ1bmN0aW9uLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBpbml0UGFsZXR0ZTogKCkgPT4gZ28uUGFsZXR0ZTtcclxuXHJcbiAgLy8gTm9kZSBkYXRhIGZvciBwYWxldHRlXHJcbiAgQElucHV0KCkgcHVibGljIG5vZGVEYXRhQXJyYXk6IEFycmF5PGdvLk9iamVjdERhdGE+O1xyXG5cclxuICAvLyBMaW5rIGRhdGEgZm9yIHBhbGV0dGUuIE9wdGlvbmFsXHJcbiAgQElucHV0KCkgcHVibGljIGxpbmtEYXRhQXJyYXk6IEFycmF5PGdvLk9iamVjdERhdGE+ID0gbnVsbDtcclxuXHJcbiAgLy8gTW9kZWwgZGF0YSBmb3IgcGFsZXR0ZS4gT3B0aW9uYWxcclxuICBASW5wdXQoKSBwdWJsaWMgbW9kZWxEYXRhOiBnby5PYmplY3REYXRhID0gbnVsbDtcclxuXHJcbiAgLy8gUGFsZXR0ZSBkaXYgY2xhc3MgbmFtZS4gVXNlIHRoaXMgbmFtZSB0byBzdHlsZSB5b3VyIHBhbGV0dGUgaW4gQ1NTXHJcbiAgQElucHV0KCkgcHVibGljIGRpdkNsYXNzTmFtZTogc3RyaW5nO1xyXG5cclxuICBASW5wdXQoKSBwdWJsaWMgc2tpcHNQYWxldHRlVXBkYXRlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8vIG1vZGVsIGNoYW5nZWQgbGlzdGVuZXIgZnVuY3Rpb24gZm9yIHBhbGV0dGVcclxuICBwdWJsaWMgbW9kZWxDaGFuZ2VkTGlzdGVuZXI6IChlOiBnby5DaGFuZ2VkRXZlbnQpID0+IHZvaWQgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gZXZlbnQgZW1pdHRlciAtLSBmaXJlcyB3aGVuIHBhbGV0dGUgbW9kZWwgY2hhbmdlcy4gQ2FwdHVyZSB0aGlzIGVtaXR0ZWQgZXZlbnQgaW4gcGFyZW50IGNvbXBvbmVudFxyXG4gIEBPdXRwdXQoKSBwdWJsaWMgbW9kZWxDaGFuZ2U6IEV2ZW50RW1pdHRlcjxnby5JbmNyZW1lbnRhbERhdGE+ID0gbmV3IEV2ZW50RW1pdHRlcjxnby5JbmNyZW1lbnRhbERhdGE+KCk7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ25nUGFsZXR0ZScsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyBwYWxldHRlRGl2OiBFbGVtZW50UmVmO1xyXG5cclxuICAvLyBUaGUgUGFsZXR0ZSBpdHNlbGZcclxuICBwdWJsaWMgcGFsZXR0ZTogZ28uUGFsZXR0ZSB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBkaWZmZXJzIGZvciBhcnJheSBpbnB1dHMgKG5vZGUgLyBsaW5rIGRhdGEgYXJyYXlzKVxyXG4gIHByaXZhdGUgX25kYURpZmZlcjogS2V5VmFsdWVEaWZmZXI8c3RyaW5nLCBhbnk+O1xyXG4gIHByaXZhdGUgX2xkYURpZmZlcjogS2V5VmFsdWVEaWZmZXI8c3RyaW5nLCBhbnk+O1xyXG5cclxuICBwcml2YXRlIF9tZGFEaWZmZXI6IEtleVZhbHVlRGlmZmVyPHN0cmluZywgYW55PjtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfa3ZkaWZmZXJzOiBLZXlWYWx1ZURpZmZlcnMsIHB1YmxpYyB6b25lOiBOZ1pvbmUpIHtcclxuICAgIC8vIGRpZmZlcnMgdXNlZCB0byBjaGVjayBpZiB0aGVyZSBoYXZlIGJlZW4gY2hhbmdlZCB0byB0aGUgYXJyYXkgQElucHV0c1xyXG4gICAgLy8gd2l0aG91dCB0aGVtLCBjaGFuZ2VzIHRvIHRoZSBpbnB1dCBhcnJheXMgd29uJ3QgcmVnaXN0ZXIgaW4gbmdPbkNoYW5nZXMsXHJcbiAgICAvLyBzaW5jZSB0aGUgYXJyYXkgcmVmZXJlbmNlIGl0c2VsZiBtYXkgYmUgdGhlIHNhbWVcclxuICAgIHRoaXMuX25kYURpZmZlciA9IHRoaXMuX2t2ZGlmZmVycy5maW5kKFtdKS5jcmVhdGUoKTtcclxuICAgIHRoaXMuX2xkYURpZmZlciA9IHRoaXMuX2t2ZGlmZmVycy5maW5kKFtdKS5jcmVhdGUoKTtcclxuXHJcbiAgICB0aGlzLl9tZGFEaWZmZXIgPSB0aGlzLl9rdmRpZmZlcnMuZmluZChbXSkuY3JlYXRlKCk7XHJcblxyXG4gIH0gLy8gZW5kIGNvbnN0cnVjdG9yXHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemUgUGFsZXR0ZSBhZnRlciB2aWV3IGluaXRcclxuICAgKi9cclxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCkge1xyXG4gICAgaWYgKCF0aGlzLnBhbGV0dGVEaXYpIHJldHVybjtcclxuXHJcbiAgICB0aGlzLnBhbGV0dGUgPSB0aGlzLmluaXRQYWxldHRlKCk7XHJcblxyXG4gICAgLy8gVGhpcyBiaXQgb2YgY29kZSBtYWtlcyBzdXJlIHRoZSBtb3VzZW1vdmUgZXZlbnQgbGlzdGVuZXJzIG9uIHRoZSBjYW52YXMgYXJlIHJ1biBvdXRzaWRlIE5nWm9uZVxyXG4gICAgLy8gVGhpcyBtYWtlcyBpdCBzbyBjaGFuZ2UgZGV0ZWN0aW9uIGlzbid0IHRyaWdnZXJlZCBldmVyeSB0aW1lIHRoZSBtb3VzZSBpcyBtb3ZlZCBpbnNpZGUgdGhlIGNhbnZhcywgZ3JlYXRseSBpbXByb3ZpbmcgcGVyZm9ybWFuY2VcclxuICAgIC8vIElmIHNvbWUgc3RhdGUtYWx0ZXJpbmcgYmVoYXZpb3IgbXVzdCBoYXBwZW4gb24gYSBtb3VzZW1vdmUgZXZlbnQgaW5zaWRlIHRoZSBwYWxldHRlLFxyXG4gICAgLy8geW91IHdpbGwgaGF2ZSB0byB1c2luZyB6b25lLnJ1bigpIHRvIG1ha2Ugc3VyZSB0aGF0IGV2ZW50IHRyaWdnZXJzIGFuZ3VsYXIgY2hhbmdlIGRldGVjdGlvblxyXG4gICAgdGhpcy5wYWxldHRlLmFkZEV2ZW50TGlzdGVuZXIgPSAoRE9NRWxlbWVudDogRWxlbWVudCB8IFdpbmRvdyB8IERvY3VtZW50LCBuYW1lOiBzdHJpbmcsIGxpc3RlbmVyOiBhbnksIGNhcHR1cmU6IGJvb2xlYW4pID0+IHtcclxuICAgICAgY29uc3Qgc3VwZXJBZGRFdmVudExpc3RlbmVyID0gZ28uRGlhZ3JhbS5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lcjtcclxuICAgICAgaWYgKG5hbWUgPT09ICdtb3VzZW1vdmUnKSB7XHJcbiAgICAgICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHN1cGVyQWRkRXZlbnRMaXN0ZW5lci5jYWxsKHRoaXMsIERPTUVsZW1lbnQsIG5hbWUsIGxpc3RlbmVyLCBjYXB0dXJlKSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICBzdXBlckFkZEV2ZW50TGlzdGVuZXIuY2FsbCh0aGlzLCBET01FbGVtZW50LCBuYW1lLCBsaXN0ZW5lciwgY2FwdHVyZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLy8gYXNzaWduIHRoZSBQYWxldHRlJ3MgZGl2LCB3aGljaCAoYW1vbmcgbWFueSBvdGhlciB0aGluZ3MpIHdpbGwgYXR0YWNoIGEgYnVuY2ggb2YgbGlzdGVuZXJzIHRvIHRoZSBjYW52YXMsXHJcbiAgICAvLyB1c2luZyB0aGUgb3ZlcnJpZGRlbiBhZGRFdmVudExpc3RlbmVyIGZ1bmN0aW9uIGFib3ZlXHJcbiAgICBjb25zdCBkaXZSZWYgPSB0aGlzLnBhbGV0dGVEaXYubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMucGFsZXR0ZS5kaXYgPSBkaXZSZWY7XHJcblxyXG4gICAgLy8gaW5pdGlhbGl6ZSBwYWxldHRlIG1vZGVsXHJcbiAgICB0aGlzLnBhbGV0dGUuZGVsYXlJbml0aWFsaXphdGlvbigoKSA9PiB7XHJcbiAgICAgIGNvbnN0IG1vZGVsID0gdGhpcy5wYWxldHRlLm1vZGVsO1xyXG4gICAgICBtb2RlbC5jb21taXQoKG06IGdvLk1vZGVsKSA9PiB7XHJcbiAgICAgICAgbS5tZXJnZU5vZGVEYXRhQXJyYXkobS5jbG9uZURlZXAodGhpcy5ub2RlRGF0YUFycmF5KSk7XHJcbiAgICAgICAgaWYgKHRoaXMubGlua0RhdGFBcnJheSAmJiBtIGluc3RhbmNlb2YgZ28uR3JhcGhMaW5rc01vZGVsKSB7XHJcbiAgICAgICAgICBtLm1lcmdlTGlua0RhdGFBcnJheShtLmNsb25lRGVlcCh0aGlzLmxpbmtEYXRhQXJyYXkpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHRoaXMubW9kZWxEYXRhKSB7XHJcbiAgICAgICAgICBtLmFzc2lnbkFsbERhdGFQcm9wZXJ0aWVzKG0ubW9kZWxEYXRhLCB0aGlzLm1vZGVsRGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucGFsZXR0ZS5sYXlvdXREaWFncmFtKHRydWUpO1xyXG4gICAgICB9LCBudWxsKTtcclxuICAgIH0pO1xyXG5cclxuXHJcbiAgICAvLyBpbml0aWFsaXplciBsaXN0ZW5lclxyXG4gICAgdGhpcy5tb2RlbENoYW5nZWRMaXN0ZW5lciA9IChlOiBnby5DaGFuZ2VkRXZlbnQpID0+IHtcclxuICAgICAgaWYgKGUuaXNUcmFuc2FjdGlvbkZpbmlzaGVkICYmIHRoaXMucGFsZXR0ZSAmJiB0aGlzLnBhbGV0dGUubW9kZWwgJiYgIXRoaXMucGFsZXR0ZS5tb2RlbC5pc1JlYWRPbmx5KSB7XHJcbiAgICAgICAgLy8gdGhpcyBtdXN0IGJlIGRvbmUgd2l0aGluIGEgTmdab25lLnJ1biBibG9jaywgc28gY2hhbmdlcyBhcmUgZGV0ZWN0ZWQgaW4gdGhlIHBhcmVudCBjb21wb25lbnRcclxuICAgICAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcclxuICAgICAgICAgIGNvbnN0IGRhdGFDaGFuZ2VzID0gZS5tb2RlbCEudG9JbmNyZW1lbnRhbERhdGEoZSk7XHJcbiAgICAgICAgICB0aGlzLm1vZGVsQ2hhbmdlLmVtaXQoZGF0YUNoYW5nZXMpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhpcy5wYWxldHRlLmFkZE1vZGVsQ2hhbmdlZExpc3RlbmVyKHRoaXMubW9kZWxDaGFuZ2VkTGlzdGVuZXIpO1xyXG4gIH0gLy8gZW5kIG5nQWZ0ZXJWaWV3SW5pdFxyXG5cclxuICAvKipcclxuICAgKiBBbHdheXMgYmUgY2hlY2tpbmcgaWYgYXJyYXkgSW5wdXQgZGF0YSBoYXMgY2hhbmdlZCAobm9kZSBhbmQgbGluayBkYXRhIGFycmF5cylcclxuICAgKi9cclxuICBwdWJsaWMgbmdEb0NoZWNrKCkge1xyXG5cclxuICAgIGlmICghdGhpcy5wYWxldHRlKSByZXR1cm47XHJcbiAgICBpZiAoIXRoaXMucGFsZXR0ZS5tb2RlbCkgcmV0dXJuO1xyXG5cclxuICAgIC8vIHRoZXNlIG5lZWQgdG8gYmUgcnVuIGVhY2ggY2hlY2ssIGV2ZW4gaWYgbm8gbWVyZ2luZyBoYXBwZW5zXHJcbiAgICAvLyBvdGhlcndpc2UsIHRoZXkgd2lsbCBkZXRlY3QgYWxsIGRpZmZzIHRoYXQgaGFwcGVuZWQgc2luY2UgbGFzdCB0aW1lIHNraXBzUGFsZXR0ZVVwZGF0ZSB3YXMgZmFsc2UsXHJcbiAgICAvLyBzdWNoIGFzIHJlbW92ZSBvcHMgdGhhdCBoYXBwZW5lZCBpbiBHb0pTIHdoZW4gc2tpcHNQYWxldHRlVXBkYXRlID0gdHJ1ZSwgXHJcbiAgICAvLyBhbmQgdGhlbiByZWFsbGxsbGx5IGJhZCBzdHVmZiBoYXBwZW5zIChkZWxldGluZyByYW5kb20gbm9kZXMsIHVwZGF0aW5nIHRoZSB3cm9uZyBQYXJ0cylcclxuICAgIC8vIEFuZ3VsYXIgZGlmZmVycyBhcmUgYSBsb3Qgb2YgZnVuXHJcbiAgICB2YXIgbm9kZURpZmZzID0gdGhpcy5fbmRhRGlmZmVyLmRpZmYodGhpcy5ub2RlRGF0YUFycmF5KTtcclxuICAgIHZhciBsaW5rRGlmZnMgPSB0aGlzLl9sZGFEaWZmZXIuZGlmZih0aGlzLmxpbmtEYXRhQXJyYXkpO1xyXG5cclxuICAgIHZhciBtb2RlbERpZmZzID0gdGhpcy5fbWRhRGlmZmVyLmRpZmYodGhpcy5tb2RlbERhdGEpO1xyXG5cclxuICAgIGlmICghbm9kZURpZmZzICYmICFsaW5rRGlmZnMgJiYgIW1vZGVsRGlmZnMpIHJldHVybjtcclxuXHJcbiAgICBpZiAodGhpcy5za2lwc1BhbGV0dGVVcGRhdGUpIHJldHVybjtcclxuXHJcbiAgICAvLyBkb24ndCBuZWVkIG1vZGVsIGNoYW5nZSBsaXN0ZW5lciB3aGlsZSBwZXJmb3JtaW5nIGtub3duIGRhdGEgdXBkYXRlc1xyXG4gICAgaWYgKHRoaXMubW9kZWxDaGFuZ2VkTGlzdGVuZXIgIT09IG51bGwpIHRoaXMucGFsZXR0ZS5tb2RlbC5yZW1vdmVDaGFuZ2VkTGlzdGVuZXIodGhpcy5tb2RlbENoYW5nZWRMaXN0ZW5lcik7XHJcblxyXG4gICAgdGhpcy5wYWxldHRlLm1vZGVsLnN0YXJ0VHJhbnNhY3Rpb24oJ3VwZGF0ZSBkYXRhJyk7XHJcbiAgICAvLyB1cGRhdGUgbW9kZWxEYXRhIGZpcnN0LCBpbiBjYXNlIGJpbmRpbmdzIG9uIG5vZGVzIC8gbGlua3MgZGVwZW5kIG9uIG1vZGVsIGRhdGFcclxuICAgIHRoaXMucGFsZXR0ZS5tb2RlbC5hc3NpZ25BbGxEYXRhUHJvcGVydGllcyh0aGlzLnBhbGV0dGUubW9kZWwubW9kZWxEYXRhLCB0aGlzLm1vZGVsRGF0YSk7XHJcbiAgICBEaWFncmFtQ29tcG9uZW50Lm1lcmdlQ2hhbmdlcyh0aGlzLCBub2RlRGlmZnMsIFwiblwiKTtcclxuICAgIERpYWdyYW1Db21wb25lbnQubWVyZ2VDaGFuZ2VzKHRoaXMsIGxpbmtEaWZmcywgXCJsXCIpO1xyXG4gICAgdGhpcy5wYWxldHRlLm1vZGVsLmNvbW1pdFRyYW5zYWN0aW9uKCd1cGRhdGUgZGF0YScpO1xyXG4gICAgLy8gcmVzZXQgdGhlIG1vZGVsIGNoYW5nZSBsaXN0ZW5lclxyXG4gICAgaWYgKHRoaXMubW9kZWxDaGFuZ2VkTGlzdGVuZXIgIT09IG51bGwpIHRoaXMucGFsZXR0ZS5tb2RlbC5hZGRDaGFuZ2VkTGlzdGVuZXIodGhpcy5tb2RlbENoYW5nZWRMaXN0ZW5lcik7XHJcblxyXG4gIH0gLy8gZW5kIG5nRG9DaGVja1xyXG5cclxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLnBhbGV0dGUuZGl2ID0gbnVsbDsgLy8gcmVtb3ZlcyBldmVudCBsaXN0ZW5lcnNcclxuICB9XHJcblxyXG59XHJcbiJdfQ== | ||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFsZXR0ZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9nb2pzLWFuZ3VsYXIvc3JjL2xpYi9wYWxldHRlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEcsT0FBTyxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0IsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBS3RELE1BQU0sT0FBTyxnQkFBZ0I7Ozs7SUF3QjNCLFlBQW1CLElBQVk7UUFBWixTQUFJLEdBQUosSUFBSSxDQUFROzs7O1FBZGYsa0JBQWEsR0FBeUIsSUFBSSxDQUFDOzs7O1FBRTNDLGNBQVMsR0FBa0IsSUFBSSxDQUFDOzs7O1FBSy9CLGdCQUFXLEdBQXFDLElBQUksWUFBWSxFQUFzQixDQUFDOzs7O1FBS2pHLFlBQU8sR0FBc0IsSUFBSSxDQUFDO0lBRUwsQ0FBQzs7Ozs7SUFLOUIsZUFBZTtRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7U0FDOUM7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNsQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxZQUFZLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUN6QyxNQUFNLElBQUksS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7U0FDckU7UUFFRCxnRUFBZ0U7UUFDaEUsZUFBZSxDQUFDLGtDQUFrQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDOzs7O2NBSXRFLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWE7UUFDNUMsSUFBSSxNQUFNLElBQUksSUFBSTtZQUFFLE9BQU87UUFDM0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsTUFBTSxDQUFDO1FBRTFCLDJCQUEyQjtRQUMzQixlQUFlLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN4RyxDQUFDOzs7OztJQUtNLFdBQVc7UUFDaEIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUs7WUFBRSxPQUFPO1FBQ2pELGVBQWUsQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5QyxDQUFDLENBQUMsbUJBQW1COzs7OztJQUdkLFdBQVc7UUFDaEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsMEJBQTBCO0lBQ3JELENBQUM7OztZQWxFRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGNBQWM7Z0JBQ3hCLFFBQVEsRUFBRSxpREFBaUQ7YUFDNUQ7Ozs7WUFOb0QsTUFBTTs7OzBCQWF4RCxLQUFLOzRCQUVMLEtBQUs7NEJBRUwsS0FBSzt3QkFFTCxLQUFLOzJCQUVMLEtBQUs7MEJBR0wsTUFBTTt5QkFFTixTQUFTLFNBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTs7Ozs7Ozs7SUFieEMsdUNBQThDOzs7OztJQUU5Qyx5Q0FBb0Q7Ozs7O0lBRXBELHlDQUEyRDs7Ozs7SUFFM0QscUNBQWdEOzs7OztJQUVoRCx3Q0FBcUM7Ozs7O0lBR3JDLHVDQUF3Rzs7Ozs7SUFFeEcsc0NBQXdFOzs7OztJQUd4RSxtQ0FBeUM7O0lBRTdCLGdDQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgTmdab25lLCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgKiBhcyBnbyBmcm9tICdnb2pzJztcclxuaW1wb3J0IHsgTmdEaWFncmFtSGVscGVyIH0gZnJvbSAnLi9uZy1kaWFncmFtLWhlbHBlcic7XHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnZ29qcy1wYWxldHRlJyxcclxuICB0ZW1wbGF0ZTogJzxkaXYgI25nUGFsZXR0ZSBbY2xhc3NOYW1lXT1kaXZDbGFzc05hbWU+PC9kaXY+J1xyXG59KVxyXG5leHBvcnQgY2xhc3MgUGFsZXR0ZUNvbXBvbmVudCB7XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhbGV0dGUgaW5pdGlhbGl6YXRpb24gZnVuY3Rpb24uIFJldHVybnMgYSBnby5QYWxldHRlLlxyXG4gICAqIERvIG5vdCBpbml0aWFsaXplIG1vZGVsIGRhdGEgaW4gdGhpcyBmdW5jdGlvbi5cclxuICAgKi9cclxuICBASW5wdXQoKSBwdWJsaWMgaW5pdFBhbGV0dGU6ICgpID0+IGdvLlBhbGV0dGU7XHJcbiAgLyoqIE5vZGUgZGF0YSBmb3IgcGFsZXR0ZSAqL1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBub2RlRGF0YUFycmF5OiBBcnJheTxnby5PYmplY3REYXRhPjtcclxuICAvKiogTGluayBkYXRhIGZvciBwYWxldHRlLiBPcHRpb25hbC4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgbGlua0RhdGFBcnJheTogQXJyYXk8Z28uT2JqZWN0RGF0YT4gPSBudWxsO1xyXG4gIC8qKiBNb2RlbCBkYXRhIGZvciBwYWxldHRlLiBPcHRpb25hbC4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgbW9kZWxEYXRhOiBnby5PYmplY3REYXRhID0gbnVsbDtcclxuICAvKiogUGFsZXR0ZSBkaXYgY2xhc3MgbmFtZS4gVXNlIHRoaXMgbmFtZSB0byBzdHlsZSB5b3VyIHBhbGV0dGUgaW4gQ1NTICovXHJcbiAgQElucHV0KCkgcHVibGljIGRpdkNsYXNzTmFtZTogc3RyaW5nO1xyXG5cclxuICAvKiogRXZlbnQgZW1pdHRlciAtLSBmaXJlcyB3aGVuIHBhbGV0dGUgbW9kZWwgY2hhbmdlcy4gQ2FwdHVyZSB0aGlzIGVtaXR0ZWQgZXZlbnQgaW4gcGFyZW50IGNvbXBvbmVudCAqL1xyXG4gIEBPdXRwdXQoKSBwdWJsaWMgbW9kZWxDaGFuZ2U6IEV2ZW50RW1pdHRlcjxnby5JbmNyZW1lbnRhbERhdGE+ID0gbmV3IEV2ZW50RW1pdHRlcjxnby5JbmNyZW1lbnRhbERhdGE+KCk7XHJcbiAgLyoqIFRoZSBESVYgZWxlbWVudCBob2xkaW5nIHRoZSBQYWxldHRlICovXHJcbiAgQFZpZXdDaGlsZCgnbmdQYWxldHRlJywgeyBzdGF0aWM6IHRydWUgfSkgcHVibGljIHBhbGV0dGVEaXY6IEVsZW1lbnRSZWY7XHJcblxyXG4gIC8qKiBUaGUgUGFsZXR0ZSBpdHNlbGYgKi9cclxuICBwdWJsaWMgcGFsZXR0ZTogZ28uUGFsZXR0ZSB8IG51bGwgPSBudWxsO1xyXG5cclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgem9uZTogTmdab25lKSB7ICB9IFxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplIFBhbGV0dGUgYWZ0ZXIgdmlldyBpbml0XHJcbiAgICovXHJcbiAgcHVibGljIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgIGlmICghdGhpcy5wYWxldHRlRGl2KSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInBhbGV0dGVEaXYgaXMgbm90IGRlZmluZWRcIik7XHJcbiAgICB9XHJcbiAgICB0aGlzLnBhbGV0dGUgPSB0aGlzLmluaXRQYWxldHRlKCk7XHJcbiAgICBpZiAoISh0aGlzLnBhbGV0dGUgaW5zdGFuY2VvZiBnby5QYWxldHRlKSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbml0UGFsZXR0ZSBmdW5jdGlvbiBkaWQgbm90IHJldHVybiBhIGdvLlBhbGV0dGVcIik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gcmVkdWNlcyBjaGFuZ2UgZGV0ZWN0aW9uIG9uIG1vdXNlIG1vdmVzLCBib29zdGluZyBwZXJmb3JtYW5jZVxyXG4gICAgTmdEaWFncmFtSGVscGVyLm1ha2VNb3VzZU1vdmVSdW5PdXRzaWRlQW5ndWxhclpvbmUodGhpcy5wYWxldHRlLCB0aGlzLnpvbmUpO1xyXG5cclxuICAgIC8vIGFzc2lnbiB0aGUgUGFsZXR0ZSdzIGRpdiwgd2hpY2ggKGFtb25nIG1hbnkgb3RoZXIgdGhpbmdzKSB3aWxsIGF0dGFjaCBhIGJ1bmNoIG9mIGxpc3RlbmVycyB0byB0aGUgY2FudmFzLFxyXG4gICAgLy8gdXNpbmcgdGhlIG92ZXJyaWRkZW4gYWRkRXZlbnRMaXN0ZW5lciBmdW5jdGlvbiBhYm92ZVxyXG4gICAgY29uc3QgZGl2UmVmID0gdGhpcy5wYWxldHRlRGl2Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBpZiAoZGl2UmVmID09IG51bGwpIHJldHVybjtcclxuICAgIHRoaXMucGFsZXR0ZS5kaXYgPSBkaXZSZWY7XHJcblxyXG4gICAgLy8gaW5pdGlhbGl6ZSBwYWxldHRlIG1vZGVsXHJcbiAgICBOZ0RpYWdyYW1IZWxwZXIuaW5pdGlhbGl6ZU1vZGVsKHRoaXMucGFsZXR0ZSwgdGhpcy5ub2RlRGF0YUFycmF5LCB0aGlzLmxpbmtEYXRhQXJyYXksIHRoaXMubW9kZWxEYXRhKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIElmIGEgY2hhbmdlIGhhcyBvY2N1cmVkIG9uIGFuIEBJbnB1dCBwcm9wZXJ0eSwgbWVyZ2UgdGhlIGFwcC1sZXZlbCBjaGFuZ2VzIHdpdGggR29KU1xyXG4gICAqL1xyXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcygpIHtcclxuICAgIGlmICghdGhpcy5wYWxldHRlIHx8ICF0aGlzLnBhbGV0dGUubW9kZWwpIHJldHVybjtcclxuICAgIE5nRGlhZ3JhbUhlbHBlci5tZXJnZUFwcERhdGFXaXRoTW9kZWwodGhpcyk7XHJcbiAgfSAvLyBlbmQgbmdPbkNoYW5nZXMgXHJcbiAgXHJcblxyXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMucGFsZXR0ZS5kaXYgPSBudWxsOyAvLyByZW1vdmVzIGV2ZW50IGxpc3RlbmVyc1xyXG4gIH1cclxuXHJcbn1cclxuIl19 |
@@ -1,46 +0,45 @@ | ||
import { EventEmitter, Component, KeyValueDiffers, NgZone, Input, Output, ViewChild, Injectable, NgModule } from '@angular/core'; | ||
import { Diagram, GraphLinksModel, Overview, Spot, Map } from 'gojs'; | ||
import { EventEmitter, Component, NgZone, Input, Output, ViewChild, Injectable, NgModule } from '@angular/core'; | ||
import { Diagram, GraphLinksModel, Palette, Overview, Spot, Map } from 'gojs'; | ||
import produce from 'immer'; | ||
/** | ||
* @fileoverview added by tsickle | ||
* Generated from: lib/diagram.component.ts | ||
* Generated from: lib/ng-diagram-helper.ts | ||
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc | ||
*/ | ||
class DiagramComponent { | ||
/** | ||
* An interface to allow methods defined below to accept Palette or Diagram Components, | ||
* without requiring DiagramComponent or PaletteComponent directly in this file | ||
* (that would create a circular dependency) | ||
* @record | ||
*/ | ||
function IDiagramOrPaletteComponent() { } | ||
if (false) { | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.modelChange; | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.zone; | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.nodeDataArray; | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.linkDataArray; | ||
/** @type {?} */ | ||
IDiagramOrPaletteComponent.prototype.modelData; | ||
} | ||
/** | ||
* Defines some shared helper static functions, used in Diagram / Palette / Overview Components | ||
*/ | ||
class NgDiagramHelper { | ||
constructor() { } | ||
/** | ||
* @param {?} _kvdiffers | ||
* Ensures mousemove event listeners on a diagram's canvas are run outside NgZone. | ||
* This way, change detection isn't triggered on each mousemove, improving performance. | ||
* If some state-alteration must happen on a mousemove event inside the diagram, use zone.run() to make sure the event triggers angular change detection. | ||
* Used by DiagramComponent, PaletteComponent, and OverviewComponent in their ngAfterViewInit lifecycle hooks | ||
* @param {?} diagram | ||
* @param {?} zone | ||
*/ | ||
constructor(_kvdiffers, zone) { | ||
this._kvdiffers = _kvdiffers; | ||
this.zone = zone; | ||
// Link data for diagram | ||
this.linkDataArray = null; // optional | ||
// optional | ||
// Model data for diagram | ||
this.modelData = null; // optional | ||
// model changed listener function for diagram | ||
this.modelChangedListener = null; | ||
this.skipsDiagramUpdate = false; | ||
// event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
this.modelChange = new EventEmitter(); | ||
this.diagram = null; | ||
// differs used to check if there have been changed to the array @Inputs | ||
// without them, changes to the input arrays won't register in ngOnChanges, | ||
// since the array reference itself may be the same | ||
this._ndaDiffer = this._kvdiffers.find([]).create(); | ||
this._ldaDiffer = this._kvdiffers.find([]).create(); | ||
this._mdaDiffer = this._kvdiffers.find([]).create(); | ||
} | ||
/** | ||
* Initializes diagram / model after view init | ||
* @return {?} | ||
*/ | ||
ngAfterViewInit() { | ||
this.diagram = this.initDiagram(); | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the diagram, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.diagram.addEventListener = (/** | ||
static makeMouseMoveRunOutsideAngularZone(diagram, zone) { | ||
diagram.addEventListener = (/** | ||
* @param {?} DOMElement | ||
@@ -56,3 +55,3 @@ * @param {?} name | ||
if (name === 'mousemove') { | ||
this.zone.runOutsideAngular((/** | ||
zone.runOutsideAngular((/** | ||
* @return {?} | ||
@@ -63,3 +62,3 @@ */ | ||
else { | ||
this.zone.run((/** | ||
zone.run((/** | ||
* @return {?} | ||
@@ -72,11 +71,13 @@ */ | ||
}); | ||
// assign the Diagram's div, which (among many other things) will attach a bunch of listeners to the canvas, | ||
// using the overridden addEventListener function above | ||
/** @type {?} */ | ||
const divRef = this.diagramDiv.nativeElement; | ||
if (divRef === null) | ||
return; | ||
this.diagram.div = divRef; | ||
// initialize the Diagram's model | ||
this.diagram.delayInitialization((/** | ||
} | ||
/** | ||
* Initialize a given diagram's model with given node / link / model data | ||
* @param {?} diagram | ||
* @param {?} nodeDataArray | ||
* @param {?} linkDataArray | ||
* @param {?} modelData | ||
* @return {?} | ||
*/ | ||
static initializeModel(diagram, nodeDataArray, linkDataArray, modelData) { | ||
diagram.delayInitialization((/** | ||
* @return {?} | ||
@@ -86,3 +87,3 @@ */ | ||
/** @type {?} */ | ||
const model = this.diagram.model; | ||
const model = diagram.model; | ||
model.commit((/** | ||
@@ -93,14 +94,28 @@ * @param {?} m | ||
(m) => { | ||
m.mergeNodeDataArray(m.cloneDeep(this.nodeDataArray)); | ||
if (this.linkDataArray && m instanceof GraphLinksModel) { | ||
m.mergeLinkDataArray(m.cloneDeep(this.linkDataArray)); | ||
m.mergeNodeDataArray(m.cloneDeep(nodeDataArray)); | ||
if (linkDataArray && m instanceof GraphLinksModel) { | ||
m.mergeLinkDataArray(m.cloneDeep(linkDataArray)); | ||
} | ||
if (this.modelData) { | ||
m.assignAllDataProperties(m.modelData, this.modelData); | ||
if (modelData) { | ||
m.assignAllDataProperties(m.modelData, modelData); | ||
} | ||
this.diagram.layoutDiagram(true); | ||
}), null); | ||
})); | ||
// initializer listener | ||
this.modelChangedListener = (/** | ||
} | ||
/** | ||
* Initialize the model changed listener for the Palette / Diagram of a given compoennt; ensure it runs inside the component's ngZone. | ||
* Those changes will be emitted through a the component's modelChange EventEmitter. | ||
* @param {?} component | ||
* @return {?} | ||
*/ | ||
static initializeModelChangedListener(component) { | ||
/** @type {?} */ | ||
var diagram = null; | ||
if (!(component.hasOwnProperty("diagram")) && !(component.hasOwnProperty("palette"))) | ||
return; | ||
if (component.hasOwnProperty("diagram")) | ||
diagram = component["diagram"]; | ||
if (component.hasOwnProperty("palette")) | ||
diagram = component["palette"]; | ||
component.modelChangedListener = (/** | ||
* @param {?} e | ||
@@ -110,5 +125,5 @@ * @return {?} | ||
(e) => { | ||
if (e.isTransactionFinished && this.diagram && this.diagram.model && !this.diagram.model.isReadOnly) { | ||
if (e.isTransactionFinished && diagram && diagram.model && !diagram.model.isReadOnly) { | ||
// this must be done within a NgZone.run block, so changes are detected in the parent component | ||
this.zone.run((/** | ||
component.zone.run((/** | ||
* @return {?} | ||
@@ -119,203 +134,113 @@ */ | ||
const dataChanges = (/** @type {?} */ (e.model)).toIncrementalData(e); | ||
this.modelChange.emit(dataChanges); | ||
component.modelChange.emit(dataChanges); | ||
})); | ||
} | ||
}); | ||
this.diagram.addModelChangedListener(this.modelChangedListener); | ||
} // end ngAfterViewInit | ||
// end ngAfterViewInit | ||
diagram.addModelChangedListener(component.modelChangedListener); | ||
} | ||
/** | ||
* Merges changes from app data into GoJS model data, | ||
* making sure only actual changes (and not falsely flagged no-ops on array / obj data props) are logged | ||
* @param {?} component an instance of DiagramComponent or PaletteComponent | ||
* @param {?} kvchanges The kvchanges object produced by either a node or link Angular differ object | ||
* @param {?} str "n" for node data changes, "l" for link data changes | ||
* | ||
* Merge the app-level node / link / model data of a supplied Diagram|Palette Component with its underlying Diagram|Palette model data | ||
* @param {?} component | ||
* @return {?} | ||
*/ | ||
static mergeChanges(component, kvchanges, str) { | ||
// helper function | ||
static mergeAppDataWithModel(component) { | ||
/** @type {?} */ | ||
var diagram = null; | ||
if (component.hasOwnProperty("diagram")) | ||
diagram = component["diagram"]; | ||
if (component.hasOwnProperty("palette")) | ||
diagram = component["palette"]; | ||
// don't need model change listener while performing known data updates | ||
/** @type {?} */ | ||
const mcl = component instanceof DiagramComponent ? component.modelChangedListener : null; | ||
if (mcl !== null) | ||
diagram.model.removeChangedListener(mcl); | ||
diagram.model.startTransaction('update data'); | ||
// update modelData first, in case bindings on nodes / links depend on model data | ||
diagram.model.assignAllDataProperties(diagram.model.modelData, component.modelData); | ||
// merge node / link data | ||
diagram.model.mergeNodeDataArray(component.nodeDataArray); | ||
if (component.linkDataArray && diagram.model instanceof GraphLinksModel) { | ||
diagram.model.mergeLinkDataArray(component.linkDataArray); | ||
} | ||
diagram.model.commitTransaction('update data'); | ||
// reset the model change listener | ||
if (mcl !== null) | ||
diagram.model.addChangedListener(mcl); | ||
} | ||
} | ||
/** | ||
* @fileoverview added by tsickle | ||
* Generated from: lib/diagram.component.ts | ||
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc | ||
*/ | ||
class DiagramComponent { | ||
/** | ||
* @param {?} zone | ||
*/ | ||
constructor(zone) { | ||
this.zone = zone; | ||
/** | ||
* @param {?} obj1 | ||
* @param {?} obj2 | ||
* @return {?} | ||
* Link data for diagram. Optional. | ||
*/ | ||
function compareObjs(obj1, obj2) { | ||
if (!obj1 || !obj2) | ||
return false; | ||
// Loop through properties in object 1 | ||
for (const p in obj1) { | ||
// Check property exists on both objects | ||
if (obj1.hasOwnProperty(p) !== obj2.hasOwnProperty(p)) | ||
return false; | ||
switch (typeof (obj1[p])) { | ||
// Deep compare objects | ||
case 'object': | ||
if (!compareObjs(obj1[p], obj2[p])) | ||
return false; | ||
break; | ||
// Compare values | ||
default: | ||
if (obj1[p] !== obj2[p]) | ||
return false; | ||
} | ||
} | ||
// Check object 2 for any extra properties | ||
for (const p in obj2) { | ||
if (typeof (obj1[p]) === 'undefined') | ||
return false; | ||
} | ||
return true; | ||
this.linkDataArray = null; | ||
/** | ||
* Model data for diagram. Optional. | ||
*/ | ||
this.modelData = null; | ||
/** | ||
* Model changed listener function for diagram | ||
*/ | ||
this.modelChangedListener = null; | ||
/** | ||
* Whether or not to skip merging app data with GoJS model data (set to true if update is coming from GoJS, false if coming from app-level, usually) | ||
*/ | ||
this.skipsDiagramUpdate = false; | ||
/** | ||
* Event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
*/ | ||
this.modelChange = new EventEmitter(); | ||
/** | ||
* The Diagram itself | ||
*/ | ||
this.diagram = null; | ||
} | ||
/** | ||
* Initializes diagram / model after view init | ||
* @return {?} | ||
*/ | ||
ngAfterViewInit() { | ||
if (!this.diagramDiv) { | ||
throw new Error("diagramDiv is not defined"); | ||
} | ||
this.diagram = this.initDiagram(); | ||
if (!(this.diagram instanceof Diagram)) { | ||
throw new Error("initDiagram function did not return a go.Diagram"); | ||
} | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.diagram, this.zone); | ||
// assign the Diagram's div, which (among many other things) will attach a bunch of listeners to the canvas, | ||
// using the overridden addEventListener function defined in makeMouseMoveRunOutsideAngularZone | ||
/** @type {?} */ | ||
var dia = component instanceof DiagramComponent ? component.diagram : component.palette; | ||
if (!dia || !dia.model) | ||
const divRef = this.diagramDiv.nativeElement; | ||
if (divRef === null) | ||
return; | ||
if (kvchanges) { | ||
// handle added nodes / links | ||
kvchanges.forEachAddedItem((/** | ||
* @param {?} r | ||
* @return {?} | ||
*/ | ||
(r) => { | ||
switch (str) { | ||
case "n": { | ||
dia.model.addNodeData(r.currentValue); | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
var m = (/** @type {?} */ (dia.model)); | ||
m.addLinkData(r.currentValue); | ||
break; | ||
} | ||
} | ||
})); | ||
// handle removed nodes / links | ||
kvchanges.forEachRemovedItem((/** | ||
* @param {?} r | ||
* @return {?} | ||
*/ | ||
(r) => { | ||
switch (str) { | ||
case "n": { | ||
/** @type {?} */ | ||
let m = dia.model; | ||
/** @type {?} */ | ||
let keyPropName = m.nodeKeyProperty.toString(); | ||
/** @type {?} */ | ||
var node = dia.findNodeForKey(r.previousValue[keyPropName]); | ||
if (node) { | ||
dia.remove(node); | ||
} | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
let m = (/** @type {?} */ (dia.model)); | ||
/** @type {?} */ | ||
var keyPropName = m.linkKeyProperty.toString(); | ||
/** @type {?} */ | ||
var link = dia.findLinkForKey(r.previousValue[keyPropName]); | ||
if (link) { | ||
dia.remove(link); | ||
} | ||
break; | ||
} | ||
} | ||
})); | ||
// handle changed data for nodes / links | ||
kvchanges.forEachChangedItem((/** | ||
* @param {?} r | ||
* @return {?} | ||
*/ | ||
(r) => { | ||
// ensure "changes" to array / object / enumerable data properties are legit | ||
/** @type {?} */ | ||
const sameVals = compareObjs(r.currentValue, r.previousValue); | ||
// update proper data object for node or link | ||
if (!sameVals) { | ||
switch (str) { | ||
case "n": { | ||
/** @type {?} */ | ||
let m = dia.model; | ||
/** @type {?} */ | ||
let keyPropName = m.nodeKeyProperty.toString(); | ||
/** @type {?} */ | ||
var node = dia.findNodeForKey(r.previousValue[keyPropName]); | ||
if (node) { | ||
// if the entry was replaced with null or undefined, just remove the entry altogther | ||
// this is still pretty bad practice -- instead, users should remove entries in their node / link / model data, not set them to null | ||
if (!r.currentValue) { | ||
dia.remove(node); | ||
} | ||
else { | ||
dia.model.assignAllDataProperties(node.data, r.currentValue); | ||
} | ||
} | ||
break; | ||
} | ||
case "l": { | ||
/** @type {?} */ | ||
let m = (/** @type {?} */ (dia.model)); | ||
/** @type {?} */ | ||
var keyPropName = m.linkKeyProperty.toString(); | ||
/** @type {?} */ | ||
var link = dia.findLinkForKey(r.previousValue[keyPropName]); | ||
if (link) { | ||
// if the entry was replaced with null or undefined, just remove the entry altogther | ||
// this is still pretty bad practice -- instead, users should remove entries in their node / link / model data, not set them to null | ||
if (!r.currentValue) { | ||
dia.remove(link); | ||
} | ||
else { | ||
dia.model.assignAllDataProperties(link.data, r.currentValue); | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
})); | ||
} | ||
} | ||
this.diagram.div = divRef; | ||
// initialize the diagram model with the provided node / link / model data | ||
NgDiagramHelper.initializeModel(this.diagram, this.nodeDataArray, this.linkDataArray, this.modelData); | ||
// initializer model listener | ||
NgDiagramHelper.initializeModelChangedListener(this); | ||
} // end ngAfterViewInit | ||
// end ngAfterViewInit | ||
/** | ||
* Always be checking if array Input data has changed (node and link data arrays) | ||
* If a change has occured on an \@Input property, merge the app-level changes with GoJS | ||
* @return {?} | ||
*/ | ||
ngDoCheck() { | ||
if (!this.diagram) | ||
ngOnChanges() { | ||
if (!this.diagram || !this.diagram.model || this.skipsDiagramUpdate) | ||
return; | ||
if (!this.diagram.model) | ||
return; | ||
// these need to be run each check, even if no merging happens | ||
// otherwise, they will detect all diffs that happened since last time skipsDiagram was false, | ||
// such as remove ops that happened in GoJS when skipsDiagram = true, | ||
// and then realllllly bad stuff happens (deleting random nodes, updating the wrong Parts) | ||
// Angular differs are a lot of fun | ||
/** @type {?} */ | ||
var nodeDiffs = this._ndaDiffer.diff(this.nodeDataArray); | ||
/** @type {?} */ | ||
var linkDiffs = this._ldaDiffer.diff(this.linkDataArray); | ||
/** @type {?} */ | ||
var modelDiffs = this._mdaDiffer.diff(this.modelData); | ||
if (!nodeDiffs && !linkDiffs && !modelDiffs) | ||
return; | ||
if (this.skipsDiagramUpdate) | ||
return; | ||
// don't need model change listener while performing known data updates | ||
if (this.modelChangedListener !== null) | ||
this.diagram.model.removeChangedListener(this.modelChangedListener); | ||
this.diagram.model.startTransaction('update data'); | ||
// update modelData first, in case bindings on nodes / links depend on model data | ||
this.diagram.model.assignAllDataProperties(this.diagram.model.modelData, this.modelData); | ||
// merge node / link data | ||
DiagramComponent.mergeChanges(this, nodeDiffs, "n"); | ||
DiagramComponent.mergeChanges(this, linkDiffs, "l"); | ||
this.diagram.model.commitTransaction('update data'); | ||
// reset the model change listener | ||
if (this.modelChangedListener !== null) | ||
this.diagram.model.addChangedListener(this.modelChangedListener); | ||
} // end ngDoCheck | ||
// end ngDoCheck | ||
NgDiagramHelper.mergeAppDataWithModel(this); | ||
} // end ngOnChanges | ||
// end ngOnChanges | ||
/** | ||
@@ -336,3 +261,2 @@ * @return {?} | ||
DiagramComponent.ctorParameters = () => [ | ||
{ type: KeyValueDiffers }, | ||
{ type: NgZone } | ||
@@ -357,40 +281,47 @@ ]; | ||
DiagramComponent.prototype.initDiagram; | ||
/** @type {?} */ | ||
/** | ||
* Node data for diagram | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.nodeDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Link data for diagram. Optional. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.linkDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Model data for diagram. Optional. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.modelData; | ||
/** @type {?} */ | ||
/** | ||
* Diagram div class name. Use this name to style your diagram in CSS. | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
/** | ||
* Model changed listener function for diagram | ||
* @type {?} | ||
*/ | ||
DiagramComponent.prototype.modelChangedListener; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.skipsDiagramUpdate; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.modelChange; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.diagramDiv; | ||
/** @type {?} */ | ||
DiagramComponent.prototype.diagram; | ||
/** | ||
* Whether or not to skip merging app data with GoJS model data (set to true if update is coming from GoJS, false if coming from app-level, usually) | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._ndaDiffer; | ||
DiagramComponent.prototype.skipsDiagramUpdate; | ||
/** | ||
* Event emitter -- fires when diagram model changes. Capture this emitted event in parent component | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._ldaDiffer; | ||
DiagramComponent.prototype.modelChange; | ||
/** | ||
* The DIV element holding the Diagram | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._mdaDiffer; | ||
DiagramComponent.prototype.diagramDiv; | ||
/** | ||
* The Diagram itself | ||
* @type {?} | ||
* @private | ||
*/ | ||
DiagramComponent.prototype._kvdiffers; | ||
DiagramComponent.prototype.diagram; | ||
/** @type {?} */ | ||
@@ -407,27 +338,23 @@ DiagramComponent.prototype.zone; | ||
/** | ||
* @param {?} _kvdiffers | ||
* @param {?} zone | ||
*/ | ||
constructor(_kvdiffers, zone) { | ||
this._kvdiffers = _kvdiffers; | ||
constructor(zone) { | ||
this.zone = zone; | ||
// Link data for palette. Optional | ||
/** | ||
* Link data for palette. Optional. | ||
*/ | ||
this.linkDataArray = null; | ||
// Model data for palette. Optional | ||
/** | ||
* Model data for palette. Optional. | ||
*/ | ||
this.modelData = null; | ||
this.skipsPaletteUpdate = false; | ||
// model changed listener function for palette | ||
this.modelChangedListener = null; | ||
// event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
/** | ||
* Event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
*/ | ||
this.modelChange = new EventEmitter(); | ||
// The Palette itself | ||
/** | ||
* The Palette itself | ||
*/ | ||
this.palette = null; | ||
// differs used to check if there have been changed to the array @Inputs | ||
// without them, changes to the input arrays won't register in ngOnChanges, | ||
// since the array reference itself may be the same | ||
this._ndaDiffer = this._kvdiffers.find([]).create(); | ||
this._ldaDiffer = this._kvdiffers.find([]).create(); | ||
this._mdaDiffer = this._kvdiffers.find([]).create(); | ||
} // end constructor | ||
// end constructor | ||
} | ||
/** | ||
@@ -438,34 +365,11 @@ * Initialize Palette after view init | ||
ngAfterViewInit() { | ||
if (!this.paletteDiv) | ||
return; | ||
if (!this.paletteDiv) { | ||
throw new Error("paletteDiv is not defined"); | ||
} | ||
this.palette = this.initPalette(); | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the palette, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.palette.addEventListener = (/** | ||
* @param {?} DOMElement | ||
* @param {?} name | ||
* @param {?} listener | ||
* @param {?} capture | ||
* @return {?} | ||
*/ | ||
(DOMElement, name, listener, capture) => { | ||
/** @type {?} */ | ||
const superAddEventListener = Diagram.prototype.addEventListener; | ||
if (name === 'mousemove') { | ||
this.zone.runOutsideAngular((/** | ||
* @return {?} | ||
*/ | ||
() => superAddEventListener.call(this, DOMElement, name, listener, capture))); | ||
} | ||
else { | ||
this.zone.run((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
superAddEventListener.call(this, DOMElement, name, listener, capture); | ||
})); | ||
} | ||
}); | ||
if (!(this.palette instanceof Palette)) { | ||
throw new Error("initPalette function did not return a go.Palette"); | ||
} | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.palette, this.zone); | ||
// assign the Palette's div, which (among many other things) will attach a bunch of listeners to the canvas, | ||
@@ -475,84 +379,18 @@ // using the overridden addEventListener function above | ||
const divRef = this.paletteDiv.nativeElement; | ||
if (divRef == null) | ||
return; | ||
this.palette.div = divRef; | ||
// initialize palette model | ||
this.palette.delayInitialization((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
/** @type {?} */ | ||
const model = this.palette.model; | ||
model.commit((/** | ||
* @param {?} m | ||
* @return {?} | ||
*/ | ||
(m) => { | ||
m.mergeNodeDataArray(m.cloneDeep(this.nodeDataArray)); | ||
if (this.linkDataArray && m instanceof GraphLinksModel) { | ||
m.mergeLinkDataArray(m.cloneDeep(this.linkDataArray)); | ||
} | ||
if (this.modelData) { | ||
m.assignAllDataProperties(m.modelData, this.modelData); | ||
} | ||
this.palette.layoutDiagram(true); | ||
}), null); | ||
})); | ||
// initializer listener | ||
this.modelChangedListener = (/** | ||
* @param {?} e | ||
* @return {?} | ||
*/ | ||
(e) => { | ||
if (e.isTransactionFinished && this.palette && this.palette.model && !this.palette.model.isReadOnly) { | ||
// this must be done within a NgZone.run block, so changes are detected in the parent component | ||
this.zone.run((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
/** @type {?} */ | ||
const dataChanges = (/** @type {?} */ (e.model)).toIncrementalData(e); | ||
this.modelChange.emit(dataChanges); | ||
})); | ||
} | ||
}); | ||
this.palette.addModelChangedListener(this.modelChangedListener); | ||
} // end ngAfterViewInit | ||
// end ngAfterViewInit | ||
NgDiagramHelper.initializeModel(this.palette, this.nodeDataArray, this.linkDataArray, this.modelData); | ||
} | ||
/** | ||
* Always be checking if array Input data has changed (node and link data arrays) | ||
* If a change has occured on an \@Input property, merge the app-level changes with GoJS | ||
* @return {?} | ||
*/ | ||
ngDoCheck() { | ||
if (!this.palette) | ||
ngOnChanges() { | ||
if (!this.palette || !this.palette.model) | ||
return; | ||
if (!this.palette.model) | ||
return; | ||
// these need to be run each check, even if no merging happens | ||
// otherwise, they will detect all diffs that happened since last time skipsPaletteUpdate was false, | ||
// such as remove ops that happened in GoJS when skipsPaletteUpdate = true, | ||
// and then realllllly bad stuff happens (deleting random nodes, updating the wrong Parts) | ||
// Angular differs are a lot of fun | ||
/** @type {?} */ | ||
var nodeDiffs = this._ndaDiffer.diff(this.nodeDataArray); | ||
/** @type {?} */ | ||
var linkDiffs = this._ldaDiffer.diff(this.linkDataArray); | ||
/** @type {?} */ | ||
var modelDiffs = this._mdaDiffer.diff(this.modelData); | ||
if (!nodeDiffs && !linkDiffs && !modelDiffs) | ||
return; | ||
if (this.skipsPaletteUpdate) | ||
return; | ||
// don't need model change listener while performing known data updates | ||
if (this.modelChangedListener !== null) | ||
this.palette.model.removeChangedListener(this.modelChangedListener); | ||
this.palette.model.startTransaction('update data'); | ||
// update modelData first, in case bindings on nodes / links depend on model data | ||
this.palette.model.assignAllDataProperties(this.palette.model.modelData, this.modelData); | ||
DiagramComponent.mergeChanges(this, nodeDiffs, "n"); | ||
DiagramComponent.mergeChanges(this, linkDiffs, "l"); | ||
this.palette.model.commitTransaction('update data'); | ||
// reset the model change listener | ||
if (this.modelChangedListener !== null) | ||
this.palette.model.addChangedListener(this.modelChangedListener); | ||
} // end ngDoCheck | ||
// end ngDoCheck | ||
NgDiagramHelper.mergeAppDataWithModel(this); | ||
} // end ngOnChanges | ||
// end ngOnChanges | ||
/** | ||
@@ -573,3 +411,2 @@ * @return {?} | ||
PaletteComponent.ctorParameters = () => [ | ||
{ type: KeyValueDiffers }, | ||
{ type: NgZone } | ||
@@ -583,3 +420,2 @@ ]; | ||
divClassName: [{ type: Input }], | ||
skipsPaletteUpdate: [{ type: Input }], | ||
modelChange: [{ type: Output }], | ||
@@ -595,40 +431,37 @@ paletteDiv: [{ type: ViewChild, args: ['ngPalette', { static: true },] }] | ||
PaletteComponent.prototype.initPalette; | ||
/** @type {?} */ | ||
/** | ||
* Node data for palette | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.nodeDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Link data for palette. Optional. | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.linkDataArray; | ||
/** @type {?} */ | ||
/** | ||
* Model data for palette. Optional. | ||
* @type {?} | ||
*/ | ||
PaletteComponent.prototype.modelData; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.skipsPaletteUpdate; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.modelChangedListener; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.modelChange; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.paletteDiv; | ||
/** @type {?} */ | ||
PaletteComponent.prototype.palette; | ||
/** | ||
* Palette div class name. Use this name to style your palette in CSS | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._ndaDiffer; | ||
PaletteComponent.prototype.divClassName; | ||
/** | ||
* Event emitter -- fires when palette model changes. Capture this emitted event in parent component | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._ldaDiffer; | ||
PaletteComponent.prototype.modelChange; | ||
/** | ||
* The DIV element holding the Palette | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._mdaDiffer; | ||
PaletteComponent.prototype.paletteDiv; | ||
/** | ||
* The Palette itself | ||
* @type {?} | ||
* @private | ||
*/ | ||
PaletteComponent.prototype._kvdiffers; | ||
PaletteComponent.prototype.palette; | ||
/** @type {?} */ | ||
@@ -649,5 +482,9 @@ PaletteComponent.prototype.zone; | ||
this.zone = zone; | ||
// The Diagram to observe with the Overview | ||
/** | ||
* The Diagram to observe with the Overview | ||
*/ | ||
this.observedDiagram = null; | ||
// The Overview itself | ||
/** | ||
* The Overview itself | ||
*/ | ||
this.overview = null; | ||
@@ -660,6 +497,10 @@ } | ||
ngAfterViewInit() { | ||
if (!this.overviewDiv) | ||
return; | ||
if (!this.overviewDiv) { | ||
throw new Error("overviewDiv is not defined"); | ||
} | ||
if (this.initOverview) { | ||
this.overview = this.initOverview(); | ||
if (!(this.overview instanceof Overview)) { | ||
throw new Error("initOverview function did not return a go.Overview"); | ||
} | ||
} | ||
@@ -670,31 +511,4 @@ else { | ||
} | ||
// This bit of code makes sure the mousemove event listeners on the canvas are run outside NgZone | ||
// This makes it so change detection isn't triggered every time the mouse is moved inside the canvas, greatly improving performance | ||
// If some state-altering behavior must happen on a mousemove event inside the overview, | ||
// you will have to using zone.run() to make sure that event triggers angular change detection | ||
this.overview.addEventListener = (/** | ||
* @param {?} DOMElement | ||
* @param {?} name | ||
* @param {?} listener | ||
* @param {?} capture | ||
* @return {?} | ||
*/ | ||
(DOMElement, name, listener, capture) => { | ||
/** @type {?} */ | ||
const superAddEventListener = Diagram.prototype.addEventListener; | ||
if (name === 'mousemove') { | ||
this.zone.runOutsideAngular((/** | ||
* @return {?} | ||
*/ | ||
() => superAddEventListener.call(this, DOMElement, name, listener, capture))); | ||
} | ||
else { | ||
this.zone.run((/** | ||
* @return {?} | ||
*/ | ||
() => { | ||
superAddEventListener.call(this, DOMElement, name, listener, capture); | ||
})); | ||
} | ||
}); | ||
// reduces change detection on mouse moves, boosting performance | ||
NgDiagramHelper.makeMouseMoveRunOutsideAngularZone(this.overview, this.zone); | ||
this.overview.div = this.overviewDiv.nativeElement; | ||
@@ -738,11 +552,23 @@ } | ||
if (false) { | ||
/** @type {?} */ | ||
/** | ||
* The function used to initialize and return the Overview | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.initOverview; | ||
/** @type {?} */ | ||
/** | ||
* The div class name that holds the Overview. Use this name to style your Overview in CSS. | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.divClassName; | ||
/** @type {?} */ | ||
/** | ||
* The Diagram to observe with the Overview | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.observedDiagram; | ||
/** @type {?} */ | ||
OverviewComponent.prototype.overviewDiv; | ||
/** @type {?} */ | ||
/** | ||
* The Overview itself | ||
* @type {?} | ||
*/ | ||
OverviewComponent.prototype.overview; | ||
@@ -759,3 +585,2 @@ /** @type {?} */ | ||
class DataSyncService { | ||
constructor() { } | ||
/** | ||
@@ -776,54 +601,62 @@ * Sync a node data array with a set of changes | ||
const modifiedNodesMap = new Map(); | ||
// account for modified node data | ||
if (changes.modifiedNodeData) { | ||
changes.modifiedNodeData.forEach((/** | ||
* @param {?} nd | ||
* @return {?} | ||
*/ | ||
(nd) => { | ||
// Get the value of the node key property checking wether is a function or a string | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
modifiedNodesMap.set(key, nd); | ||
for (let i = 0; i < nodeData.length; i++) { | ||
// nodeData is immutable, modify it using the immer package's "produce" function (creates new array) | ||
/** @type {?} */ | ||
var newNodeDataArray = produce(nodeData, (/** | ||
* @param {?} draft | ||
* @return {?} | ||
*/ | ||
(draft) => { | ||
// account for modified node data | ||
if (changes.modifiedNodeData) { | ||
changes.modifiedNodeData.forEach((/** | ||
* @param {?} nd | ||
* @return {?} | ||
*/ | ||
(nd) => { | ||
// Get the value of the node key property checking wether is a function or a string | ||
/** @type {?} */ | ||
const ndEntry = nodeData[i]; | ||
const key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
modifiedNodesMap.set(key, nd); | ||
for (let i = 0; i < nodeData.length; i++) { | ||
/** @type {?} */ | ||
const ndEntry = nodeData[i]; | ||
/** @type {?} */ | ||
const keyNdEntry = model ? model.getKeyForNodeData(ndEntry) : ndEntry['key']; | ||
if (keyNdEntry === key) { | ||
draft[i] = nd; | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted node data | ||
if (changes.insertedNodeKeys) { | ||
changes.insertedNodeKeys.forEach((/** | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
(key) => { | ||
/** @type {?} */ | ||
const keyNdEntry = model ? model.getKeyForNodeData(ndEntry) : ndEntry['key']; | ||
if (keyNdEntry === key) { | ||
nodeData[i] = nd; | ||
const nd = modifiedNodesMap.get(key); | ||
if (nd) { | ||
draft.push(nd); | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted node data | ||
if (changes.insertedNodeKeys) { | ||
changes.insertedNodeKeys.forEach((/** | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
(key) => { | ||
/** @type {?} */ | ||
const nd = modifiedNodesMap.get(key); | ||
if (nd) { | ||
nodeData.push(nd); | ||
} | ||
})); | ||
} | ||
// account for removed node data | ||
if (changes.removedNodeKeys) { | ||
nodeData = nodeData.filter((/** | ||
* @param {?} nd | ||
* @return {?} | ||
*/ | ||
(nd) => { | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
if (changes.removedNodeKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
return nodeData; | ||
})); | ||
} | ||
// account for removed node data | ||
if (changes.removedNodeKeys) { | ||
return draft.filter((/** | ||
* @param {?} nd | ||
* @return {?} | ||
*/ | ||
(nd) => { | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForNodeData(nd) : nd['key']; | ||
if (changes.removedNodeKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
return newNodeDataArray; | ||
} | ||
@@ -845,53 +678,60 @@ /** | ||
const modifiedLinksMap = new Map(); | ||
// account for modified link data | ||
if (changes.modifiedLinkData) { | ||
changes.modifiedLinkData.forEach((/** | ||
* @param {?} ld | ||
* @return {?} | ||
*/ | ||
(ld) => { | ||
// Get the value of the link key | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
modifiedLinksMap.set(key, ld); | ||
for (let i = 0; i < linkData.length; i++) { | ||
// linkData is immutable, modify it using the immer package's "produce" function (creates new array) | ||
linkData = produce(linkData, (/** | ||
* @param {?} draft | ||
* @return {?} | ||
*/ | ||
draft => { | ||
// account for modified link data | ||
if (changes.modifiedLinkData) { | ||
changes.modifiedLinkData.forEach((/** | ||
* @param {?} ld | ||
* @return {?} | ||
*/ | ||
(ld) => { | ||
// Get the value of the link key | ||
/** @type {?} */ | ||
const ldEntry = linkData[i]; | ||
const key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
modifiedLinksMap.set(key, ld); | ||
for (let i = 0; i < linkData.length; i++) { | ||
/** @type {?} */ | ||
const ldEntry = linkData[i]; | ||
/** @type {?} */ | ||
const keyLdEntry = model ? model.getKeyForLinkData(ldEntry) : ldEntry['key']; | ||
if (keyLdEntry === key) { | ||
draft[i] = ld; | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted link data | ||
if (changes.insertedLinkKeys) { | ||
changes.insertedLinkKeys.forEach((/** | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
(key) => { | ||
/** @type {?} */ | ||
const keyLdEntry = model ? model.getKeyForLinkData(ldEntry) : ldEntry['key']; | ||
if (keyLdEntry === key) { | ||
linkData[i] = ld; | ||
const nd = modifiedLinksMap.get(key); | ||
if (nd) { | ||
draft.push(nd); | ||
} | ||
} | ||
})); | ||
} | ||
// account for inserted link data | ||
if (changes.insertedLinkKeys) { | ||
changes.insertedLinkKeys.forEach((/** | ||
* @param {?} key | ||
* @return {?} | ||
*/ | ||
(key) => { | ||
/** @type {?} */ | ||
const nd = modifiedLinksMap.get(key); | ||
if (nd) { | ||
linkData.push(nd); | ||
} | ||
})); | ||
} | ||
// account for removed link data | ||
if (changes.removedLinkKeys) { | ||
linkData = linkData.filter((/** | ||
* @param {?} ld | ||
* @return {?} | ||
*/ | ||
(ld) => { | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
if (changes.removedLinkKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
} | ||
// account for removed link data | ||
if (changes.removedLinkKeys) { | ||
return draft.filter((/** | ||
* @param {?} ld | ||
* @return {?} | ||
*/ | ||
(ld) => { | ||
/** @type {?} */ | ||
const key = model ? model.getKeyForLinkData(ld) : ld['key']; | ||
if (changes.removedLinkKeys.includes(key)) { | ||
return false; | ||
} | ||
return true; | ||
})); | ||
} | ||
})); | ||
return linkData; | ||
@@ -918,4 +758,2 @@ } | ||
]; | ||
/** @nocollapse */ | ||
DataSyncService.ctorParameters = () => []; | ||
@@ -922,0 +760,0 @@ /** |
@@ -1,1 +0,1 @@ | ||
{"__symbolic":"module","version":4,"metadata":{"DiagramComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":3,"character":1},"arguments":[{"selector":"gojs-diagram","template":"<div #ngDiagram [className]=divClassName></div>"}]}],"members":{"initDiagram":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":13,"character":3}}]}],"nodeDataArray":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":16,"character":3}}]}],"linkDataArray":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":19,"character":3}}]}],"modelData":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":22,"character":3}}]}],"divClassName":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":25,"character":3}}]}],"skipsDiagramUpdate":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":30,"character":3}}]}],"modelChange":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output","line":33,"character":3}}]}],"diagramDiv":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":35,"character":3},"arguments":["ngDiagram",{"static":true}]}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"KeyValueDiffers","line":44,"character":34},{"__symbolic":"reference","module":"@angular/core","name":"NgZone","line":44,"character":64}]}],"ngAfterViewInit":[{"__symbolic":"method"}],"ngDoCheck":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}]}},"PaletteComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":3,"character":1},"arguments":[{"selector":"gojs-palette","template":"<div #ngPalette [className]=divClassName></div>"}]}],"members":{"initPalette":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":13,"character":3}}]}],"nodeDataArray":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":16,"character":3}}]}],"linkDataArray":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":19,"character":3}}]}],"modelData":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":22,"character":3}}]}],"divClassName":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":25,"character":3}}]}],"skipsPaletteUpdate":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":27,"character":3}}]}],"modelChange":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output","line":33,"character":3}}]}],"paletteDiv":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":35,"character":3},"arguments":["ngPalette",{"static":true}]}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"KeyValueDiffers","line":46,"character":34},{"__symbolic":"reference","module":"@angular/core","name":"NgZone","line":46,"character":64}]}],"ngAfterViewInit":[{"__symbolic":"method"}],"ngDoCheck":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}]}},"OverviewComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":3,"character":1},"arguments":[{"selector":"gojs-overview","template":"<div #ngOverview [className]=divClassName></div>"}]}],"members":{"initOverview":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":10,"character":3}}]}],"divClassName":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":13,"character":3}}]}],"observedDiagram":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":16,"character":3}}]}],"overviewDiv":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":18,"character":3},"arguments":["ngOverview",{"static":true}]}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"NgZone","line":23,"character":27}]}],"ngAfterViewInit":[{"__symbolic":"method"}],"ngOnChanges":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}]}},"GojsAngularModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule","line":6,"character":1},"arguments":[{"declarations":[{"__symbolic":"reference","name":"DiagramComponent"},{"__symbolic":"reference","name":"OverviewComponent"},{"__symbolic":"reference","name":"PaletteComponent"}],"imports":[],"providers":[{"__symbolic":"reference","name":"DataSyncService"}],"exports":[{"__symbolic":"reference","name":"DiagramComponent"},{"__symbolic":"reference","name":"OverviewComponent"},{"__symbolic":"reference","name":"PaletteComponent"}]}]}],"members":{}},"DataSyncService":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":3,"character":1}}],"members":{"__ctor__":[{"__symbolic":"constructor"}]}}},"origins":{"DiagramComponent":"./lib/diagram.component","PaletteComponent":"./lib/palette.component","OverviewComponent":"./lib/overview.component","GojsAngularModule":"./lib/gojs-angular.module","DataSyncService":"./lib/data-sync.service"},"importAs":"gojs-angular"} | ||
{"__symbolic":"module","version":4,"metadata":{"DiagramComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":4,"character":1},"arguments":[{"selector":"gojs-diagram","template":"<div #ngDiagram [className]=divClassName></div>"}]}],"members":{"initDiagram":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":14,"character":3}}]}],"nodeDataArray":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":16,"character":3}}]}],"linkDataArray":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":18,"character":3}}]}],"modelData":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":20,"character":3}}]}],"divClassName":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":22,"character":3}}]}],"skipsDiagramUpdate":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":26,"character":3}}]}],"modelChange":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output","line":28,"character":3}}]}],"diagramDiv":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":30,"character":3},"arguments":["ngDiagram",{"static":true}]}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"NgZone","line":34,"character":27}]}],"ngAfterViewInit":[{"__symbolic":"method"}],"ngOnChanges":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}]}},"PaletteComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":3,"character":1},"arguments":[{"selector":"gojs-palette","template":"<div #ngPalette [className]=divClassName></div>"}]}],"members":{"initPalette":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":13,"character":3}}]}],"nodeDataArray":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":15,"character":3}}]}],"linkDataArray":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":17,"character":3}}]}],"modelData":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":19,"character":3}}]}],"divClassName":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":21,"character":3}}]}],"modelChange":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Output","line":24,"character":3}}]}],"paletteDiv":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":26,"character":3},"arguments":["ngPalette",{"static":true}]}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"NgZone","line":31,"character":27}]}],"ngAfterViewInit":[{"__symbolic":"method"}],"ngOnChanges":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}]}},"OverviewComponent":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":4,"character":1},"arguments":[{"selector":"gojs-overview","template":"<div #ngOverview [className]=divClassName></div>"}]}],"members":{"initOverview":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":11,"character":3}}]}],"divClassName":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":13,"character":3}}]}],"observedDiagram":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input","line":15,"character":3}}]}],"overviewDiv":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":17,"character":3},"arguments":["ngOverview",{"static":true}]}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"NgZone","line":22,"character":27}]}],"ngAfterViewInit":[{"__symbolic":"method"}],"ngOnChanges":[{"__symbolic":"method"}],"ngOnDestroy":[{"__symbolic":"method"}]}},"GojsAngularModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule","line":6,"character":1},"arguments":[{"declarations":[{"__symbolic":"reference","name":"DiagramComponent"},{"__symbolic":"reference","name":"OverviewComponent"},{"__symbolic":"reference","name":"PaletteComponent"}],"imports":[],"providers":[{"__symbolic":"reference","name":"DataSyncService"}],"exports":[{"__symbolic":"reference","name":"DiagramComponent"},{"__symbolic":"reference","name":"OverviewComponent"},{"__symbolic":"reference","name":"PaletteComponent"}]}]}],"members":{}},"DataSyncService":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Injectable","line":4,"character":1}}],"members":{}}},"origins":{"DiagramComponent":"./lib/diagram.component","PaletteComponent":"./lib/palette.component","OverviewComponent":"./lib/overview.component","GojsAngularModule":"./lib/gojs-angular.module","DataSyncService":"./lib/data-sync.service"},"importAs":"gojs-angular"} |
import * as go from 'gojs'; | ||
export declare class DataSyncService { | ||
constructor(); | ||
/** | ||
@@ -5,0 +4,0 @@ * Sync a node data array with a set of changes |
@@ -1,5 +0,4 @@ | ||
import { ElementRef, EventEmitter, KeyValueDiffers, NgZone } from '@angular/core'; | ||
import { ElementRef, EventEmitter, NgZone } from '@angular/core'; | ||
import * as go from 'gojs'; | ||
export declare class DiagramComponent { | ||
private _kvdiffers; | ||
zone: NgZone; | ||
@@ -11,15 +10,21 @@ /** | ||
initDiagram: () => go.Diagram; | ||
/** Node data for diagram */ | ||
nodeDataArray: Array<go.ObjectData>; | ||
/** Link data for diagram. Optional. */ | ||
linkDataArray: Array<go.ObjectData>; | ||
/** Model data for diagram. Optional. */ | ||
modelData: go.ObjectData; | ||
/** Diagram div class name. Use this name to style your diagram in CSS. */ | ||
divClassName: string; | ||
modelChangedListener: (e: go.ChangedEvent) => void | null; | ||
/** Model changed listener function for diagram */ | ||
modelChangedListener: ((e: go.ChangedEvent) => void) | null; | ||
/** Whether or not to skip merging app data with GoJS model data (set to true if update is coming from GoJS, false if coming from app-level, usually) */ | ||
skipsDiagramUpdate: boolean; | ||
/** Event emitter -- fires when diagram model changes. Capture this emitted event in parent component */ | ||
modelChange: EventEmitter<go.IncrementalData>; | ||
/** The DIV element holding the Diagram */ | ||
diagramDiv: ElementRef; | ||
/** The Diagram itself */ | ||
diagram: go.Diagram; | ||
private _ndaDiffer; | ||
private _ldaDiffer; | ||
private _mdaDiffer; | ||
constructor(_kvdiffers: KeyValueDiffers, zone: NgZone); | ||
constructor(zone: NgZone); | ||
/** | ||
@@ -30,14 +35,6 @@ * Initializes diagram / model after view init | ||
/** | ||
* Merges changes from app data into GoJS model data, | ||
* making sure only actual changes (and not falsely flagged no-ops on array / obj data props) are logged | ||
* @param component an instance of DiagramComponent or PaletteComponent | ||
* @param kvchanges The kvchanges object produced by either a node or link Angular differ object | ||
* @param str "n" for node data changes, "l" for link data changes | ||
* */ | ||
static mergeChanges(component: any, kvchanges: any, str: any): boolean; | ||
/** | ||
* Always be checking if array Input data has changed (node and link data arrays) | ||
* If a change has occured on an @Input property, merge the app-level changes with GoJS | ||
*/ | ||
ngDoCheck(): void; | ||
ngOnChanges(): void; | ||
ngOnDestroy(): void; | ||
} |
@@ -5,6 +5,10 @@ import { ElementRef, NgZone, SimpleChanges } from '@angular/core'; | ||
zone: NgZone; | ||
/** The function used to initialize and return the Overview */ | ||
initOverview: () => go.Overview; | ||
/** The div class name that holds the Overview. Use this name to style your Overview in CSS. */ | ||
divClassName: string; | ||
/** The Diagram to observe with the Overview */ | ||
observedDiagram: go.Diagram; | ||
overviewDiv: ElementRef; | ||
/** The Overview itself */ | ||
overview: go.Overview | null; | ||
@@ -11,0 +15,0 @@ constructor(zone: NgZone); |
@@ -1,5 +0,4 @@ | ||
import { ElementRef, EventEmitter, KeyValueDiffers, NgZone } from '@angular/core'; | ||
import { ElementRef, EventEmitter, NgZone } from '@angular/core'; | ||
import * as go from 'gojs'; | ||
export declare class PaletteComponent { | ||
private _kvdiffers; | ||
zone: NgZone; | ||
@@ -11,15 +10,17 @@ /** | ||
initPalette: () => go.Palette; | ||
/** Node data for palette */ | ||
nodeDataArray: Array<go.ObjectData>; | ||
/** Link data for palette. Optional. */ | ||
linkDataArray: Array<go.ObjectData>; | ||
/** Model data for palette. Optional. */ | ||
modelData: go.ObjectData; | ||
/** Palette div class name. Use this name to style your palette in CSS */ | ||
divClassName: string; | ||
skipsPaletteUpdate: boolean; | ||
modelChangedListener: (e: go.ChangedEvent) => void | null; | ||
/** Event emitter -- fires when palette model changes. Capture this emitted event in parent component */ | ||
modelChange: EventEmitter<go.IncrementalData>; | ||
/** The DIV element holding the Palette */ | ||
paletteDiv: ElementRef; | ||
/** The Palette itself */ | ||
palette: go.Palette | null; | ||
private _ndaDiffer; | ||
private _ldaDiffer; | ||
private _mdaDiffer; | ||
constructor(_kvdiffers: KeyValueDiffers, zone: NgZone); | ||
constructor(zone: NgZone); | ||
/** | ||
@@ -30,6 +31,6 @@ * Initialize Palette after view init | ||
/** | ||
* Always be checking if array Input data has changed (node and link data arrays) | ||
* If a change has occured on an @Input property, merge the app-level changes with GoJS | ||
*/ | ||
ngDoCheck(): void; | ||
ngOnChanges(): void; | ||
ngOnDestroy(): void; | ||
} |
{ | ||
"name": "gojs-angular", | ||
"version": "1.0.17", | ||
"version": "2.0.0", | ||
"peerDependencies": { | ||
@@ -9,3 +9,4 @@ "@angular/common": ">=11.0.0", | ||
"dependencies": { | ||
"tslib": "^2.0.0" | ||
"tslib": "^2.0.0", | ||
"immer": "^9.0.1" | ||
}, | ||
@@ -12,0 +13,0 @@ "main": "bundles/gojs-angular.umd.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
25
292241
4
2549
1
0
2
+ Addedimmer@^9.0.1
+ Addedimmer@9.0.21(transitive)