Function returning sane layout settings for the given graph.

@param  {Graph}  graph - Target graph.
@return {object}
167350
function inferSettings(graph) {
  var order = graph.order;

  return {
    barnesHutOptimize: order > 2000,
    strongGravityMode: true,
    gravity: 0.05,
    scalingRatio: 10,
    slowDown: 1 + Math.log(order)
  };
}
209828
def define_layout
      super do |components|
        components << Scruffy::Components::Title.new(:title, :position => [5, 2], :size => [90, 7])
                      
        components << Scruffy::Components::Viewport.new(:one, :position => [10, 50], 
                                                        :size => VIEWPORT_SIZE, :skewY => '-25', 
                                                        &graph_block(:one))
        components << Scruffy::Components::Viewport.new(:two, :position => [30, 50], 
                                                        :size => VIEWPORT_SIZE, :skewY => '-25', 
                                                        &graph_block(:two))
        components << Scruffy::Components::Viewport.new(:three, :position => [50, 50], 
                                                        :size => VIEWPORT_SIZE, :skewY => '-25', 
                                                        &graph_block(:three))
        components << Scruffy::Components::Viewport.new(:four, :position => [70, 50], 
                                                        :size => VIEWPORT_SIZE, :skewY => '-25', 
                                                        &graph_block(:four))


        components << Scruffy::Components::Legend.new(:legend, :position => [5, 13], :size => [90, 5])
      end
    end
1151975
function initVivaGraph(){
    g = Viva.Graph.graph();
    isPaused = false;

    divGraph = document.getElementById('divGraph');

    $('#divGraph').append("<div id='loadingText' class='hero-body has-text-centered'><h1 class='title'>Loading...</h1></div>");

    console.time("nodesFromMWG");
    graph.indexes(WORLD, TIME, function (indexNames) {
        var defer = graph.newCounter(indexNames.length);
        for (var i = 0; i < indexNames.length; ++i) {
            const indexName = indexNames[i];
            /*graph.getIndexNode(WORLD, TIME, indexName, function (node) {
             console.log(node.toString());
             });*/
            graph.findAll(WORLD, TIME, indexName, function (nodes) {
                // transform every mwg nodes and add them to a global array
                for (var j = 0; j < nodes.length; ++j){
                    addToGlobalNodes(nodes[j]);
                }
                defer.count();
            });
        }

        defer.then(function() {
            console.timeEnd("nodesFromMWG");
            console.time("nodesToVivagraph");
            // add only 'nbNodesToDisplay' nodes to the graph
            var nbNodesToDisplay = (gAllNodes.length > NB_NODES_TO_DISPLAY ? NB_NODES_TO_DISPLAY : gAllNodes.length);
            for (var i = 0; i < nbNodesToDisplay; ++i){
                addNodeToGraph(gAllNodes[i]);
            }
            for (var i = 0; i < gNodesWithRel.length; ++i){
                addRelToGraph(gNodesWithRel[i]);
            }
            gRootNodes = _.difference(gAllNodes, gChildrenNodes);
            createTree();
            var maxChildNodes = getMaxChildNodes();
            console.timeEnd("nodesToVivagraph");

            console.time("rendering+loading");
            graphics = Viva.Graph.View.webglGraphics();
            graphics
                .node(function(node){
                    return Viva.Graph.View.webglSquare(NODE_SIZE, colorsByNodeType[node.data._type]);
                })
                .link(function(link) {
                    return Viva.Graph.View.webglLine(colorsByLinkType[link.data]);
                });

            var events = Viva.Graph.webglInputEvents(graphics, g);

            events.mouseEnter(function (vivagraphNode) {
                /*var nodeUI = graphics.getNodeUI(vivagraphNode.id);
                 nodeUI.color = '0x00BFFFFF';
                 renderer.rerender();*/
            }).mouseLeave(function (vivagraphNode) {
                /* var nodeUI = graphics.getNodeUI(vivagraphNode.id);
                 nodeUI.color = hexColorToWebGLColor(colorsByNodeType[vivagraphNode.data._type]);
                 renderer.rerender();*/
            }).dblClick(function (vivagraphNode) {
                drawNodeContext(vivagraphNode.data._id, NB_HOPS);
            }).click(function (vivagraphNode) {
                highlightNodeWebGL(vivagraphNode.data);
                displayNameDOM(vivagraphNode.data);
                globalFunc.setNodeDetailOnClick(vivagraphNode.data);
            });

            //TODO : slow things really badly
            /*
             graphics.placeNode(function(ui, pos){
             var label = $('.nodeLabel');
             if (label.length){
             var nodePos = layout.getNodePosition(label.attr('id'));
             var domPos = {
             x: nodePos.x,
             y: nodePos.y
             };

             graphics.transformGraphToClientCoordinates(domPos);
             label.css({'left' : domPos.x, 'top' : domPos.y});

             //hide label if it goes out of the divGraph layout
             if (domPos.x < 0 || domPos.y < 0) {
             label.hide();
             } else {
             label.show();
             }
             }
             });
             */

            console.time("loading data in components");
            // Load the necessary stuff (nodes) in the react components
            globalFunc.addNodesInList();
            globalFunc.setTypesInList();
            globalFunc.loadRootNodesInTree();
            globalFunc.loadTree();
            console.timeEnd("loading data in components");

            var springLength = 200;
            var displayedChildNodes = Math.ceil(maxChildNodes / (gAllNodes.length / nbNodesToDisplay));
            var springLengthCoeff = (displayedChildNodes <= 250 ? 1 : displayedChildNodes / 250);
            layout = Viva.Graph.Layout.forceDirected(g, {
                springLength : springLength * springLengthCoeff,
                springCoeff : 0.0008,
                dragCoeff : 0.02
            });

            renderer = Viva.Graph.View.renderer(g, {
                graphics : graphics,
                layout: layout,
                container: divGraph,
                prerender: 50
            });

            $('#loadingText').hide();

            renderer.run();
            console.timeEnd("rendering+loading");

            console.time("table+events");
            createTableLayout();
            initJQueryEvents();
            console.timeEnd("table+events");

            console.timeEnd("all");
        });
    });


}
570980
function (graph, opts, params) {
    if (graph.children.length == 0) return '';

    function getRels(node) {
      var rels = [];
      node.children.forEach(function(childNode) {
        rels.push('(' + node.name + ')-[__rel_' + childNode.name + ':' + childNode.comp.rel + ']->(' + childNode.name + ')');
        rels.push.apply(rels, getRels(childNode));
      });
      return rels;
    }
    
    return 'CREATE UNIQUE ' + getRels(graph).join(',');
  }
1203335
function loadPrettyGraphSONSync(graph, filename) {
        var jsonText = fs.readFileSync(filename, { encoding: 'utf8' });
        var jsonObjArray = JSON.parse(jsonText);
        var jsonTextArray = _.map(jsonObjArray, JSON.stringify);
        var uglyText = jsonTextArray.join('\n');
        var StringInputStream = Tinkerpop.autoImport('StringInputStream');
        var stream = StringInputStream.from(uglyText);
        var builder = Tinkerpop.GraphSONReader.build();
        var mapper = _newGraphSONMapperSync();
        builder.mapper(mapper);
        var reader = builder.create();
        reader.readGraph(stream, graph);
        return graph;
    }
1187995
function Axes( graph ) {

	// INSTANCE ATTRIBUTES //

	this._parent = graph;
	this._root = undefined;
	this._children = {};
	this._config = [
		{
			"display": true,
			"scale": "x",
			"label": "x",
			"ticks": {
				"display": true,
				"num": 5,
				"format": null,
				"padding": 3,
				"innerSize": 6,
				"outerSize": 6,
				"rotation": 0,
				"direction": "out"
			},
			"orient": "bottom"
		},
		{
			"display": true,
			"scale": "y",
			"label": "y",
			"ticks": {
				"display": true,
				"num": 5,
				"format": null,
				"padding": 3,
				"innerSize": 6,
				"outerSize": 6,
				"rotation": 0,
				"direction": "out"
			},
			"orient": "left"
		}
	];

	// GENERATORS //

	this._xAxis = this.axis()
		.scale( graph._xScale )
		.orient( this._config[ 0 ].orient )
		.ticks( this._config[ 0 ].ticks.num )
		.innerTickSize( this._config[ 0 ].ticks.innerSize )
		.outerTickSize( this._config[ 0 ].ticks.outerSize )
		.tickPadding( this._config[ 0 ].ticks.padding )
		.tickFormat( this._config[ 0 ].ticks.format );

	this._yAxis = this.axis()
		.scale( graph._yScale )
		.orient( this._config[ 1 ].orient )
		.ticks( this._config[ 1 ].ticks.num )
		.innerTickSize( this._config[ 1 ].ticks.innerSize )
		.outerTickSize( this._config[ 1 ].ticks.outerSize )
		.tickPadding( this._config[ 1 ].ticks.padding )
		.tickFormat( this._config[ 1 ].ticks.format );

	// REGISTER //
	if ( graph._config.hasOwnProperty( 'axes' ) ) {
		graph._config.axes.push( this._config );
	} else {
		graph._config.axes = [ this._config ];
	}
	if ( graph._children.hasOwnProperty( 'axes' ) ) {
		graph._children.axes.push( this );
	} else {
		graph._children.axes = [ this ];
	}

	return this;

}
311295
function(){
    if(this.busy)
      return;

    var that = this,
        GUtil = Graph.Util,
        config = this.config,
        graph = this.graph,
        parents = GUtil.getParents(graph.getNode(this.clickedNode && this.clickedNode.id || this.root)),
        parent = parents[0],
        clickedNode = parent,
        previousClickedNode = this.clickedNode;

    this.busy = true;
    this.events.hoveredNode = false;

    if(!parent) {
      this.busy = false;
      return;
    }

    //final plot callback
    callback = {
      onComplete: function() {
        that.clickedNode = parent;
        if(config.request) {
          that.requestNodes(parent, {
            onComplete: function() {
              that.compute();
              that.plot();
              that.busy = false;
            }
          });
        } else {
          that.compute();
          that.plot();
          that.busy = false;
        }
      }
    };

    //animate node positions
    if(config.animate) {
      this.clickedNode = clickedNode;
      this.compute('end');
      //animate the visible subtree only
      this.clickedNode = previousClickedNode;
      this.fx.animate({
        modes:['linear', 'node-property:width:height'],
        duration: 1000,
        onComplete: function() {
          //animate the parent subtree
          that.clickedNode = clickedNode;
          //change nodes alpha
          graph.nodeList.setDataset(['current', 'end'], {
            'alpha': [0, 1]
          });
          GUtil.eachSubgraph(previousClickedNode, function(node) {
            node.setData('alpha', 1);
          }, "ignore");
          that.fx.animate({
            duration: 500,
            modes:['node-property:alpha'],
            onComplete: function() {
              callback.onComplete();
            }
          });
        }
      });
    } else {
      callback.onComplete();
    }
  }
772945
def pretty_view(graph, oriented=False, construction=False,
                graphviz_prog=DEFAULT_GRAPHVIZ_PROG):
    """"""
    layout = create_layout(graph, graphviz_prog=graphviz_prog)
    matrix_view = defaultdict(lambda: ' ')

    # Add the edge to the view

    # print('GRAPH EDGES:', tuple(graph.edges()))
    # print('LAYOUT:', layout)

    edges = ((layout[source], layout[target])
             for source, target in graph.edges())
    # print('EDGES:', tuple(edges))

    for source, target in edges:
        previous_edge_char = None
        previous_position = source
        while source != target:
            for is_dir, transform, edge_char in DIRECTIONS:
                first_loop = previous_edge_char is None
                if is_dir(source, target):
                    previous_source = source
                    source = transform(source)
                    if not first_loop:  # first loop: no previous char
                        char = CHARACTER[previous_edge_char, edge_char]
                        if not isinstance(char, str):
                            char = char.value
                        matrix_view[previous_source] = char
                        if construction:
                            old = defaultdict(lambda: ' ', matrix_view)
                            yield view.build(matrix_view)
                        assert isinstance(matrix_view[previous_source], str)
                    if source != target:
                        previous_edge_char = edge_char
                    previous_position = previous_source
                    break  # for loop ; don't test the remain directions

        if oriented:
            matrix_view[previous_position] = ORIENTATION[previous_edge_char, edge_char]
        if construction:
            yield view.build(matrix_view)

    # mark the place where nodes labels will be added
    # for node, coords in layout.items():
        # matrix_view[coords] = node[0]
    # Add the node labels to the view
    # matrix_view = view.clean(matrix_view)
    for node, (x, y) in layout.items():
        if len(node) == 1:
            matrix_view[x, y] = node
            continue
        row_min, row_max = (view.previous_unwrittable_on_row(matrix_view, (x, y)),
                            view.next_unwrittable_on_row(matrix_view, (x, y)))
        col_min, col_max = (view.previous_unwrittable_on_col(matrix_view, (x, y)),
                              view.next_unwrittable_on_col(matrix_view, (x, y)))
        # print('NODE ' + node + ':',
              # '→row: [{};{}]'.format(row_min, row_max).ljust(20),
              # '↓col: [{};{}]'.format(col_min, col_max))
        print_coords = [itertools.count(x), itertools.cycle((y,))]
        if row_min is None:  # write left to right, end at (x, y)
            if row_max is None or row_max > (x + len(node) / 2):  # enough space at the right
                factor = 2
            else:
                factor = 1
            print_coords[0] = tuple(
                x - (len(node) // factor) + offset + 1
                for offset in range(len(node))
            )
            # print('DEBUG 1:', y, len(node), print_coords[0])
        elif row_max is None:  # write left to right, beginning at (x, y)
            if row_min < (x - len(node) / 2):  # enough space at the left
                factor = 1
            else:
                factor = 0
            print_coords[0] = tuple(
                x + offset - (len(node) // 2) * factor
                for offset in range(len(node))
            )
            # print('DEBUG 2:', print_coords[0])
        elif (row_max - row_min) > len(node) + 1:  # write left to right, if enough place
            print_coords[0] = tuple(
                x + offset
                for offset in range(len(node))
            )
            # print('DEBUG 3:', print_coords[0])

        elif col_min is None:  # write up to down, end at (x, y)
            if col_max is None or col_max > (x + len(node) / 2):  # enough space at the right
                factor = 2
            else:
                factor = 1
            print_coords = (itertools.cycle((x,)), tuple(
                y - (len(node) // factor) + offset + 1
                for offset in range(len(node))
            ))
            # print('DEBUG 4:', y, len(node), print_coords[1])
        elif col_max is None:  # write up to down, beginning at (x, y)
            if col_min < (x - len(node) / 2):  # enough space at the left
                factor = 1
            else:
                factor = 0
            print_coords = (itertools.cycle((x,)), tuple(
                y + offset - (len(node) // 2) * factor
                for offset in range(len(node))
            ))
            # print('DEBUG 5:', print_coords[1])
        elif (col_max - col_min) > len(node) + 1:  # write up to down, if enough place
            print_coords = (itertools.cycle((x,)), tuple(
                y + offset
                for offset in range(len(node))
            ))
            # print('DEBUG 6:', print_coords[1])
        else:  # not enough space
            if (row_max - row_min) > (col_max - col_min):
                # more space on Y axis
                node = node[:row_max - row_min]  # cut the node
                print_coords = (itertools.cycle((x,)), tuple(
                    x + offset
                    for offset in range(len(node))
                ))
                # print('DEBUG 7:', print_coords[1])
            else:
                # more space on X axis
                node = node[:col_max - col_min]  # cut the node
                print_coords[0] = tuple(
                    x + offset
                    for offset in range(len(node))
                )
                # print('DEBUG 8:', print_coords[0])

        for letter, i, j in zip(node, *print_coords):
            matrix_view[i, j] = letter




    if construction:
        yield view.build(matrix_view)
    else:
        yield from view.build(matrix_view)
277243
function _prettyGraphSONString(ugly) {
        var lines = ugly.trim().split(require('os').EOL);
        var vertices = _.map(lines, function (line) { return _parseVertex(line); });
        vertices.sort(_compareById);
        // Compute the stable JSON.
        var stringifyOpts = {
            space: 2
        };
        var prettyString = jsonStableStringify(vertices, stringifyOpts) + '\n';
        return prettyString;
    }
434926
function createGraphvizOptions(config) {
	const graphVizOptions = config.graphVizOptions || {};

	return {
		G: Object.assign({
			overlap: false,
			pad: 0.3,
			rankdir: config.rankdir,
			layout: config.layout,
			bgcolor: config.backgroundColor
		}, graphVizOptions.G),
		E: Object.assign({
			color: config.edgeColor
		}, graphVizOptions.E),
		N: Object.assign({
			fontname: config.fontName,
			fontsize: config.fontSize,
			color: config.nodeColor,
			shape: config.nodeShape,
			style: config.nodeStyle,
			height: 0,
			fontcolor: config.nodeColor
		}, graphVizOptions.N)
	};
}
373894
function () {
		var center = this.center,
			chart = this.chart,
			titleOptions = this.options.title;
		
		return { 
			x: chart.plotLeft + center[0] + (titleOptions.x || 0), 
			y: chart.plotTop + center[1] - ({ high: 0.5, middle: 0.25, low: 0 }[titleOptions.align] * 
				center[2]) + (titleOptions.y || 0)  
		};
	}
1083582
function Area( graph ) {

	// INSTANCE ATTRIBUTES //

	this._parent = graph;
	this._root = undefined;
	this._children = {};
	this._config = {
		"type": "area",
		"interpolation": {
			"mode": "linear",
			"tension": 0.7
		},
		"labels": []
	};

	// DATA //

	this._data = graph._data;

	// TRANSFORMS //

	this._transforms = {
		'x': function X( d ) {
			return graph._xScale( d[ 0 ] );
		},
		'y0': function Y0( d ) {
			return graph._yScale( 0 );
		},
		'y1': function Y1( d ) {
			return graph._yScale( 0 + d[ 1 ] );
		}
	};

	// GENERATOR //

	this._path = this.path()
		.x( this._transforms.x )
		.y0( this._transforms.y0 )
		.y1( this._transforms.y1 )
		.interpolate( this._config.interpolation.mode )
		.tension( this._config.interpolation.tension );

	// REGISTER //
	if ( graph._config.hasOwnProperty( 'marks' ) ) {
		graph._config.marks.push( this._config );
	} else {
		graph._config.marks = [ this._config ];
	}
	if ( graph._children.hasOwnProperty( 'marks' ) ) {
		graph._children.marks.push( this );
	} else {
		graph._children.marks = [ this ];
	}

	return this;
}
822363
function aliasesInLayout(layout, sizes){
    return Object.keys(computeLayout(layout, sizes, {
      width: 100,
      height: 100
    }));
  }
942396
function buildSceneGraph(scene) {
	    var fontSize = App.defaults.size;
	    if (parseFloat(scene.theme.size)) {
	        fontSize = scene.theme.size;
	    } else if (parseFloat(scene.flags.size)) {
	        fontSize = scene.flags.size;
	    }

	    scene.font = {
	        family: scene.theme.font ? scene.theme.font : 'Arial, Helvetica, Open Sans, sans-serif',
	        size: textSize(scene.width, scene.height, fontSize, App.defaults.scale),
	        units: scene.theme.units ? scene.theme.units : App.defaults.units,
	        weight: scene.theme.fontweight ? scene.theme.fontweight : 'bold'
	    };

	    scene.text = scene.theme.text || Math.floor(scene.width) + 'x' + Math.floor(scene.height);

	    scene.noWrap = scene.theme.nowrap || scene.flags.nowrap;

	    scene.align = scene.theme.align || scene.flags.align || 'center';

	    switch (scene.flags.textmode) {
	        case 'literal':
	            scene.text = scene.flags.dimensions.width + 'x' + scene.flags.dimensions.height;
	            break;
	        case 'exact':
	            if (!scene.flags.exactDimensions) break;
	            scene.text = Math.floor(scene.flags.exactDimensions.width) + 'x' + Math.floor(scene.flags.exactDimensions.height);
	            break;
	    }

	    var lineWrap = scene.flags.lineWrap || App.setup.lineWrapRatio;
	    var sceneMargin = scene.width * lineWrap;
	    var maxLineWidth = sceneMargin;

	    var sceneGraph = new SceneGraph({
	        width: scene.width,
	        height: scene.height
	    });

	    var Shape = sceneGraph.Shape;

	    var holderBg = new Shape.Rect('holderBg', {
	        fill: scene.theme.bg
	    });

	    holderBg.resize(scene.width, scene.height);
	    sceneGraph.root.add(holderBg);

	    if (scene.flags.outline) {
	        var outlineColor = new Color(holderBg.properties.fill);
	        outlineColor = outlineColor.lighten(outlineColor.lighterThan('7f7f7f') ? -0.1 : 0.1);
	        holderBg.properties.outline = {
	            fill: outlineColor.toHex(true),
	            width: 2
	        };
	    }

	    var holderTextColor = scene.theme.fg;

	    if (scene.flags.autoFg) {
	        var holderBgColor = new Color(holderBg.properties.fill);
	        var lightColor = new Color('fff');
	        var darkColor = new Color('000', {
	            'alpha': 0.285714
	        });

	        holderTextColor = holderBgColor.blendAlpha(holderBgColor.lighterThan('7f7f7f') ? darkColor : lightColor).toHex(true);
	    }

	    var holderTextGroup = new Shape.Group('holderTextGroup', {
	        text: scene.text,
	        align: scene.align,
	        font: scene.font,
	        fill: holderTextColor
	    });

	    holderTextGroup.moveTo(null, null, 1);
	    sceneGraph.root.add(holderTextGroup);

	    var tpdata = holderTextGroup.textPositionData = stagingRenderer(sceneGraph);
	    if (!tpdata) {
	        throw 'Holder: staging fallback not supported yet.';
	    }
	    holderTextGroup.properties.leading = tpdata.boundingBox.height;

	    var textNode = null;
	    var line = null;

	    function finalizeLine(parent, line, width, height) {
	        line.width = width;
	        line.height = height;
	        parent.width = Math.max(parent.width, line.width);
	        parent.height += line.height;
	    }

	    if (tpdata.lineCount > 1) {
	        var offsetX = 0;
	        var offsetY = 0;
	        var lineIndex = 0;
	        var lineKey;
	        line = new Shape.Group('line' + lineIndex);

	        //Double margin so that left/right-aligned next is not flush with edge of image
	        if (scene.align === 'left' || scene.align === 'right') {
	            maxLineWidth = scene.width * (1 - (1 - lineWrap) * 2);
	        }

	        for (var i = 0; i < tpdata.words.length; i++) {
	            var word = tpdata.words[i];
	            textNode = new Shape.Text(word.text);
	            var newline = word.text == '\\n';
	            if (!scene.noWrap && (offsetX + word.width >= maxLineWidth || newline === true)) {
	                finalizeLine(holderTextGroup, line, offsetX, holderTextGroup.properties.leading);
	                holderTextGroup.add(line);
	                offsetX = 0;
	                offsetY += holderTextGroup.properties.leading;
	                lineIndex += 1;
	                line = new Shape.Group('line' + lineIndex);
	                line.y = offsetY;
	            }
	            if (newline === true) {
	                continue;
	            }
	            textNode.moveTo(offsetX, 0);
	            offsetX += tpdata.spaceWidth + word.width;
	            line.add(textNode);
	        }

	        finalizeLine(holderTextGroup, line, offsetX, holderTextGroup.properties.leading);
	        holderTextGroup.add(line);

	        if (scene.align === 'left') {
	            holderTextGroup.moveTo(scene.width - sceneMargin, null, null);
	        } else if (scene.align === 'right') {
	            for (lineKey in holderTextGroup.children) {
	                line = holderTextGroup.children[lineKey];
	                line.moveTo(scene.width - line.width, null, null);
	            }

	            holderTextGroup.moveTo(0 - (scene.width - sceneMargin), null, null);
	        } else {
	            for (lineKey in holderTextGroup.children) {
	                line = holderTextGroup.children[lineKey];
	                line.moveTo((holderTextGroup.width - line.width) / 2, null, null);
	            }

	            holderTextGroup.moveTo((scene.width - holderTextGroup.width) / 2, null, null);
	        }

	        holderTextGroup.moveTo(null, (scene.height - holderTextGroup.height) / 2, null);

	        //If the text exceeds vertical space, move it down so the first line is visible
	        if ((scene.height - holderTextGroup.height) / 2 < 0) {
	            holderTextGroup.moveTo(null, 0, null);
	        }
	    } else {
	        textNode = new Shape.Text(scene.text);
	        line = new Shape.Group('line0');
	        line.add(textNode);
	        holderTextGroup.add(line);

	        if (scene.align === 'left') {
	            holderTextGroup.moveTo(scene.width - sceneMargin, null, null);
	        } else if (scene.align === 'right') {
	            holderTextGroup.moveTo(0 - (scene.width - sceneMargin), null, null);
	        } else {
	            holderTextGroup.moveTo((scene.width - tpdata.boundingBox.width) / 2, null, null);
	        }

	        holderTextGroup.moveTo(null, (scene.height - tpdata.boundingBox.height) / 2, null);
	    }

	    //todo: renderlist
	    return sceneGraph;
	}
1230705
function getBoundaries(graph, config, level, orn, prop) {
    var dim = config.Node;
    var multitree = config.multitree;
    if (dim.overridable) {
      var w = -1, h = -1;
      graph.eachNode(function(n) {
        if (n._depth == level
            && (!multitree || ('$orn' in n.data) && n.data.$orn == orn)) {
          var dw = n.getData('width', prop);
          var dh = n.getData('height', prop);
          w = (w < dw) ? dw : w;
          h = (h < dh) ? dh : h;
        }
      });
      return {
        'width' : w < 0 ? dim.width : w,
        'height' : h < 0 ? dim.height : h
      };
    } else {
      return dim;
    }
  }
981819
function(modes) {
      var graph = this.viz.graph,
          accessors = {
            'node-property': {
              'getter': 'getData',
              'setter': 'setData'
            },
            'edge-property': {
              'getter': 'getData',
              'setter': 'setData'
            },
            'node-style': {
              'getter': 'getCanvasStyle',
              'setter': 'setCanvasStyle'
            },
            'edge-style': {
              'getter': 'getCanvasStyle',
              'setter': 'setCanvasStyle'
            }
          };

      //parse modes
      var m = {};
      if($.type(modes) == 'array') {
        for(var i=0, len=modes.length; i < len; i++) {
          var elems = modes[i].split(':');
          m[elems.shift()] = elems;
        }
      } else {
        for(var p in modes) {
          if(p == 'position') {
            m[modes.position] = [];
          } else {
            m[p] = $.splat(modes[p]);
          }
        }
      }
      
      graph.eachNode(function(node) { 
        node.startPos.set(node.pos);
        $.each(['node-property', 'node-style'], function(p) {
          if(p in m) {
            var prop = m[p];
            for(var i=0, l=prop.length; i < l; i++) {
              node[accessors[p].setter](prop[i], node[accessors[p].getter](prop[i]), 'start');
            }
          }
        });
        $.each(['edge-property', 'edge-style'], function(p) {
          if(p in m) {
            var prop = m[p];
            node.eachAdjacency(function(adj) {
              for(var i=0, l=prop.length; i < l; i++) {
                adj[accessors[p].setter](prop[i], adj[accessors[p].getter](prop[i]), 'start');
              }
            });
          }
        });
      });
      return m;
    }
691163
function layoutPositions(layout, options, fn) {
    var nodes = this.nodes();
    var cy = this.cy();
    var layoutEles = options.eles; // nodes & edges

    var getMemoizeKey = function getMemoizeKey(node) {
      return node.id();
    };

    var fnMem = memoize(fn, getMemoizeKey); // memoized version of position function

    layout.emit({
      type: 'layoutstart',
      layout: layout
    });
    layout.animations = [];

    var calculateSpacing = function calculateSpacing(spacing, nodesBb, pos) {
      var center = {
        x: nodesBb.x1 + nodesBb.w / 2,
        y: nodesBb.y1 + nodesBb.h / 2
      };
      var spacingVector = {
        // scale from center of bounding box (not necessarily 0,0)
        x: (pos.x - center.x) * spacing,
        y: (pos.y - center.y) * spacing
      };
      return {
        x: center.x + spacingVector.x,
        y: center.y + spacingVector.y
      };
    };

    var useSpacingFactor = options.spacingFactor && options.spacingFactor !== 1;

    var spacingBb = function spacingBb() {
      if (!useSpacingFactor) {
        return null;
      }

      var bb = makeBoundingBox();

      for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        var pos = fnMem(node, i);
        expandBoundingBoxByPoint(bb, pos.x, pos.y);
      }

      return bb;
    };

    var bb = spacingBb();
    var getFinalPos = memoize(function (node, i) {
      var newPos = fnMem(node, i);

      if (useSpacingFactor) {
        var spacing = Math.abs(options.spacingFactor);
        newPos = calculateSpacing(spacing, bb, newPos);
      }

      if (options.transform != null) {
        newPos = options.transform(node, newPos);
      }

      return newPos;
    }, getMemoizeKey);

    if (options.animate) {
      for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        var newPos = getFinalPos(node, i);
        var animateNode = options.animateFilter == null || options.animateFilter(node, i);

        if (animateNode) {
          var ani = node.animation({
            position: newPos,
            duration: options.animationDuration,
            easing: options.animationEasing
          });
          layout.animations.push(ani);
        } else {
          node.position(newPos);
        }
      }

      if (options.fit) {
        var fitAni = cy.animation({
          fit: {
            boundingBox: layoutEles.boundingBoxAt(getFinalPos),
            padding: options.padding
          },
          duration: options.animationDuration,
          easing: options.animationEasing
        });
        layout.animations.push(fitAni);
      } else if (options.zoom !== undefined && options.pan !== undefined) {
        var zoomPanAni = cy.animation({
          zoom: options.zoom,
          pan: options.pan,
          duration: options.animationDuration,
          easing: options.animationEasing
        });
        layout.animations.push(zoomPanAni);
      }

      layout.animations.forEach(function (ani) {
        return ani.play();
      });
      layout.one('layoutready', options.ready);
      layout.emit({
        type: 'layoutready',
        layout: layout
      });
      Promise$1.all(layout.animations.map(function (ani) {
        return ani.promise();
      })).then(function () {
        layout.one('layoutstop', options.stop);
        layout.emit({
          type: 'layoutstop',
          layout: layout
        });
      });
    } else {
      nodes.positions(getFinalPos);

      if (options.fit) {
        cy.fit(options.eles, options.padding);
      }

      if (options.zoom != null) {
        cy.zoom(options.zoom);
      }

      if (options.pan) {
        cy.pan(options.pan);
      }

      layout.one('layoutready', options.ready);
      layout.emit({
        type: 'layoutready',
        layout: layout
      });
      layout.one('layoutstop', options.stop);
      layout.emit({
        type: 'layoutstop',
        layout: layout
      });
    }

    return this; // chaining
  }