summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/adaptagrams/libcola
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/adaptagrams/libcola')
-rw-r--r--src/3rdparty/adaptagrams/libcola/CMakeLists.txt30
-rw-r--r--src/3rdparty/adaptagrams/libcola/Makefile.am60
-rw-r--r--src/3rdparty/adaptagrams/libcola/box.cpp111
-rw-r--r--src/3rdparty/adaptagrams/libcola/box.h82
-rw-r--r--src/3rdparty/adaptagrams/libcola/cc_clustercontainmentconstraints.cpp194
-rw-r--r--src/3rdparty/adaptagrams/libcola/cc_clustercontainmentconstraints.h52
-rw-r--r--src/3rdparty/adaptagrams/libcola/cc_nonoverlapconstraints.cpp590
-rw-r--r--src/3rdparty/adaptagrams/libcola/cc_nonoverlapconstraints.h210
-rw-r--r--src/3rdparty/adaptagrams/libcola/cluster.cpp719
-rw-r--r--src/3rdparty/adaptagrams/libcola/cluster.h371
-rw-r--r--src/3rdparty/adaptagrams/libcola/cola.cpp700
-rw-r--r--src/3rdparty/adaptagrams/libcola/cola.h1002
-rw-r--r--src/3rdparty/adaptagrams/libcola/cola_log.h204
-rw-r--r--src/3rdparty/adaptagrams/libcola/colafd.cpp1681
-rw-r--r--src/3rdparty/adaptagrams/libcola/commondefs.h98
-rw-r--r--src/3rdparty/adaptagrams/libcola/compound_constraints.cpp1671
-rw-r--r--src/3rdparty/adaptagrams/libcola/compound_constraints.h829
-rw-r--r--src/3rdparty/adaptagrams/libcola/conjugate_gradient.cpp137
-rw-r--r--src/3rdparty/adaptagrams/libcola/conjugate_gradient.h36
-rw-r--r--src/3rdparty/adaptagrams/libcola/connected_components.cpp160
-rw-r--r--src/3rdparty/adaptagrams/libcola/connected_components.h54
-rw-r--r--src/3rdparty/adaptagrams/libcola/convex_hull.cpp129
-rw-r--r--src/3rdparty/adaptagrams/libcola/convex_hull.h31
-rw-r--r--src/3rdparty/adaptagrams/libcola/doc/description.doc50
-rw-r--r--src/3rdparty/adaptagrams/libcola/exceptions.h54
-rw-r--r--src/3rdparty/adaptagrams/libcola/gradient_projection.cpp482
-rw-r--r--src/3rdparty/adaptagrams/libcola/gradient_projection.h165
-rw-r--r--src/3rdparty/adaptagrams/libcola/libcola.pc.in11
-rw-r--r--src/3rdparty/adaptagrams/libcola/output_svg.cpp389
-rw-r--r--src/3rdparty/adaptagrams/libcola/output_svg.h80
-rw-r--r--src/3rdparty/adaptagrams/libcola/pseudorandom.cpp48
-rw-r--r--src/3rdparty/adaptagrams/libcola/pseudorandom.h44
-rw-r--r--src/3rdparty/adaptagrams/libcola/shapepair.cpp47
-rw-r--r--src/3rdparty/adaptagrams/libcola/shapepair.h49
-rw-r--r--src/3rdparty/adaptagrams/libcola/shortest_paths.h245
-rw-r--r--src/3rdparty/adaptagrams/libcola/sparse_matrix.h140
-rw-r--r--src/3rdparty/adaptagrams/libcola/straightener.cpp798
-rw-r--r--src/3rdparty/adaptagrams/libcola/straightener.h389
-rwxr-xr-xsrc/3rdparty/adaptagrams/libcola/tests/FixedRelativeConstraint01.cpp51
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/Makefile.am68
-rwxr-xr-xsrc/3rdparty/adaptagrams/libcola/tests/StillOverlap01.cpp221
-rwxr-xr-xsrc/3rdparty/adaptagrams/libcola/tests/StillOverlap02.cpp1863
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/boundary.cpp121
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/connected_components.cpp69
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/constrained.cpp99
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/containment.cpp89
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/containment2.cpp157
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/convex_hull.cpp180
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/cycle_detector.cpp386
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/data/1138_bus.txt1458
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/data/uetzNetworkGSC-all.gml26139
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/gml_graph.cpp257
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/graphlayouttest.h275
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/initialOverlap.cpp168
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/invalid.cpp80
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/large_graph.cpp144
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/makefeasible.cpp368
-rwxr-xr-xsrc/3rdparty/adaptagrams/libcola/tests/makefeasible02.cpp932
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/makemovie.sh10
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/max_acyclic_subgraph.cpp346
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/overlappingClusters01.cpp333
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/overlappingClusters02.cpp100
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/overlappingClusters04.cpp61
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/page_bounds.cpp102
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/planar.cpp287
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/random_graph.cpp113
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/rectangularClusters01.cpp1135
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/rectclustershapecontainment.cpp2173
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/resize.cpp132
-rwxr-xr-xsrc/3rdparty/adaptagrams/libcola/tests/runtest.sh8
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/scale_free.cpp135
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/shortest_paths.cpp140
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/small_graph.cpp111
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/sparse_matrix.cpp88
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/test_cg.cpp164
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/topology.cpp177
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/trees.cpp103
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/unconstrained.cpp71
-rw-r--r--src/3rdparty/adaptagrams/libcola/tests/unsatisfiable.cpp85
-rwxr-xr-xsrc/3rdparty/adaptagrams/libcola/tests/view_cd_output.sh43
-rwxr-xr-xsrc/3rdparty/adaptagrams/libcola/tests/view_mas_output.sh43
-rw-r--r--src/3rdparty/adaptagrams/libcola/unused.h26
82 files changed, 51253 insertions, 0 deletions
diff --git a/src/3rdparty/adaptagrams/libcola/CMakeLists.txt b/src/3rdparty/adaptagrams/libcola/CMakeLists.txt
new file mode 100644
index 0000000..59bbacc
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/CMakeLists.txt
@@ -0,0 +1,30 @@
+
+set(libcola_SRC
+ box.cpp
+ cluster.cpp
+ cola.cpp
+ convex_hull.cpp
+ compound_constraints.cpp
+ conjugate_gradient.cpp
+ connected_components.cpp
+ gradient_projection.cpp
+ shapepair.cpp
+ straightener.cpp
+
+
+ # -------
+ # Headers
+ box.h
+ cluster.h
+ cola.h
+ compound_constraints.h
+ conjugate_gradient.h
+ convex_hull.h
+ gradient_projection.h
+ shapepair.cpp
+ shortest_paths.h
+ straightener.h
+)
+
+include_directories("${CMAKE_CURRENT_SOURCE_DIR}/..")
+add_inkscape_lib(cola_LIB "${libcola_SRC}")
diff --git a/src/3rdparty/adaptagrams/libcola/Makefile.am b/src/3rdparty/adaptagrams/libcola/Makefile.am
new file mode 100644
index 0000000..e35f7ae
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/Makefile.am
@@ -0,0 +1,60 @@
+EXTRA_DIST=libcola.pc.in
+
+lib_LTLIBRARIES = libcola.la
+libcola_la_CPPFLAGS = -I$(top_srcdir) $(CAIROMM_CFLAGS) -I$(includedir)/libcola -fPIC
+
+# Depends on libvpsc
+libcola_la_LIBADD = $(top_builddir)/libvpsc/libvpsc.la $(CAIROMM_LIBS)
+
+libcola_la_SOURCES = cola.h\
+ cola.cpp\
+ colafd.cpp\
+ conjugate_gradient.cpp\
+ conjugate_gradient.h\
+ exceptions.h\
+ gradient_projection.cpp\
+ gradient_projection.h\
+ shortest_paths.h\
+ straightener.h\
+ straightener.cpp\
+ connected_components.cpp\
+ convex_hull.h\
+ convex_hull.cpp\
+ cluster.cpp\
+ compound_constraints.h\
+ compound_constraints.cpp\
+ pseudorandom.h \
+ pseudorandom.cpp \
+ output_svg.cpp\
+ output_svg.h \
+ unused.h \
+ cc_clustercontainmentconstraints.cpp \
+ cc_clustercontainmentconstraints.h \
+ cc_nonoverlapconstraints.cpp \
+ cc_nonoverlapconstraints.h \
+ box.cpp \
+ box.h \
+ shapepair.cpp \
+ shapepainr.h
+
+libcolaincludedir = $(includedir)/libcola
+libcolainclude_HEADERS = cola.h\
+ cluster.h\
+ commondefs.h\
+ compound_constraints.h\
+ pseudorandom.h \
+ exceptions.h\
+ gradient_projection.h\
+ sparse_matrix.h\
+ straightener.h \
+ output_svg.h \
+ unused.h \
+ cc_clustercontainmentconstraints.h \
+ cc_nonoverlapconstraints.h \
+ box.h \
+ shapepair.h
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libcola.pc
+
+SUBDIRS = . tests
diff --git a/src/3rdparty/adaptagrams/libcola/box.cpp b/src/3rdparty/adaptagrams/libcola/box.cpp
new file mode 100644
index 0000000..8ad3cba
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/box.cpp
@@ -0,0 +1,111 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Michael Wybrow
+ *
+*/
+
+#include "libcola/box.h"
+
+namespace cola {
+
+Box::Box(double xMin, double xMax, double yMin, double yMax)
+{
+ m_min[vpsc::XDIM] = nonNegative(xMin);
+ m_max[vpsc::XDIM] = nonNegative(xMax);
+ m_min[vpsc::YDIM] = nonNegative(yMin);
+ m_max[vpsc::YDIM] = nonNegative(yMax);
+}
+
+Box::Box(double all)
+{
+ double value = nonNegative(all);
+ m_min[vpsc::XDIM] = value;
+ m_max[vpsc::XDIM] = value;
+ m_min[vpsc::YDIM] = value;
+ m_max[vpsc::YDIM] = value;
+}
+
+Box::Box()
+{
+ m_min[vpsc::XDIM] = 0;
+ m_max[vpsc::XDIM] = 0;
+ m_min[vpsc::YDIM] = 0;
+ m_max[vpsc::YDIM] = 0;
+}
+
+Box::~Box()
+{
+}
+
+bool Box::empty(void) const
+{
+ // values will be nonnegative so can sum to check if empty.
+ int total = m_min[vpsc::XDIM] + m_max[vpsc::XDIM] +
+ m_min[vpsc::YDIM] + m_max[vpsc::YDIM];
+ return (total == 0);
+}
+
+void Box::outputCode(FILE *fp) const
+{
+ if ((m_min[vpsc::XDIM] == m_max[vpsc::XDIM]) &&
+ (m_min[vpsc::XDIM] == m_min[vpsc::YDIM]) &&
+ (m_min[vpsc::XDIM] == m_max[vpsc::YDIM]))
+ {
+ fprintf(fp, "Box(%g)", m_min[vpsc::XDIM]);
+ }
+ else
+ {
+ fprintf(fp, "Box(%g, %g, %g, %g)", m_min[vpsc::XDIM],
+ m_max[vpsc::XDIM], m_min[vpsc::YDIM], m_max[vpsc::YDIM]);
+ }
+}
+
+vpsc::Rectangle Box::rectangleByApplyingBox(
+ const vpsc::Rectangle rectangle) const
+{
+ if (!rectangle.isValid())
+ {
+ return rectangle;
+ }
+
+ return vpsc::Rectangle(
+ rectangle.getMinX() - m_min[vpsc::XDIM],
+ rectangle.getMaxX() + m_max[vpsc::XDIM],
+ rectangle.getMinY() - m_min[vpsc::YDIM],
+ rectangle.getMaxY() + m_max[vpsc::YDIM]);
+}
+
+double Box::nonNegative(double value)
+{
+ return (value >= 0) ? value: 0;
+}
+
+double Box::min(size_t dim) const
+{
+ return (dim < 2) ? m_min[dim] : 0;
+}
+
+double Box::max(size_t dim) const
+{
+ return (dim < 2) ? m_max[dim] : 0;
+}
+
+
+}
+
diff --git a/src/3rdparty/adaptagrams/libcola/box.h b/src/3rdparty/adaptagrams/libcola/box.h
new file mode 100644
index 0000000..ff8f018
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/box.h
@@ -0,0 +1,82 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Michael Wybrow
+ *
+*/
+
+#ifndef LIBCOLA_BOX_H
+#define LIBCOLA_BOX_H
+
+#include <cstdio>
+
+#include "libvpsc/rectangle.h"
+
+
+namespace cola {
+
+/**
+ * @brief A box consisting of four edge values for representing padding or
+ * margins for rectangles.
+ */
+class Box
+{
+ public:
+ /**
+ * @brief Constructs a padding or margin box consisting of a value for
+ * each edge.
+ *
+ * Values should be nonnegative.
+ *
+ * @param[in] xMin Minimum horizontal value.
+ * @param[in] xMax Maximum horizontal value.
+ * @param[in] yMin Minimum vertical value.
+ * @param[in] yMax Maximum vertical value.
+ */
+ Box(double xMin, double xMax, double yMin, double yMax);
+ /**
+ * @brief Constructs a padding or margin box consisting of a value for
+ * each edge.
+ *
+ * Values should be nonnegative.
+ *
+ * @param[in] all The value to be used for all four edges.
+ */
+ Box(double all);
+ /**
+ * @brief Constructs an empty padding or margin box.
+ */
+ Box();
+ ~Box();
+
+ bool empty(void) const;
+ double min(size_t dim) const;
+ double max(size_t dim) const;
+ void outputCode(FILE *fp) const;
+ vpsc::Rectangle rectangleByApplyingBox(
+ const vpsc::Rectangle rectangle) const;
+
+ private:
+ static double nonNegative(double value);
+
+ double m_min[2];
+ double m_max[2];
+};
+
+} // namespace cola
+#endif
diff --git a/src/3rdparty/adaptagrams/libcola/cc_clustercontainmentconstraints.cpp b/src/3rdparty/adaptagrams/libcola/cc_clustercontainmentconstraints.cpp
new file mode 100644
index 0000000..390f5e1
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cc_clustercontainmentconstraints.cpp
@@ -0,0 +1,194 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2010 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Michael Wybrow
+ *
+*/
+
+#include <sstream>
+
+#include "libcola/cola.h"
+#include "libcola/compound_constraints.h"
+#include "libcola/cc_clustercontainmentconstraints.h"
+
+using vpsc::XDIM;
+using vpsc::YDIM;
+
+
+namespace cola {
+
+static const int AboveBoundary = 1;
+static const int BelowBoundary = -1;
+
+class ClusterShapeOffsets : public SubConstraintInfo
+{
+ public:
+ ClusterShapeOffsets(unsigned ind, vpsc::Dim dim, double offset, int boundarySide,
+ unsigned int boundaryVar) :
+ SubConstraintInfo(ind),
+ offset(offset),
+ dim(dim),
+ boundarySide(boundarySide),
+ boundaryVar(boundaryVar)
+ {
+ }
+ double offset; // half the width or height value
+ vpsc::Dim dim; // The dimension
+ int boundarySide; // The boundary side we are constraining on.
+ unsigned int boundaryVar; // The boundary var.
+};
+
+
+ClusterContainmentConstraints::ClusterContainmentConstraints(Cluster *cluster,
+ unsigned int priority, std::vector<vpsc::Rectangle*>& boundingBoxes)
+ : CompoundConstraint(vpsc::HORIZONTAL, priority)
+{
+ Box padding = cluster->padding();
+ _combineSubConstraints = true;
+ for (std::set<unsigned>::iterator curr = cluster->nodes.begin();
+ curr != cluster->nodes.end(); ++curr)
+ {
+ unsigned id = *curr;
+ double halfW = (boundingBoxes[id]->width() / 2.0);
+ double halfH = (boundingBoxes[id]->height() / 2.0);
+ _subConstraintInfo.push_back(new ClusterShapeOffsets(
+ id, XDIM, halfW + padding.min(XDIM), AboveBoundary,
+ cluster->clusterVarId));
+ _subConstraintInfo.push_back(new ClusterShapeOffsets(
+ id, XDIM, halfW + padding.max(XDIM), BelowBoundary,
+ cluster->clusterVarId + 1));
+ _subConstraintInfo.push_back(new ClusterShapeOffsets(
+ id, YDIM, halfH + padding.min(YDIM), AboveBoundary,
+ cluster->clusterVarId));
+ _subConstraintInfo.push_back(new ClusterShapeOffsets(
+ id, YDIM, halfH + padding.max(YDIM), BelowBoundary,
+ cluster->clusterVarId + 1));
+ }
+ for (std::vector<Cluster *>::iterator curr = cluster->clusters.begin();
+ curr != cluster->clusters.end(); ++curr)
+ {
+ Cluster *childCluster = *curr;
+ Box margin = childCluster->margin();
+ _subConstraintInfo.push_back(new ClusterShapeOffsets(
+ childCluster->clusterVarId, XDIM,
+ padding.min(XDIM) + margin.min(XDIM), AboveBoundary,
+ cluster->clusterVarId));
+ _subConstraintInfo.push_back(new ClusterShapeOffsets(
+ childCluster->clusterVarId + 1, XDIM,
+ padding.max(XDIM) + margin.max(XDIM), BelowBoundary,
+ cluster->clusterVarId + 1));
+ _subConstraintInfo.push_back(new ClusterShapeOffsets(
+ childCluster->clusterVarId, YDIM,
+ padding.min(YDIM) + margin.min(YDIM), AboveBoundary,
+ cluster->clusterVarId));
+ _subConstraintInfo.push_back(new ClusterShapeOffsets(
+ childCluster->clusterVarId + 1, YDIM,
+ padding.max(YDIM) + margin.max(YDIM), BelowBoundary,
+ cluster->clusterVarId + 1));
+ }
+}
+
+
+std::string ClusterContainmentConstraints::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "ClusterContainmentConstraints()";
+ return stream.str();
+}
+
+
+void ClusterContainmentConstraints::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ COLA_UNUSED(dim);
+ COLA_UNUSED(vars);
+}
+
+
+
+SubConstraintAlternatives
+ClusterContainmentConstraints::getCurrSubConstraintAlternatives(vpsc::Variables vs[])
+{
+ SubConstraintAlternatives alternatives;
+
+ ClusterShapeOffsets *info = static_cast<ClusterShapeOffsets *>
+ (_subConstraintInfo[_currSubConstraintIndex]);
+
+ assertValidVariableIndex(vs[_primaryDim], info->varIndex);
+ if (info->boundarySide == BelowBoundary)
+ {
+ // Constrain the objects with negative offsets to be
+ // to the left of the boundary.
+ vpsc::Constraint constraint = vpsc::Constraint(
+ vs[info->dim][info->varIndex], vs[info->dim][info->boundaryVar],
+ info->offset);
+ alternatives.push_back(SubConstraint(info->dim, constraint));
+ }
+ else
+ {
+ // Constrain the objects with positive offsets to be
+ // to the right of the boundary.
+ vpsc::Constraint constraint = vpsc::Constraint(
+ vs[info->dim][info->boundaryVar], vs[info->dim][info->varIndex],
+ info->offset);
+ alternatives.push_back(SubConstraint(info->dim, constraint));
+ }
+
+ //fprintf(stderr, "===== BOUNDARYLINE ALTERNATIVES -======\n");
+ return alternatives;
+}
+
+
+void ClusterContainmentConstraints::generateSeparationConstraints(
+ const vpsc::Dim dim, vpsc::Variables& vs, vpsc::Constraints& cs,
+ std::vector<vpsc::Rectangle*>& bbs)
+{
+ COLA_UNUSED(bbs);
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ ClusterShapeOffsets *info = static_cast<ClusterShapeOffsets *> (*o);
+
+ if (info->dim != dim)
+ {
+ continue;
+ }
+
+ vpsc::Constraint *constraint = nullptr;
+ if (info->boundarySide == BelowBoundary)
+ {
+ // Constrain the objects with negative offsets to be
+ // to the left of the boundary.
+ constraint = new vpsc::Constraint(vs[info->varIndex],
+ vs[info->boundaryVar], info->offset);
+ }
+ else
+ {
+ // Constrain the objects with positive offsets to be
+ // to the right of the boundary.
+ constraint = new vpsc::Constraint(vs[info->boundaryVar],
+ vs[info->varIndex], info->offset);
+ }
+ constraint->creator = this;
+ cs.push_back(constraint);
+ }
+}
+
+
+} // namespace cola
+
diff --git a/src/3rdparty/adaptagrams/libcola/cc_clustercontainmentconstraints.h b/src/3rdparty/adaptagrams/libcola/cc_clustercontainmentconstraints.h
new file mode 100644
index 0000000..5fbe75e
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cc_clustercontainmentconstraints.h
@@ -0,0 +1,52 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2010 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Michael Wybrow
+ *
+*/
+
+#ifndef COLA_CC_CLUSTERCONTAINMENTCONSTRAINTS_H
+#define COLA_CC_CLUSTERCONTAINMENTCONSTRAINTS_H
+
+#include <vector>
+#include "libcola/compound_constraints.h"
+
+namespace vpsc {
+class Rectangle;
+}
+
+namespace cola {
+
+class ClusterContainmentConstraints : public CompoundConstraint
+{
+ public:
+ ClusterContainmentConstraints(Cluster *cluster, unsigned int priority,
+ std::vector<vpsc::Rectangle*>& boundingBoxes);
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& cs,
+ std::vector<vpsc::Rectangle*>& bbs);
+ std::string toString(void) const;
+};
+
+
+} // namespace cola
+#endif // COLA_CC_CLUSTERCONTAINMENTCONSTRAINTS
diff --git a/src/3rdparty/adaptagrams/libcola/cc_nonoverlapconstraints.cpp b/src/3rdparty/adaptagrams/libcola/cc_nonoverlapconstraints.cpp
new file mode 100644
index 0000000..69502d0
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cc_nonoverlapconstraints.cpp
@@ -0,0 +1,590 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2010-2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Michael Wybrow
+ *
+*/
+
+#include <sstream>
+
+#include "libcola/cola.h"
+#include "libcola/compound_constraints.h"
+#include "libcola/cc_nonoverlapconstraints.h"
+
+using vpsc::XDIM;
+using vpsc::YDIM;
+
+
+namespace cola {
+
+//-----------------------------------------------------------------------------
+// NonOverlapConstraintExemptions code
+//-----------------------------------------------------------------------------
+
+NonOverlapConstraintExemptions::NonOverlapConstraintExemptions()
+{
+}
+
+void NonOverlapConstraintExemptions::addExemptGroupOfNodes(
+ ListOfNodeIndexes listOfNodeGroups)
+{
+ m_exempt_pairs.clear();
+
+ const size_t listSize = listOfNodeGroups.size();
+ for (size_t l = 0; l < listSize; ++l)
+ {
+ NodeIndexes ids(listOfNodeGroups[l]);
+
+ // Sort and remove duplicate IDs for this group.
+ std::sort(ids.begin(), ids.end());
+ NodeIndexes::iterator last = std::unique(ids.begin(), ids.end());
+ ids.erase(last, ids.end());
+
+ // Add all combinations of pairs of IDs for this group to m_exempt_pairs
+ const size_t idsSize = ids.size();
+ for (size_t i = 0; i < idsSize; ++i)
+ {
+ for (size_t j = i + 1; j < idsSize; ++j)
+ {
+ m_exempt_pairs.insert(ShapePair(ids[i], ids[j]));
+ }
+ }
+
+ }
+}
+
+bool NonOverlapConstraintExemptions::shapePairIsExempt(
+ ShapePair shapePair) const
+{
+ return (m_exempt_pairs.count(shapePair) == 1);
+}
+
+//-----------------------------------------------------------------------------
+// NonOverlapConstraints code
+//-----------------------------------------------------------------------------
+
+NonOverlapConstraints::NonOverlapConstraints(
+ NonOverlapConstraintExemptions *exemptions, unsigned int priority)
+ : CompoundConstraint(vpsc::HORIZONTAL, priority),
+ pairInfoListSorted(false),
+ initialSortCompleted(false),
+ m_exemptions(exemptions)
+{
+ // All work is done by repeated addShape() calls.
+}
+
+void NonOverlapConstraints::addShape(unsigned id, double halfW, double halfH,
+ unsigned int group, std::set<unsigned> exemptions)
+{
+ // Setup pairInfos for all other shapes.
+ for (std::map<unsigned, OverlapShapeOffsets>::iterator curr =
+ shapeOffsets.begin(); curr != shapeOffsets.end(); ++curr)
+ {
+ unsigned otherId = curr->first;
+ if ((shapeOffsets[otherId].group == group) && (id != otherId) && exemptions.count(otherId)==0)
+ {
+ if (m_exemptions &&
+ m_exemptions->shapePairIsExempt(ShapePair(otherId, id)))
+ {
+ continue;
+ }
+
+ // Apply non-overlap only to objects in the same group (cluster).
+ pairInfoList.push_back(ShapePairInfo(otherId, id));
+ }
+ }
+
+ shapeOffsets[id] = OverlapShapeOffsets(id, halfW, halfH, group);
+}
+
+void NonOverlapConstraints::resizeShape(unsigned id, double halfW, double halfH)
+{
+ OverlapShapeOffsets oso = shapeOffsets[id];
+ oso.resize(halfW, halfH);
+}
+
+void NonOverlapConstraints::removeShape(unsigned id)
+{
+ // Remove the OverlapShapeOffsets object for this id.
+ shapeOffsets.erase(id);
+ // Remove all ShapePairInfo objects having this id as one of their two indices.
+ std::list<ShapePairInfo>::iterator it = pairInfoList.begin();
+ while (it != pairInfoList.end()) {
+ ShapePairInfo spi = *it;
+ if (spi.varIndex1==id || spi.varIndex2==id) {
+ it = pairInfoList.erase(it); // now it points to next list element after one erased
+ } else {
+ it++;
+ }
+ }
+}
+
+// This is expected to be called after all addNode calls.
+void NonOverlapConstraints::addCluster(Cluster *cluster, unsigned int group)
+{
+ unsigned id = cluster->clusterVarId;
+ // Setup pairInfos for all other shapes.
+ for (std::map<unsigned, OverlapShapeOffsets>::iterator curr =
+ shapeOffsets.begin(); curr != shapeOffsets.end(); ++curr)
+ {
+ unsigned otherId = curr->first;
+ if (shapeOffsets[otherId].group != group)
+ {
+ // Don't apply if not in same group.
+ continue;
+ }
+ if (cluster->nodes.count(otherId) > 0)
+ {
+ // Don't apply non-overlap to child nodes.
+ continue;
+ }
+ if (m_cluster_cluster_exemptions.count(ShapePair(id, otherId)) > 0)
+ {
+ // Don't apply if exempt due to non-strict cluster hierarchy.
+ continue;
+ }
+ // Apply non-overlap only to objects in the same group (cluster).
+ pairInfoList.push_back(ShapePairInfo(otherId, id));
+ }
+
+ shapeOffsets[id] = OverlapShapeOffsets(id, cluster, group);
+}
+
+
+void NonOverlapConstraints::setClusterClusterExemptions(
+ std::set<ShapePair> exemptions)
+{
+ m_cluster_cluster_exemptions = exemptions;
+}
+
+void NonOverlapConstraints::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ COLA_UNUSED(dim);
+ COLA_UNUSED(vars);
+}
+
+void NonOverlapConstraints::computeOverlapForShapePairInfo(ShapePairInfo& info,
+ vpsc::Variables vs[])
+{
+ OverlapShapeOffsets& shape1 = shapeOffsets[info.varIndex1];
+ OverlapShapeOffsets& shape2 = shapeOffsets[info.varIndex2];
+
+ double xPos1 = vs[0][info.varIndex1]->finalPosition;
+ double xPos2 = vs[0][info.varIndex2]->finalPosition;
+ double yPos1 = vs[1][info.varIndex1]->finalPosition;
+ double yPos2 = vs[1][info.varIndex2]->finalPosition;
+
+ double left1 = xPos1 - shape1.halfDim[0];
+ double right1 = xPos1 + shape1.halfDim[0];
+ double bottom1 = yPos1 - shape1.halfDim[1];
+ double top1 = yPos1 + shape1.halfDim[1];
+
+ if (shape1.cluster)
+ {
+ COLA_ASSERT(shape1.halfDim[0] == 0);
+ COLA_ASSERT(shape1.halfDim[1] == 0);
+ COLA_ASSERT(info.varIndex1 + 1 < vs[0].size());
+ right1 = vs[0][info.varIndex1 + 1]->finalPosition;
+ COLA_ASSERT(info.varIndex1 + 1 < vs[1].size());
+ top1 = vs[1][info.varIndex1 + 1]->finalPosition;
+ left1 -= shape1.rectPadding.min(XDIM);
+ bottom1 -= shape1.rectPadding.min(YDIM);
+ right1 += shape1.rectPadding.max(XDIM);
+ top1 += shape1.rectPadding.max(YDIM);
+ }
+
+ double left2 = xPos2 - shape2.halfDim[0];
+ double right2 = xPos2 + shape2.halfDim[0];
+ double bottom2 = yPos2 - shape2.halfDim[1];
+ double top2 = yPos2 + shape2.halfDim[1];
+
+ if (shape2.cluster)
+ {
+ COLA_ASSERT(shape2.halfDim[0] == 0);
+ COLA_ASSERT(shape2.halfDim[1] == 0);
+ COLA_ASSERT(info.varIndex2 + 1 < vs[0].size());
+ right2 = vs[0][info.varIndex2 + 1]->finalPosition;
+ COLA_ASSERT(info.varIndex2 + 1 < vs[1].size());
+ top2 = vs[1][info.varIndex2 + 1]->finalPosition;
+ left2 -= shape2.rectPadding.min(XDIM);
+ bottom2 -= shape2.rectPadding.min(YDIM);
+ right2 += shape2.rectPadding.max(XDIM);
+ top2 += shape2.rectPadding.max(YDIM);
+ }
+
+ // If lr < 0, then left edge of shape1 is on the left
+ // of right edge of shape2.
+ double spaceR = left2 - right1;
+ double spaceL = left1 - right2;
+ // Below
+ double spaceA = bottom2 - top1;
+ // Above
+ double spaceB = bottom1 - top2;
+
+ double costL = 0;
+ double costR = 0;
+ double costB = 0;
+ double costA = 0;
+ info.overlapMax = 0;
+ bool xOverlap = false;
+ bool yOverlap = false;
+ if ((spaceR < 0) && (spaceL < 0))
+ {
+ costL = std::max(-spaceL, 0.0);
+ costR = std::max(-spaceR, 0.0);
+
+ info.overlapMax = std::max(costL, costR);
+
+ xOverlap = true;
+ }
+ if ((spaceB < 0) && (spaceA < 0))
+ {
+ costB = std::max(-spaceB, 0.0);
+ costA = std::max(-spaceA, 0.0);
+
+ info.overlapMax = std::max(info.overlapMax, costB);
+ info.overlapMax = std::max(info.overlapMax, costA);
+
+ yOverlap = true;
+ }
+
+ if (!xOverlap || !yOverlap)
+ {
+ // Overlap must occur in both dimensions.
+ info.overlapMax = 0;
+ }
+ else
+ {
+ // Increase the overlap value for overlap where one shape is fully
+ // within the other. This results in these situations being
+ // resolved first and will sometimes prevent us from committing to
+ // bad non-overlap choices and getting stuck later.
+ // XXX Another alternative would be to look at previously added
+ // non-overlap constraints that become unsatified and then
+ // allow them to be rechosen maybe just a single time.
+ double penalty = 100000;
+ if ( (left1 >= left2) && (right1 <= right2) &&
+ (bottom1 >= bottom2) && (top1 <= top2) )
+ {
+ // Shape 1 is inside shape 2.
+ double smallShapeArea = (right1 - left1) * (top1 - bottom1);
+ info.overlapMax = penalty + smallShapeArea;
+ }
+ else if ( (left2 >= left1) && (right2 <= right1) &&
+ (bottom2 >= bottom1) && (top2 <= top1) )
+ {
+ // Shape 2 is inside shape 1.
+ double smallShapeArea = (right2 - left2) * (top2 - bottom2);
+ info.overlapMax = penalty + smallShapeArea;
+ }
+ // There is overlap.
+ //printf("[%02d][%02d] L %g, R %G, B %g, A %g\n", info.varIndex1,
+ // info.varIndex2, spaceL, spaceR, spaceB, spaceA);
+ }
+}
+
+std::string NonOverlapConstraints::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "NonOverlapConstraints()";
+ return stream.str();
+}
+
+void NonOverlapConstraints::computeAndSortOverlap(vpsc::Variables vs[])
+{
+ for (std::list<ShapePairInfo>::iterator curr = pairInfoList.begin();
+ curr != pairInfoList.end(); ++curr)
+ {
+ ShapePairInfo& info = static_cast<ShapePairInfo&> (*curr);
+
+ if (info.processed)
+ {
+ // Once we reach the processed nodes, which will always be at
+ // the back, we can some computing overlap since this no longer
+ // matters.
+ break;
+ }
+ computeOverlapForShapePairInfo(info, vs);
+ }
+ pairInfoList.sort();
+}
+
+
+void NonOverlapConstraints::markCurrSubConstraintAsActive(const bool satisfiable)
+{
+ ShapePairInfo info = pairInfoList.front();
+ pairInfoList.pop_front();
+
+ info.processed = true;
+ info.satisfied = satisfiable;
+ info.overlapMax = 0;
+
+ pairInfoList.push_back(info);
+ pairInfoListSorted = false;
+}
+
+
+
+SubConstraintAlternatives
+NonOverlapConstraints::getCurrSubConstraintAlternatives(vpsc::Variables vs[])
+{
+ SubConstraintAlternatives alternatives;
+ if (initialSortCompleted == false)
+ {
+ // Initally sort the shape pair info objects.
+ computeAndSortOverlap(vs);
+ pairInfoListSorted = true;
+ initialSortCompleted = true;
+ }
+
+ // Take the first in the list.
+ ShapePairInfo& info = pairInfoList.front();
+ if (pairInfoListSorted == false)
+ {
+ // Only need to compute if not sorted.
+ computeOverlapForShapePairInfo(info, vs);
+ }
+
+ if (info.overlapMax == 0)
+ {
+ if (pairInfoListSorted)
+ {
+ // Seeing no overlap in the sorted list means we have solved
+ // all non-overlap. Nothing more to do.
+ _currSubConstraintIndex = pairInfoList.size();
+ return alternatives;
+ }
+ computeAndSortOverlap(vs);
+ pairInfoListSorted = true;
+ return alternatives;
+ }
+ OverlapShapeOffsets& shape1 = shapeOffsets[info.varIndex1];
+ OverlapShapeOffsets& shape2 = shapeOffsets[info.varIndex2];
+
+ double xSepL = shape1.halfDim[0] + shape2.halfDim[0];
+ double ySepB = shape1.halfDim[1] + shape2.halfDim[1];
+ double xSepR = xSepL;
+ double ySepT = ySepB;
+
+ unsigned varIndexL1 = info.varIndex1;
+ unsigned varIndexL2 = info.varIndex2;
+ // Clusters have left and right variables, instead of centre variables.
+ unsigned varIndexR1 =
+ (shape1.cluster) ? (info.varIndex1 + 1) : info.varIndex1;
+ unsigned varIndexR2 =
+ (shape2.cluster) ? (info.varIndex2 + 1) : info.varIndex2;
+
+ assertValidVariableIndex(vs[XDIM], varIndexL1);
+ assertValidVariableIndex(vs[YDIM], varIndexL1);
+ assertValidVariableIndex(vs[XDIM], varIndexR1);
+ assertValidVariableIndex(vs[YDIM], varIndexR1);
+ assertValidVariableIndex(vs[XDIM], varIndexL2);
+ assertValidVariableIndex(vs[YDIM], varIndexL2);
+ assertValidVariableIndex(vs[XDIM], varIndexR2);
+ assertValidVariableIndex(vs[YDIM], varIndexR2);
+
+ //
+ double xSepCostL = xSepL;
+ double xSepCostR = xSepR;
+ double ySepCostB = ySepB;
+ double ySepCostT = ySepT;
+
+ double desiredX1 = vs[XDIM][info.varIndex1]->desiredPosition;
+ double desiredY1 = vs[YDIM][info.varIndex1]->desiredPosition;
+ double desiredX2 = vs[XDIM][info.varIndex2]->desiredPosition;
+ double desiredY2 = vs[YDIM][info.varIndex2]->desiredPosition;
+
+ // Clusters have two variables instead of a centre variable -- one for
+ // each boundary side, so we need to remap the desired positions and the
+ // separations values for the purposes of cost sorting.
+ if (shape1.cluster)
+ {
+ double width = vs[XDIM][info.varIndex1 + 1]->finalPosition -
+ vs[XDIM][info.varIndex1]->finalPosition;
+ double height = vs[YDIM][info.varIndex1 + 1]->finalPosition -
+ vs[YDIM][info.varIndex1]->finalPosition;
+ desiredX1 += width / 2;
+ desiredY1 += height / 2;
+ xSepCostL += width / 2;
+ xSepCostR += width / 2;
+ ySepCostB += height / 2;
+ ySepCostT += height / 2;
+ xSepL += shape1.rectPadding.min(XDIM);
+ xSepR += shape1.rectPadding.max(XDIM);
+ ySepB += shape1.rectPadding.min(YDIM);
+ ySepT += shape1.rectPadding.max(YDIM);
+ }
+ if (shape2.cluster)
+ {
+ double width = vs[XDIM][info.varIndex2 + 1]->finalPosition -
+ vs[XDIM][info.varIndex2]->finalPosition;
+ double height = vs[YDIM][info.varIndex2 + 1]->finalPosition -
+ vs[YDIM][info.varIndex2]->finalPosition;
+ desiredX2 += width / 2;
+ desiredY2 += height / 2;
+ xSepCostL += width / 2;
+ xSepCostR += width / 2;
+ ySepCostB += height / 2;
+ ySepCostT += height / 2;
+ xSepL += shape2.rectPadding.min(XDIM);
+ xSepR += shape2.rectPadding.max(XDIM);
+ ySepB += shape2.rectPadding.min(YDIM);
+ ySepT += shape2.rectPadding.max(YDIM);
+ }
+
+ // We get problems with numerical inaccuracy in the topology constraint
+ // generation, so make sure the rectagles are separated by at least a
+ // tiny distance.
+ xSepL += 10e-10;
+ xSepR += 10e-10;
+ ySepB += 10e-10;
+ ySepT += 10e-10;
+
+ // Compute the cost to move in each direction based on the
+ // desired positions for the two objects.
+ double costR = xSepCostR - (desiredX2 - desiredX1);
+ double costL = xSepCostL - (desiredX1 - desiredX2);
+
+ double costT = ySepCostT - (desiredY2 - desiredY1);
+ double costB = ySepCostB - (desiredY1 - desiredY2);
+
+ vpsc::Constraint constraintL(vs[XDIM][varIndexR2],
+ vs[XDIM][varIndexL1], xSepL);
+ alternatives.push_back(SubConstraint(XDIM, constraintL, costL));
+
+ vpsc::Constraint constraintR(vs[XDIM][varIndexR1],
+ vs[XDIM][varIndexL2], xSepR);
+ alternatives.push_back(SubConstraint(XDIM, constraintR, costR));
+
+ vpsc::Constraint constraintB(vs[YDIM][varIndexR2],
+ vs[YDIM][varIndexL1], ySepB);
+ alternatives.push_back(SubConstraint(YDIM, constraintB, costB));
+
+ vpsc::Constraint constraintT(vs[YDIM][varIndexR1],
+ vs[YDIM][varIndexL2], ySepT);
+ alternatives.push_back(SubConstraint(YDIM, constraintT, costT));
+
+ //fprintf(stderr, "===== NONOVERLAP ALTERNATIVES -====== \n");
+
+ return alternatives;
+}
+
+
+bool NonOverlapConstraints::subConstraintsRemaining(void) const
+{
+ //printf(". %3d of %4d\n", _currSubConstraintIndex, pairInfoList.size());
+ return _currSubConstraintIndex < pairInfoList.size();
+}
+
+
+void NonOverlapConstraints::markAllSubConstraintsAsInactive(void)
+{
+ for (std::list<ShapePairInfo>::iterator curr = pairInfoList.begin();
+ curr != pairInfoList.end(); ++curr)
+ {
+ ShapePairInfo& info = (*curr);
+ info.satisfied = false;
+ info.processed = false;
+ }
+ _currSubConstraintIndex = 0;
+ initialSortCompleted = false;
+}
+
+
+void NonOverlapConstraints::generateSeparationConstraints(
+ const vpsc::Dim dim, vpsc::Variables& vs, vpsc::Constraints& cs,
+ std::vector<vpsc::Rectangle*>& boundingBoxes)
+{
+ for (std::list<ShapePairInfo>::iterator info = pairInfoList.begin();
+ info != pairInfoList.end(); ++info)
+ {
+ assertValidVariableIndex(vs, info->varIndex1);
+ assertValidVariableIndex(vs, info->varIndex2);
+
+ OverlapShapeOffsets& shape1 = shapeOffsets[info->varIndex1];
+ OverlapShapeOffsets& shape2 = shapeOffsets[info->varIndex2];
+
+ vpsc::Rectangle rect1 = (shape1.cluster) ?
+ shape1.cluster->bounds : *boundingBoxes[info->varIndex1];
+ vpsc::Rectangle rect2 = (shape2.cluster) ?
+ shape2.cluster->bounds : *boundingBoxes[info->varIndex2];
+
+ double pos1 = rect1.getCentreD(dim);
+ double pos2 = rect2.getCentreD(dim);
+
+ double below1 = shape1.halfDim[dim];
+ double above1 = shape1.halfDim[dim];
+ double below2 = shape2.halfDim[dim];
+ double above2 = shape2.halfDim[dim];
+
+ vpsc::Variable *varLeft1 = nullptr;
+ vpsc::Variable *varLeft2 = nullptr;
+ vpsc::Variable *varRight1 = nullptr;
+ vpsc::Variable *varRight2 = nullptr;
+ if (shape1.cluster)
+ {
+ // Must constraint to cluster boundary variables.
+ varLeft1 = vs[shape1.cluster->clusterVarId];
+ varRight1 = vs[shape1.cluster->clusterVarId + 1];
+ rect1 = shape1.cluster->margin().rectangleByApplyingBox(rect1);
+ below1 = shape1.cluster->margin().min(dim);
+ above1 = shape1.cluster->margin().max(dim);
+ }
+ else
+ {
+ // Must constrain to rectangle centre postion variable.
+ varLeft1 = varRight1 = vs[info->varIndex1];
+ }
+
+ if (shape2.cluster)
+ {
+ // Must constraint to cluster boundary variables.
+ varLeft2 = vs[shape2.cluster->clusterVarId];
+ varRight2 = vs[shape2.cluster->clusterVarId + 1];
+ rect2 = shape2.cluster->margin().rectangleByApplyingBox(rect2);
+ below2 = shape2.cluster->margin().min(dim);
+ above2 = shape2.cluster->margin().max(dim);
+ }
+ else
+ {
+ // Must constrain to rectangle centre postion variable.
+ varLeft2 = varRight2 = vs[info->varIndex2];
+ }
+
+ if (rect1.overlapD(!dim, &rect2) > 0.0005)
+ {
+ vpsc::Constraint *constraint = nullptr;
+ if (pos1 < pos2)
+ {
+ constraint = new vpsc::Constraint(varRight1, varLeft2,
+ above1 + below2);
+ }
+ else
+ {
+ constraint = new vpsc::Constraint(varRight2, varLeft1,
+ below1 + above2);
+ }
+ constraint->creator = this;
+ cs.push_back(constraint);
+ }
+ }
+}
+
+
+} // namespace cola
diff --git a/src/3rdparty/adaptagrams/libcola/cc_nonoverlapconstraints.h b/src/3rdparty/adaptagrams/libcola/cc_nonoverlapconstraints.h
new file mode 100644
index 0000000..0904ece
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cc_nonoverlapconstraints.h
@@ -0,0 +1,210 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2010-2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Michael Wybrow
+ *
+*/
+
+#ifndef COLA_CC_NONOVERLAPCONSTRAINTS_H
+#define COLA_CC_NONOVERLAPCONSTRAINTS_H
+
+#include <vector>
+
+#include "libcola/cola.h"
+#include "libcola/compound_constraints.h"
+#include "libcola/shapepair.h"
+
+namespace vpsc {
+class Rectangle;
+}
+
+namespace cola {
+
+class Cluster;
+
+class OverlapShapeOffsets : public SubConstraintInfo
+{
+ public:
+ OverlapShapeOffsets(unsigned ind, double xOffset, double yOffset,
+ unsigned int group)
+ : SubConstraintInfo(ind),
+ cluster(nullptr),
+ rectPadding(0),
+ group(group)
+ {
+ halfDim[0] = xOffset;
+ halfDim[1] = yOffset;
+ }
+ OverlapShapeOffsets(unsigned ind, Cluster *cluster, unsigned int group)
+ : SubConstraintInfo(ind),
+ cluster(cluster),
+ rectPadding(cluster->margin()),
+ group(group)
+ {
+ halfDim[0] = 0;
+ halfDim[1] = 0;
+ }
+ OverlapShapeOffsets()
+ : SubConstraintInfo(1000000),
+ cluster(nullptr),
+ rectPadding(0)
+ {
+ }
+ bool usesClusterBounds(void) const
+ {
+ return (cluster && !cluster->clusterIsFromFixedRectangle());
+ }
+ void resize(double xOffset, double yOffset)
+ {
+ halfDim[0] = xOffset;
+ halfDim[1] = yOffset;
+ }
+ Cluster *cluster;
+ double halfDim[2]; // Half width and height values.
+ Box rectPadding; // Used for cluster padding.
+ unsigned int group;
+};
+
+
+class ShapePairInfo
+{
+ public:
+ ShapePairInfo(unsigned ind1, unsigned ind2, unsigned ord = 1)
+ : order(ord),
+ satisfied(false),
+ processed(false)
+ {
+ COLA_ASSERT(ind1 != ind2);
+ // Assign the lesser value to varIndex1.
+ varIndex1 = (ind1 < ind2) ? ind1 : ind2;
+ // Assign the greater value to varIndex2.
+ varIndex2 = (ind1 > ind2) ? ind1 : ind2;
+ }
+ bool operator<(const ShapePairInfo& rhs) const
+ {
+ // Make sure the processed ones are at the end after sorting.
+ int processedInt = processed ? 1 : 0;
+ int rhsProcessedInt = rhs.processed ? 1 : 0;
+ if (processedInt != rhsProcessedInt)
+ {
+ return processedInt < rhsProcessedInt;
+ }
+ // Use cluster ordering for primary sorting.
+ if (order != rhs.order)
+ {
+ return order < rhs.order;
+ }
+ return overlapMax > rhs.overlapMax;
+ }
+ unsigned short order;
+ unsigned short varIndex1;
+ unsigned short varIndex2;
+ bool satisfied;
+ bool processed;
+ double overlapMax;
+};
+
+
+// Stores IDs of all rectangles exempt from non-overlap constraints.
+class NonOverlapConstraintExemptions {
+ public:
+ NonOverlapConstraintExemptions();
+ void addExemptGroupOfNodes(ListOfNodeIndexes listOfNodeGroups);
+ bool shapePairIsExempt(ShapePair shapePair) const;
+ std::set<ShapePair> getExemptPairs(void) {return m_exempt_pairs;}
+
+ private:
+ std::set<ShapePair> m_exempt_pairs;
+};
+
+// Non-overlap constraints prevent a set of given shapes from overlapping.
+class NonOverlapConstraints : public CompoundConstraint {
+ public:
+ NonOverlapConstraints(NonOverlapConstraintExemptions *exemptions,
+ unsigned int priority = PRIORITY_NONOVERLAP);
+ //! @brief Use this method to add all the shapes between which you want
+ //! to prevent overlaps.
+ //! @param id This will be used as index into both the vars and
+ //! boundingBoxes vectors when you call the
+ //! generateSeparationConstraints method.
+ //! @param halfW If you add two shapes with half-widths hwi and hwj, then
+ //! if a horizontal separation constraint is generated between
+ //! them its gap will be hwi + hwj.
+ //! @param halfH Similar to halfW.
+ //! @param group Assign a group number to this shape. A separation constraint
+ //! will be generated between two shapes only if they belong to
+ //! the same group. This is useful for clusters.
+ //! @param exemptions Optional set of IDs of shapes to be skipped, i.e. such that
+ //! a separation constraint should /not/ be generated between
+ //! that shape and the one being added.
+ void addShape(unsigned id, double halfW, double halfH,
+ unsigned int group = 1, std::set<unsigned> exemptions = std::set<unsigned>());
+ void resizeShape(unsigned id, double halfW, double halfH);
+ void removeShape(unsigned id);
+ void addCluster(Cluster *cluster, unsigned int group);
+ void computeAndSortOverlap(vpsc::Variables vs[]);
+ void markCurrSubConstraintAsActive(const bool satisfiable);
+ void markAllSubConstraintsAsInactive(void);
+ bool subConstraintsRemaining(void) const;
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ std::string toString(void) const;
+ void setClusterClusterExemptions(std::set<ShapePair> exemptions);
+
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& gcs);
+ //! @brief Generate separation constraints in one dimension, to ensure
+ //! nonoverlap between all shapes in that dimension.
+ //! @param dim The dimension for which to generate constraints.
+ //! @param vars The variables between which the constraints will hold.
+ //! @param gcs The generated constraints will be added to this vector.
+ //! @param boundingBoxes For those id's corresponding to added shapes
+ //! (not clusters), the rectangle boundingBox[id] will be consulted
+ //! in order to determine:
+ //! (1) whether a separation constraint is called for, i.e. whether the
+ //! shapes in question span any of the same coods in the dimension
+ //! opposite to dim;
+ //! (2) which var is left and which is right in the separation constraint.
+ //! Note however that the dimensions of the boundingBoxes do NOT determine
+ //! the gaps of the separation constraints, which are instead based on the
+ //! half-width and half-height passed when adding the shapes.
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& gcs,
+ std::vector<vpsc::Rectangle*>& boundingBoxes);
+
+ private:
+ void computeOverlapForShapePairInfo(ShapePairInfo& info,
+ vpsc::Variables vs[]);
+
+ std::list<ShapePairInfo> pairInfoList;
+ std::map<unsigned, OverlapShapeOffsets> shapeOffsets;
+ bool pairInfoListSorted;
+ bool initialSortCompleted;
+
+ // Cluster variables
+ size_t clusterVarStartIndex;
+ size_t currClusterIndex;
+ size_t clusterMode;
+
+ NonOverlapConstraintExemptions *m_exemptions;
+ std::set<ShapePair> m_cluster_cluster_exemptions;
+};
+
+} // namespace cola
+#endif // COLA_CC_NONOVERLAPCONSTRAINTS
diff --git a/src/3rdparty/adaptagrams/libcola/cluster.cpp b/src/3rdparty/adaptagrams/libcola/cluster.cpp
new file mode 100644
index 0000000..6fbfc0b
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cluster.cpp
@@ -0,0 +1,719 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+ * Michael Wybrow
+*/
+
+#include "libvpsc/assertions.h"
+#include "libcola/commondefs.h"
+#include "libcola/cola.h"
+#include "libcola/convex_hull.h"
+#include "libcola/cluster.h"
+
+using vpsc::generateXConstraints;
+using vpsc::generateYConstraints;
+using namespace std;
+
+namespace cola {
+
+Cluster::Cluster()
+ : bounds(),
+ clusterVarId(0),
+ varWeight(0.0001),
+ internalEdgeWeightFactor(1.),
+ desiredBoundsSet(false),
+ desiredBounds()
+{
+ // XXX We use a really low weight here until we properly set the source
+ // of the variable value back in updatePositions() type manner.
+ varWeight = 0.0000001;
+}
+
+Cluster::~Cluster()
+{
+ for_each(clusters.begin(), clusters.end(), delete_object());
+ clusters.clear();
+}
+
+void Cluster::setDesiredBounds(const vpsc::Rectangle db)
+{
+ desiredBoundsSet = true;
+ desiredBounds = db;
+}
+
+void Cluster::unsetDesiredBounds(void)
+{
+ desiredBoundsSet=false;
+}
+
+
+// Checks to see if the shape at the given index is contained within this
+// cluster or its child clusters.
+//
+void Cluster::countContainedNodes(std::vector<unsigned>& counts)
+{
+ vector<unsigned> invalidNodes;
+ for (set<unsigned>::iterator it = nodes.begin(); it != nodes.end(); ++it)
+ {
+ unsigned nodeIndex = *it;
+ if (nodeIndex < counts.size())
+ {
+ // Node index is valid, increase count.
+ counts[*it] += 1;
+ }
+ else
+ {
+ fprintf(stderr, "Warning: Invalid node index %u specified in "
+ "cluster. Ignoring...\n", nodeIndex);
+ invalidNodes.push_back(nodeIndex);
+ }
+ }
+ for (size_t i = 0; i < invalidNodes.size(); ++i)
+ {
+ nodes.erase(invalidNodes[i]);
+ }
+
+ for (vector<Cluster*>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->countContainedNodes(counts);
+ }
+}
+
+void Cluster::computeBoundingRect(const vpsc::Rectangles& rs)
+{
+ bounds = vpsc::Rectangle();
+ for (vector<Cluster*>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->computeBoundingRect(rs);
+ vpsc::Rectangle rectangle =
+ (*i)->margin().rectangleByApplyingBox((*i)->bounds);
+ bounds = bounds.unionWith(rectangle);
+ }
+ for (set<unsigned>::const_iterator i = nodes.begin();
+ i != nodes.end(); ++i)
+ {
+ vpsc::Rectangle* r=rs[*i];
+ bounds = bounds.unionWith(*r);
+ }
+ bounds = padding().rectangleByApplyingBox(bounds);
+}
+
+void Cluster::computeVarRect(vpsc::Variables& vars, size_t dim)
+{
+ if ((clusterVarId > 0) && (vars.size() > clusterVarId))
+ {
+ varRect.setMinD(dim, vars[clusterVarId]->finalPosition);
+ varRect.setMaxD(dim, vars[clusterVarId + 1]->finalPosition);
+ }
+
+ for (vector<Cluster*>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->computeVarRect(vars, dim);
+ }
+}
+
+bool Cluster::clusterIsFromFixedRectangle(void) const
+{
+ return false;
+}
+
+void ConvexCluster::computeBoundary(const vpsc::Rectangles& rs)
+{
+ unsigned n = 4 * nodes.size();
+ valarray<double> X(n);
+ valarray<double> Y(n);
+ unsigned pctr = 0;
+ vector<unsigned> nodesVector(nodes.begin(), nodes.end());
+ for (size_t i = 0; i < nodesVector.size(); ++i)
+ {
+ vpsc::Rectangle* r=rs[nodesVector[i]];
+ // Bottom Right
+ X[pctr]=r->getMaxX();
+ Y[pctr++]=r->getMinY();
+ // Top Right
+ X[pctr]=r->getMaxX();
+ Y[pctr++]=r->getMaxY();
+ // Top Left
+ X[pctr]=r->getMinX();
+ Y[pctr++]=r->getMaxY();
+ // Bottom Left
+ X[pctr]=r->getMinX();
+ Y[pctr++]=r->getMinY();
+ }
+ /*
+ for(unsigned i=0;i<n;i++) {
+ printf("X[%d]=%f, Y[%d]=%f;\n",i,X[i],i,Y[i]);
+ }
+ */
+ vector<unsigned> hull;
+ hull::convex(X,Y,hull);
+ hullX.resize(hull.size());
+ hullY.resize(hull.size());
+ hullRIDs.resize(hull.size());
+ hullCorners.resize(hull.size());
+ for (unsigned j=0;j<hull.size();j++)
+ {
+ hullX[j]=X[hull[j]];
+ hullY[j]=Y[hull[j]];
+ hullRIDs[j]=nodesVector[hull[j]/4];
+ hullCorners[j]=hull[j]%4;
+ }
+}
+
+
+void ConvexCluster::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " ConvexCluster *cluster%llu = new ConvexCluster();\n",
+ (unsigned long long) this);
+ for(set<unsigned>::const_iterator i = nodes.begin();
+ i != nodes.end(); ++i)
+ {
+ fprintf(fp, " cluster%llu->addChildNode(%u);\n",
+ (unsigned long long) this, *i);
+ }
+ for(vector<Cluster *>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->printCreationCode(fp);
+ fprintf(fp, " cluster%llu->addChildCluster(cluster%llu);\n",
+ (unsigned long long) this, (unsigned long long) *i);
+ }
+}
+
+void ConvexCluster::outputToSVG(FILE *fp) const
+{
+ for(vector<Cluster *>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->outputToSVG(fp);
+ }
+}
+
+
+RectangularCluster::RectangularCluster()
+ : Cluster(),
+ m_rectangle_index(-1),
+ m_margin(0),
+ m_padding(0)
+{
+ minEdgeRect[vpsc::XDIM] = nullptr;
+ minEdgeRect[vpsc::YDIM] = nullptr;
+ maxEdgeRect[vpsc::XDIM] = nullptr;
+ maxEdgeRect[vpsc::YDIM] = nullptr;
+}
+
+RectangularCluster::RectangularCluster(unsigned rectIndex)
+ : Cluster(),
+ m_rectangle_index(rectIndex),
+ m_margin(0),
+ m_padding(0)
+{
+ minEdgeRect[vpsc::XDIM] = nullptr;
+ minEdgeRect[vpsc::YDIM] = nullptr;
+ maxEdgeRect[vpsc::XDIM] = nullptr;
+ maxEdgeRect[vpsc::YDIM] = nullptr;
+}
+
+RectangularCluster::~RectangularCluster()
+{
+ for (size_t dim = 0; dim < 2; ++dim)
+ {
+ if (minEdgeRect[dim])
+ {
+ delete minEdgeRect[dim];
+ minEdgeRect[dim] = nullptr;
+ }
+ if (maxEdgeRect[dim])
+ {
+ delete maxEdgeRect[dim];
+ maxEdgeRect[dim] = nullptr;
+ }
+ }
+}
+
+void RectangularCluster::setMargin(const Box margin)
+{
+ m_margin = margin;
+}
+
+
+void RectangularCluster::setMargin(double margin)
+{
+ m_margin = Box(margin);
+}
+
+
+Box RectangularCluster::margin(void) const
+{
+ return m_margin;
+}
+
+
+void RectangularCluster::setPadding(const Box padding)
+{
+ m_padding = padding;
+}
+
+
+void RectangularCluster::setPadding(double padding)
+{
+ m_padding = Box(padding);
+}
+
+
+Box RectangularCluster::padding(void) const
+{
+ return m_padding;
+}
+
+
+void RectangularCluster::countContainedNodes(std::vector<unsigned>& counts)
+{
+ if (m_rectangle_index >= 0)
+ {
+ // This cluster is the shape in question.
+ counts[m_rectangle_index] += 1;
+ }
+ Cluster::countContainedNodes(counts);
+}
+
+
+void RectangularCluster::generateFixedRectangleConstraints(
+ cola::CompoundConstraints& idleConstraints,
+ vpsc::Rectangles& rc, vpsc::Variables (&vars)[2]) const
+{
+ COLA_UNUSED(vars);
+
+ if (m_rectangle_index < 0)
+ {
+ // Not based on a Rectangle.
+ return;
+ }
+
+ double halfWidth = rc[m_rectangle_index]->width() / 2;
+ double halfHeight = rc[m_rectangle_index]->height() / 2;
+
+ cola::SeparationConstraint *sc =
+ new cola::SeparationConstraint(vpsc::XDIM, clusterVarId,
+ m_rectangle_index, halfWidth, true);
+ idleConstraints.push_back(sc);
+ sc = new cola::SeparationConstraint(vpsc::XDIM,
+ m_rectangle_index, clusterVarId + 1, halfWidth, true);
+ idleConstraints.push_back(sc);
+
+ sc = new cola::SeparationConstraint(vpsc::YDIM,
+ clusterVarId, m_rectangle_index, halfHeight, true);
+ idleConstraints.push_back(sc);
+ sc = new cola::SeparationConstraint(vpsc::YDIM,
+ m_rectangle_index, clusterVarId + 1, halfHeight, true);
+ idleConstraints.push_back(sc);
+}
+
+
+void RectangularCluster::computeBoundary(const vpsc::Rectangles& rs)
+{
+ double xMin=DBL_MAX, xMax=-DBL_MAX, yMin=DBL_MAX, yMax=-DBL_MAX;
+ for (std::set<unsigned>::iterator it = nodes.begin();
+ it != nodes.end(); ++it)
+ {
+ xMin=std::min(xMin,rs[*it]->getMinX());
+ xMax=std::max(xMax,rs[*it]->getMaxX());
+ yMin=std::min(yMin,rs[*it]->getMinY());
+ yMax=std::max(yMax,rs[*it]->getMaxY());
+ }
+ hullX.resize(4);
+ hullY.resize(4);
+ hullX[3]=xMin;
+ hullY[3]=yMin;
+ hullX[2]=xMin;
+ hullY[2]=yMax;
+ hullX[1]=xMax;
+ hullY[1]=yMax;
+ hullX[0]=xMax;
+ hullY[0]=yMin;
+}
+
+
+void RectangularCluster::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " RectangularCluster *cluster%llu = "
+ "new RectangularCluster(",
+ (unsigned long long) this);
+ if (m_rectangle_index != -1)
+ {
+ fprintf(fp, "%d", m_rectangle_index);
+ }
+ fprintf(fp, ");\n");
+ if (!m_margin.empty())
+ {
+ fprintf(fp, " cluster%llu->setMargin(",
+ (unsigned long long) this);
+ m_margin.outputCode(fp);
+ fprintf(fp, ");\n");
+ }
+ if (!m_padding.empty())
+ {
+ fprintf(fp, " cluster%llu->setPadding(",
+ (unsigned long long) this);
+ m_padding.outputCode(fp);
+ fprintf(fp, ");\n");
+ }
+ for(set<unsigned>::const_iterator i = nodes.begin();
+ i != nodes.end(); ++i)
+ {
+ fprintf(fp, " cluster%llu->addChildNode(%u);\n",
+ (unsigned long long) this, *i);
+ }
+ for(vector<Cluster *>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->printCreationCode(fp);
+ fprintf(fp, " cluster%llu->addChildCluster(cluster%llu);\n",
+ (unsigned long long) this, (unsigned long long) *i);
+ }
+}
+
+void RectangularCluster::outputToSVG(FILE *fp) const
+{
+ double rounding = 4;
+ if (varRect.isValid())
+ {
+ fprintf(fp, "<rect id=\"cluster-%llu-r\" x=\"%g\" y=\"%g\" width=\"%g\" "
+ "height=\"%g\" style=\"stroke-width: 1px; stroke: black; "
+ "fill: green; fill-opacity: 0.3;\" rx=\"%g\" ry=\"%g\" />\n",
+ (unsigned long long) this, varRect.getMinX(), varRect.getMinY(),
+ varRect.getMaxX() - varRect.getMinX(),
+ varRect.getMaxY() - varRect.getMinY(), rounding, rounding);
+ }
+ else
+ {
+ fprintf(fp, "<rect id=\"cluster-%llu\" x=\"%g\" y=\"%g\" width=\"%g\" "
+ "height=\"%g\" style=\"stroke-width: 1px; stroke: black; "
+ "fill: red; fill-opacity: 0.3;\" rx=\"%g\" ry=\"%g\" />\n",
+ (unsigned long long) this, bounds.getMinX(), bounds.getMinY(),
+ bounds.getMaxX() - bounds.getMinX(),
+ bounds.getMaxY() - bounds.getMinY(), rounding, rounding);
+ }
+
+ for(vector<Cluster *>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->outputToSVG(fp);
+ }
+}
+
+
+
+int RectangularCluster::rectangleIndex(void) const
+{
+ return m_rectangle_index;
+}
+
+bool RectangularCluster::clusterIsFromFixedRectangle(void) const
+{
+ return (m_rectangle_index >= 0);
+}
+
+void RectangularCluster::computeBoundingRect(const vpsc::Rectangles& rs)
+{
+ if (clusterIsFromFixedRectangle())
+ {
+ // For bounds, just use this shape's rectangle.
+ bounds = *(rs[m_rectangle_index]);
+ }
+ else
+ {
+ Cluster::computeBoundingRect(rs);
+ }
+}
+void RectangularCluster::addChildNode(unsigned index)
+{
+ if ((m_rectangle_index == (int) index) && (m_rectangle_index > 0))
+ {
+ fprintf(stderr, "Warning: ignoring cluster (%u) added as child of "
+ "itself.\n", index);
+ return;
+ }
+ Cluster::addChildNode(index);
+}
+
+
+RootCluster::RootCluster()
+ : m_allows_multiple_parents(false)
+{
+}
+
+void Cluster::recPathToCluster(RootCluster *rootCluster, Clusters currentPath)
+{
+ // Reset cluster-cluster overlap exceptions.
+ m_cluster_cluster_overlap_exceptions.clear();
+ m_nodes_replaced_with_clusters.clear();
+ m_overlap_replacement_map.clear();
+
+ // Add this cluster to the path.
+ currentPath.push_back(this);
+
+ // Recusively all on each child cluster.
+ for (unsigned i = 0; i < clusters.size(); ++i)
+ {
+ clusters[i]->recPathToCluster(rootCluster, currentPath);
+ }
+
+ // And store the path to each child node.
+ for (std::set<unsigned>::iterator it = nodes.begin();
+ it != nodes.end(); ++it)
+ {
+ rootCluster->m_cluster_vectors_leading_to_nodes[*it].
+ push_back(currentPath);
+ }
+}
+
+
+void RootCluster::calculateClusterPathsToEachNode(size_t nodesCount)
+{
+ m_cluster_vectors_leading_to_nodes.clear();
+ m_cluster_vectors_leading_to_nodes.resize(nodesCount);
+
+ recPathToCluster(this, Clusters());
+
+ for (unsigned i = 0; i < m_cluster_vectors_leading_to_nodes.size(); ++i)
+ {
+ size_t paths = m_cluster_vectors_leading_to_nodes[i].size();
+ for (size_t j = 1; j < paths; ++j)
+ {
+ for (size_t k = 0; k < j; ++k)
+ {
+ // For each pair of paths.
+
+ // Find the lowest common ancestor by finding where the two
+ // paths from the root cluster to node i diverge.
+ Clusters pathJ = m_cluster_vectors_leading_to_nodes[i][j];
+ Clusters pathK = m_cluster_vectors_leading_to_nodes[i][k];
+ size_t lcaIndex = 0;
+ while ((lcaIndex < pathJ.size()) &&
+ (lcaIndex < pathK.size()) &&
+ (pathJ[lcaIndex] == pathK[lcaIndex]))
+ {
+ ++lcaIndex;
+ }
+ COLA_ASSERT(lcaIndex > 0);
+
+ // lcaIndex will be the clusters/nodes that need to overlap
+ // due to these two paths to node i.
+ size_t lcaChildJIndex = i;
+ size_t lcaChildKIndex = i;
+ Cluster *lcaChildJCluster = nullptr;
+ Cluster *lcaChildKCluster = nullptr;
+
+ // lcaIndex < path{J,K}.size() means the child J or K of
+ // the lca is a Cluster. At least one of them will always
+ // be a cluster.
+ COLA_ASSERT((lcaIndex < pathJ.size()) ||
+ (lcaIndex < pathK.size()));
+ if (lcaIndex < pathJ.size())
+ {
+ lcaChildJCluster = pathJ[lcaIndex];
+ lcaChildJIndex = lcaChildJCluster->clusterVarId;
+ }
+ if (lcaIndex < pathK.size())
+ {
+ lcaChildKCluster = pathK[lcaIndex];
+ lcaChildKIndex = lcaChildKCluster->clusterVarId;
+ }
+
+ // We want to exclude the overlapping children of the lca
+ // from having non-overlap constraints generated for them
+ // (siblings of a particular cluster usually have
+ // non-overlap constraints generated for them).
+ Cluster *lcaCluster = pathJ[lcaIndex - 1];
+ lcaCluster->m_cluster_cluster_overlap_exceptions.insert(
+ ShapePair(lcaChildJIndex, lcaChildKIndex));
+
+ if (lcaChildJCluster)
+ {
+ // In cluster J, replace node i with cluster K for the
+ // purpose of non-overlap with siblings, and remember
+ // this replacement so we can still generate non-overlap
+ // constraints between multiple nodes that are children
+ // of the same overlapping clusters.
+ lcaChildJCluster->m_overlap_replacement_map[i] =
+ lcaChildKCluster;
+ lcaChildJCluster->m_nodes_replaced_with_clusters.insert(i);
+ }
+
+ if (lcaChildKCluster)
+ {
+ // In cluster K, replace node i with cluster J for the
+ // purpose of non-overlap with siblings, and remember
+ // this replacement so we can still generate non-overlap
+ // constraints between multiple nodes that are children
+ // of the same overlapping clusters.
+ lcaChildKCluster->m_overlap_replacement_map[i] =
+ lcaChildJCluster;
+ lcaChildKCluster->m_nodes_replaced_with_clusters.insert(i);
+ }
+ }
+ }
+ }
+}
+
+
+void RootCluster::computeBoundary(const vpsc::Rectangles& rs)
+{
+ for (unsigned i = 0; i < clusters.size(); ++i)
+ {
+ clusters[i]->computeBoundary(rs);
+ }
+}
+
+void RootCluster::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " RootCluster *cluster%llu = new RootCluster();\n",
+ (unsigned long long) this);
+ for(set<unsigned>::const_iterator i = nodes.begin();
+ i != nodes.end(); ++i)
+ {
+ fprintf(fp, " cluster%llu->addChildNode(%u);\n",
+ (unsigned long long) this, *i);
+ }
+ for(vector<Cluster *>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->printCreationCode(fp);
+ fprintf(fp, " cluster%llu->addChildCluster(cluster%llu);\n",
+ (unsigned long long) this, (unsigned long long) *i);
+ }
+}
+
+void RootCluster::outputToSVG(FILE *fp) const
+{
+ for(vector<Cluster *>::const_iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->outputToSVG(fp);
+ }
+
+}
+
+
+bool RootCluster::allowsMultipleParents(void) const
+{
+ return m_allows_multiple_parents;
+}
+
+void RootCluster::setAllowsMultipleParents(const bool value)
+{
+ m_allows_multiple_parents = value;
+}
+
+void Cluster::updateBounds(const vpsc::Dim dim)
+{
+ if (dim == vpsc::HORIZONTAL)
+ {
+ bounds = vpsc::Rectangle(vMin->finalPosition, vMax->finalPosition,
+ bounds.getMinY(), bounds.getMaxY());
+ }
+ else
+ {
+ bounds = vpsc::Rectangle(bounds.getMinX(), bounds.getMaxX(),
+ vMin->finalPosition, vMax->finalPosition);
+ }
+ for (unsigned i=0; i < clusters.size(); ++i)
+ {
+ clusters[i]->updateBounds(dim);
+ }
+}
+
+
+void Cluster::createVars(const vpsc::Dim dim, const vpsc::Rectangles& rs,
+ vpsc::Variables& vars)
+{
+ for (vector<Cluster*>::iterator i = clusters.begin();
+ i != clusters.end(); ++i)
+ {
+ (*i)->createVars(dim, rs, vars);
+ }
+ if (dim==vpsc::HORIZONTAL)
+ {
+ double desiredMinX = bounds.getMinX(), desiredMaxX = bounds.getMaxX();
+ if (desiredBoundsSet)
+ {
+ desiredMinX = desiredBounds.getMinX();
+ desiredMaxX = desiredBounds.getMaxX();
+ }
+ clusterVarId = vars.size();
+ vars.push_back(vXMin = new vpsc::Variable(
+ vars.size(), desiredMinX, varWeight));
+ vars.push_back(vXMax = new vpsc::Variable(
+ vars.size(), desiredMaxX, varWeight));
+ }
+ else
+ {
+ double desiredMinY = bounds.getMinY(), desiredMaxY = bounds.getMaxY();
+ if (desiredBoundsSet)
+ {
+ desiredMinY = desiredBounds.getMinY();
+ desiredMaxY = desiredBounds.getMaxY();
+ }
+ clusterVarId = vars.size();
+ vars.push_back(vYMin = new vpsc::Variable(
+ vars.size(), desiredMinY, varWeight));
+ vars.push_back(vYMax = new vpsc::Variable(
+ vars.size(), desiredMaxY, varWeight));
+ }
+}
+
+// Returns the total area covered by contents of this cluster (not
+// including space between nodes/clusters).
+//
+double Cluster::area(const vpsc::Rectangles& rs)
+{
+ double a = 0;
+ for (set<unsigned>::iterator i = nodes.begin(); i != nodes.end(); ++i)
+ {
+ vpsc::Rectangle *r = rs[*i];
+ a += r->width() * r->height();
+ }
+ for (Clusters::iterator i = clusters.begin(); i!= clusters.end(); ++i)
+ {
+ a += (*i)->area(rs);
+ }
+ return a;
+}
+
+void Cluster::addChildNode(unsigned index)
+{
+ this->nodes.insert(index);
+}
+
+void Cluster::addChildCluster(Cluster *cluster)
+{
+ if (cluster == this)
+ {
+ fprintf(stderr, "Warning: ignoring cluster added as child of itself.\n");
+ return;
+ }
+ this->clusters.push_back(cluster);
+}
+
+
+} // namespace cola
diff --git a/src/3rdparty/adaptagrams/libcola/cluster.h b/src/3rdparty/adaptagrams/libcola/cluster.h
new file mode 100644
index 0000000..118d703
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cluster.h
@@ -0,0 +1,371 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+ * Michael Wybrow
+*/
+
+#ifndef COLA_CLUSTER_H
+#define COLA_CLUSTER_H
+
+#include <cstdio>
+
+#include "libvpsc/rectangle.h"
+#include "libvpsc/variable.h"
+
+#include "libcola/compound_constraints.h"
+#include "libcola/commondefs.h"
+#include "libcola/box.h"
+#include "libcola/shapepair.h"
+
+namespace cola {
+
+class Cluster;
+typedef std::vector<Cluster *> Clusters;
+typedef std::vector<Clusters> ClustersList;
+
+/**
+ * @brief A cluster defines a hierarchical partitioning over the nodes
+ * which should be kept disjoint by the layout somehow.
+ *
+ * You should not use this directly. This is an abstract base class.
+ * At the top level you should be using RootCluster, and then below that
+ * either RectangualarCLuster or ConvexCluster.
+ */
+class Cluster
+{
+ public:
+ Cluster();
+
+// To prevent C++ objects from being destroyed in garbage collected languages
+// when the libraries are called from SWIG, we hide the declarations of the
+// destructors and prevent generation of default destructors.
+#ifndef SWIG
+ virtual ~Cluster();
+#endif
+ virtual void computeBoundary(const vpsc::Rectangles& rs) = 0;
+ virtual void computeBoundingRect(const vpsc::Rectangles& rs);
+
+ /**
+ * @brief Mark a rectangle as being a child of this cluster.
+ *
+ * @param[in] index The index of the Rectangle in the rectangles vector.
+ */
+ virtual void addChildNode(unsigned index);
+ /**
+ * @brief Mark a cluster as being a sub-cluster of this cluster.
+ *
+ * @param[in] cluster The Cluster to be marked as a sub-cluster.
+ */
+ void addChildCluster(Cluster *cluster);
+
+ virtual cola::Box padding(void) const
+ {
+ return cola::Box();
+ }
+ virtual cola::Box margin(void) const
+ {
+ return cola::Box();
+ }
+
+ void setDesiredBounds(const vpsc::Rectangle bounds);
+ void unsetDesiredBounds();
+ void createVars(const vpsc::Dim dim, const vpsc::Rectangles& rs,
+ vpsc::Variables& vars);
+ virtual void printCreationCode(FILE *fp) const = 0;
+ virtual void countContainedNodes(std::vector<unsigned>& counts);
+ virtual bool clusterIsFromFixedRectangle(void) const;
+ virtual void outputToSVG(FILE *fp) const = 0;
+
+ // Returns the total area covered by contents of this cluster
+ // (not including space between nodes/clusters).
+ double area(const vpsc::Rectangles& rs);
+
+ // Sets bounds based on the finalPositions of vMin and vMax.
+ //
+ void updateBounds(const vpsc::Dim dim);
+
+ virtual void computeVarRect(vpsc::Variables& vs, size_t dim);
+
+ vpsc::Rectangle bounds;
+ vpsc::Rectangle varRect;
+ vpsc::Variable *vXMin, *vXMax, *vYMin, *vYMax;
+
+ // This will be the id of the left/bottom boundary,
+ // and the right/top will be clusterVarId + 1.
+ unsigned clusterVarId;
+
+ double varWeight;
+ double internalEdgeWeightFactor;
+ std::set<unsigned> nodes;
+ std::vector<Cluster*> clusters;
+ std::valarray<double> hullX, hullY;
+
+ protected:
+ void recPathToCluster(RootCluster *rootCluster,
+ Clusters currentPath);
+ bool includesAllNodesFrom(const Cluster *rhs) const;
+
+ // The following are for handling the generation of the correct
+ // set of non-overlap constraints in the case overlapping clusters
+ // (i.e., multiple inheritence). 1) We need to exclude the overlapping
+ // clusters from having non-overlap constraints. 2) We replace nodes
+ // with multiple parent clusters when enforcing non-overlap with their
+ // siblings and instead inforce non-overlap with the other clusters
+ // they are part of, since otherwise there is nothing stopping the
+ // other siblings of each cluster from overlapping each other. 3) We
+ // also need to enforce overlap still between the set of nodes replaced
+ // from each cluster in this way, since they may now be part of some
+ // new set.
+ std::set<ShapePair> m_cluster_cluster_overlap_exceptions;
+ std::map<unsigned, Cluster *> m_overlap_replacement_map;
+ std::set<unsigned> m_nodes_replaced_with_clusters;
+
+ private:
+ friend class ConstrainedFDLayout;
+ friend class RootCluster;
+
+ bool desiredBoundsSet;
+ vpsc::Rectangle desiredBounds;
+
+ vpsc::Variable *vMin, *vMax;
+};
+
+
+/**
+ * @brief Holds the cluster hierarchy specification for a diagram.
+ *
+ * This is not considered a cluster itself, but it records all the nodes in
+ * the diagram not contained within any clusters, as well as optionally a
+ * hierarchy of clusters.
+ *
+ * You can add clusters via addChildCluster() and nodes via addChildNode().
+ *
+ * You can specify just the shapes contained in clusters, but not the nodes
+ * at this top level---the library will add any remaining nodes not appearing
+ * in the cluster hierarchy as children of the root cluster.
+ *
+ * It is possible to add a node as the child of two parent clusters. In this
+ * case, the clusters will overlap to contain this (and possibly other nodes).
+ * The library will warn you if you do this unless you have called the method
+ * setAllowsMultipleParents() to mark this intention.
+ *
+ * Be careful not to create cycles in the cluster hierarchy (i.e., to mark
+ * two clusters as children of each other. The library does not check for
+ * this and strange things may occur.
+ */
+class RootCluster : public Cluster
+{
+ public:
+ RootCluster();
+ void computeBoundary(const vpsc::Rectangles& rs);
+ // There are just shapes at the top level, so
+ // effectively no clusters in the diagram scene.
+ bool flat(void) const
+ {
+ return clusters.empty();
+ }
+ virtual void printCreationCode(FILE *fp) const;
+ virtual void outputToSVG(FILE *fp) const;
+
+ //! Returns true if this cluster hierarchy allows multiple parents,
+ //! otherwise returns false.
+ //!
+ //! Defaults to false. If this is false, the library will display
+ //! warnings if you add a single node to multiple clusters.
+ //!
+ //! @sa setAllowsMultipleParents()
+ bool allowsMultipleParents(void) const;
+
+ //! Set whether the cluster hierarchy should allow multiple parents.
+ //!
+ //! @param value New value for this setting.
+ //!
+ //! sa allowsMultipleParents()
+ void setAllowsMultipleParents(const bool value);
+ private:
+ void calculateClusterPathsToEachNode(size_t nodesCount);
+
+ friend class ConstrainedFDLayout;
+ friend class Cluster;
+
+ bool m_allows_multiple_parents;
+
+ std::vector<ClustersList> m_cluster_vectors_leading_to_nodes;
+};
+
+/**
+ * @brief Defines a rectangular cluster, either variable-sized with floating
+ * sides or a fixed size based on a particular rectangle.
+ *
+ * The chosen constructor decides the type and behaviour of the cluster.
+ */
+class RectangularCluster : public Cluster
+{
+ public:
+ /**
+ * @brief A rectangular cluster of variable size that contains
+ * its children.
+ */
+ RectangularCluster();
+ /**
+ * @brief A fixed size rectangular cluster based on a particular
+ * rectangle.
+ *
+ * This rectangle might be constrained in the other ways like normal
+ * rectangles.
+ *
+ * @param[in] rectIndex The index of the rectangle that this cluster
+ * represents.
+ */
+ RectangularCluster(unsigned rectIndex);
+
+ /**
+ * @brief Sets the margin size for this cluster.
+ *
+ * This value represents the outer spacing that will be put between
+ * the cluster boundary on all sides and other clusters (plus their
+ * margin) and rectangles at the same level when non-overlap
+ * constraints are enabled.
+ *
+ * @param[in] margin The size of the margin for this cluster.
+ */
+ void setMargin(double margin);
+ /**
+ * @brief Sets the margin box for this cluster.
+ *
+ * This box represents the outer spacing that will be put between
+ * the cluster boundary and other clusters (plus their margin) and
+ * rectangles at the same level when non-overlap constraints are
+ * enabled.
+ *
+ * @param[in] margin The box representing the margins for this
+ * cluster.
+ */
+ void setMargin(const cola::Box margin);
+ /**
+ * @brief Returns the margin box for this cluster.
+ *
+ * @return The margin box for the cluster.
+ */
+ cola::Box margin(void) const;
+
+ /**
+ * @brief Sets the padding size for this cluster.
+ *
+ * This value represents the inner spacing that will be put between
+ * the cluster boundary and other child clusters (plus their margin)
+ * and child rectangles on all sides.
+ *
+ * @param[in] padding The size of the padding for this cluster.
+ */
+ void setPadding(double padding);
+ /**
+ * @brief Sets the padding box for this cluster.
+ *
+ * This box represents the inner spacing that will be put between
+ * the cluster boundary and other child clusters (plus their margin)
+ * and child rectangles for each edge.
+ *
+ * @param[in] padding The Box representing padding values for this
+ * cluster.
+ */
+ void setPadding(const cola::Box padding);
+ /**
+ * @brief Returns the padding box for this cluster.
+ *
+ * @return The padding box for the cluster.
+ */
+ cola::Box padding(void) const;
+
+#ifndef SWIG
+ virtual ~RectangularCluster();
+#endif
+ void computeBoundary(const vpsc::Rectangles& rs);
+ virtual void countContainedNodes(std::vector<unsigned>& counts);
+ virtual void printCreationCode(FILE *fp) const;
+ virtual void outputToSVG(FILE *fp) const;
+ virtual void computeBoundingRect(const vpsc::Rectangles& rs);
+ virtual void addChildNode(unsigned index);
+ inline vpsc::Rectangle *getMinEdgeRect(const vpsc::Dim dim)
+ {
+ if (minEdgeRect[dim])
+ {
+ delete minEdgeRect[dim];
+ }
+ minEdgeRect[dim] = new vpsc::Rectangle(bounds);
+
+ // Set the Min and Max positions to be the min minus an offset.
+ double edgePosition = minEdgeRect[dim]->getMinD(dim);
+ minEdgeRect[dim]->setMinD(dim, edgePosition - m_margin.min(dim));
+ minEdgeRect[dim]->setMaxD(dim, edgePosition);
+
+ return minEdgeRect[dim];
+ }
+
+ inline vpsc::Rectangle *getMaxEdgeRect(const vpsc::Dim dim)
+ {
+ if (maxEdgeRect[dim])
+ {
+ delete maxEdgeRect[dim];
+ }
+ maxEdgeRect[dim] = new vpsc::Rectangle(bounds);
+
+ // Set the Min and Max positions to be the max plus an offset.
+ double edgePosition = maxEdgeRect[dim]->getMaxD(dim);
+ maxEdgeRect[dim]->setMaxD(dim, edgePosition + m_margin.max(dim));
+ maxEdgeRect[dim]->setMinD(dim, edgePosition);
+
+ return maxEdgeRect[dim];
+ }
+ virtual bool clusterIsFromFixedRectangle(void) const;
+ int rectangleIndex(void) const;
+
+ // For fixed sized clusters based on a rectangle, this method
+ // generates the constraints that attach the cluster edges to the
+ // centre position of the relevant rectangle.
+ void generateFixedRectangleConstraints(
+ cola::CompoundConstraints& idleConstraints,
+ vpsc::Rectangles& rc, vpsc::Variables (&vars)[2]) const;
+
+ private:
+ vpsc::Rectangle *minEdgeRect[2];
+ vpsc::Rectangle *maxEdgeRect[2];
+ int m_rectangle_index;
+ Box m_margin;
+ Box m_padding;
+};
+
+/**
+ * @brief Defines a cluster that will be treated as a convex boundary around
+ * the child nodes and clusters.
+ */
+class ConvexCluster : public Cluster
+{
+ public:
+ void computeBoundary(const vpsc::Rectangles& rs);
+ virtual void printCreationCode(FILE *fp) const;
+ virtual void outputToSVG(FILE *fp) const;
+
+ std::valarray<unsigned> hullRIDs;
+ std::valarray<unsigned char> hullCorners;
+};
+
+
+} // namespace cola
+#endif // COLA_CLUSTER_H
diff --git a/src/3rdparty/adaptagrams/libcola/cola.cpp b/src/3rdparty/adaptagrams/libcola/cola.cpp
new file mode 100644
index 0000000..739c6ea
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cola.cpp
@@ -0,0 +1,700 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+*/
+
+#include <cmath>
+
+#include "libvpsc/assertions.h"
+#include "libcola/commondefs.h"
+#include "libcola/cola.h"
+#include "libcola/conjugate_gradient.h"
+#include "libcola/straightener.h"
+#include "libcola/shortest_paths.h"
+#include "libcola/cluster.h"
+
+using namespace std;
+using namespace vpsc;
+using straightener::generateClusterBoundaries;
+
+namespace cola {
+
+ConstrainedMajorizationLayout
+::ConstrainedMajorizationLayout(
+ vector<Rectangle*>& rs,
+ const vector<Edge>& es,
+ RootCluster *clusterHierarchy,
+ const double idealLength,
+ EdgeLengths eLengths,
+ TestConvergence *doneTest,
+ PreIteration* preIteration,
+ bool useNeighbourStress)
+ : n(rs.size()),
+ lap2(valarray<double>(n*n)),
+ Dij(valarray<double>(n*n)),
+ tol(1e-7),
+ done(doneTest),
+ using_default_done(false),
+ preIteration(preIteration),
+ X(valarray<double>(n)), Y(valarray<double>(n)),
+ stickyNodes(false),
+ startX(valarray<double>(n)), startY(valarray<double>(n)),
+ constrainedLayout(false),
+ nonOverlappingClusters(false),
+ clusterHierarchy(clusterHierarchy),
+ gpX(nullptr), gpY(nullptr),
+ ccs(nullptr),
+ unsatisfiableX(nullptr), unsatisfiableY(nullptr),
+ avoidOverlaps(None),
+ straightenEdges(nullptr),
+ bendWeight(0.1), potBendWeight(0.1),
+ xSkipping(true),
+ scaling(true),
+ externalSolver(false),
+ majorization(true)
+{
+ if (done == nullptr)
+ {
+ done = new TestConvergence();
+ using_default_done = true;
+ }
+
+ boundingBoxes.resize(rs.size());
+ copy(rs.begin(),rs.end(),boundingBoxes.begin());
+
+ done->reset();
+
+ COLA_ASSERT(!straightenEdges||straightenEdges->size()==es.size());
+
+ double** D=new double*[n];
+ for(unsigned i=0;i<n;i++) {
+ D[i]=new double[n];
+ }
+
+ std::valarray<double> edgeLengths(eLengths.data(), eLengths.size());
+ // Correct zero or negative entries in eLengths array.
+ for (size_t i = 0; i < edgeLengths.size(); ++i)
+ {
+ if (edgeLengths[i] <= 0)
+ {
+ fprintf(stderr, "Warning: ignoring non-positive length at index %d "
+ "in ideal edge length array.\n", (int) i);
+ edgeLengths[i] = 1;
+ }
+ }
+
+ if (useNeighbourStress) {
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=0;j<n;j++) {
+ D[i][j]=std::numeric_limits<double>::max();
+ }
+ }
+ bool haveLengths = edgeLengths.size() == es.size();
+ for (unsigned i = 0; i < es.size(); i++) {
+ unsigned source = es[i].first;
+ unsigned target = es[i].second;
+ D[source][target] = D[target][source] = (haveLengths ? edgeLengths[i] : 1.0);
+ }
+ } else {
+ shortest_paths::johnsons(n,D,es,edgeLengths);
+ //shortest_paths::neighbours(n,D,es,edgeLengths);
+ }
+
+ edge_length = idealLength;
+ if(clusterHierarchy) {
+ for(Clusters::const_iterator i=clusterHierarchy->clusters.begin();
+ i!=clusterHierarchy->clusters.end();i++) {
+ Cluster *c=*i;
+ for(set<unsigned>::iterator j=c->nodes.begin();j!=c->nodes.end();j++) {
+ for(set<unsigned>::iterator k=c->nodes.begin();k!=c->nodes.end();k++) {
+ unsigned a=*j, b=*k;
+ if(a==b) continue;
+ D[a][b]/=c->internalEdgeWeightFactor;
+ }
+ }
+ }
+ }
+ // Lij_{i!=j}=1/(Dij^2)
+ //
+ for(unsigned i = 0; i<n; i++) {
+ X[i]=rs[i]->getCentreX();
+ Y[i]=rs[i]->getCentreY();
+ double degree = 0;
+ for(unsigned j=0;j<n;j++) {
+ double d = edge_length * D[i][j];
+ Dij[i*n + j] = d;
+ if(i==j) continue;
+ double lij=0;
+ if(d!=0 && !std::isinf(d)) {
+ lij=1./(d*d);
+ }
+ degree += lap2[i*n + j] = lij;
+ }
+ lap2[i*n + i]=-degree;
+ delete [] D[i];
+ }
+ //GradientProjection::dumpSquareMatrix(Dij);
+ delete [] D;
+}
+// stickyNodes adds a small force attracting nodes
+// back to their starting positions
+void ConstrainedMajorizationLayout::setStickyNodes(
+ const double stickyWeight,
+ valarray<double> const & startX,
+ valarray<double> const & startY) {
+ COLA_ASSERT( startX.size()==n && startY.size()==n);
+ stickyNodes = true;
+ // not really constrained but we want to use GP solver rather than
+ // ConjugateGradient
+ constrainedLayout = true;
+ this->stickyWeight=stickyWeight;
+ this->startX = startX;
+ this->startY = startY;
+ for(unsigned i = 0; i<n; i++) {
+ lap2[i*n+i]-=stickyWeight;
+ }
+}
+
+void ConstrainedMajorizationLayout::majorize(
+ valarray<double> const & Dij, GradientProjection* gp,
+ valarray<double>& coords,
+ valarray<double> const & startCoords)
+{
+ double L_ij,dist_ij,degree;
+ /* compute the vector b */
+ /* multiply on-the-fly with distance-based laplacian */
+ valarray<double> b(n);
+ for (unsigned i = 0; i < n; i++) {
+ b[i] = degree = 0;
+ for (unsigned j = 0; j < n; j++) {
+ if (j == i) continue;
+ dist_ij = euclidean_distance(i, j);
+ /* skip zero distances */
+ if (dist_ij > 1e-30 && Dij[i*n+j] > 1e-30 && Dij[i*n+j] < 1e10) {
+ /* calculate L_ij := w_{ij}*d_{ij}/dist_{ij} */
+ L_ij = 1.0 / (dist_ij * Dij[i*n+j]);
+ degree -= L_ij;
+ b[i] += L_ij * coords[j];
+ }
+ }
+ if(stickyNodes) {
+ //double l = startCoords[i]-coords[i];
+ //l/=10.;
+ //b[i]-=stickyWeight*(coords[i]+l);
+ b[i] -= stickyWeight*startCoords[i];
+ }
+ b[i] += degree * coords[i];
+ COLA_ASSERT(!std::isnan(b[i]));
+ }
+ if(constrainedLayout) {
+ //printf("GP iteration...\n");
+ gp->solve(b,coords);
+ } else {
+ //printf("CG iteration...\n");
+ conjugate_gradient(lap2, coords, b, n, tol, n);
+ }
+ moveBoundingBoxes();
+}
+void ConstrainedMajorizationLayout::newton(
+ valarray<double> const & Dij, GradientProjection* gp,
+ valarray<double>& coords,
+ valarray<double> const & startCoords)
+{
+ COLA_UNUSED(startCoords);
+ /* compute the vector b */
+ /* multiply on-the-fly with distance-based laplacian */
+ valarray<double> b(n);
+ valarray<double> A(n*n);
+ for (unsigned i = 0; i < n; i++) {
+ b[i] = 0;
+ double Aii = 0;
+ for (unsigned j = 0; j < n; j++) {
+ if (j == i) continue;
+ double d = Dij[i*n+j];
+ double l = euclidean_distance(i,j);
+ double dx = coords[i]-coords[j];
+ double dy2 = l*l - dx*dx;
+ /* skip zero distances */
+ if (l > 1e-30
+ && d > 1e-30 && d < 1e10) {
+ if(d>80 && l > d) continue;
+ b[i]+=dx*(l-d)/(l*d*d);
+ Aii-=A[i*n+j]=(d*dy2/(l*l*l)-1)/(d*d);
+ }
+ }
+ A[i*n+i]=Aii;
+ }
+ if(constrainedLayout) {
+ //printf("GP iteration...\n");
+ gp->solve(b,coords);
+ } else {
+ //printf("CG iteration...\n");
+ /*
+ unsigned N=n-1;
+ valarray<double> b2(N);
+ valarray<double> A2(N*N);
+ valarray<double> x(N);
+ for(unsigned i=0;i<N;i++) {
+ b2=b[i];
+ x=coords[i];
+ for(unsigned j=0;j<N;j++) {
+ A2[i*N+j]=A[i*n+j];
+ }
+ }
+ conjugate_gradient(A2, x, b2, N, tol, N);
+ */
+ //valarray<double> x=coords;
+ //x-=x.sum()/n;
+ //conjugate_gradient(A, x, b, n, tol, n);
+ //double stepsize=0.5;
+ valarray<double> x=b;
+ // stepsize = g.g / (g A g)
+ double numerator = 0;
+ for(unsigned i=0;i<n;i++) {
+ numerator+=x[i]*x[i];
+ }
+ double denominator = 0;
+ for(unsigned i=0;i<n;i++) {
+ double r=0;
+ for(unsigned j=0;j<n;j++) {
+ r+=A[i*n+j]*x[j];
+ }
+ denominator+=r*x[i];
+ }
+ double stepsize=numerator/(2*denominator);
+ double oldstress=compute_stress(Dij);
+ valarray<double> oldcoords=coords;
+ while(stepsize>0.00001) {
+ coords=oldcoords-stepsize*x;
+ double stress=compute_stress(Dij);
+ printf(" stress=%f, stepsize=%f\n",stress,stepsize);
+ if(oldstress>=stress) {
+ break;
+ }
+ coords=oldcoords;
+ stepsize*=0.5;
+ }
+ }
+ moveBoundingBoxes();
+}
+inline double ConstrainedMajorizationLayout
+::compute_stress(valarray<double> const &Dij) {
+ double sum = 0, d, diff;
+ for (unsigned i = 1; i < n; i++) {
+ for (unsigned j = 0; j < i; j++) {
+ d = Dij[i*n+j];
+ if(!std::isinf(d)&&d!=numeric_limits<double>::max()) {
+ diff = d - euclidean_distance(i,j);
+ if(d>80&&diff<0) continue;
+ sum += diff*diff / (d*d);
+ }
+ }
+ if(stickyNodes) {
+ double l = startX[i]-X[i];
+ sum += stickyWeight*l*l;
+ l = startY[i]-Y[i];
+ sum += stickyWeight*l*l;
+ }
+ }
+ //printf("stress=%f\n",sum);
+ return sum;
+}
+
+void ConstrainedMajorizationLayout::run(bool x, bool y) {
+ if(constrainedLayout) {
+ vector<vpsc::Rectangle*>* pbb = boundingBoxes.empty()?nullptr:&boundingBoxes;
+ SolveWithMosek mosek = Off;
+ if(externalSolver) mosek=Outer;
+ // scaling doesn't currently work with straighten edges because sparse
+ // matrix used with dummy nodes is not properly scaled at the moment.
+ if(straightenEdges) setScaling(false);
+ gpX=new GradientProjection(
+ HORIZONTAL,&lap2,tol,100,ccs,unsatisfiableX,
+ avoidOverlaps,clusterHierarchy,pbb,scaling,mosek);
+ gpY=new GradientProjection(
+ VERTICAL,&lap2,tol,100,ccs,unsatisfiableY,
+ avoidOverlaps,clusterHierarchy,pbb,scaling,mosek);
+ }
+ if(n>0) do {
+ // to enforce clusters with non-intersecting, convex boundaries we
+ // could create cluster boundaries here with chains of dummy nodes (a
+ // dummy node for each vertex of the convex hull) connected by dummy
+ // straightenEdges and we'd then continue on to straightenEdges below.
+ // This should work assuming we already have a feasible (i.e. non
+ // overlapping cluster) state. The former could be enforced by an
+ // earlier stage involving simple rectangular cluster boundaries.
+ vector<straightener::Edge*> cedges;
+ if(!straightenEdges && nonOverlappingClusters) {
+ straightenEdges = &cedges;
+ }
+ if(preIteration) {
+ if ((*preIteration)()) {
+ for(vector<Lock>::iterator l=preIteration->locks.begin();
+ l!=preIteration->locks.end();l++) {
+ unsigned id=l->getID();
+ double x=l->pos(HORIZONTAL), y=l->pos(VERTICAL);
+ X[id]=x;
+ Y[id]=y;
+ if(stickyNodes) {
+ startX[id]=x;
+ startY[id]=y;
+ }
+ boundingBoxes[id]->moveCentre(x,y);
+ if(constrainedLayout) {
+ gpX->fixPos(id,X[id]);
+ gpY->fixPos(id,Y[id]);
+ }
+ }
+ } else { break; }
+ }
+ /* Axis-by-axis optimization: */
+ if(straightenEdges) {
+ if(x) straighten(*straightenEdges,HORIZONTAL);
+ if(y) straighten(*straightenEdges,VERTICAL);
+ } else {
+ if(majorization) {
+ if(x) majorize(Dij,gpX,X,startX);
+ if(y) majorize(Dij,gpY,Y,startY);
+ } else {
+ if(x) newton(Dij,gpX,X,startX);
+ if(y) newton(Dij,gpY,Y,startY);
+ }
+ }
+ if(clusterHierarchy) {
+ for(Clusters::iterator c=clusterHierarchy->clusters.begin();
+ c!=clusterHierarchy->clusters.end();c++) {
+ (*c)->computeBoundary(boundingBoxes);
+ }
+ }
+ if(preIteration && constrainedLayout) {
+ for(vector<Lock>::iterator l=preIteration->locks.begin();
+ l!=preIteration->locks.end();l++) {
+ gpX->unfixPos(l->getID());
+ gpY->unfixPos(l->getID());
+ }
+ }
+ } while(!(*done)(compute_stress(Dij),X,Y));
+}
+double ConstrainedMajorizationLayout::computeStress() {
+ return compute_stress(Dij);
+}
+void ConstrainedMajorizationLayout::runOnce(bool x, bool y) {
+ if(constrainedLayout) {
+ vector<vpsc::Rectangle*>* pbb = boundingBoxes.empty()?nullptr:&boundingBoxes;
+ SolveWithMosek mosek = Off;
+ if(externalSolver) mosek=Outer;
+ // scaling doesn't currently work with straighten edges because sparse
+ // matrix used with dummy nodes is not properly scaled at the moment.
+ if(straightenEdges) setScaling(false);
+ gpX=new GradientProjection(
+ HORIZONTAL,&lap2,tol,100,ccs,unsatisfiableX,
+ avoidOverlaps,clusterHierarchy,pbb,scaling,mosek);
+ gpY=new GradientProjection(
+ VERTICAL,&lap2,tol,100,ccs,unsatisfiableY,
+ avoidOverlaps,clusterHierarchy,pbb,scaling,mosek);
+ }
+ if(n>0) {
+ // to enforce clusters with non-intersecting, convex boundaries we
+ // could create cluster boundaries here with chains of dummy nodes (a
+ // dummy node for each vertex of the convex hull) connected by dummy
+ // straightenEdges and we'd then continue on to straightenEdges below.
+ // This should work assuming we already have a feasible (i.e. non
+ // overlapping cluster) state. The former could be enforced by an
+ // earlier stage involving simple rectangular cluster boundaries.
+ vector<straightener::Edge*> cedges;
+ if(!straightenEdges && nonOverlappingClusters) {
+ straightenEdges = &cedges;
+ }
+ if(preIteration) {
+ if ((*preIteration)()) {
+ for(vector<Lock>::iterator l=preIteration->locks.begin();
+ l!=preIteration->locks.end();l++) {
+ unsigned id=l->getID();
+ double x=l->pos(HORIZONTAL), y=l->pos(VERTICAL);
+ X[id]=x;
+ Y[id]=y;
+ if(stickyNodes) {
+ startX[id]=x;
+ startY[id]=y;
+ }
+ boundingBoxes[id]->moveCentre(x,y);
+ if(constrainedLayout) {
+ gpX->fixPos(id,X[id]);
+ gpY->fixPos(id,Y[id]);
+ }
+ }
+ } else { return; }
+ }
+ /* Axis-by-axis optimization: */
+ if(straightenEdges) {
+ if(x) straighten(*straightenEdges,HORIZONTAL);
+ if(y) straighten(*straightenEdges,VERTICAL);
+ } else {
+ if(majorization) {
+ if(x) majorize(Dij,gpX,X,startX);
+ if(y) majorize(Dij,gpY,Y,startY);
+ } else {
+ if(x) newton(Dij,gpX,X,startX);
+ if(y) newton(Dij,gpY,Y,startY);
+ }
+ }
+ if(clusterHierarchy) {
+ for(Clusters::iterator c=clusterHierarchy->clusters.begin();
+ c!=clusterHierarchy->clusters.end();c++) {
+ (*c)->computeBoundary(boundingBoxes);
+ }
+ }
+ if(preIteration && constrainedLayout) {
+ for(vector<Lock>::iterator l=preIteration->locks.begin();
+ l!=preIteration->locks.end();l++) {
+ gpX->unfixPos(l->getID());
+ gpY->unfixPos(l->getID());
+ }
+ }
+ }
+}
+void ConstrainedMajorizationLayout::straighten(vector<straightener::Edge*>& sedges, Dim dim) {
+ GradientProjection * gp;
+ valarray<double>* coords;
+ valarray<double>* startCoords;
+ if(dim==HORIZONTAL) {
+ gp=gpX;
+ coords=&X;
+ startCoords=&startX;
+ } else {
+ gp=gpY;
+ coords=&Y;
+ startCoords=&startY;
+ }
+ vector<straightener::Node*> snodes;
+ if(dim==HORIZONTAL) {
+ Rectangle::setXBorder(0.0001);
+ }
+ for (unsigned i=0;i<n;i++) {
+ snodes.push_back(new straightener::Node(i,boundingBoxes[i]));
+ }
+ if(dim==HORIZONTAL) {
+ Rectangle::setXBorder(0);
+ }
+ for (unsigned i=n;i<gp->getNumStaticVars();i++) {
+ // insert some dummy nodes
+ snodes.push_back(new straightener::Node(i,-100,-100));
+ }
+ vector<straightener::Cluster*> sclusters;
+
+ if(nonOverlappingClusters && clusterHierarchy) {
+ generateClusterBoundaries(dim,snodes,sedges,boundingBoxes,
+ *clusterHierarchy,sclusters);
+ }
+ vector<SeparationConstraint*> cs;
+ straightener::generateConstraints(dim,snodes,sedges,cs,xSkipping);
+ straightener::LinearConstraints linearConstraints;
+ for(unsigned i=0;i<sedges.size();i++) {
+ sedges[i]->nodePath(snodes,!nonOverlappingClusters);
+ vector<unsigned>& path=sedges[i]->path;
+ vector<unsigned>& activePath=sedges[i]->activePath;
+ // take u and v as the ends of the line
+ // unsigned u=path[0];
+ // unsigned v=path[path.size()-1];
+ double total_length=0;
+ for(unsigned j=1;j<path.size();j++) {
+ unsigned u=path[j-1], v=path[j];
+ total_length+=snodes[u]->euclidean_distance(snodes[v]);
+ }
+ // keep potential bends straight
+ for(unsigned j=1;j<activePath.size();j++) {
+ unsigned uj=activePath[j-1], vj=activePath[j];
+ unsigned u=path[uj], v=path[vj];
+ for(unsigned k=uj+1;k<vj;k++) {
+ unsigned b=path[k];
+ // might be useful to have greater weight for potential bends than actual bends
+ linearConstraints.push_back(new straightener::LinearConstraint(
+ *snodes[u],*snodes[v],*snodes[b],-potBendWeight));
+ }
+ }
+ // straighten actual bends
+ for(unsigned j=1;j<activePath.size()-1;j++) {
+ unsigned u=path[activePath[j-1]],
+ b=path[activePath[j]],
+ v=path[activePath[j+1]];
+ linearConstraints.push_back(new straightener::LinearConstraint(
+ *snodes[u],*snodes[v],*snodes[b],-bendWeight));
+ }
+ }
+ //std::cout << (dim==HORIZONTAL?"X":"Y") << " snodes.size "<<snodes.size()<< " n="<<n<<std::endl;
+ //std::cout << "Generated "<<linearConstraints.size()<< " linear constraints"<<std::endl;
+ SparseMap Q(snodes.size());
+ for(straightener::LinearConstraints::iterator i=linearConstraints.begin();
+ i!= linearConstraints.end();i++) {
+ straightener::LinearConstraint* c=*i;
+ Q(c->u,c->u)+=c->w*c->duu;
+ Q(c->u,c->v)+=c->w*c->duv;
+ Q(c->u,c->b)+=c->w*c->dub;
+ Q(c->v,c->u)+=c->w*c->duv;
+ Q(c->v,c->v)+=c->w*c->dvv;
+ Q(c->v,c->b)+=c->w*c->dvb;
+ Q(c->b,c->b)+=c->w*c->dbb;
+ Q(c->b,c->u)+=c->w*c->dub;
+ Q(c->b,c->v)+=c->w*c->dvb;
+ }
+ double boundaryWeight = 0.0001;
+ for(unsigned i=0;i<sclusters.size();i++) {
+ // for each cluster boundary chain create an attractive force between
+ // each pair of adjacent nodes
+ straightener::Cluster* c = sclusters[i];
+ for(unsigned j=0;j<c->boundary.size();j++) {
+ straightener::Edge* e = c->boundary[j];
+ Q(e->startNode,e->endNode)+=boundaryWeight;
+ Q(e->endNode,e->startNode)+=boundaryWeight;
+ Q(e->startNode,e->startNode)-=boundaryWeight;
+ Q(e->endNode,e->endNode)-=boundaryWeight;
+ }
+ }
+ constrainedLayout = true;
+ SparseMatrix sparseQ(Q);
+ gp->straighten(&sparseQ,cs,snodes);
+ //return;
+ majorize(Dij,gp,*coords,*startCoords);
+ valarray<double> const & r=gp->getFullResult();
+ for(unsigned i=0;i<snodes.size();i++) {
+ snodes[i]->pos[dim] = r[i];
+ }
+ for(unsigned i=0;i<sedges.size();i++) {
+ sedges[i]->createRouteFromPath(snodes);
+ sedges[i]->dummyNodes.clear();
+ sedges[i]->path.clear();
+ }
+ for(unsigned i=0;i<sclusters.size();i++) {
+ straightener::Cluster *sc = sclusters[i];
+ //sc->updateActualBoundary();
+ delete sc;
+ }
+ for(unsigned i=0;i<cs.size();i++) {
+ delete cs[i];
+ }
+ for(unsigned i=0;i<linearConstraints.size();i++) {
+ delete linearConstraints[i];
+ }
+ for(unsigned i=0;i<snodes.size();i++) {
+ delete snodes[i];
+ }
+}
+
+Rectangle bounds(vector<Rectangle*>& rs) {
+ COLA_ASSERT(!rs.empty());
+
+ double left = rs[0]->getMinX(), right = rs[0]->getMaxX(),
+ top = rs[0]->getMinY(), bottom = rs[0]->getMaxY();
+
+ for(unsigned i = 1; i < rs.size(); i++) {
+ left = min(left,rs[i]->getMinX());
+ right = max(right,rs[i]->getMaxX());
+ top = min(top,rs[i]->getMinY());
+ bottom = max(bottom,rs[i]->getMaxY());
+ }
+ return Rectangle(left, right, top, bottom);
+}
+
+#if 0
+ void removeClusterOverlap(RootCluster& clusterHierarchy, vpsc::Rectangles& rs, Locks& locks, vpsc::Dim dim) {
+ if(clusterHierarchy.nodes.size()>0 || clusterHierarchy.clusters.size()>0) {
+ vpsc::Variables vars;
+ vpsc::Constraints cs;
+ for(unsigned i=0;i<rs.size();i++) {
+ vars.push_back(new vpsc::Variable(i, rs[i]->getCentreD(dim)));
+ }
+
+ clusterHierarchy.computeBoundingRect(rs);
+ clusterHierarchy.createVars(dim,rs,vars);
+ clusterHierarchy.generateNonOverlapConstraints(dim, cola::Both, rs, vars, cs);
+
+ /*
+ if(dim==vpsc::HORIZONTAL) {
+ vpsc::Rectangle::setXBorder(0.001);
+ // use rs->size() rather than n because some of the variables may
+ // be dummy vars with no corresponding rectangle
+ generateXConstraints(rs,vars,cs,true);
+ vpsc::Rectangle::setXBorder(0);
+ } else {
+ generateYConstraints(rs,vars,cs);
+ }
+ */
+ for(Locks::iterator l=locks.begin();
+ l!=locks.end();l++) {
+ unsigned id=l->getID();
+ double x=l->pos(HORIZONTAL), y=l->pos(VERTICAL);
+ Variable* v=vars[id];
+ v->desiredPosition = (dim==vpsc::HORIZONTAL)?x:y;
+ v->weight = 1000;
+ }
+ /*
+ vpsc::Solver s(vars,cs);
+ try {
+ s.satisfy();
+ } catch(const char* e) {
+ cerr << "ERROR from solver in GraphData::removeOverlap : " << e << endl;
+ }
+ */
+ vpsc::IncSolver s(vars,cs);
+ try {
+ s.solve();
+ } catch(const char* e) {
+ cerr << "ERROR from solver in GraphData::removeOverlap : " << e << endl;
+ }
+ clusterHierarchy.updateBounds(dim);
+ /*
+ for(unsigned i=0;i<cs.size();++i) {
+ if(cs[i]->unsatisfiable) {
+ cout << "Unsatisfiable constraint: " << *cs[i] << endl;
+ }
+ }
+ */
+ for(unsigned i=0;i<rs.size();i++) {
+ rs[i]->moveCentreD(dim,vars[i]->finalPosition);
+ }
+ for(Locks::iterator l=locks.begin();
+ l!=locks.end();l++) {
+ //unsigned id=l->getID();
+ }
+ for_each(vars.begin(),vars.end(),delete_object());
+ for_each(cs.begin(),cs.end(),delete_object());
+ }
+ }
+ void removeClusterOverlapFast(RootCluster& clusterHierarchy, vpsc::Rectangles& rs, Locks& locks) {
+ removeClusterOverlap(clusterHierarchy, rs, locks, vpsc::HORIZONTAL);
+ removeClusterOverlap(clusterHierarchy, rs, locks, vpsc::VERTICAL);
+ }
+#endif
+
+ ConstrainedMajorizationLayout* simpleCMLFactory(
+ vpsc::Rectangles& rs,
+ std::vector<Edge> const & es,
+ RootCluster* clusterHierarchy,
+ const double idealLength,
+ bool useNeighbourStress
+ ) {
+ cola::EdgeLengths eLengths;
+ for(size_t i = 0; i < es.size(); ++i) {
+ eLengths.push_back(1);
+ }
+ return new ConstrainedMajorizationLayout(rs, es, clusterHierarchy, idealLength,
+ eLengths, nullptr, nullptr, useNeighbourStress);
+ };
+
+} // namespace cola
diff --git a/src/3rdparty/adaptagrams/libcola/cola.h b/src/3rdparty/adaptagrams/libcola/cola.h
new file mode 100644
index 0000000..40043cd
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cola.h
@@ -0,0 +1,1002 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2015 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+ * Michael Wybrow
+*/
+
+#ifndef COLA_H
+#define COLA_H
+
+#include <utility>
+#include <iterator>
+#include <vector>
+#include <valarray>
+#include <algorithm>
+#include <cmath>
+#include <iostream>
+
+#include "libcola/gradient_projection.h"
+#include "libcola/cluster.h"
+#include "libcola/straightener.h"
+#include "libcola/exceptions.h"
+#include "libcola/pseudorandom.h"
+
+namespace vpsc { class Rectangle; }
+namespace topology {
+ class ColaTopologyAddon;
+}
+namespace dialect {
+ class Graph;
+}
+
+
+/**
+ * @namespace cola
+ * @brief libcola: Force-directed network layout subject to
+ * separation constraints library.
+ *
+ * You should use COLA via an instance of the ConstrainedFDLayout class.
+*/
+namespace cola {
+
+class NonOverlapConstraints;
+class NonOverlapConstraintExemptions;
+
+//! @brief A vector of node Indexes.
+typedef std::vector<unsigned> NodeIndexes;
+
+//! @brief A vector of NodeIndexes.
+typedef std::vector<NodeIndexes> ListOfNodeIndexes;
+
+//! Edges are simply a pair of indices to entries in the Node vector
+typedef std::pair<unsigned, unsigned> Edge;
+
+//! EdgeLengths is a vector of ideal lengths for edges corresponding to
+//! edges in the edge list.
+typedef std::vector<double> EdgeLengths;
+#define StandardEdgeLengths EdgeLengths()
+
+/**
+ * @brief A Lock specifies a required position for a node.
+ */
+class Lock {
+public:
+ Lock() {}
+ /**
+ * @brief Constructs a Lock object for a given node and position.
+ *
+ * @param[in] id The index of the node in the Rectangles vector.
+ * @param[in] X The node's fixed position in the x-dimension.
+ * @param[in] Y The node's fixed position in the y-dimension.
+ */
+ Lock(unsigned id, double X, double Y) : id(id), x(X), y(Y) {
+ }
+ unsigned getID() const {
+ return id;
+ }
+ double pos(vpsc::Dim dim) const {
+ return dim==vpsc::HORIZONTAL?x:y;
+ }
+private:
+ unsigned id;
+ double x;
+ double y;
+};
+//! @brief A vector of Lock objects.
+typedef std::vector<cola::Lock> Locks;
+
+/**
+ * @brief A Resize specifies a new required bounding box for a node.
+ */
+class Resize {
+public:
+ Resize() {}
+ /**
+ * @brief Constructs a Resize object for a given node and it's new
+ * bounding box.
+ *
+ * @param[in] id The index of the node in the Rectangles vector.
+ * @param[in] x The minimum horizontal value for the node's new
+ * bounding box.
+ * @param[in] y The minimum vertical value for the node's new
+ * bounding box.
+ * @param[in] w The width value for the node's new bounding box.
+ * @param[in] h The height value for the node's new bounding box.
+ */
+ Resize(unsigned id, double x, double y, double w, double h)
+ : id(id), target(x,x+w,y,y+h) {}
+ unsigned getID() const {
+ return id;
+ }
+ const vpsc::Rectangle* getTarget() const {
+ return &target;
+ }
+private:
+ unsigned id;
+ vpsc::Rectangle target;
+};
+//! @brief A vector of Resize objects.
+typedef std::vector<cola::Resize> Resizes;
+
+/*
+ * Setting a desired position for a node adds a term to the goal function
+ * drawing the node towards that desired position
+ */
+struct DesiredPosition {
+ unsigned id;
+ double x;
+ double y;
+ double weight;
+};
+typedef std::vector<cola::DesiredPosition> DesiredPositions;
+
+/*
+ * desired positions which should override those computed by applying forces
+ * are passed in for a set of nodes. The first entry is the Node->id, the
+ * second is the desired position.
+ */
+typedef std::pair<unsigned,double> DesiredPositionInDim;
+typedef std::vector<DesiredPositionInDim> DesiredPositionsInDim;
+
+/**
+ * @brief A default functor that is called before each iteration in the
+ * main loop of the ConstrainedFDLayout::run() method.
+ *
+ * Override the operator() for things like locking the position of nodes
+ * for the duration of the iteration.
+ *
+ * If the operator() returns false the subsequent iterations are
+ * abandoned, i.e., layout ends immediately. You can make it return true
+ * when a user-interrupt is detected, for instance.
+ */
+class PreIteration {
+public:
+ /**
+ * @brief Constructs a PreIteration object that handles locking and
+ * resizing of nodes.
+ *
+ * @param[in] locks A list of nodes (by index) and positions at which
+ * they should be locked.
+ * @param[in] resizes A list of nodes (by index) and required dimensions
+ * for their bounding rects to be resized to.
+ */
+ PreIteration(
+ Locks& locks=__locksNotUsed,
+ Resizes& resizes=__resizesNotUsed)
+ : locks(locks)
+ , resizes(resizes)
+ , changed(true) {}
+ PreIteration(Resizes& resizes)
+ : locks(__locksNotUsed)
+ , resizes(resizes)
+ , changed(true) {}
+
+// To prevent C++ objects from being destroyed in garbage collected languages
+// when the libraries are called from SWIG, we hide the declarations of the
+// destructors and prevent generation of default destructors.
+#ifndef SWIG
+ virtual ~PreIteration() {}
+#endif
+ virtual bool operator()() { return true; }
+ Locks& locks;
+ Resizes& resizes;
+ bool changed;
+private:
+ static Locks __locksNotUsed;
+ static Resizes __resizesNotUsed;
+};
+
+/**
+ * @brief A default functor that is called after each iteration of the layout
+ * algorithm.
+ *
+ * You can either instantiate ConstrainedFDLayout with an instance of this
+ * class setting the tolerance and maxiterations as desired, or create a
+ * derived class implementing the operator() to do your own convergence test,
+ * or create your own operator() that calls the TestConvergence::operator() in
+ * order to do any other post processing you might need, e.g., to animate
+ * changes.
+ */
+class TestConvergence {
+public:
+ double old_stress;
+ TestConvergence(const double tol = 1e-4, const unsigned maxiterations = 100)
+ : tolerance(tol),
+ maxiterations(maxiterations)
+ { reset(); }
+ virtual ~TestConvergence() {}
+
+public:
+ virtual bool operator()(const double new_stress, std::valarray<double> & X, std::valarray<double> & Y)
+ {
+ COLA_UNUSED(X);
+ COLA_UNUSED(Y);
+
+ iterations++;
+ //std::cout<<"iteration="<<iterations<<", old_stress="<<old_stress<<", new_stress="<<new_stress<<std::endl;
+ if (old_stress == DBL_MAX) {
+ old_stress = new_stress;
+ return iterations >= maxiterations;
+ }
+ // converged if relative decrease in stress falls below threshold
+ // or if stress increases (shouldn't happen for straight majorization)
+ bool converged =
+ (old_stress - new_stress) / (new_stress + 1e-10) < tolerance
+ || iterations > maxiterations;
+ old_stress = new_stress;
+ return converged;
+ }
+ void reset() {
+ old_stress = DBL_MAX;
+ iterations = 0;
+ }
+ const double tolerance;
+ const unsigned maxiterations;
+ unsigned iterations;
+};
+
+/**
+ * @brief Implements the Constrained Majorization graph layout algorithm
+ * (deprecated).
+ *
+ * The optimisation method used is "stress majorization", where a sequence of
+ * quadratic functions which strictly bound the stress from above, is solved
+ * to monotonically reduce the stress (by iteratively changing the
+ * configuration of nodes).
+ *
+ * Once the problem has been set up, call run() or runOnce() to run the
+ * layout algorithm.
+ *
+ * @note We recommend the use of ConstrainedFDLayout instead of this class.
+ * ConstrainedFDLayout tends to produce better results and has more
+ * features. We are no longer working on ConstrainedMajorizationLayout.
+ */
+class ConstrainedMajorizationLayout {
+public:
+ /**
+ * @brief Constructs a constrained majorization layout instance.
+ *
+ * @param[in] rs Bounding boxes of nodes at their initial positions.
+ * @param[in] es Simple pair edges, giving indices of the start and end
+ * nodes in rs.
+ * @param[in] clusterHierarchy A pointer to a RootCluster object defining
+ * the cluster hierarchy (optional).
+ * @param[in] idealLength Aa scalar modifier of ideal edge lengths in
+ * eLengths.
+ * @param[in] eLengths Individual ideal lengths for edges.
+ * The actual ideal length used for the ith edge is
+ * idealLength*eLengths[i], or if eLengths is empty
+ * then just idealLength is used (i.e., eLengths[i]
+ * is assumed to be 1).
+ * @param[in] done A test of convergence operation called at the end of
+ * each iteration (optional).
+ * @param[in] preIteration An operation called before each iteration
+ * (optional).
+ */
+ ConstrainedMajorizationLayout(
+ vpsc::Rectangles& rs,
+ std::vector<Edge> const & es,
+ RootCluster* clusterHierarchy,
+ const double idealLength,
+ EdgeLengths eLengths = StandardEdgeLengths,
+ TestConvergence *doneTest = nullptr,
+ PreIteration* preIteration=nullptr,
+ bool useNeighbourStress = false);
+ /**
+ * @brief Specify a set of compound constraints to apply to the layout.
+ *
+ * @param[in] ccs The compound constraints.
+ */
+ void setConstraints(cola::CompoundConstraints* ccs) {
+ constrainedLayout = true;
+ this->ccs=ccs;
+ }
+
+ void setConstraintsVector(cola::CompoundConstraints& ccs) {
+ constrainedLayout = true;
+ cola::CompoundConstraints *ccsp = new cola::CompoundConstraints;
+ for (size_t i = 0; i < ccs.size(); ++i) {
+ ccsp->push_back(ccs.at(i));
+ }
+ this->ccs=ccsp;
+ }
+
+ /**
+ * @brief Register to receive information about unsatisfiable constraints.
+ *
+ * In the case of unsatisifiable constraints, the solver will drop
+ * unsatisfiable constraints of lowest priority. Information about these
+ * will be written to these lists after each iteration of constrained
+ * layout.
+ *
+ * param[out] unsatisfiableX A pointer to an UnsatisfiableConstraintInfos
+ * object that will be used to record
+ * unsatisfiable constraints in the x-dimension.
+ * param[out] unsatisfiableY A pointer to an UnsatisfiableConstraintInfos
+ * object that will be used to record
+ * unsatisfiable constraints in the y-dimension.
+ */
+ void setUnsatisfiableConstraintInfo(
+ UnsatisfiableConstraintInfos *unsatisfiableX,
+ UnsatisfiableConstraintInfos *unsatisfiableY) {
+ this->unsatisfiableX = unsatisfiableX;
+ this->unsatisfiableY = unsatisfiableY;
+ }
+ /**
+ * Sticky nodes causes nodes to spring back to (startX,startY) when
+ * unconstrained.
+ */
+ void setStickyNodes(const double stickyWeight,
+ std::valarray<double> const & startX,
+ std::valarray<double> const & startY);
+
+ /**
+ * Scaling speeds up the solver by conditioning the quadratic terms matrix.
+ */
+ void setScaling(bool scaling) {
+ this->scaling=scaling;
+ }
+ /**
+ * Says that the Mosek optimisation library should be used to solve the
+ * quadratic programs rather than the libvpsc solver.
+ */
+ void setExternalSolver(bool externalSolver) {
+ this->externalSolver=externalSolver;
+ }
+ /**
+ * At each iteration of layout, generate constraints to avoid overlaps.
+ * If bool horizontal is true, all overlaps will be resolved horizontally,
+ * otherwise some overlaps will be left to be resolved vertically where
+ * doing so leads to less displacement
+ */
+ void setAvoidOverlaps(bool horizontal = false) {
+ constrainedLayout = true;
+ this->avoidOverlaps = horizontal ? Horizontal : Both;
+ }
+ /**
+ * Add constraints to prevent clusters overlapping.
+ */
+ void setNonOverlappingClusters() {
+ constrainedLayout = true;
+ nonOverlappingClusters = true;
+ }
+ /**
+ * For the specified edges (with routings), generate dummy vars and
+ * constraints to try and straighten them. bendWeight controls how hard we
+ * try to straighten existing bends potBendWeight controls how much we try
+ * to keep straight edges straight
+ */
+ void setStraightenEdges(std::vector<straightener::Edge*>* straightenEdges,
+ double bendWeight = 0.01, double potBendWeight = 0.1,
+ bool xSkipping = true) {
+ for(std::vector<straightener::Edge*>::const_iterator e=straightenEdges->begin();
+ e!=straightenEdges->end();e++) {
+ (*e)->rerouteAround(boundingBoxes);
+ }
+ constrainedLayout = true;
+ this->xSkipping = xSkipping;
+ this->straightenEdges = straightenEdges;
+ this->bendWeight = bendWeight;
+ this->potBendWeight = potBendWeight;
+ }
+ /**
+ * Update position of bounding boxes.
+ */
+ void moveBoundingBoxes() {
+ for(unsigned i=0;i<n;i++) {
+ boundingBoxes[i]->moveCentre(X[i],Y[i]);
+ }
+ }
+
+ ~ConstrainedMajorizationLayout() {
+ if (using_default_done)
+ {
+ delete done;
+ }
+
+ if(constrainedLayout) {
+ delete gpX;
+ delete gpY;
+ }
+ }
+ /**
+ * @brief Implements the main layout loop, taking descent steps until
+ * stress is no-longer significantly reduced.
+ *
+ * @param[in] x If true, layout will be performed in x-dimension
+ * (default: true).
+ * @param[in] y If true, layout will be performed in y-dimension
+ * (default: true).
+ */
+ void run(bool x=true, bool y=true);
+ /**
+ * @brief Same as run(), but only applies one iteration.
+ *
+ * This may be useful here it's too hard to implement a call-back
+ * (e.g., in java apps).
+ *
+ * @param[in] x If true, layout will be performed in x-dimension
+ * (default: true).
+ * @param[in] y If true, layout will be performed in y-dimension
+ * (default: true).
+ */
+ void runOnce(bool x=true, bool y=true);
+ void straighten(std::vector<straightener::Edge*>&, vpsc::Dim);
+ void setConstrainedLayout(bool c) {
+ constrainedLayout=c;
+ }
+ double computeStress();
+private:
+ double euclidean_distance(unsigned i, unsigned j) {
+ return sqrt(
+ (X[i] - X[j]) * (X[i] - X[j]) +
+ (Y[i] - Y[j]) * (Y[i] - Y[j]));
+ }
+ double compute_stress(std::valarray<double> const & Dij);
+ void majorize(std::valarray<double> const & Dij,GradientProjection* gp, std::valarray<double>& coords, std::valarray<double> const & startCoords);
+ void newton(std::valarray<double> const & Dij,GradientProjection* gp, std::valarray<double>& coords, std::valarray<double> const & startCoords);
+ unsigned n; //< number of nodes
+ //std::valarray<double> degrees;
+ std::valarray<double> lap2; //< graph laplacian
+ std::valarray<double> Q; //< quadratic terms matrix used in computations
+ std::valarray<double> Dij; //< all pairs shortest path distances
+ double tol; //< convergence tolerance
+ TestConvergence *done; //< functor used to determine if layout is finished
+ bool using_default_done; // Whether we allocated a default TestConvergence object.
+ PreIteration* preIteration; //< client can use this to create locks on nodes
+ vpsc::Rectangles boundingBoxes; //< node bounding boxes
+ /*
+ * stickyNodes controls whether nodes are attracted to their starting
+ * positions (at time of ConstrainedMajorizationLayout instantiation)
+ * stored in startX, startY
+ */
+ std::valarray<double> X, Y;
+ bool stickyNodes;
+ double stickyWeight;
+ std::valarray<double> startX;
+ std::valarray<double> startY;
+ double edge_length;
+ bool constrainedLayout;
+ bool nonOverlappingClusters;
+ /*
+ * A cluster is a set of nodes that are somehow semantically grouped
+ * and should therefore be kept together a bit more tightly than, and
+ * preferably without overlapping, the rest of the graph.
+ *
+ * We achieve this by augmenting the L matrix with stronger attractive
+ * forces between all members of a cluster (other than the root)
+ * and by maintaining a (preferably convex) hull around those
+ * constituents which, using constraints and dummy variables, is
+ * prevented from overlapping other parts of the graph.
+ *
+ * Clusters are defined over the graph in a hierarchy starting with
+ * a single root cluster.
+ *
+ * Need to:
+ * - augment Lap matrix with intra cluster forces
+ * - compute convex hull of each cluster
+ * - from convex hull generate "StraightenEdges"
+ */
+ RootCluster *clusterHierarchy;
+ GradientProjection *gpX, *gpY;
+ cola::CompoundConstraints *ccs;
+ UnsatisfiableConstraintInfos *unsatisfiableX, *unsatisfiableY;
+ NonOverlapConstraintsMode avoidOverlaps;
+ std::vector<straightener::Edge*>* straightenEdges;
+
+ double bendWeight, potBendWeight;
+ /*
+ * determines whether we should leave some overlaps to be resolved
+ * vertically when generating straightening constraints in the x-dim
+ */
+ bool xSkipping;
+ /*
+ * when using the gradient projection optimisation method, the following
+ * controls whether the problem should be preconditioned by affine scaling
+ */
+ bool scaling;
+ /*
+ * if the Mosek quadratic programming environment is available it may be
+ * used to solve each iteration of stress majorization... slow but useful
+ * for testing
+ */
+ bool externalSolver;
+ bool majorization;
+};
+
+vpsc::Rectangle bounds(vpsc::Rectangles& rs);
+
+class ConstrainedFDLayout;
+
+/**
+ * @brief Interface for writing COLA addons to handle topology preserving
+ * layout.
+ */
+class TopologyAddonInterface
+{
+ public:
+ TopologyAddonInterface()
+ {
+ }
+
+ virtual ~TopologyAddonInterface()
+ {
+ }
+
+ virtual TopologyAddonInterface *clone(void) const
+ {
+ return new TopologyAddonInterface(*this);
+ }
+
+ virtual void freeAssociatedObjects(void)
+ {
+ }
+
+ virtual void handleResizes(const Resizes& resizeList, unsigned n,
+ std::valarray<double>& X, std::valarray<double>& Y,
+ cola::CompoundConstraints& ccs,
+ vpsc::Rectangles& boundingBoxes,
+ cola::RootCluster* clusterHierarchy)
+ {
+ COLA_UNUSED(resizeList);
+ COLA_UNUSED(n);
+ COLA_UNUSED(X);
+ COLA_UNUSED(Y);
+ COLA_UNUSED(ccs);
+ COLA_UNUSED(boundingBoxes);
+ COLA_UNUSED(clusterHierarchy);
+ }
+ virtual void computePathLengths(unsigned short** G)
+ {
+ COLA_UNUSED(G);
+ }
+ virtual double computeStress(void) const
+ {
+ return 0;
+ }
+ virtual bool useTopologySolver(void) const
+ {
+ return false;
+ }
+ virtual void makeFeasible(bool generateNonOverlapConstraints,
+ vpsc::Rectangles& boundingBoxes,
+ cola::RootCluster* clusterHierarchy)
+ {
+ COLA_UNUSED(generateNonOverlapConstraints);
+ COLA_UNUSED(boundingBoxes);
+ COLA_UNUSED(clusterHierarchy);
+ }
+ virtual void moveTo(const vpsc::Dim dim, vpsc::Variables& vs,
+ vpsc::Constraints& cs, std::valarray<double> &coords,
+ cola::RootCluster* clusterHierarchy)
+ {
+ COLA_UNUSED(dim);
+ COLA_UNUSED(vs);
+ COLA_UNUSED(cs);
+ COLA_UNUSED(coords);
+ COLA_UNUSED(clusterHierarchy);
+ }
+ virtual double applyForcesAndConstraints(ConstrainedFDLayout *layout,
+ const vpsc::Dim dim, std::valarray<double>& g,
+ vpsc::Variables& vs, vpsc::Constraints& cs,
+ std::valarray<double> &coords,
+ DesiredPositionsInDim& des, double oldStress)
+ {
+ COLA_UNUSED(layout);
+ COLA_UNUSED(dim);
+ COLA_UNUSED(g);
+ COLA_UNUSED(vs);
+ COLA_UNUSED(cs);
+ COLA_UNUSED(coords);
+ COLA_UNUSED(des);
+ COLA_UNUSED(oldStress);
+ return 0;
+ }
+};
+
+
+/**
+ * @brief Implements a constrained force-directed layout algorithm.
+ *
+ * This method is based on a non-linear gradient projection technique.
+ * Conceptually it's similar to a force directed method like
+ * Fruchterman-Reingold---but using a more principled goal function and
+ * optimisation techniques.
+ */
+class ConstrainedFDLayout {
+public:
+ /**
+ * @brief Constructs a constrained force-directed layout instance.
+ *
+ * If an empty edges (es) vector is passed to the constructor, then
+ * constraint satisfaction will be performed, but no force-directed
+ * layout. In this case, idealLength and eLengths have no effect.
+ *
+ * Conversely, if no constraints or clusters are specified and no overlap
+ * prevention is enabled, but edge info is given, then pure force-directed
+ * layout will be performed.
+ *
+ * @param[in] rs Bounding boxes of nodes at their initial positions.
+ * @param[in] es Simple pair edges, giving indices of the start and end
+ * nodes in rs.
+ * @param[in] idealLength A scalar modifier of ideal edge lengths in
+ * eLengths or of 1 if no ideal lengths are
+ * specified.
+ * @param[in] eLengths Individual ideal lengths for edges.
+ * The actual ideal length used for the ith edge is
+ * idealLength*eLengths[i], or if eLengths is nullptr a
+ * then just idealLength is used (i.e., eLengths[i]
+ * is assumed to be 1).
+ * @param[in] done A test of convergence operation called at the end of
+ * each iteration (optional). If not given, uses a
+ * default TestConvergence object.
+ * @param[in] preIteration An operation called before each iteration
+ * (optional).
+ */
+ ConstrainedFDLayout(
+ const vpsc::Rectangles& rs,
+ const std::vector<cola::Edge>& es,
+ const double idealLength,
+ const EdgeLengths& eLengths = StandardEdgeLengths,
+ TestConvergence* doneTest = nullptr,
+ PreIteration* preIteration = nullptr);
+ ~ConstrainedFDLayout();
+
+ /**
+ * @brief Implements the main layout loop, taking descent steps until
+ * stress is no-longer significantly reduced.
+ *
+ * @param[in] x If true, layout will be performed in x-dimension
+ * (default: true).
+ * @param[in] y If true, layout will be performed in y-dimension
+ * (default: true).
+ */
+ void run(bool x=true, bool y=true);
+
+ /**
+ * @brief Same as run(), but only applies one iteration.
+ *
+ * This may be useful here it's too hard to implement a call-back
+ * (e.g., in java apps).
+ *
+ * @param[in] x If true, layout will be performed in x-dimension
+ * (default: true).
+ * @param[in] y If true, layout will be performed in y-dimension
+ * (default: true).
+ */
+ void runOnce(bool x=true, bool y=true);
+
+ /**
+ * @brief Specify a set of compound constraints to apply to the layout.
+ *
+ * @param[in] ccs The compound constraints.
+ */
+ void setConstraints(const cola::CompoundConstraints& ccs);
+
+ /**
+ * @brief Specifies whether non-overlap constraints should be
+ * automatically generated between all nodes, as well as any
+ * exemptions to this.
+ *
+ * The optional second parameter indicates groups of nodes that should be
+ * exempt from having non-overlap constraints generated between each other.
+ * For example, you might want to do this for nodes representing ports, or
+ * the child nodes in a particular cluster.
+ *
+ * @param[in] avoidOverlaps New boolean value for this option.
+ * @param[in] listOfNodeGroups A list of groups of node indexes which will
+ * not have non-overlap constraints generated
+ * between each other.
+ */
+ void setAvoidNodeOverlaps(bool avoidOverlaps,
+ ListOfNodeIndexes listOfNodeGroups =
+ ListOfNodeIndexes());
+
+ /**
+ * @brief Set an addon for doing topology preserving layout.
+ *
+ * It is expected that you would use the topology::ColaTopologyAddon()
+ * from libtopology rather than write your own. This is done so that
+ * libcola does not have to depend on libtopology.
+ *
+ * @param[in] topology Instance of a class implementing the
+ * TopologyAddonInterface.
+ * @sa topology::ColaTopologyAddon
+ */
+ void setTopology(TopologyAddonInterface *topology);
+ TopologyAddonInterface *getTopology(void);
+
+ void setDesiredPositions(DesiredPositions *desiredPositions);
+
+ /**
+ * @brief Specifies an optional hierarchy for clustering nodes.
+ *
+ * @param[in] hierarchy A pointer to a RootCluster object defining the
+ * the cluster hierarchy (optional).
+ */
+ void setClusterHierarchy(RootCluster *hierarchy)
+ {
+ clusterHierarchy = hierarchy;
+ }
+ /**
+ * @brief Register to receive information about unsatisfiable constraints.
+ *
+ * In the case of unsatisifiable constraints, the solver will drop
+ * unsatisfiable constraints of lowest priority. Information about these
+ * will be written to these lists after each iteration of constrained
+ * layout.
+ *
+ * param[out] unsatisfiableX A pointer to a UnsatisfiableConstraintInfos
+ * object that will be used to record
+ * unsatisfiable constraints in the x-dimension.
+ * param[out] unsatisfiableY A pointer to a UnsatisfiableConstraintInfos
+ * object that will be used to record
+ * unsatisfiable constraints in the y-dimension.
+ */
+ void setUnsatisfiableConstraintInfo(
+ UnsatisfiableConstraintInfos *unsatisfiableX,
+ UnsatisfiableConstraintInfos *unsatisfiableY)
+ {
+ unsatisfiable.resize(2);
+ unsatisfiable[0]=unsatisfiableX;
+ unsatisfiable[1]=unsatisfiableY;
+ }
+ /**
+ * @brief Finds a feasible starting position for nodes that satisfies the
+ * given constraints.
+ *
+ * Starts with an initial position (x, y) for the nodes. This position
+ * is then iteratively updated with a greedy heuristic that tries adding
+ * additional constraints based on compound constraint priority to the
+ * satisfiable set, so as to satisfy as many of the placement constraints
+ * as possible. This includes automatically generated constraints for
+ * non-overlap and cluster containment.
+ *
+ * @param[in] xBorder Optional border width to add to left and right
+ * sides of rectangles. Defaults to 1.
+ * @param[in] yBorder Optional border width to add to top and bottom
+ * sides of rectangles. Defaults to 1.
+ *
+ * @note This method doesn't do force-directed layout. All forces are
+ * ignored and it merely satisfies the constraints with minimal
+ * movement to nodes.
+ */
+ void makeFeasible(double xBorder=1, double yBorder=1);
+
+ /**
+ * @brief A convenience method that can be called from Java to free
+ * the memory of nodes (Rectangles), CompoundConstraints, etc.
+ *
+ * This assumes that the ConstrainedFDLayout instance takes ownership
+ * of all the objects passed to it.
+ *
+ * This is useful because in SWIG we have problems with Java wrapper
+ * classes going out of scope and causing objects like Rectanges to
+ * sometimes be freed when the layout instance still needs them. For
+ * this reason we prevent the Java wrappers from deleting the internal
+ * C++ instances, and let them be cleaned up later via this method.
+ */
+ void freeAssociatedObjects(void);
+
+ //! @brief Generates an SVG file containing debug output and code that
+ //! can be used to regenerate the instance.
+ //!
+ //! This method can be called before or after run() or makeFeasible()
+ //! have been called.
+ //!
+ //! @param[in] filename A string indicating the filename (without
+ //! extension) for the output file. Defaults to
+ //! "libcola-debug.svg" if no filename is given.
+ //!
+ void outputInstanceToSVG(std::string filename = std::string());
+
+ /**
+ * @brief Specifies whether neighbour stress should be used.
+ *
+ * Under neighbour stress, only the terms representing neighbouring
+ * nodes contribute to the stress function. This can help to distribute
+ * nodes more evenly, eliminating long-range forces.
+ *
+ * Default value is false.
+ *
+ * @param[in] useNeighbourStress New boolean value for this option.
+ */
+ void setUseNeighbourStress(bool useNeighbourStress);
+
+ /**
+ * @brief Retrieve a copy of the "D matrix" computed by the computePathLengths
+ * method, linearised as a vector.
+ *
+ * This is especially useful for projects in SWIG target languages that want to
+ * do their own computations with stress.
+ *
+ * D is the required euclidean distances between pairs of nodes
+ * based on the shortest paths between them (using
+ * m_idealEdgeLength*eLengths[edge] as the edge length, if eLengths array
+ * is provided otherwise just m_idealEdgeLength).
+ *
+ * @return vector representing the D matrix.
+ */
+ std::vector<double> readLinearD(void);
+
+ /**
+ * @brief Retrieve a copy of the "G matrix" computed by the computePathLengths
+ * method, linearised as a vector.
+ *
+ * * This is especially useful for projects in SWIG target languages that want to
+ * do their own computations with stress.
+ *
+ * G is a matrix of unsigned ints such that G[u][v]=
+ * 0 if there are no forces required between u and v
+ * (for example, if u and v are in unconnected components)
+ * 1 if attractive forces are required between u and v
+ * (i.e. if u and v are immediately connected by an edge and there is
+ * no topology route between u and v (for which an attractive force
+ * is computed elsewhere))
+ * 2 if no attractive force is required between u and v but there is
+ * a connected path between them.
+ *
+ * @return vector representing the G matrix.
+ */
+ std::vector<unsigned> readLinearG(void);
+
+ double computeStress() const;
+
+private:
+ unsigned n; // number of nodes
+ std::valarray<double> X, Y;
+ vpsc::Rectangles boundingBoxes;
+ double applyForcesAndConstraints(const vpsc::Dim dim,const double oldStress);
+ double computeStepSize(const SparseMatrix& H, const std::valarray<double>& g,
+ const std::valarray<double>& d) const;
+ void computeDescentVectorOnBothAxes(const bool xaxis, const bool yaxis,
+ double stress, std::valarray<double>& x0, std::valarray<double>& x1);
+ void moveTo(const vpsc::Dim dim, std::valarray<double>& target);
+ double applyDescentVector(
+ const std::valarray<double>& d,
+ const std::valarray<double>& oldCoords,
+ std::valarray<double> &coords,
+ const double oldStress,
+ double stepsize
+ /*,topology::TopologyConstraints *s=nullptr*/);
+ void computePathLengths(
+ const std::vector<Edge>& es, std::valarray<double> eLengths);
+ void generateNonOverlapAndClusterCompoundConstraints(
+ vpsc::Variables (&vs)[2]);
+ void handleResizes(const Resizes&);
+ void setPosition(std::valarray<double>& pos);
+ void moveBoundingBoxes();
+ bool noForces(double, double, unsigned) const;
+ void computeForces(const vpsc::Dim dim, SparseMap &H,
+ std::valarray<double> &g);
+ void recGenerateClusterVariablesAndConstraints(
+ vpsc::Variables (&vars)[2], unsigned int& priority,
+ cola::NonOverlapConstraints *noc, Cluster *cluster,
+ cola::CompoundConstraints& idleConstraints);
+ std::vector<double> offsetDir(double minD);
+
+ void computeNeighbours(std::vector<Edge> es);
+ std::vector<std::vector<unsigned> > neighbours;
+ std::vector<std::vector<double> > neighbourLengths;
+ TestConvergence *done;
+ bool using_default_done; // Whether we allocated a default TestConvergence object.
+ PreIteration* preIteration;
+ cola::CompoundConstraints ccs;
+ double** D;
+ unsigned short** G;
+ double minD;
+ PseudoRandom random;
+
+ TopologyAddonInterface *topologyAddon;
+ std::vector<UnsatisfiableConstraintInfos*> unsatisfiable;
+ bool rungekutta;
+ DesiredPositions *desiredPositions;
+ cola::CompoundConstraints extraConstraints;
+
+ RootCluster *clusterHierarchy;
+ double rectClusterBuffer;
+ double m_idealEdgeLength;
+ bool m_generateNonOverlapConstraints;
+ bool m_useNeighbourStress;
+ const std::valarray<double> m_edge_lengths;
+
+ NonOverlapConstraintExemptions *m_nonoverlap_exemptions;
+
+ friend class topology::ColaTopologyAddon;
+ friend class dialect::Graph;
+};
+
+struct ProjectionResult {
+ int errorLevel;
+ std::string unsatinfo;
+};
+
+/**
+ * @brief Attempt to do a projection onto a vector of cola CompoundConstraints.
+ * @param dim the dimension in which to perform the projection
+ * @param rs the rectangles representing the nodes
+ * @param ccs the constraints
+ * @param preventOverlaps boolean saying whether you want overlap prevention
+ * constraints to be automatically generated
+ * @param accept an integer indicating which types of infeasibilities you will accept.
+ * The default value of 0 means you accept no infeasibility.
+ * For other values, see the description of the "errorLevel" in the
+ * doctext for the solve function below.
+ * @param debugLevel see solve function below
+ * @note Rectangle positions are updated if and only if the error level is less
+ * than or equal to the accept level.
+ * @return a ProjectionResult indicating whether the projection was feasible or not.
+ * @sa solve
+ */
+ProjectionResult projectOntoCCs(vpsc::Dim dim, vpsc::Rectangles &rs, cola::CompoundConstraints ccs,
+ bool preventOverlaps, int accept=0, unsigned debugLevel=0);
+
+/**
+ * @brief Constructs a solver and attempts to solve the passed constraints on the passed vars.
+ * @param debugLevel: controls how much information comes back when the projection fails. See below.
+ * @return a ProjectionResult, containing:
+ * errorLevel:
+ * 0: all constraints were satisfiable.
+ * 1: some constraints were unsatisfiable, but they were all nonoverlap constraints.
+ * 2: some constraints were unsatisfiable which were /not/ nonoverlap constraints.
+ * unsatinfo:
+ * The amount of information reported depends on the debugLevel:
+ * 0: nothing reported (empty string)
+ * 1: description of the unsatisfied constraints
+ * 2: the info from level 1, plus a description of all "related" constraints (those sharing a variable).
+ * This is useful for understanding the conflicts.
+ */
+ProjectionResult solve(vpsc::Variables &vs, vpsc::Constraints &cs, vpsc::Rectangles &rs,
+ unsigned debugLevel=0);
+
+
+ConstrainedMajorizationLayout* simpleCMLFactory(
+ vpsc::Rectangles& rs,
+ std::vector<Edge> const & es,
+ RootCluster* clusterHierarchy,
+ const double idealLength,
+ bool useNeighbourStress = false
+ );
+
+/*
+ * find shortest path lengths from node s to all other nodes.
+ * @param s starting node
+ * @param n total number of nodes
+ * @param d n vector of path lengths
+ * @param es edge pairs
+ * @param eLengths edge weights
+ */
+void dijkstra(const unsigned s, const unsigned n, double* d,
+ const std::vector<cola::Edge>& es,
+ const std::valarray<double> & eLengths);
+
+#if 0
+void removeClusterOverlapFast(RootCluster& clusterHierarchy, vpsc::Rectangles& rs, Locks& locks);
+#endif
+
+void setupVarsAndConstraints(unsigned n, const CompoundConstraints& ccs,
+ const vpsc::Dim dim, vpsc::Rectangles& boundingBoxes,
+ RootCluster *clusterHierarchy,
+ vpsc::Variables& vs, vpsc::Constraints& cs,
+ std::valarray<double> &coords);
+void setVariableDesiredPositions(vpsc::Variables& vs, vpsc::Constraints& cs,
+ const DesiredPositionsInDim& des, std::valarray<double>& coords);
+
+}
+#endif // COLA_H
diff --git a/src/3rdparty/adaptagrams/libcola/cola_log.h b/src/3rdparty/adaptagrams/libcola/cola_log.h
new file mode 100644
index 0000000..5909c93
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/cola_log.h
@@ -0,0 +1,204 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+/*
+Logging code from DJJ article: http://www.ddj.com/cpp/201804215.
+
+Title: Logging In C++
+Author: Petru Marginean
+Keywords: OCT07 C++
+Description: Unpublished source code accompanying the article by Petru Marginean, in which he presents a C++ logging framework that is typesafe, thread-safe, and portable.
+ */
+#ifndef __COLA_LOG_H__
+#define __COLA_LOG_H__
+
+#include <sstream>
+#include <string>
+#include <cstdio>
+#include <iomanip>
+
+namespace cola {
+inline std::string NowTime();
+
+enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
+
+template <typename T>
+class Log
+{
+public:
+ Log();
+ virtual ~Log();
+ std::ostringstream& Get(TLogLevel level = logINFO);
+public:
+ static TLogLevel& ReportingLevel();
+ static std::string ToString(TLogLevel level);
+ static TLogLevel FromString(const std::string& level);
+protected:
+ std::ostringstream os;
+private:
+ Log(const Log&);
+ Log& operator =(const Log&);
+};
+
+template <typename T>
+Log<T>::Log()
+{
+}
+
+template <typename T>
+std::ostringstream& Log<T>::Get(TLogLevel level)
+{
+ os << "- " << NowTime();
+ os << " " << ToString(level) << ": ";
+ os << std::string(level > logDEBUG ? level - logDEBUG : 0, '\t');
+ return os;
+}
+
+template <typename T>
+Log<T>::~Log()
+{
+ os << std::endl;
+ T::Output(os.str());
+}
+
+template <typename T>
+TLogLevel& Log<T>::ReportingLevel()
+{
+ static TLogLevel reportingLevel = cola::logDEBUG4;
+ return reportingLevel;
+}
+
+template <typename T>
+std::string Log<T>::ToString(TLogLevel level)
+{
+ static const char* const buffer[] = {"ERROR", "WARNING", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4"};
+ return buffer[level];
+}
+
+template <typename T>
+TLogLevel Log<T>::FromString(const std::string& level)
+{
+ if (level == "DEBUG4")
+ return logDEBUG4;
+ if (level == "DEBUG3")
+ return logDEBUG3;
+ if (level == "DEBUG2")
+ return logDEBUG2;
+ if (level == "DEBUG1")
+ return logDEBUG1;
+ if (level == "DEBUG")
+ return logDEBUG;
+ if (level == "INFO")
+ return logINFO;
+ if (level == "WARNING")
+ return logWARNING;
+ if (level == "ERROR")
+ return logERROR;
+ Log<T>().Get(logWARNING) << "Unknown logging level '" << level << "'. Using INFO level as default.";
+ return logINFO;
+}
+
+class Output2FILE
+{
+public:
+ static FILE*& Stream();
+ static void Output(const std::string& msg);
+};
+
+inline FILE*& Output2FILE::Stream()
+{
+ static FILE* pStream = stderr;
+ return pStream;
+}
+
+inline void Output2FILE::Output(const std::string& msg)
+{
+ FILE* pStream = Stream();
+ if (!pStream)
+ return;
+ fprintf(pStream, "%s", msg.c_str());
+ fflush(pStream);
+}
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+# if defined (BUILDING_FILELOG_DLL)
+# define FILELOG_DECLSPEC __declspec (dllexport)
+# elif defined (USING_FILELOG_DLL)
+# define FILELOG_DECLSPEC __declspec (dllimport)
+# else
+# define FILELOG_DECLSPEC
+# endif // BUILDING_DBSIMPLE_DLL
+#else
+# define FILELOG_DECLSPEC
+#endif // _WIN32
+
+class FILELOG_DECLSPEC FILELog : public Log<Output2FILE> {};
+//typedef Log<Output2FILE> FILELog;
+
+#ifndef FILELOG_MAX_LEVEL
+#define FILELOG_MAX_LEVEL cola::logDEBUG4
+#endif
+
+#define FILE_LOG(level) \
+ if (level > FILELOG_MAX_LEVEL) ;\
+ else if (level > cola::FILELog::ReportingLevel() || !cola::Output2FILE::Stream()) ; \
+ else cola::FILELog().Get(level)
+
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+
+#include <windows.h>
+
+inline std::string NowTime()
+{
+ const int MAX_LEN = 200;
+ char buffer[MAX_LEN];
+ if (GetTimeFormatA(LOCALE_USER_DEFAULT, 0, 0,
+ "HH':'mm':'ss", buffer, MAX_LEN) == 0)
+ return "Error in NowTime()";
+
+ static DWORD first = GetTickCount();
+ std::stringstream result;
+ result << buffer << "." << std::setfill('0') << std::setw(3) << ((long)(GetTickCount() - first) % 1000);
+ return result.str();
+}
+
+#else
+
+#include <sys/time.h>
+
+inline std::string NowTime()
+{
+ char buffer[11];
+ time_t t;
+ time(&t);
+ tm r;
+ strftime(buffer, sizeof(buffer), "%X", localtime_r(&t, &r));
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ std::stringstream result;
+ result << buffer << "." << std::setfill('0') << std::setw(3) << ((long)tv.tv_usec / 1000);
+ return result.str();
+}
+
+#endif //WIN32
+
+} // namespace cola
+
+#endif //__COLA_LOG_H__
diff --git a/src/3rdparty/adaptagrams/libcola/colafd.cpp b/src/3rdparty/adaptagrams/libcola/colafd.cpp
new file mode 100644
index 0000000..8476f6b
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/colafd.cpp
@@ -0,0 +1,1681 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2015 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+ * Michael Wybrow
+ *
+*/
+
+// cmath needs ::strcpy_s under MinGW so include cstring.
+#include <cstring>
+
+#include <vector>
+#include <cmath>
+#include <limits>
+
+#include "libvpsc/solve_VPSC.h"
+#include "libvpsc/variable.h"
+#include "libvpsc/constraint.h"
+#include "libvpsc/rectangle.h"
+#include "libvpsc/exceptions.h"
+
+#include "libcola/commondefs.h"
+#include "libcola/cola.h"
+#include "libcola/shortest_paths.h"
+#include "libcola/straightener.h"
+#include "libcola/cc_clustercontainmentconstraints.h"
+#include "libcola/cc_nonoverlapconstraints.h"
+
+#ifdef MAKEFEASIBLE_DEBUG
+ #include "libcola/output_svg.h"
+#endif
+
+// Needs to come last since it will include windows.h on WIN32 and
+// may mess up C++ std library include on GCC 4.4
+#include "libcola/cola_log.h"
+
+using namespace std;
+using vpsc::Dim;
+using vpsc::XDIM;
+using vpsc::YDIM;
+using vpsc::IncSolver;
+using vpsc::Variable;
+using vpsc::Variables;
+using vpsc::Constraint;
+using vpsc::Constraints;
+using vpsc::Rectangle;
+using vpsc::Rectangles;
+
+namespace cola {
+
+template <class T>
+void delete_vector(vector<T*> &v) {
+ for_each(v.begin(),v.end(),delete_object());
+ v.clear();
+}
+Resizes PreIteration::__resizesNotUsed;
+Locks PreIteration::__locksNotUsed;
+inline double dotProd(valarray<double> x, valarray<double> y) {
+ COLA_ASSERT(x.size()==y.size());
+ double dp=0;
+ for(unsigned i=0;i<x.size();i++) {
+ dp+=x[i]*y[i];
+ }
+ return dp;
+}
+template <typename T>
+void dumpSquareMatrix(unsigned n, T** L) {
+ printf("Matrix %dX%d\n{",n,n);
+ for(unsigned i=0;i<n;i++) {
+ printf("{");
+ for(unsigned j=0;j<n;j++) {
+ std::cout<<L[i][j];
+ char c=j==n-1?'}':',';
+ printf("%c",c);
+ }
+ char c=i==n-1?'}':',';
+ printf("%c\n",c);
+ }
+}
+
+ConstrainedFDLayout::ConstrainedFDLayout(const vpsc::Rectangles& rs,
+ const std::vector< Edge >& es, const double idealLength,
+ const EdgeLengths& eLengths,
+ TestConvergence *doneTest, PreIteration* preIteration)
+ : n(rs.size()),
+ X(valarray<double>(n)),
+ Y(valarray<double>(n)),
+ done(doneTest),
+ using_default_done(false),
+ preIteration(preIteration),
+ topologyAddon(new TopologyAddonInterface()),
+ rungekutta(true),
+ desiredPositions(nullptr),
+ clusterHierarchy(nullptr),
+ rectClusterBuffer(0),
+ m_idealEdgeLength(idealLength),
+ m_generateNonOverlapConstraints(false),
+ m_useNeighbourStress(false),
+ m_edge_lengths(eLengths.data(), eLengths.size()),
+ m_nonoverlap_exemptions(new NonOverlapConstraintExemptions())
+{
+ minD = DBL_MAX;
+
+ if (done == nullptr)
+ {
+ done = new TestConvergence();
+ using_default_done = true;
+ }
+
+ computeNeighbours(es);
+
+ //FILELog::ReportingLevel() = logDEBUG1;
+ FILELog::ReportingLevel() = logERROR;
+ boundingBoxes = rs;
+ done->reset();
+ unsigned i=0;
+ for(vpsc::Rectangles::const_iterator ri=rs.begin();ri!=rs.end();++ri,++i) {
+ X[i]=(*ri)->getCentreX();
+ Y[i]=(*ri)->getCentreY();
+ FILE_LOG(logDEBUG) << *ri;
+ }
+ D=new double*[n];
+ G=new unsigned short*[n];
+ for(unsigned i=0;i<n;i++) {
+ D[i]=new double[n];
+ G[i]=new unsigned short[n];
+ }
+
+ computePathLengths(es,m_edge_lengths);
+}
+
+std::vector<double> ConstrainedFDLayout::readLinearD(void)
+{
+ std::vector<double> d;
+ d.resize(n*n);
+ for (unsigned i = 0; i < n; ++i) {
+ for (unsigned j = 0; j < n; ++j) {
+ d[n*i + j] = D[i][j];
+ }
+ }
+ return d;
+}
+
+std::vector<unsigned> ConstrainedFDLayout::readLinearG(void)
+{
+ std::vector<unsigned> g;
+ g.resize(n*n);
+ for (unsigned i = 0; i < n; ++i) {
+ for (unsigned j = 0; j < n; ++j) {
+ g[n*i + j] = G[i][j];
+ }
+ }
+ return g;
+}
+
+void ConstrainedFDLayout::computeNeighbours(vector<Edge> es) {
+ for (unsigned i = 0; i < n; ++i) {
+ neighbours.push_back(vector<unsigned>(n));
+ }
+ for (vector<Edge>::iterator it = es.begin(); it!=es.end(); ++it) {
+ Edge e = *it;
+ unsigned s = e.first, t = e.second;
+ neighbours[s][t] = 1;
+ neighbours[t][s] = 1;
+ }
+}
+
+void dijkstra(const unsigned s, const unsigned n, double* d,
+ const vector<Edge>& es, const std::valarray<double> & eLengths)
+{
+ shortest_paths::dijkstra(s,n,d,es,eLengths);
+}
+
+void ConstrainedFDLayout::setConstraints(const cola::CompoundConstraints& ccs)
+{
+ this->ccs = ccs;
+}
+
+void ConstrainedFDLayout::setAvoidNodeOverlaps(bool avoidOverlaps,
+ std::vector<std::vector<unsigned> > listOfNodeGroups)
+{
+ m_generateNonOverlapConstraints = avoidOverlaps;
+ m_nonoverlap_exemptions->addExemptGroupOfNodes(listOfNodeGroups);
+}
+
+void ConstrainedFDLayout::setUseNeighbourStress(bool useNeighbourStress)
+{
+ m_useNeighbourStress = useNeighbourStress;
+}
+
+void ConstrainedFDLayout::setDesiredPositions(DesiredPositions *desiredPositions)
+{
+ this->desiredPositions = desiredPositions;
+}
+
+
+/*
+ * Sets up the D and G matrices. D is the required euclidean distances
+ * between pairs of nodes based on the shortest paths between them (using
+ * m_idealEdgeLength*eLengths[edge] as the edge length, if eLengths array
+ * is provided otherwise just m_idealEdgeLength). G is a matrix of
+ * unsigned ints such that G[u][v]=
+ * 0 if there are no forces required between u and v
+ * (for example, if u and v are in unconnected components)
+ * 1 if attractive forces are required between u and v
+ * (i.e. if u and v are immediately connected by an edge and there is
+ * no topology route between u and v (for which an attractive force
+ * is computed elsewhere))
+ * 2 if no attractive force is required between u and v but there is
+ * a connected path between them.
+ */
+void ConstrainedFDLayout::computePathLengths(
+ const vector<Edge>& es, std::valarray<double> eLengths)
+{
+ // Correct zero or negative entries in eLengths array.
+ for (size_t i = 0; i < eLengths.size(); ++i)
+ {
+ if (eLengths[i] <= 0)
+ {
+ fprintf(stderr, "Warning: ignoring non-positive length at index %d "
+ "in ideal edge length array.\n", (int) i);
+ eLengths[i] = 1;
+ }
+ }
+
+ shortest_paths::johnsons(n,D,es,eLengths);
+ //dumpSquareMatrix<double>(n,D);
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=0;j<n;j++) {
+ if(i==j) continue;
+ double& d=D[i][j];
+ unsigned short& p=G[i][j];
+ p=2;
+ if(d==DBL_MAX) {
+ // i and j are in disconnected subgraphs
+ p=0;
+ } else {
+ d*=m_idealEdgeLength;
+ }
+
+ if ((d > 0) && (d < minD)) {
+ minD = d;
+ }
+ }
+ }
+ if (minD == DBL_MAX) minD = 1;
+
+ for(vector<Edge>::const_iterator e=es.begin();e!=es.end();++e) {
+ unsigned u=e->first, v=e->second;
+ G[u][v]=G[v][u]=1;
+ }
+ topologyAddon->computePathLengths(G);
+ //dumpSquareMatrix<short>(n,G);
+}
+
+typedef valarray<double> Position;
+void getPosition(Position& X, Position& Y, Position& pos) {
+ unsigned n=X.size();
+ COLA_ASSERT(Y.size()==n);
+ COLA_ASSERT(pos.size()==2*n);
+ for(unsigned i=0;i<n;++i) {
+ pos[i]=X[i];
+ pos[i+n]=Y[i];
+ }
+}
+/*
+ * moves all rectangles to the desired position while respecting
+ * constraints.
+ * @param pos target positions of both axes
+ */
+void ConstrainedFDLayout::setPosition(Position& pos) {
+ COLA_ASSERT(Y.size()==X.size());
+ COLA_ASSERT(pos.size()==2*X.size());
+ moveTo(vpsc::HORIZONTAL,pos);
+ moveTo(vpsc::VERTICAL,pos);
+}
+/*
+ * Layout is performed by minimizing the P-stress goal function iteratively.
+ * At each iteration taking a step in the steepest-descent direction.
+ * x0 is the current position, x1 is the x0 - descentvector.
+ */
+void ConstrainedFDLayout::computeDescentVectorOnBothAxes(
+ const bool xAxis, const bool yAxis,
+ double stress, Position& x0, Position& x1) {
+ setPosition(x0);
+ if(xAxis) {
+ applyForcesAndConstraints(vpsc::HORIZONTAL,stress);
+ }
+ if(yAxis) {
+ applyForcesAndConstraints(vpsc::VERTICAL,stress);
+ }
+ getPosition(X,Y,x1);
+}
+
+/*
+ * run() implements the main layout loop, taking descent steps until
+ * stress is no-longer significantly reduced.
+ * done is a callback used to check stress but also to report updated
+ * positions.
+ */
+void ConstrainedFDLayout::run(const bool xAxis, const bool yAxis)
+{
+ // This generates constraints for non-overlap inside and outside
+ // of clusters. To assign correct variable indexes it requires
+ // that vs[] contains elements equal to the number of rectangles.
+ vpsc::Variables vs[2];
+ vs[0].resize(n);
+ vs[1].resize(n);
+ generateNonOverlapAndClusterCompoundConstraints(vs);
+
+ FILE_LOG(logDEBUG) << "ConstrainedFDLayout::run...";
+ double stress=DBL_MAX;
+ do {
+ if(preIteration) {
+ if(!(*preIteration)()) {
+ break;
+ }
+ //printf("preIteration->changed=%d\n",preIteration->changed);
+ if(preIteration->changed) {
+ stress=DBL_MAX;
+ }
+ if(preIteration->resizes.size()>0) {
+ FILE_LOG(logDEBUG) << " Resize event!";
+ handleResizes(preIteration->resizes);
+ }
+ }
+ unsigned N=2*n;
+ Position x0(N),x1(N);
+ getPosition(X,Y,x0);
+ if(rungekutta) {
+ Position a(N),b(N),c(N),d(N),ia(N),ib(N);
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,x0,a);
+ ia=x0+(a-x0)/2.0;
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,ia,b);
+ ib=x0+(b-x0)/2.0;
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,ib,c);
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,c,d);
+ x1=a+2.0*b+2.0*c+d;
+ x1/=6.0;
+ } else {
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,x0,x1);
+ }
+ setPosition(x1);
+ stress=computeStress();
+ FILE_LOG(logDEBUG) << "stress="<<stress;
+ } while(!(*done)(stress,X,Y));
+ for(unsigned i=0;i<n;i++) {
+ vpsc::Rectangle *r=boundingBoxes[i];
+ FILE_LOG(logDEBUG) << *r;
+ }
+ FILE_LOG(logDEBUG) << "ConstrainedFDLayout::run done.";
+
+ // Clear extra constraints.
+ for_each(extraConstraints.begin(), extraConstraints.end(), delete_object());
+ extraConstraints.clear();
+
+ // Free extra variables used for cluster containment.
+ for (size_t dim = 0; dim < 2; ++dim)
+ {
+ for (size_t i = n; i < vs[dim].size(); ++i)
+ {
+ delete vs[dim][i];
+ }
+ }
+}
+
+/*
+ * Same as run, but only applies one iteration. This may be useful
+ * where it's too hard to implement a call-back (e.g. in java apps)
+ */
+void ConstrainedFDLayout::runOnce(const bool xAxis, const bool yAxis) {
+ if(n==0) return;
+ double stress=DBL_MAX;
+ unsigned N=2*n;
+ Position x0(N),x1(N);
+ getPosition(X,Y,x0);
+ if(rungekutta) {
+ Position a(N),b(N),c(N),d(N),ia(N),ib(N);
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,x0,a);
+ ia=x0+(a-x0)/2.0;
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,ia,b);
+ ib=x0+(b-x0)/2.0;
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,ib,c);
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,c,d);
+ x1=a+2.0*b+2.0*c+d;
+ x1/=6.0;
+ } else {
+ computeDescentVectorOnBothAxes(xAxis,yAxis,stress,x0,x1);
+ }
+}
+
+
+// Used for sorting the CompoundConstraints from lowest priority to highest.
+static bool cmpCompoundConstraintPriority(const cola::CompoundConstraint *lhs,
+ const cola::CompoundConstraint *rhs)
+{
+ return lhs->priority() < rhs->priority();
+}
+
+
+void ConstrainedFDLayout::recGenerateClusterVariablesAndConstraints(
+ vpsc::Variables (&vars)[2], unsigned int& priority,
+ cola::NonOverlapConstraints *noc, Cluster *cluster,
+ cola::CompoundConstraints& idleConstraints)
+{
+ for (std::vector<Cluster*>::iterator curr = cluster->clusters.begin();
+ curr != cluster->clusters.end(); ++curr)
+ {
+ // For each of the child clusters, recursively call this function.
+ recGenerateClusterVariablesAndConstraints(vars, priority,
+ noc, *curr, idleConstraints);
+ }
+
+ if ( (noc == nullptr) && (dynamic_cast<RootCluster *> (cluster) == nullptr) )
+ {
+ double freeWeight = 0.00000000001;
+ // Then create left and right variables for the boundary of this
+ // cluster.
+ vpsc::Variable *variable = nullptr;
+ cluster->clusterVarId = vars[XDIM].size();
+ COLA_ASSERT(vars[XDIM].size() == vars[YDIM].size());
+ // Left:
+ variable = new vpsc::Variable(vars[XDIM].size(),
+ cluster->bounds.getMinX(), freeWeight);
+ vars[XDIM].push_back(variable);
+ // Right:
+ variable = new vpsc::Variable(vars[XDIM].size(),
+ cluster->bounds.getMaxX(), freeWeight);
+ vars[XDIM].push_back(variable);
+ // Bottom::
+ variable = new vpsc::Variable(vars[YDIM].size(),
+ cluster->bounds.getMinY(), freeWeight);
+ vars[YDIM].push_back(variable);
+ // Top:
+ variable = new vpsc::Variable(vars[YDIM].size(),
+ cluster->bounds.getMaxY(), freeWeight);
+ vars[YDIM].push_back(variable);
+
+ RectangularCluster *rc = dynamic_cast<RectangularCluster *> (cluster);
+ if (rc)
+ {
+ rc->generateFixedRectangleConstraints(idleConstraints,
+ boundingBoxes, vars);
+ }
+
+ priority--;
+ cola::ClusterContainmentConstraints *ccc =
+ new cola::ClusterContainmentConstraints(cluster, priority,
+ boundingBoxes);
+ idleConstraints.push_back(ccc);
+ }
+
+ if (noc)
+ {
+ // Enforce non-overlap between all the shapes and clusters at this
+ // level.
+ //printf("Cluster #%d non-overlap constraints - nodes %d clusters %d\n",
+ // (int) cluster->clusterVarId, (int) cluster->nodes.size(),
+ // (int) cluster->clusters.size());
+ unsigned int group = cluster->clusterVarId;
+ // The set of clusters to put non-overlap constraints between is the
+ // child clusters of this cluster. We will also add any overlapping
+ // clusters (due to multiple inheritence) to this set.
+ std::set<Cluster *> expandedClusterSet(cluster->clusters.begin(),
+ cluster->clusters.end());
+ for (std::set<unsigned>::iterator curr = cluster->nodes.begin();
+ curr != cluster->nodes.end(); ++curr)
+ {
+ unsigned id = *curr;
+
+ if (cluster->m_overlap_replacement_map.count(id) > 0)
+ {
+ // This shape is child of another cluster also, so replace
+ // this node with the other cluster for the purpose of
+ // non-overlap with other children of the current cluster.
+ expandedClusterSet.insert(
+ cluster->m_overlap_replacement_map[id]);
+ }
+ // Normal case: Add shape for generation of non-overlap
+ // constraints.
+ noc->addShape(id, boundingBoxes[id]->width() / 2,
+ boundingBoxes[id]->height() / 2, group);
+ }
+ for (std::set<Cluster*>::iterator curr = expandedClusterSet.begin();
+ curr != expandedClusterSet.end(); ++curr)
+ {
+ Cluster *cluster = *curr;
+ RectangularCluster *rectCluster =
+ dynamic_cast<RectangularCluster *> (cluster);
+ if (rectCluster && rectCluster->clusterIsFromFixedRectangle())
+ {
+ // Treat it like a shape for non-overlap.
+ unsigned id = rectCluster->rectangleIndex();
+ noc->addShape(id, boundingBoxes[id]->width() / 2,
+ boundingBoxes[id]->height() / 2, group);
+ }
+ else
+ {
+ // Normal cluster.
+ noc->addCluster(cluster, group);
+ }
+ }
+
+ // For the set of shapes that have been replaced due to multiple
+ // inheritance, still generate overlap constraints between them.
+ // (The group uses the ID of the right side variable of the cluster
+ // so it is not the same group as the cluster itself.)
+ for (std::set<unsigned>::iterator curr =
+ cluster->m_nodes_replaced_with_clusters.begin();
+ curr != cluster->m_nodes_replaced_with_clusters.end(); ++curr)
+ {
+ unsigned id = *curr;
+ noc->addShape(id, boundingBoxes[id]->width() / 2,
+ boundingBoxes[id]->height() / 2, group + 1);
+ }
+
+ }
+}
+
+void ConstrainedFDLayout::generateNonOverlapAndClusterCompoundConstraints(
+ vpsc::Variables (&vs)[2])
+{
+ if (clusterHierarchy && !clusterHierarchy->flat())
+ {
+ // Add remaining nodes that aren't contained within any clusters
+ // as children of the root cluster.
+ std::vector<unsigned> nodesInClusterCounts(boundingBoxes.size(), 0);
+ clusterHierarchy->countContainedNodes(nodesInClusterCounts);
+
+ for (unsigned int i = 0; i < nodesInClusterCounts.size(); ++i)
+ {
+ unsigned count = nodesInClusterCounts[i];
+ if (!clusterHierarchy->allowsMultipleParents() &&
+ count > 1)
+ {
+ fprintf(stderr, "Warning: node %u is contained in %d "
+ "clusters.\n", i, count);
+ }
+
+ if (count == 0)
+ {
+ // Not present in hierarchy, so add to root cluster.
+ clusterHierarchy->nodes.insert(i);
+ }
+ }
+
+ // Add non-overlap and containment constraints for all clusters
+ // and nodes.
+ unsigned int priority = PRIORITY_NONOVERLAP;
+ clusterHierarchy->computeBoundingRect(boundingBoxes);
+
+ // Generate the containment constraints
+ recGenerateClusterVariablesAndConstraints(vs, priority,
+ nullptr, clusterHierarchy, extraConstraints);
+
+ // Compute overlapping clusters.
+ clusterHierarchy->calculateClusterPathsToEachNode(boundingBoxes.size());
+
+ // Generate non-overlap constraints between all clusters and
+ // all contained nodes.
+ if (m_generateNonOverlapConstraints)
+ {
+ priority--;
+ cola::NonOverlapConstraints *noc =
+ new cola::NonOverlapConstraints(m_nonoverlap_exemptions,
+ priority);
+ noc->setClusterClusterExemptions(
+ clusterHierarchy->m_cluster_cluster_overlap_exceptions);
+ recGenerateClusterVariablesAndConstraints(vs, priority,
+ noc, clusterHierarchy, extraConstraints);
+ extraConstraints.push_back(noc);
+ }
+ }
+ else if (m_generateNonOverlapConstraints)
+ {
+ // Add standard non-overlap constraints between each pair of
+ // nodes.
+ cola::NonOverlapConstraints *noc =
+ new cola::NonOverlapConstraints(m_nonoverlap_exemptions);
+ for (unsigned int i = 0; i < boundingBoxes.size(); ++i)
+ {
+ noc->addShape(i, boundingBoxes[i]->width() / 2,
+ boundingBoxes[i]->height() / 2);
+ }
+ extraConstraints.push_back(noc);
+ }
+}
+
+void ConstrainedFDLayout::makeFeasible(double xBorder, double yBorder)
+{
+ vpsc::Variables vs[2];
+ vpsc::Constraints valid[2];
+
+ vpsc::Rectangle::setXBorder(xBorder);
+ vpsc::Rectangle::setYBorder(yBorder);
+
+ // Populate all the variables for shapes.
+ for (unsigned int dim = 0; dim < 2; ++dim)
+ {
+ vs[dim] = vpsc::Variables(boundingBoxes.size());
+ for (unsigned int i = 0; i < vs[dim].size(); ++i)
+ {
+ double pos = (dim == 0) ?
+ boundingBoxes[i]->getCentreX() :
+ boundingBoxes[i]->getCentreY();
+ vs[dim][i] = new vpsc::Variable(i, pos, 1);
+ }
+ }
+
+ vector<double> priorPos(boundingBoxes.size());
+
+ generateNonOverlapAndClusterCompoundConstraints(vs);
+
+ // Make a copy of the compound constraints and sort them by priority.
+ cola::CompoundConstraints idleConstraints = ccs;
+ // Append extraConstraints to idleConstraints.
+ idleConstraints.insert(idleConstraints.end(),
+ extraConstraints.begin(), extraConstraints.end());
+
+ std::sort(idleConstraints.begin(), idleConstraints.end(),
+ cmpCompoundConstraintPriority);
+
+ // Initialise extra variables for compound constraints.
+ for (unsigned int dim = 0; dim < 2; ++dim)
+ {
+ generateVariables(idleConstraints, (vpsc::Dim) dim, vs[dim]);
+ }
+
+#ifdef MAKEFEASIBLE_DEBUG
+ int iteration = 0;
+ vector<string> labels(boundingBoxes.size());
+ for(unsigned i=0;i<boundingBoxes.size();++i)
+ {
+ stringstream ss;
+ ss << i;
+ labels[i]=ss.str();
+ }
+#endif
+
+ // We can keep adding new constraints to the existing VPSC instances so
+ // long as everything is satisfiable. Only when it's not do we discard
+ // the existing VPSC instance for that dimension and create a new one.
+ vpsc::IncSolver *solver[2] = { nullptr };
+
+ // Main makeFeasible loop.
+ while (!idleConstraints.empty())
+ {
+ // idleConstraints is sorted lowest to highest priority, so the
+ // highest priority constraint will be at the back of the vector.
+ cola::CompoundConstraint *cc = idleConstraints.back();
+ idleConstraints.pop_back();
+
+#ifdef MAKEFEASIBLE_DEBUG
+ {
+ // Debugging SVG time slice output.
+ std::vector<cola::Edge> es;
+ for (unsigned int i = 0; i < boundingBoxes.size(); ++i)
+ {
+ boundingBoxes[i]->moveCentreX(vs[0][i]->finalPosition);
+ boundingBoxes[i]->moveCentreY(vs[1][i]->finalPosition);
+ }
+ iteration++;
+ std::sstream filename;
+ filename << "out/file-" << std::setfill('0') << std::setw(5) << iteration << ".pdf";
+
+ OutputFile of(boundingBoxes,es,clusterHierarchy,filename.str().c_str(),true,false);
+ of.setLabels(labels);
+ of.generate();
+ }
+#endif
+
+ cc->markAllSubConstraintsAsInactive();
+ bool subConstraintSatisfiable = true;
+
+ if (cc->shouldCombineSubConstraints())
+ {
+ // We are processing a combined set of satisfiable constraints,
+ // such as for containment within cluster boundary variables, so
+ // we just add all the required constraints and solve in both
+ // the X and Y dimension once to set the cluster boundaries to
+ // meaningful values.
+ while (cc->subConstraintsRemaining())
+ {
+ cola::SubConstraintAlternatives alternatives =
+ cc->getCurrSubConstraintAlternatives(vs);
+ // There should be no alternatives, just guaranteed
+ // satisfiable constraints.
+ COLA_ASSERT(alternatives.size() == 1);
+ vpsc::Dim& dim = alternatives.front().dim;
+ vpsc::Constraint& constraint = alternatives.front().constraint;
+ vpsc::Constraint *newConstraint =
+ new vpsc::Constraint(constraint);
+ valid[dim].push_back(newConstraint);
+ if (solver[dim])
+ {
+ // If we have an existing valid solver instance, add the
+ // constraint to that.
+ solver[dim]->addConstraint(newConstraint);
+ }
+ cc->markCurrSubConstraintAsActive(subConstraintSatisfiable);
+ }
+ // Satisfy the constraints in each dimension.
+ for (size_t dim = 0; dim < 2; ++dim)
+ {
+ if (solver[dim] == nullptr)
+ {
+ // Create a new VPSC solver if necessary.
+ solver[dim] = new vpsc::IncSolver(vs[dim], valid[dim]);
+ }
+ solver[dim]->satisfy();
+ }
+ continue;
+ }
+
+ while (cc->subConstraintsRemaining())
+ {
+ cola::SubConstraintAlternatives alternatives =
+ cc->getCurrSubConstraintAlternatives(vs);
+ alternatives.sort();
+
+ if (alternatives.empty())
+ {
+ continue;
+ }
+
+ while (!alternatives.empty())
+ {
+ // Reset subConstraintSatisfiable for new solve.
+ subConstraintSatisfiable = true;
+
+ vpsc::Dim& dim = alternatives.front().dim;
+ vpsc::Constraint& constraint = alternatives.front().constraint;
+
+ // Store current values for variables.
+ for (unsigned int i = 0; i < priorPos.size(); ++i)
+ {
+ priorPos[i] = vs[dim][i]->finalPosition;
+ }
+
+ // Some solving...
+ try
+ {
+ // Add the constraint from this alternative to the
+ // valid constraint set.
+ vpsc::Constraint *newConstraint =
+ new vpsc::Constraint(constraint);
+ valid[dim].push_back(newConstraint);
+
+ //fprintf(stderr, ".%d %3d - ", dim, valid[dim].size());
+
+ // Try to satisfy this set of constraints..
+ if (solver[dim] == nullptr)
+ {
+ // Create a new VPSC solver if necessary.
+ solver[dim] = new vpsc::IncSolver(vs[dim], valid[dim]);
+ }
+ else
+ {
+ // Or just add the constraint to the existing solver.
+ solver[dim]->addConstraint(newConstraint);
+ }
+ solver[dim]->satisfy();
+ }
+ catch (char *str)
+ {
+ subConstraintSatisfiable = false;
+
+ std::cerr << "++++ IN ERROR BLOCK" << std::endl;
+ std::cerr << str << std::endl;
+ for (vpsc::Rectangles::iterator r = boundingBoxes.begin();
+ r != boundingBoxes.end(); ++r)
+ {
+ std::cerr << **r <<std::endl;
+ }
+ }
+ for (size_t i = 0; i < valid[dim].size(); ++i)
+ {
+ if (valid[dim][i]->unsatisfiable)
+ {
+ // It might have made one of the earlier added
+ // constraints unsatisfiable, so we mark that one
+ // as okay since we will be reverting the most
+ // recent one.
+ valid[dim][i]->unsatisfiable = false;
+
+ subConstraintSatisfiable = false;
+ }
+ }
+
+ if (!subConstraintSatisfiable)
+ {
+ // Since we had unsatisfiable constraints we must
+ // discard this solver instance.
+ delete solver[dim];
+ solver[dim] = nullptr;
+
+ // Restore previous values for variables.
+ for (unsigned int i = 0; i < priorPos.size(); ++i)
+ {
+ vs[dim][i]->finalPosition = priorPos[i];
+ }
+
+ // Delete the newly added (and unsatisfiable)
+ // constraint from the valid constraint set.
+ delete valid[dim].back();
+ valid[dim].pop_back();
+ }
+ else
+ {
+ // Satisfied, so don't need to consider other alternatives.
+ break;
+ }
+ // Move on to the next alternative.
+ alternatives.pop_front();
+ }
+#ifdef MAKEFEASIBLE_DEBUG
+ if (true || idleConstraints.size() == 0)
+ {
+ // Debugging SVG time slice output, but don't show this for
+ // constraints that promised satisfiable.
+ std::vector<cola::Edge> es;
+ for (unsigned int i = 0; i < boundingBoxes.size(); ++i)
+ {
+ boundingBoxes[i]->moveCentreX(vs[0][i]->finalPosition);
+ boundingBoxes[i]->moveCentreY(vs[1][i]->finalPosition);
+ }
+ iteration++;
+ std::sstream filename;
+ filename << "out/file-" << std::setfill('0') << std::setw(5) << iteration << ".pdf";
+
+ OutputFile of(boundingBoxes,es,clusterHierarchy,filename.str().c_str(),
+ true,false);
+ of.setLabels(labels);
+ of.generate();
+ }
+#endif
+ cc->markCurrSubConstraintAsActive(subConstraintSatisfiable);
+ }
+ }
+
+ // Delete the persistent VPSC solver instances.
+ for (size_t dim = 0; dim < 2; ++dim)
+ {
+ if (solver[dim])
+ {
+ delete solver[dim];
+ solver[dim] = nullptr;
+ }
+ }
+
+ // Write positions from solver variables back to Rectangles.
+ for (unsigned int i = 0; i < boundingBoxes.size(); ++i)
+ {
+ boundingBoxes[i]->moveCentreX(vs[0][i]->finalPosition);
+ boundingBoxes[i]->moveCentreY(vs[1][i]->finalPosition);
+ }
+
+ vpsc::Rectangle::setXBorder(0);
+ vpsc::Rectangle::setYBorder(0);
+
+ // Cleanup.
+ for (unsigned int dim = 0; dim < 2; ++dim)
+ {
+ for_each(valid[dim].begin(), valid[dim].end(), delete_object());
+ for_each(vs[dim].begin(), vs[dim].end(), delete_object());
+ }
+
+ topologyAddon->makeFeasible(m_generateNonOverlapConstraints,
+ boundingBoxes, clusterHierarchy);
+
+ // Update the X and Y vectors with the new shape positions.
+ for (unsigned int i = 0; i < boundingBoxes.size(); ++i)
+ {
+ X[i] = boundingBoxes[i]->getCentreX();
+ Y[i] = boundingBoxes[i]->getCentreY();
+ }
+
+ // Clear extra constraints for cluster containment and non-overlap.
+ for_each(extraConstraints.begin(), extraConstraints.end(), delete_object());
+ extraConstraints.clear();
+}
+
+ConstrainedFDLayout::~ConstrainedFDLayout()
+{
+ if (using_default_done)
+ {
+ delete done;
+ }
+
+ for (unsigned i = 0; i < n; ++i)
+ {
+ delete [] G[i];
+ delete [] D[i];
+ }
+ delete [] G;
+ delete [] D;
+ delete topologyAddon;
+ delete m_nonoverlap_exemptions;
+}
+
+void ConstrainedFDLayout::freeAssociatedObjects(void)
+{
+ // Free Rectangles
+ for_each(boundingBoxes.begin(), boundingBoxes.end(), delete_object());
+ boundingBoxes.clear();
+
+ // Free compound constraints
+ std::list<CompoundConstraint *> freeList(ccs.begin(), ccs.end());
+ freeList.sort();
+ freeList.unique();
+ if (freeList.size() != ccs.size())
+ {
+ // The compound constraint list had repeated elements.
+ fprintf(stderr, "Warning: CompoundConstraints vector contained %d "
+ "duplicates.\n", (int) (ccs.size() - freeList.size()));
+ }
+ ccs.clear();
+ for_each(freeList.begin(), freeList.end(), delete_object());
+
+ if (clusterHierarchy)
+ {
+ delete clusterHierarchy;
+ clusterHierarchy = nullptr;
+ }
+
+ topologyAddon->freeAssociatedObjects();
+}
+
+void ConstrainedFDLayout::setTopology(TopologyAddonInterface *newTopology)
+{
+ COLA_ASSERT(topologyAddon);
+ delete topologyAddon;
+ topologyAddon = newTopology->clone();
+}
+
+TopologyAddonInterface *ConstrainedFDLayout::getTopology(void)
+{
+ return topologyAddon->clone();
+}
+
+
+void setupVarsAndConstraints(unsigned n, const CompoundConstraints& ccs,
+ const vpsc::Dim dim, vpsc::Rectangles& boundingBoxes,
+ RootCluster *clusterHierarchy,
+ vpsc::Variables& vs, vpsc::Constraints& cs,
+ valarray<double> &coords)
+{
+ vs.resize(n);
+ for (unsigned i = 0; i < n; ++i)
+ {
+ vs[i] = new vpsc::Variable(i, coords[i]);
+ }
+
+ if (clusterHierarchy && !clusterHierarchy->flat())
+ {
+ // Create variables for clusters
+ clusterHierarchy->computeBoundingRect(boundingBoxes);
+ clusterHierarchy->createVars(dim, boundingBoxes, vs);
+ }
+
+ for (CompoundConstraints::const_iterator c = ccs.begin();
+ c != ccs.end(); ++c)
+ {
+ (*c)->generateVariables(dim, vs);
+ }
+ for (CompoundConstraints::const_iterator c = ccs.begin();
+ c != ccs.end(); ++c)
+ {
+ (*c)->generateSeparationConstraints(dim, vs, cs, boundingBoxes);
+ }
+}
+
+
+static void setupExtraConstraints(const CompoundConstraints& ccs,
+ const vpsc::Dim dim, vpsc::Variables& vs, vpsc::Constraints& cs,
+ vpsc::Rectangles& boundingBoxes)
+{
+ for (CompoundConstraints::const_iterator c = ccs.begin();
+ c != ccs.end(); ++c)
+ {
+ (*c)->generateVariables(dim, vs);
+ }
+ for (CompoundConstraints::const_iterator c = ccs.begin();
+ c != ccs.end(); ++c)
+ {
+ (*c)->generateSeparationConstraints(dim, vs, cs, boundingBoxes);
+ }
+}
+
+void updateCompoundConstraints(const vpsc::Dim dim,
+ const CompoundConstraints& ccs)
+{
+ for (CompoundConstraints::const_iterator c = ccs.begin();
+ c != ccs.end(); ++c)
+ {
+ (*c)->updatePosition(dim);
+ }
+}
+void project(vpsc::Variables& vs, vpsc::Constraints& cs, valarray<double>& coords) {
+ unsigned n=coords.size();
+ vpsc::IncSolver s(vs,cs);
+ s.solve();
+ for(unsigned i=0;i<n;++i) {
+ coords[i]=vs[i]->finalPosition;
+ }
+}
+void setVariableDesiredPositions(vpsc::Variables& vs, vpsc::Constraints& cs,
+ const DesiredPositionsInDim& des, valarray<double>& coords)
+{
+ COLA_UNUSED(cs);
+
+ unsigned n=coords.size();
+ COLA_ASSERT(vs.size()>=n);
+ for(unsigned i=0;i<n;++i) {
+ vpsc::Variable* v=vs[i];
+ v->desiredPosition = coords[i];
+ v->weight=1;
+ }
+ for (DesiredPositionsInDim::const_iterator d=des.begin();
+ d!=des.end(); ++d) {
+ COLA_ASSERT(d->first<vs.size());
+ vpsc::Variable* v=vs[d->first];
+ v->desiredPosition = d->second;
+ v->weight=10000;
+ }
+}
+void checkUnsatisfiable(const vpsc::Constraints& cs,
+ UnsatisfiableConstraintInfos* unsatisfiable) {
+ for(vpsc::Constraints::const_iterator c=cs.begin();c!=cs.end();++c) {
+ if((*c)->unsatisfiable) {
+ UnsatisfiableConstraintInfo* i=new UnsatisfiableConstraintInfo(*c);
+ unsatisfiable->push_back(i);
+ }
+ }
+}
+
+void ConstrainedFDLayout::handleResizes(const Resizes& resizeList)
+{
+ topologyAddon->handleResizes(resizeList, n, X, Y, ccs, boundingBoxes,
+ clusterHierarchy);
+}
+
+/*
+ * move positions of nodes in specified axis while respecting constraints
+ * @param dim axis
+ * @param target array of desired positions (for both axes)
+ */
+void ConstrainedFDLayout::moveTo(const vpsc::Dim dim, Position& target) {
+ COLA_ASSERT(target.size()==2*n);
+ FILE_LOG(logDEBUG) << "ConstrainedFDLayout::moveTo(): dim="<<dim;
+ valarray<double> &coords = (dim==vpsc::HORIZONTAL)?X:Y;
+ vpsc::Variables vs;
+ vpsc::Constraints cs;
+ setupVarsAndConstraints(n, ccs, dim, boundingBoxes,
+ clusterHierarchy, vs, cs, coords);
+ DesiredPositionsInDim des;
+ if(preIteration) {
+ for(vector<Lock>::iterator l=preIteration->locks.begin();
+ l!=preIteration->locks.end();l++) {
+ des.push_back(make_pair(l->getID(),l->pos(dim)));
+ FILE_LOG(logDEBUG1)<<"desi: v["<<l->getID()<<"]=("<<l->pos(vpsc::HORIZONTAL)
+ <<","<<l->pos(vpsc::VERTICAL)<<")";
+ }
+ }
+ for(unsigned i=0, j=(dim==vpsc::HORIZONTAL?0:n);i<n;++i,++j) {
+ vpsc::Variable* v=vs[i];
+ v->desiredPosition = target[j];
+ }
+ setVariableDesiredPositions(vs,cs,des,coords);
+ if (topologyAddon->useTopologySolver())
+ {
+ topologyAddon->moveTo(dim, vs, cs, coords, clusterHierarchy);
+ } else {
+ // Add non-overlap constraints, but not variables again.
+ setupExtraConstraints(extraConstraints, dim, vs, cs, boundingBoxes);
+ // Projection.
+ project(vs,cs,coords);
+ moveBoundingBoxes();
+ }
+ updateCompoundConstraints(dim, ccs);
+ for_each(vs.begin(),vs.end(),delete_object());
+ for_each(cs.begin(),cs.end(),delete_object());
+}
+/*
+ * The following computes an unconstrained solution then uses Projection to
+ * make this solution feasible with respect to constraints by moving things as
+ * little as possible. If "meta-constraints" such as avoidOverlaps or edge
+ * straightening are required then dummy variables will be generated.
+ */
+double ConstrainedFDLayout::applyForcesAndConstraints(const vpsc::Dim dim, const double oldStress) {
+ FILE_LOG(logDEBUG) << "ConstrainedFDLayout::applyForcesAndConstraints(): dim="<<dim;
+ valarray<double> g(n);
+ valarray<double> &coords = (dim==vpsc::HORIZONTAL)?X:Y;
+ DesiredPositionsInDim des;
+ if(preIteration) {
+ for(vector<Lock>::iterator l=preIteration->locks.begin();
+ l!=preIteration->locks.end();l++) {
+ des.push_back(make_pair(l->getID(),l->pos(dim)));
+ FILE_LOG(logDEBUG1)<<"desi: v["<<l->getID()<<"]=("<<l->pos(vpsc::HORIZONTAL)
+ <<","<<l->pos(vpsc::VERTICAL)<<")";
+ }
+ }
+ vpsc::Variables vs;
+ vpsc::Constraints cs;
+ double stress;
+ setupVarsAndConstraints(n, ccs, dim, boundingBoxes,
+ clusterHierarchy, vs, cs, coords);
+
+ if (topologyAddon->useTopologySolver())
+ {
+ stress = topologyAddon->applyForcesAndConstraints(this, dim, g, vs, cs,
+ coords, des, oldStress);
+ } else {
+ // Add non-overlap constraints, but not variables again.
+ setupExtraConstraints(extraConstraints, dim, vs, cs, boundingBoxes);
+ // Projection.
+ SparseMap HMap(n);
+ computeForces(dim,HMap,g);
+ SparseMatrix H(HMap);
+ valarray<double> oldCoords=coords;
+ applyDescentVector(g,oldCoords,coords,oldStress,computeStepSize(H,g,g));
+ setVariableDesiredPositions(vs,cs,des,coords);
+ project(vs,cs,coords);
+ valarray<double> d(n);
+ d=oldCoords-coords;
+ double stepsize=computeStepSize(H,g,d);
+ stepsize=max(0.,min(stepsize,1.));
+ //printf(" dim=%d beta: ",dim);
+ stress = applyDescentVector(d,oldCoords,coords,oldStress,stepsize);
+ moveBoundingBoxes();
+ }
+ updateCompoundConstraints(dim, ccs);
+ if(unsatisfiable.size()==2) {
+ checkUnsatisfiable(cs,unsatisfiable[dim]);
+ }
+ FILE_LOG(logDEBUG) << "ConstrainedFDLayout::applyForcesAndConstraints... done, stress="<<stress;
+ if (clusterHierarchy)
+ {
+ clusterHierarchy->computeVarRect(vs, dim);
+ clusterHierarchy->computeBoundingRect(boundingBoxes);
+ }
+
+ for_each(vs.begin(),vs.end(),delete_object());
+ for_each(cs.begin(),cs.end(),delete_object());
+ return stress;
+}
+/*
+ * Attempts to set coords=oldCoords-stepsize*d. If this does not reduce
+ * the stress from oldStress then stepsize is halved. This is repeated
+ * until stepsize falls below a threshhold.
+ * @param d is a descent vector (a movement vector intended to reduce the
+ * stress)
+ * @param oldCoords are the previous position vector
+ * @param coords will hold the new position after applying d
+ * @param stepsize is a scalar multiple of the d to apply
+ */
+double ConstrainedFDLayout::applyDescentVector(
+ valarray<double> const &d,
+ valarray<double> const &oldCoords,
+ valarray<double> &coords,
+ const double oldStress,
+ double stepsize
+ )
+{
+ COLA_UNUSED(oldStress);
+
+ COLA_ASSERT(d.size()==oldCoords.size());
+ COLA_ASSERT(d.size()==coords.size());
+ while(fabs(stepsize)>0.00000000001) {
+ coords=oldCoords-stepsize*d;
+ double stress=computeStress();
+ //printf(" applyDV: oldstress=%f, stress=%f, stepsize=%f\n", oldStress,stress,stepsize);
+ //if(oldStress>=stress) {
+ return stress;
+ //}
+ coords=oldCoords;
+ stepsize*=0.5;
+ }
+ return computeStress();
+}
+
+
+// Computes X and Y offsets for nodes that are at the same position.
+std::vector<double> ConstrainedFDLayout::offsetDir(double minD)
+{
+ std::vector<double> u(2);
+ double l = 0;
+ for (size_t i = 0; i < 2; ++i)
+ {
+ double x = u[i] = random.getNextBetween(0.01, 1) - 0.5;
+ l += x * x;
+ }
+ l = sqrt(l);
+
+ for (size_t i = 0; i < 2; ++i)
+ {
+ u[i] *= (minD / l);
+ }
+
+ return u;
+}
+
+
+/*
+ * Computes:
+ * - the matrix of second derivatives (the Hessian) H, used in
+ * calculating stepsize; and
+ * - the vector g, the negative gradient (steepest-descent) direction.
+ */
+void ConstrainedFDLayout::computeForces(
+ const vpsc::Dim dim,
+ SparseMap &H,
+ valarray<double> &g) {
+ if(n==1) return;
+ g=0;
+ // for each node:
+ for(unsigned u=0;u<n;u++) {
+ // Stress model
+ double Huu=0;
+ for(unsigned v=0;v<n;v++) {
+ if(u==v) continue;
+ if (m_useNeighbourStress && neighbours[u][v]!=1) continue;
+
+ // The following loop randomly displaces nodes that are at identical positions
+ double rx=X[u]-X[v], ry=Y[u]-Y[v];
+ double sd2 = rx*rx+ry*ry;
+ unsigned maxDisplaces = n; // avoid infinite loop in the case of numerical issues, such as huge values
+
+ while (maxDisplaces--)
+ {
+ if ((sd2) > 1e-3)
+ {
+ break;
+ }
+
+ std::vector<double> rd = offsetDir(minD);
+ X[v] += rd[0];
+ Y[v] += rd[1];
+ rx=X[u]-X[v], ry=Y[u]-Y[v];
+ sd2 = rx*rx+ry*ry;
+ }
+
+ unsigned short p = G[u][v];
+ // no forces between disconnected parts of the graph
+ if(p==0) continue;
+ double l=sqrt(sd2);
+ double d=D[u][v];
+ if(l>d && p>1) continue; // attractive forces not required
+ double d2=d*d;
+ /* force apart zero distances */
+ if (l < 1e-30) {
+ l=0.1;
+ }
+ double dx=dim==vpsc::HORIZONTAL?rx:ry;
+ double dy=dim==vpsc::HORIZONTAL?ry:rx;
+ g[u]+=dx*(l-d)/(d2*l);
+ Huu-=H(u,v)=(d*dy*dy/(l*l*l)-1)/d2;
+ }
+ H(u,u)=Huu;
+ }
+ if(desiredPositions) {
+ for(DesiredPositions::const_iterator p=desiredPositions->begin();
+ p!=desiredPositions->end();++p) {
+ unsigned i = p->id;
+ double d=(dim==vpsc::HORIZONTAL)
+ ?p->x-X[i]:p->y-Y[i];
+ d*=p->weight;
+ g[i]-=d;
+ H(i,i)+=p->weight;
+ }
+ }
+}
+/*
+ * Returns the optimal step-size in the direction d, given gradient g and
+ * hessian H.
+ */
+double ConstrainedFDLayout::computeStepSize(
+ SparseMatrix const &H,
+ valarray<double> const &g,
+ valarray<double> const &d) const
+{
+ COLA_ASSERT(g.size()==d.size());
+ COLA_ASSERT(g.size()==H.rowSize());
+ // stepsize = g'd / (d' H d)
+ double numerator = dotProd(g,d);
+ valarray<double> Hd(d.size());
+ H.rightMultiply(d,Hd);
+ double denominator = dotProd(d,Hd);
+ //COLA_ASSERT(numerator>=0);
+ //COLA_ASSERT(denominator>=0);
+ if(denominator==0) return 0;
+ return numerator/denominator;
+}
+/*
+ * Just computes the cost (Stress) at the current X,Y position
+ * used to test termination.
+ * This method will call preIteration if one is set.
+ */
+double ConstrainedFDLayout::computeStress() const {
+ FILE_LOG(logDEBUG)<<"ConstrainedFDLayout::computeStress()";
+ double stress=0;
+ for(unsigned u=0;(u + 1)<n;u++) {
+ for(unsigned v=u+1;v<n;v++) {
+ if (m_useNeighbourStress && neighbours[u][v]!=1) continue;
+ unsigned short p=G[u][v];
+ // no forces between disconnected parts of the graph
+ if(p==0) continue;
+ double rx=X[u]-X[v], ry=Y[u]-Y[v];
+ double l=sqrt(rx*rx+ry*ry);
+ double d=D[u][v];
+ if(l>d && p>1) continue; // no attractive forces required
+ double d2=d*d;
+ double rl=d-l;
+ double s=rl*rl/d2;
+ stress+=s;
+ FILE_LOG(logDEBUG2)<<"s("<<u<<","<<v<<")="<<s;
+ }
+ }
+ if(preIteration) {
+ if ((*preIteration)()) {
+ for(vector<Lock>::iterator l=preIteration->locks.begin();
+ l!=preIteration->locks.end();l++) {
+ double dx=l->pos(vpsc::HORIZONTAL)-X[l->getID()], dy=l->pos(vpsc::VERTICAL)-Y[l->getID()];
+ double s=10000*(dx*dx+dy*dy);
+ stress+=s;
+ FILE_LOG(logDEBUG2)<<"d("<<l->getID()<<")="<<s;
+ }
+ }
+ }
+ stress += topologyAddon->computeStress();
+ if(desiredPositions) {
+ for(DesiredPositions::const_iterator p = desiredPositions->begin();
+ p!=desiredPositions->end();++p) {
+ double dx = X[p->id] - p->x, dy = Y[p->id] - p->y;
+ stress+=0.5*p->weight*(dx*dx+dy*dy);
+ }
+ }
+ return stress;
+}
+void ConstrainedFDLayout::moveBoundingBoxes() {
+ for(unsigned i=0;i<n;i++) {
+ boundingBoxes[i]->moveCentre(X[i],Y[i]);
+ }
+}
+
+static const double LIMIT = 100000000;
+
+static void reduceRange(double& val)
+{
+ val = std::min(val, LIMIT);
+ val = std::max(val, -LIMIT);
+}
+
+void ConstrainedFDLayout::outputInstanceToSVG(std::string instanceName)
+{
+ std::string filename;
+ if (!instanceName.empty())
+ {
+ filename = instanceName;
+ }
+ else
+ {
+ filename = "libcola-debug";
+ }
+ filename += ".svg";
+ FILE *fp = fopen(filename.c_str(), "w");
+
+ if (fp == nullptr)
+ {
+ return;
+ }
+
+
+ double minX = LIMIT;
+ double minY = LIMIT;
+ double maxX = -LIMIT;
+ double maxY = -LIMIT;
+
+ // Find the bounds of the diagram.
+ for (size_t i = 0; i < boundingBoxes.size(); ++i)
+ {
+ double rMinX = boundingBoxes[i]->getMinX();
+ double rMaxX = boundingBoxes[i]->getMaxX();
+ double rMinY = boundingBoxes[i]->getMinY();
+ double rMaxY = boundingBoxes[i]->getMaxY();
+
+ reduceRange(rMinX);
+ reduceRange(rMaxX);
+ reduceRange(rMinY);
+ reduceRange(rMaxY);
+
+ if (rMinX > -LIMIT)
+ {
+ minX = std::min(minX, rMinX);
+ }
+ if (rMaxX < LIMIT)
+ {
+ maxX = std::max(maxX,rMaxX);
+ }
+ if (rMinY > -LIMIT)
+ {
+ minY = std::min(minY, rMinY);
+ }
+ if (rMaxY < LIMIT)
+ {
+ maxY = std::max(maxY, rMaxY);
+ }
+ }
+
+ minX -= 50;
+ minY -= 50;
+ maxX += 50;
+ maxY += 50;
+
+ fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ fprintf(fp, "<svg xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" xmlns=\"http://www.w3.org/2000/svg\" width=\"100%%\" height=\"100%%\" viewBox=\"%g %g %g %g\">\n", minX, minY, maxX - minX, maxY - minY);
+
+ // Output source code to generate this ConstrainedFDLayout instance.
+ fprintf(fp, "<!-- Source code to generate this instance:\n");
+ fprintf(fp, "#include <vector>\n");
+ fprintf(fp, "#include <utility>\n");
+ fprintf(fp, "#include \"libcola/cola.h\"\n");
+ fprintf(fp, "using namespace cola;\n");
+ fprintf(fp, "int main(void) {\n");
+ fprintf(fp, " CompoundConstraints ccs;\n");
+ fprintf(fp, " std::vector<Edge> es;\n");
+ fprintf(fp, " EdgeLengths eLengths;\n");
+ fprintf(fp, " double defaultEdgeLength=%g;\n", m_idealEdgeLength);
+ fprintf(fp, " std::vector<vpsc::Rectangle*> rs;\n");
+ fprintf(fp, " vpsc::Rectangle *rect = nullptr;\n\n");
+ for (size_t i = 0; i < boundingBoxes.size(); ++i)
+ {
+ fprintf(fp, " rect = new vpsc::Rectangle(%g, %g, %g, %g);\n",
+ boundingBoxes[i]->getMinX(), boundingBoxes[i]->getMaxX(),
+ boundingBoxes[i]->getMinY(), boundingBoxes[i]->getMaxY());
+ fprintf(fp, " rs.push_back(rect);\n\n");
+ }
+
+ for (size_t i = 0; i < n; ++i)
+ {
+ for (size_t j = i + 1; j < n; ++j)
+ {
+ if (G[i][j] == 1)
+ {
+ fprintf(fp, " es.push_back(std::make_pair(%lu, %lu));\n", i, j);
+ }
+ }
+ }
+ fprintf(fp, "\n");
+
+ if (m_edge_lengths.size() > 0)
+ {
+ fprintf(fp, " eLengths.resize(%d);\n", (int) m_edge_lengths.size());
+ for (size_t i = 0; i < m_edge_lengths.size(); ++i)
+ {
+ fprintf(fp, " eLengths[%d] = %g;\n", (int) i, m_edge_lengths[i]);
+ }
+ fprintf(fp, "\n");
+ }
+
+ for (cola::CompoundConstraints::iterator c = ccs.begin();
+ c != ccs.end(); ++c)
+ {
+ (*c)->printCreationCode(fp);
+ }
+
+ fprintf(fp, " ConstrainedFDLayout alg(rs, es, defaultEdgeLength, eLengths);\n");
+ if (clusterHierarchy)
+ {
+ clusterHierarchy->printCreationCode(fp);
+ fprintf(fp, " alg.setClusterHierarchy(cluster%llu);\n",
+ (unsigned long long) clusterHierarchy);
+ }
+ fprintf(fp, " alg.setConstraints(ccs);\n");
+ fprintf(fp, " alg.setAvoidNodeOverlaps(%s);\n",
+ (m_generateNonOverlapConstraints) ? "true" : "false");
+ fprintf(fp, " alg.makeFeasible();\n");
+ fprintf(fp, " alg.run();\n");
+ fprintf(fp, " alg.freeAssociatedObjects();\n");
+ fprintf(fp, " return 0;\n");
+ fprintf(fp, "};\n");
+ fprintf(fp, "-->\n");
+
+ if (clusterHierarchy)
+ {
+ clusterHierarchy->computeBoundingRect(boundingBoxes);
+ fprintf(fp, "<g inkscape:groupmode=\"layer\" "
+ "inkscape:label=\"Clusters\">\n");
+ clusterHierarchy->outputToSVG(fp);
+ fprintf(fp, "</g>\n");
+ }
+
+ fprintf(fp, "<g inkscape:groupmode=\"layer\" "
+ "inkscape:label=\"Rects\">\n");
+ for (size_t i = 0; i < boundingBoxes.size(); ++i)
+ {
+ double minX = boundingBoxes[i]->getMinX();
+ double maxX = boundingBoxes[i]->getMaxX();
+ double minY = boundingBoxes[i]->getMinY();
+ double maxY = boundingBoxes[i]->getMaxY();
+
+ fprintf(fp, "<rect id=\"rect-%u\" x=\"%g\" y=\"%g\" width=\"%g\" "
+ "height=\"%g\" style=\"stroke-width: 1px; stroke: black; "
+ "fill: blue; fill-opacity: 0.3;\" />\n",
+ (unsigned) i, minX, minY, maxX - minX, maxY - minY);
+ }
+ fprintf(fp, "</g>\n");
+
+ fprintf(fp, "<g inkscape:groupmode=\"layer\" "
+ "inkscape:label=\"Edges\">\n");
+ for (size_t i = 0; i < n; ++i)
+ {
+ for (size_t j = i + 1; j < n; ++j)
+ {
+ if (G[i][j] == 1)
+ {
+ fprintf(fp, "<path d=\"M %g %g L %g %g\" "
+ "style=\"stroke-width: 1px; stroke: black;\" />\n",
+ boundingBoxes[i]->getCentreX(),
+ boundingBoxes[i]->getCentreY(),
+ boundingBoxes[j]->getCentreX(),
+ boundingBoxes[j]->getCentreY());
+ }
+ }
+ }
+ fprintf(fp, "</g>\n");
+
+ fprintf(fp, "</svg>\n");
+ fclose(fp);
+}
+
+ProjectionResult projectOntoCCs(Dim dim, Rectangles &rs, CompoundConstraints ccs,
+ bool preventOverlaps, int accept, unsigned debugLevel)
+{
+ size_t n = rs.size();
+ // Set up nonoverlap constraints if desired.
+ NonOverlapConstraintExemptions *nocexemps = nullptr;
+ NonOverlapConstraints *noc = nullptr;
+ if (preventOverlaps) {
+ nocexemps = new NonOverlapConstraintExemptions();
+ noc = new NonOverlapConstraints(nocexemps);
+ for (size_t i = 0; i < n; ++i) {
+ noc->addShape(i, rs[i]->width()/2.0, rs[i]->height()/2.0);
+ }
+ ccs.push_back(noc);
+ }
+ // Set up vars and constraints.
+ Variables vs;
+ Constraints cs;
+ vs.resize(n);
+ for (size_t i = 0; i < n; ++i) {
+ vs[i] = new Variable(i, rs[i]->getCentreD(dim));
+ }
+ for (CompoundConstraints::iterator it=ccs.begin(); it!=ccs.end(); ++it) {
+ CompoundConstraint *cc = *it;
+ cc->generateVariables(dim, vs);
+ cc->generateSeparationConstraints(dim, vs, cs, rs);
+ }
+ // Solve, if possible.
+ ProjectionResult result = solve(vs, cs, rs, debugLevel);
+ // If good enough, accept positions.
+ if (result.errorLevel <= accept) {
+ for (size_t i = 0; i < n; ++i) {
+ rs[i]->moveCentreD(dim, vs[i]->finalPosition);
+ }
+ }
+ // Clean up
+ for (Variables::iterator it=vs.begin(); it!=vs.end(); ++it) delete *it;
+ for (Constraints::iterator it=cs.begin(); it!=cs.end(); ++it) delete *it;
+ delete noc;
+ delete nocexemps;
+ // Return
+ return result;
+}
+
+ProjectionResult solve(Variables &vs, Constraints &cs, Rectangles &rs, unsigned debugLevel)
+{
+ int result = 0;
+ IncSolver solv(vs,cs);
+ try {
+ solv.solve();
+ } catch (vpsc::UnsatisfiedConstraint uc) {
+ }
+ for (Constraints::iterator it=cs.begin(); it!=cs.end(); it++) {
+ Constraint *c = *it;
+ if (c->unsatisfiable) {
+ CompoundConstraint *cc = (CompoundConstraint*)(c->creator);
+ if (cc->toString() == "NonOverlapConstraints()") {
+ result = 1;
+ } else {
+ result = 2;
+ break;
+ }
+ }
+ }
+ std::string unsatinfo;
+ if (debugLevel>0) {
+ std::set<Variable*> varsInvolved;
+ unsatinfo += "===================================================\n";
+ unsatinfo += "UNSATISFIED CONSTRAINTS:\n";
+ char buf [1000];
+ for (Constraints::iterator it=cs.begin(); it!=cs.end(); it++) {
+ Constraint *c = *it;
+ if (c->unsatisfiable) {
+ varsInvolved.insert(c->left);
+ varsInvolved.insert(c->right);
+ sprintf(buf, "v_%d + %f", c->left->id, c->gap);
+ unsatinfo += buf;
+ unsatinfo += c->equality ? " == " : " <= ";
+ sprintf(buf, "v_%d\n", c->right->id);
+ unsatinfo += buf;
+ if ((unsigned) c->left->id < rs.size()) {
+ Rectangle *r = rs[c->left->id];
+ sprintf(buf, " v_%d rect: [%f, %f] x [%f, %f]\n", c->left->id,
+ r->getMinX(), r->getMaxX(), r->getMinY(), r->getMaxY());
+ unsatinfo += buf;
+ }
+ if ((unsigned) c->right->id < rs.size()) {
+ Rectangle *r = rs[c->right->id];
+ sprintf(buf, " v_%d rect: [%f, %f] x [%f, %f]\n", c->right->id,
+ r->getMinX(), r->getMaxX(), r->getMinY(), r->getMaxY());
+ unsatinfo += buf;
+ }
+ CompoundConstraint *cc = (CompoundConstraint*)(c->creator);
+ unsatinfo += " Creator: " + cc->toString() + "\n";
+ }
+ }
+ if (debugLevel>1) {
+ unsatinfo += "--------------------------------------------------\n";
+ unsatinfo += "RELATED CONSTRAINTS:\n";
+ std::set<Variable*>::iterator lit, rit, eit = varsInvolved.end();
+ for (Constraints::iterator it=cs.begin(); it!=cs.end(); it++) {
+ Constraint *c = *it;
+ lit = varsInvolved.find(c->left);
+ rit = varsInvolved.find(c->right);
+ if (lit != eit || rit != eit) {
+ sprintf(buf, "v_%d + %f", c->left->id, c->gap);
+ unsatinfo += buf;
+ unsatinfo += c->equality ? " == " : " <= ";
+ sprintf(buf, "v_%d\n", c->right->id);
+ unsatinfo += buf;
+ if ((unsigned) c->left->id < rs.size()) {
+ Rectangle *r = rs[c->left->id];
+ sprintf(buf, " v_%d rect: [%f, %f] x [%f, %f]\n", c->left->id,
+ r->getMinX(), r->getMaxX(), r->getMinY(), r->getMaxY());
+ unsatinfo += buf;
+ }
+ if ((unsigned) c->right->id < rs.size()) {
+ Rectangle *r = rs[c->right->id];
+ sprintf(buf, " v_%d rect: [%f, %f] x [%f, %f]\n", c->right->id,
+ r->getMinX(), r->getMaxX(), r->getMinY(), r->getMaxY());
+ unsatinfo += buf;
+ }
+ CompoundConstraint *cc = (CompoundConstraint*)(c->creator);
+ unsatinfo += " Creator: " + cc->toString() + "\n";
+ }
+ }
+ }
+ }
+ ProjectionResult pr;
+ pr.errorLevel = result;
+ pr.unsatinfo = unsatinfo;
+ return pr;
+}
+
+} // namespace cola
diff --git a/src/3rdparty/adaptagrams/libcola/commondefs.h b/src/3rdparty/adaptagrams/libcola/commondefs.h
new file mode 100644
index 0000000..6d56f62
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/commondefs.h
@@ -0,0 +1,98 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef _COMMONDEFS_H
+#define _COMMONDEFS_H
+
+/* Notes to compilation using MSVC.
+
+ Compiler options:
+ /Zc:forScope
+*/
+#if defined(_MSC_VER)
+// Microsoft Visual C++ (MS VC) specific code goes here
+#include <float.h>
+#include <malloc.h> // Contains _alloca
+#endif
+
+#include "libvpsc/assertions.h"
+#include <valarray>
+
+namespace cola {
+
+/*
+ * resolve overlaps:
+ * None: not at all
+ * Horizontal: only horizontally
+ * Both: resolve in either Horizontal or Vertical direction
+ * depending on which leads to less displacement
+ */
+enum NonOverlapConstraintsMode { None, Horizontal, Both };
+
+class FixedList {
+public:
+ FixedList(const unsigned n) : array(std::valarray<bool>(n)),allFixed(false)
+ {
+ array=false;
+ }
+ void set(const unsigned i, const bool value=true) {
+ COLA_ASSERT(i<array.size());
+ array[i]=value;
+ }
+ bool check(const unsigned i) const {
+ if(allFixed||i>=array.size()) {
+ return false;
+ }
+ return array[i];
+ }
+ void unsetAll() {
+ array=false;
+ }
+ void fixAll(bool val) {
+ allFixed=val;
+ }
+private:
+ std::valarray<bool> array;
+ bool allFixed;
+};
+
+/*
+ * templated delete functor for use in for_each loop over vector
+ */
+struct delete_object
+{
+ template <typename T>
+ void operator()(T *ptr){ delete ptr;}
+};
+/*
+ * Sum over the results of calling operation for each member in the
+ * iterator. Handier than std::accumulate because we can use with
+ * mem_fun to pass in a getter method.
+ */
+template <class InputIterator, class T, class Operation >
+T sum_over(InputIterator beg, InputIterator end, T init, Operation op)
+{
+ for ( ; beg != end; ++beg)
+ init = init + op(*beg);
+ return init;
+}
+} // namespace cola
+
+#endif
diff --git a/src/3rdparty/adaptagrams/libcola/compound_constraints.cpp b/src/3rdparty/adaptagrams/libcola/compound_constraints.cpp
new file mode 100644
index 0000000..af9fa3e
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/compound_constraints.cpp
@@ -0,0 +1,1671 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+ * Michael Wybrow
+*/
+
+#include <algorithm>
+#include <climits>
+#include <sstream>
+
+#include <libvpsc/variable.h>
+#include <libvpsc/constraint.h>
+#include <libvpsc/assertions.h>
+
+#include "libcola/cola.h"
+#include "libcola/compound_constraints.h"
+#include "libcola/exceptions.h"
+
+using std::vector;
+using vpsc::XDIM;
+using vpsc::YDIM;
+
+namespace cola {
+
+void SubConstraintInfo::updateVarIDsWithMapping(
+ const VariableIDMap& idMap, bool forward)
+{
+ varIndex = idMap.mappingForVariable(varIndex, forward);
+}
+
+//-----------------------------------------------------------------------------
+// BoundaryConstraint code
+//-----------------------------------------------------------------------------
+
+class Offset : public SubConstraintInfo
+{
+ public:
+ Offset(unsigned ind, double offset) :
+ SubConstraintInfo(ind),
+ distOffset(offset)
+ {
+ }
+ double distOffset;
+};
+
+
+BoundaryConstraint::BoundaryConstraint(const vpsc::Dim dim)
+ : CompoundConstraint(dim),
+ position(0),
+ variable(nullptr)
+{
+}
+
+
+void BoundaryConstraint::updatePosition(const vpsc::Dim dim)
+{
+ if (dim == _primaryDim)
+ {
+ position = variable->finalPosition;
+ }
+}
+
+
+void BoundaryConstraint::addShape(const unsigned int index,
+ const double offset)
+{
+ _subConstraintInfo.push_back(new Offset(index, offset));
+}
+
+
+void BoundaryConstraint::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " BoundaryConstraint *boundary%llu = "
+ "new BoundaryConstraint(vpsc::%cDIM);\n",
+ (unsigned long long) this, (_primaryDim == 0) ? 'X' : 'Y');
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ Offset *info = static_cast<Offset *> (*o);
+ fprintf(fp, " boundary%llu->addShape(%u, %g);\n",
+ (unsigned long long) this, info->varIndex, info->distOffset);
+ }
+ fprintf(fp, " ccs.push_back(boundary%llu);\n\n",
+ (unsigned long long) this);
+}
+
+
+std::string BoundaryConstraint::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "BoundaryConstraint(";
+ stream << "dim: " << ((_primaryDim == 0) ? 'X' : 'Y');
+ stream << "): {";
+ bool first = true;
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ Offset *info = static_cast<Offset *> (*o);
+ if (!first)
+ {
+ stream << ", ";
+ }
+ stream << "(" << "rect: " << info->varIndex << ", offset: " << info->distOffset << ")";
+ first = false;
+ }
+ stream << "}";
+ return stream.str();
+}
+
+
+void BoundaryConstraint::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ if (dim == _primaryDim)
+ {
+ // Just one variable is generated, associated with the position
+ // of the boundary. This variable can float freely.
+ variable = new vpsc::Variable(vars.size(), position, freeWeight);
+ vars.push_back(variable);
+ }
+}
+
+
+void BoundaryConstraint::generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs)
+{
+ COLA_UNUSED(bbs);
+ if (dim == _primaryDim)
+ {
+ COLA_ASSERT(variable != nullptr);
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ Offset *info = static_cast<Offset *> (*o);
+ assertValidVariableIndex(vars, info->varIndex);
+ vpsc::Constraint *constraint = nullptr;
+ if (info->distOffset < 0)
+ {
+ // Constrain the objects with negative offsets to be
+ // to the left of the boundary.
+ constraint = new vpsc::Constraint(vars[info->varIndex],
+ variable, -info->distOffset);
+ }
+ else
+ {
+ // Constrain the objects with positive offsets to be
+ // to the right of the boundary.
+ constraint = new vpsc::Constraint(variable,
+ vars[info->varIndex], info->distOffset);
+ }
+ constraint->creator = this;
+ cs.push_back(constraint);
+ }
+ }
+}
+
+
+SubConstraintAlternatives
+BoundaryConstraint::getCurrSubConstraintAlternatives(vpsc::Variables vs[])
+{
+ SubConstraintAlternatives alternatives;
+
+ Offset *info = static_cast<Offset *>
+ (_subConstraintInfo[_currSubConstraintIndex]);
+
+ assertValidVariableIndex(vs[_primaryDim], info->varIndex);
+ if (info->distOffset < 0)
+ {
+ // Constrain the objects with negative offsets to be
+ // to the left of the boundary.
+ vpsc::Constraint constraint = vpsc::Constraint(
+ vs[_primaryDim][info->varIndex], variable, -info->distOffset);
+ alternatives.push_back(SubConstraint(_primaryDim, constraint));
+ }
+ else
+ {
+ // Constrain the objects with positive offsets to be
+ // to the right of the boundary.
+ vpsc::Constraint constraint = vpsc::Constraint(
+ variable, vs[_primaryDim][info->varIndex], info->distOffset);
+ alternatives.push_back(SubConstraint(_primaryDim, constraint));
+ }
+
+ //fprintf(stderr, "===== BOUNDARYLINE ALTERNATIVES -======\n");
+ return alternatives;
+}
+
+
+
+//-----------------------------------------------------------------------------
+// AlignmentConstraint code
+//-----------------------------------------------------------------------------
+
+AlignmentConstraint::AlignmentConstraint(const vpsc::Dim dim, double position)
+ : CompoundConstraint(dim),
+ indicator(nullptr),
+ variable(nullptr),
+ _position(position),
+ _isFixed(false)
+{
+}
+
+
+void AlignmentConstraint::addShape(const unsigned int index,
+ const double offset)
+{
+ _subConstraintInfo.push_back(new Offset(index, offset));
+}
+
+
+void AlignmentConstraint::updatePosition(const vpsc::Dim dim)
+{
+ if (dim == _primaryDim)
+ {
+ _position = variable->finalPosition;
+ }
+}
+
+
+void AlignmentConstraint::fixPos(double pos)
+{
+ _position = pos;
+ _isFixed = true;
+}
+
+
+void AlignmentConstraint::unfixPos()
+{
+ _isFixed = false;
+}
+
+
+double AlignmentConstraint::position(void) const
+{
+ return _position;
+}
+
+bool AlignmentConstraint::isFixed(void) const
+{
+ return _isFixed;
+}
+
+void AlignmentConstraint::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ if (dim == _primaryDim)
+ {
+ // Variable representing the position of a guideline.
+ variable = new vpsc::Variable(vars.size(), _position, freeWeight);
+ if (_isFixed)
+ {
+ variable->fixedDesiredPosition = true;
+ variable->weight = 100000;
+ }
+ vars.push_back(variable);
+ }
+}
+
+
+void AlignmentConstraint::generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs)
+{
+ COLA_UNUSED(bbs);
+ if (dim == _primaryDim)
+ {
+ COLA_ASSERT(variable != nullptr);
+ // Constrain each object to be offset from the guideline by
+ // some exact amount.
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ Offset *info = static_cast<Offset *> (*o);
+ assertValidVariableIndex(vars, info->varIndex);
+ vpsc::Constraint *constraint = new vpsc::Constraint(
+ variable, vars[info->varIndex], info->distOffset, true);
+ constraint->creator = this;
+ cs.push_back(constraint);
+ }
+ }
+}
+
+void AlignmentConstraint::updateShapeOffsetsForDifferentCentres(
+ const std::vector<double>& offsets, bool forward)
+{
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ Offset *info = static_cast<Offset *> (*o);
+ if (offsets[info->varIndex] == 0)
+ {
+ continue;
+ }
+
+ if (forward)
+ {
+ info->distOffset -= offsets[info->varIndex];
+ }
+ else
+ {
+ info->distOffset += offsets[info->varIndex];
+ }
+ }
+}
+
+void AlignmentConstraint::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " AlignmentConstraint *alignment%llu = "
+ "new AlignmentConstraint(vpsc::%cDIM, %g);\n",
+ (unsigned long long) this, (_primaryDim == 0) ? 'X' : 'Y',
+ _position);
+ if (_isFixed)
+ {
+ fprintf(fp, " alignment%llu->fixPos(%g);\n",
+ (unsigned long long) this, _position);
+ }
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ Offset *info = static_cast<Offset *> (*o);
+ fprintf(fp, " alignment%llu->addShape(%u, %g);\n",
+ (unsigned long long) this, info->varIndex, info->distOffset);
+ }
+ fprintf(fp, " ccs.push_back(alignment%llu);\n\n",
+ (unsigned long long) this);
+}
+
+
+std::string AlignmentConstraint::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "AlignmentConstraint(";
+ stream << "dim: " << ((_primaryDim == 0) ? 'X' : 'Y');
+ stream << ", pos: " << _position;
+ if (_isFixed)
+ {
+ stream << ", fixed: true";
+ }
+#if 0
+ // TODO: buggy. Not the right value.
+ if (variable)
+ {
+ stream << ", varInd: " << variable->id;
+ }
+#endif
+ stream << "): {";
+ bool first = true;
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ Offset *info = static_cast<Offset *> (*o);
+ if (!first)
+ {
+ stream << ", ";
+ }
+ stream << "(" << "rect: " << info->varIndex << ", offset: " << info->distOffset << ")";
+ first = false;
+ }
+ stream << "}";
+ return stream.str();
+}
+
+
+SubConstraintAlternatives
+AlignmentConstraint::getCurrSubConstraintAlternatives(vpsc::Variables vs[])
+{
+ SubConstraintAlternatives alternatives;
+
+ Offset *info = static_cast<Offset *>
+ (_subConstraintInfo[_currSubConstraintIndex]);
+
+ assertValidVariableIndex(vs[_primaryDim], info->varIndex);
+ vpsc::Constraint constraint(variable, vs[_primaryDim][info->varIndex],
+ info->distOffset, true);
+ alternatives.push_back(SubConstraint(_primaryDim, constraint));
+
+ //fprintf(stderr, "===== ALIGN ALTERNATIVES -======\n");
+ return alternatives;
+}
+
+
+//-----------------------------------------------------------------------------
+// SeparationConstraint code
+//-----------------------------------------------------------------------------
+
+
+class VarIndexPair : public SubConstraintInfo
+{
+ public:
+ VarIndexPair(unsigned ind1, unsigned ind2)
+ : SubConstraintInfo(ind1),
+ lConstraint(nullptr),
+ rConstraint(nullptr),
+ varIndex2(ind2)
+ {
+ }
+ VarIndexPair(AlignmentConstraint *l, AlignmentConstraint *r)
+ : SubConstraintInfo(0),
+ lConstraint(l),
+ rConstraint(r),
+ varIndex2(0)
+ {
+ }
+ unsigned indexL(void) const
+ {
+ return (lConstraint) ?
+ (unsigned) lConstraint->variable->id : varIndex;
+ }
+ unsigned indexR(void) const
+ {
+ return (rConstraint) ?
+ (unsigned) rConstraint->variable->id : varIndex2;
+ }
+ void updateVarIDsWithMapping(const VariableIDMap& idMap, bool forward)
+ {
+ varIndex = idMap.mappingForVariable(varIndex, forward);
+ varIndex2 = idMap.mappingForVariable(varIndex2, forward);
+ }
+
+ AlignmentConstraint *lConstraint;
+ AlignmentConstraint *rConstraint;
+ unsigned varIndex2;
+};
+
+
+SeparationConstraint::SeparationConstraint(const vpsc::Dim dim,
+ unsigned l, unsigned r, double g, bool equality)
+ : CompoundConstraint(dim),
+ gap(g),
+ equality(equality),
+ vpscConstraint(nullptr)
+{
+ _subConstraintInfo.push_back(new VarIndexPair(l, r));
+}
+
+
+SeparationConstraint::SeparationConstraint(const vpsc::Dim dim,
+ AlignmentConstraint *l, AlignmentConstraint *r, double g,
+ bool equality)
+ : CompoundConstraint(dim),
+ gap(g),
+ equality(equality)
+{
+ COLA_ASSERT(l);
+ COLA_ASSERT(r);
+
+ _subConstraintInfo.push_back(new VarIndexPair(l, r));
+}
+
+
+void SeparationConstraint::printCreationCode(FILE *fp) const
+{
+ assert(_subConstraintInfo.size() == 1);
+ VarIndexPair *varIndexPair = (VarIndexPair *) _subConstraintInfo.front();
+ if (varIndexPair->lConstraint && varIndexPair->rConstraint)
+ {
+ fprintf(fp, " SeparationConstraint *separation%llu = "
+ "new SeparationConstraint(vpsc::%cDIM, alignment%llu, "
+ "alignment%llu, %g, %s);\n",
+ (unsigned long long) this, (_primaryDim == 0) ? 'X' : 'Y',
+ (unsigned long long) varIndexPair->lConstraint,
+ (unsigned long long) varIndexPair->rConstraint, gap,
+ (equality) ? "true" : "false");
+ }
+ else
+ {
+ fprintf(fp, " SeparationConstraint *separation%llu = "
+ "new SeparationConstraint(vpsc::%cDIM, %u, %u, %g, %s);\n",
+ (unsigned long long) this, (_primaryDim == 0) ? 'X' : 'Y',
+ varIndexPair->indexL(), varIndexPair->indexR(), gap,
+ (equality) ? "true" : "false");
+ }
+ fprintf(fp, " ccs.push_back(separation%llu);\n\n",
+ (unsigned long long) this);
+}
+
+
+std::string SeparationConstraint::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "SeparationConstraint(";
+ stream << "dim: " << ((_primaryDim == 0) ? 'X' : 'Y');
+ stream << ", sep: " << gap;
+ stream << ", equality: " << ((equality) ? "true" : "false");
+ stream << "): {";
+ VarIndexPair *varIndexPair = (VarIndexPair *) _subConstraintInfo.front();
+ if (varIndexPair->lConstraint && varIndexPair->rConstraint)
+ {
+ stream << "(alignment: " << varIndexPair->indexL() << "), ";
+ stream << "(alignment: " << varIndexPair->indexR() << "), ";
+ }
+ else
+ {
+ stream << "(rect: " << varIndexPair->indexL() << "), ";
+ stream << "(rect: " << varIndexPair->indexR() << "), ";
+ }
+ stream << "}";
+ return stream.str();
+}
+
+
+void SeparationConstraint::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ COLA_UNUSED(dim);
+ COLA_UNUSED(vars);
+
+ // No additional variables are required!
+}
+
+
+SubConstraintAlternatives
+SeparationConstraint::getCurrSubConstraintAlternatives(vpsc::Variables vs[])
+{
+ SubConstraintAlternatives alternatives;
+
+ VarIndexPair *info = static_cast<VarIndexPair *>
+ (_subConstraintInfo[_currSubConstraintIndex]);
+
+ assertValidVariableIndex(vs[_primaryDim], info->indexL());
+ assertValidVariableIndex(vs[_primaryDim], info->indexR());
+ vpsc::Constraint constraint(vs[_primaryDim][info->indexL()],
+ vs[_primaryDim][info->indexR()], gap, equality);
+ alternatives.push_back(SubConstraint(_primaryDim, constraint));
+
+ //fprintf(stderr, "===== SEPARATION ALTERNATIVES -======\n");
+ return alternatives;
+}
+
+
+void SeparationConstraint::generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vs, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs)
+{
+ COLA_UNUSED(bbs);
+ if (dim == _primaryDim)
+ {
+ VarIndexPair *info =
+ static_cast<VarIndexPair *> (_subConstraintInfo.front());
+
+ unsigned left = info->indexL();
+ unsigned right = info->indexR();
+ assertValidVariableIndex(vs, left);
+ assertValidVariableIndex(vs, right);
+ vpscConstraint =
+ new vpsc::Constraint(vs[left], vs[right], gap, equality);
+ vpscConstraint->creator = this;
+ cs.push_back(vpscConstraint);
+ }
+}
+
+
+unsigned SeparationConstraint::left(void) const
+{
+ VarIndexPair *info =
+ static_cast<VarIndexPair *> (_subConstraintInfo.front());
+
+ return info->indexL();
+}
+
+
+unsigned SeparationConstraint::right(void) const
+{
+ VarIndexPair *info =
+ static_cast<VarIndexPair *> (_subConstraintInfo.front());
+
+ return info->indexR();
+}
+
+
+void SeparationConstraint::setSeparation(double gap)
+{
+ this->gap = gap;
+ if (vpscConstraint != nullptr)
+ {
+ vpscConstraint->gap = gap;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// OrthogonalEdgeConstraint code
+//-----------------------------------------------------------------------------
+
+OrthogonalEdgeConstraint::OrthogonalEdgeConstraint(const vpsc::Dim dim,
+ unsigned l, unsigned r)
+ : CompoundConstraint(dim),
+ left(l),
+ right(r),
+ vpscConstraint(nullptr)
+{
+}
+
+
+void OrthogonalEdgeConstraint::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ COLA_UNUSED(dim);
+ COLA_UNUSED(vars);
+
+ // No additional variables are required!
+}
+
+
+void OrthogonalEdgeConstraint::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " /* OrthogonalEdgeConstraint *orthogonal%llu = nullptr; */\n\n",
+ (unsigned long long) this);
+}
+
+
+std::string OrthogonalEdgeConstraint::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "OrthogonalEdgeConstraint()";
+ return stream.str();
+}
+
+
+
+SubConstraintAlternatives
+OrthogonalEdgeConstraint::getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[])
+{
+ COLA_UNUSED(vs);
+
+ // XXX: What to do here?
+ _currSubConstraintIndex = _subConstraintInfo.size();
+ return SubConstraintAlternatives();
+}
+
+
+void OrthogonalEdgeConstraint::generateSeparationConstraints(
+ const vpsc::Dim dim, vpsc::Variables& vs, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs)
+{
+ COLA_UNUSED(bbs);
+ if (dim == _primaryDim)
+ {
+ assertValidVariableIndex(vs, left);
+ assertValidVariableIndex(vs, right);
+ vpscConstraint = new vpsc::Constraint(vs[left], vs[right], 0, true);
+ vpscConstraint->creator = this;
+ cs.push_back(vpscConstraint);
+ }
+}
+
+
+void OrthogonalEdgeConstraint::generateTopologyConstraints(const vpsc::Dim k,
+ const vpsc::Rectangles& rs, vector<vpsc::Variable*> const & vars,
+ vector<vpsc::Constraint*> & cs)
+{
+ assertValidVariableIndex(vars, left);
+ assertValidVariableIndex(vars, right);
+ double lBound, rBound, pos;
+ if (k == vpsc::HORIZONTAL)
+ {
+ lBound = rs[left]->getCentreY();
+ rBound = rs[right]->getCentreY();
+ pos = rs[left]->getCentreX();
+ }
+ else
+ {
+ lBound = rs[left]->getCentreX();
+ rBound = rs[right]->getCentreX();
+ pos = rs[left]->getCentreY();
+ }
+ double minBound = std::min(lBound, rBound);
+ double maxBound = std::max(lBound, rBound);
+ for (unsigned i = 0; i < rs.size(); ++i)
+ {
+ if (i==left || i==right) continue;
+ vpsc::Rectangle *r = rs[i];
+ if (r->allowOverlap()) continue;
+ double l, rMin, rMax, rCentre;
+ rectBounds(k, r, rMin, rMax, rCentre, l);
+ if ( ((rMin >= minBound) && (rMin <= maxBound)) ||
+ ((rMax >= minBound) && (rMax <= maxBound)))
+ {
+ double g = l / 2;
+ if (rCentre < pos)
+ {
+ cs.push_back(new vpsc::Constraint(vars[i], vars[left], g));
+ }
+ else
+ {
+ cs.push_back(new vpsc::Constraint(vars[left], vars[i], g));
+ }
+ }
+ }
+}
+
+
+void OrthogonalEdgeConstraint::rectBounds(const vpsc::Dim k,
+ vpsc::Rectangle const *r, double& cmin, double& cmax,
+ double& centre, double & l) const
+{
+ if (k == vpsc::HORIZONTAL)
+ {
+ cmin = r->getMinY();
+ cmax = r->getMaxY();
+ centre = r->getCentreX();
+ l = r->width();
+ }
+ else
+ {
+ cmin = r->getMinX();
+ cmax = r->getMaxX();
+ centre = r->getCentreY();
+ l = r->height();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// MultiSeparationConstraint code
+//-----------------------------------------------------------------------------
+
+class AlignmentPair : public SubConstraintInfo
+{
+ public:
+ AlignmentPair(AlignmentConstraint *ac1, AlignmentConstraint *ac2)
+ : SubConstraintInfo(0),
+ alignment1(ac1),
+ alignment2(ac2)
+ {
+ }
+ AlignmentConstraint *alignment1;
+ AlignmentConstraint *alignment2;
+};
+
+
+MultiSeparationConstraint::MultiSeparationConstraint(const vpsc::Dim dim,
+ double minSep, bool equality)
+ : CompoundConstraint(dim),
+ indicator(nullptr),
+ sep(minSep),
+ equality(equality)
+{
+}
+
+
+void MultiSeparationConstraint::addAlignmentPair(AlignmentConstraint *ac1,
+ AlignmentConstraint *ac2)
+{
+ _subConstraintInfo.push_back(new AlignmentPair(ac1, ac2));
+}
+
+
+void MultiSeparationConstraint::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " MultiSeparationConstraint *multiSep%llu = "
+ "new MultiSeparationConstraint(vpsc::%cDIM, %g, %s);\n",
+ (unsigned long long) this, (_primaryDim == 0) ? 'X' : 'Y', sep,
+ (equality) ? "true" : "false");
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ AlignmentPair *pair = static_cast<AlignmentPair *> (*o);
+ fprintf(fp, " multiSep%llu->addAlignmentPair("
+ "alignment%llu, alignment%llu);\n",
+ (unsigned long long) this,
+ (unsigned long long) pair->alignment1,
+ (unsigned long long) pair->alignment2);
+ }
+ fprintf(fp, " ccs.push_back(multiSep%llu);\n\n",
+ (unsigned long long) this);
+}
+
+
+std::string MultiSeparationConstraint::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "MultiSeparationConstraint(";
+ stream << "dim: " << ((_primaryDim == 0) ? 'X' : 'Y');
+ stream << ", sep: " << sep;
+ stream << ", equality: " << ((equality) ? "true" : "false");
+ stream << "): {";
+ bool first = true;
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ if (!first)
+ {
+ stream << ", ";
+ }
+ AlignmentPair *pair = static_cast<AlignmentPair *> (*o);
+ stream << "(alignment: " << pair->alignment1->variable->id
+ << ", alignment: " << pair->alignment2->variable->id << ")";
+ first = false;
+ }
+ stream << "}";
+ return stream.str();
+}
+
+
+void MultiSeparationConstraint::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ COLA_UNUSED(dim);
+ COLA_UNUSED(vars);
+
+ // No additional variables are required!
+}
+
+
+SubConstraintAlternatives
+MultiSeparationConstraint::getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[])
+{
+ COLA_UNUSED(vs);
+
+ SubConstraintAlternatives alternatives;
+
+ AlignmentPair *info = static_cast<AlignmentPair *>
+ (_subConstraintInfo[_currSubConstraintIndex]);
+
+ AlignmentConstraint *c1 = info->alignment1;
+ AlignmentConstraint *c2 = info->alignment2;
+ if (!c1->variable || !c2->variable)
+ {
+ throw InvalidConstraint(this);
+ }
+ vpsc::Constraint constraint(c1->variable, c2->variable, sep, equality);
+ alternatives.push_back(SubConstraint(_primaryDim, constraint));
+
+ //fprintf(stderr, "===== MULTI SEPARATION ALTERNATIVES -======\n");
+ return alternatives;
+}
+
+
+void MultiSeparationConstraint::setSeparation(double sep)
+{
+ this->sep = sep;
+}
+
+
+void MultiSeparationConstraint::generateSeparationConstraints(
+ const vpsc::Dim dim, vpsc::Variables& vs, vpsc::Constraints& gcs,
+ vpsc::Rectangles& bbs)
+{
+ COLA_UNUSED(vs);
+ COLA_UNUSED(bbs);
+
+ if (dim == _primaryDim)
+ {
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ AlignmentPair *info = static_cast<AlignmentPair *> (*o);
+ AlignmentConstraint *c1 = info->alignment1;
+ AlignmentConstraint *c2 = info->alignment2;
+ if (!c1->variable || !c2->variable)
+ {
+ throw InvalidConstraint(this);
+ }
+ vpsc::Constraint *c = new vpsc::Constraint(
+ c1->variable, c2->variable, sep, equality);
+ c->creator = this;
+ gcs.push_back(c);
+ cs.push_back(c);
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// DistributionConstraint code
+//-----------------------------------------------------------------------------
+
+DistributionConstraint::DistributionConstraint(const vpsc::Dim dim)
+ : CompoundConstraint(dim),
+ indicator(nullptr)
+{
+}
+
+
+void DistributionConstraint::addAlignmentPair(AlignmentConstraint *ac1,
+ AlignmentConstraint *ac2)
+{
+ _subConstraintInfo.push_back(new AlignmentPair(ac1, ac2));
+}
+
+
+void DistributionConstraint::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ COLA_UNUSED(dim);
+ COLA_UNUSED(vars);
+
+ // No additional variables are required!
+}
+
+
+void DistributionConstraint::setSeparation(double sep)
+{
+ this->sep = sep;
+}
+
+
+void DistributionConstraint::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " DistributionConstraint *distribution%llu = "
+ "new DistributionConstraint(vpsc::%cDIM);\n",
+ (unsigned long long) this, (_primaryDim == 0) ? 'X' : 'Y');
+ fprintf(fp, " distribution%llu->setSeparation(%g);\n",
+ (unsigned long long) this, sep);
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ AlignmentPair *pair = static_cast<AlignmentPair *> (*o);
+ fprintf(fp, " distribution%llu->addAlignmentPair("
+ "alignment%llu, alignment%llu);\n",
+ (unsigned long long) this,
+ (unsigned long long) pair->alignment1,
+ (unsigned long long) pair->alignment2);
+ }
+ fprintf(fp, " ccs.push_back(distribution%llu);\n\n",
+ (unsigned long long) this);
+}
+
+
+std::string DistributionConstraint::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "DistributionConstraint(";
+ stream << "dim: " << ((_primaryDim == 0) ? 'X' : 'Y');
+ stream << ", sep: " << sep;
+ stream << "): {";
+ bool first = true;
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ if (!first)
+ {
+ stream << ", ";
+ }
+ AlignmentPair *pair = static_cast<AlignmentPair *> (*o);
+ stream << "(alignment: " << pair->alignment1->variable->id
+ << ", alignment: " << pair->alignment2->variable->id << ")";
+ first = false;
+ }
+ stream << "}";
+ return stream.str();
+}
+
+
+SubConstraintAlternatives
+DistributionConstraint::getCurrSubConstraintAlternatives(vpsc::Variables vs[])
+{
+ COLA_UNUSED(vs);
+
+ SubConstraintAlternatives alternatives;
+
+ AlignmentPair *info = static_cast<AlignmentPair *>
+ (_subConstraintInfo[_currSubConstraintIndex]);
+ AlignmentConstraint *c1 = info->alignment1;
+ AlignmentConstraint *c2 = info->alignment2;
+ if (!c1->variable || !c2->variable)
+ {
+ throw InvalidConstraint(this);
+ }
+ vpsc::Constraint constraint(c1->variable, c2->variable, sep, true);
+ alternatives.push_back(SubConstraint(_primaryDim, constraint));
+
+ //fprintf(stderr, "===== DISTRIBUTION ALTERNATIVES -======\n");
+ return alternatives;
+}
+
+
+void DistributionConstraint::generateSeparationConstraints(
+ const vpsc::Dim dim, vpsc::Variables& vars, vpsc::Constraints& gcs,
+ vpsc::Rectangles& bbs)
+{
+ COLA_UNUSED(vars);
+ COLA_UNUSED(bbs);
+
+ if (dim == _primaryDim)
+ {
+ cs.clear();
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ AlignmentPair *info = static_cast<AlignmentPair *> (*o);
+ AlignmentConstraint *c1 = info->alignment1;
+ AlignmentConstraint *c2 = info->alignment2;
+ if (!c1->variable || !c2->variable)
+ {
+ throw InvalidConstraint(this);
+ }
+ vpsc::Constraint *c=new vpsc::Constraint(
+ c1->variable, c2->variable, sep, true);
+ c->creator = this;
+ gcs.push_back(c);
+ cs.push_back(c);
+#if 0
+ // The following was an experiment to allow variable distributions
+ // solved by optimisation rather than satisfying constraints
+ if(isVariable) {
+ // set second derivatives of:
+ // (u + g - v)^2 = g^2 + 2gu + u^2 - 2gv - 2uv + v^2
+ (*Q)[make_pair(c1->variable->id,c1->variable->id)]+=w;
+ (*Q)[make_pair(c2->variable->id,c2->variable->id)]+=w;
+ (*Q)[make_pair(variable->id,variable->id)]+=w;
+ (*Q)[make_pair(c1->variable->id,c2->variable->id)]-=w;
+ (*Q)[make_pair(c2->variable->id,c1->variable->id)]-=w;
+ (*Q)[make_pair(c1->variable->id,variable->id)]+=w;
+ (*Q)[make_pair(variable->id,c1->variable->id)]+=w;
+ (*Q)[make_pair(c2->variable->id,variable->id)]-=w;
+ (*Q)[make_pair(variable->id,c2->variable->id)]-=w;
+ }
+#endif
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// FixedRelativeConstraint code
+//-----------------------------------------------------------------------------
+
+class RelativeOffset : public SubConstraintInfo
+{
+ public:
+ RelativeOffset(unsigned indL, unsigned indR, vpsc::Dim dim,
+ double offset)
+ : SubConstraintInfo(indL),
+ varIndex2(indR),
+ dim(dim),
+ distOffset(offset)
+ {
+ }
+ void updateVarIDsWithMapping(const VariableIDMap& idMap, bool forward)
+ {
+ varIndex = idMap.mappingForVariable(varIndex, forward);
+ varIndex2 = idMap.mappingForVariable(varIndex2, forward);
+ }
+
+ unsigned varIndex2;
+ vpsc::Dim dim;
+ double distOffset;
+};
+
+
+FixedRelativeConstraint::FixedRelativeConstraint(const vpsc::Rectangles& rs,
+ std::vector<unsigned> shapeIds, const bool fixedPosition)
+ : CompoundConstraint(vpsc::XDIM),
+ m_fixed_position(fixedPosition),
+ m_shape_vars(shapeIds)
+{
+ _combineSubConstraints = true;
+
+ // Make sure that m_shape_vars doesn't contain duplicates.
+ std::sort(m_shape_vars.begin(), m_shape_vars.end());
+ std::vector<unsigned>::iterator last =
+ std::unique(m_shape_vars.begin(), m_shape_vars.end());
+ m_shape_vars.erase(last, m_shape_vars.end());
+
+ unsigned firstId = UINT_MAX;
+ COLA_ASSERT(m_shape_vars.size() >= 2);
+ for (std::vector<unsigned>::iterator it = m_shape_vars.begin();
+ it != m_shape_vars.end(); ++it)
+ {
+ COLA_ASSERT(*it < rs.size());
+
+ if (it == m_shape_vars.begin())
+ {
+ firstId = *it;
+ }
+ else
+ {
+ unsigned thisId = *it;
+ _subConstraintInfo.push_back(
+ new RelativeOffset(firstId, thisId, vpsc::XDIM,
+ rs[thisId]->getCentreX() - rs[firstId]->getCentreX()));
+ _subConstraintInfo.push_back(
+ new RelativeOffset(firstId, thisId, vpsc::YDIM,
+ rs[thisId]->getCentreY() - rs[firstId]->getCentreY()));
+ }
+ }
+}
+
+void FixedRelativeConstraint::updateVarIDsWithMapping(
+ const VariableIDMap& idMap, bool forward)
+{
+ CompoundConstraint::updateVarIDsWithMapping(idMap, forward);
+
+ // We need to map variables in m_shape_vars too,
+ // since this is used in generateVariables().
+ for (size_t i = 0; i < m_shape_vars.size(); ++i)
+ {
+ m_shape_vars[i] = idMap.mappingForVariable(m_shape_vars[i], forward);
+ }
+}
+
+
+
+void FixedRelativeConstraint::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ COLA_UNUSED(dim);
+ COLA_UNUSED(vars);
+
+ // No additional variables are required!
+
+ // Fix shape positions if required.
+ if (m_fixed_position)
+ {
+ for (std::vector<unsigned>::iterator it = m_shape_vars.begin();
+ it != m_shape_vars.end(); ++it)
+ {
+ vars[*it]->fixedDesiredPosition = true;
+ vars[*it]->weight = 100000;
+ }
+ }
+}
+
+
+void FixedRelativeConstraint::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " std::vector<unsigned> fixedRelativeSet%llu;\n",
+ (unsigned long long) this);
+ for (std::vector<unsigned>::const_iterator it = m_shape_vars.begin();
+ it != m_shape_vars.end(); ++it)
+ {
+ fprintf(fp, " fixedRelativeSet%llu.push_back(%u);\n",
+ (unsigned long long) this, *it);
+ }
+ fprintf(fp, " FixedRelativeConstraint *fixedRelative%llu = "
+ "new FixedRelativeConstraint(rs, fixedRelativeSet%llu, %s);\n",
+ (unsigned long long) this, (unsigned long long) this,
+ (m_fixed_position) ? "true" : "false");
+ fprintf(fp, " ccs.push_back(fixedRelative%llu);\n\n",
+ (unsigned long long) this);
+}
+
+
+std::string FixedRelativeConstraint::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "FixedRelativeConstraint(";
+ stream << "fixedPos: " << ((m_fixed_position) ? "true" : "false");
+ stream << "): {";
+ bool first = true;
+ for (std::vector<unsigned>::const_iterator it = m_shape_vars.begin();
+ it != m_shape_vars.end(); ++it)
+ {
+ if (!first)
+ {
+ stream << ", ";
+ }
+ stream << "(rect: " << *it << ")";
+ first = false;
+ }
+ stream << "}";
+ return stream.str();
+}
+
+
+SubConstraintAlternatives
+FixedRelativeConstraint::getCurrSubConstraintAlternatives(vpsc::Variables vs[])
+{
+ COLA_UNUSED(vs);
+
+ SubConstraintAlternatives alternatives;
+
+ RelativeOffset *offset = static_cast<RelativeOffset *>
+ (_subConstraintInfo[_currSubConstraintIndex]);
+
+ vpsc::Dim dim = offset->dim;
+ vpsc::Constraint constraint(vs[dim][offset->varIndex],
+ vs[dim][offset->varIndex2], offset->distOffset, true);
+ alternatives.push_back(SubConstraint(dim, constraint));
+
+ //fprintf(stderr, "===== FixedRelativeConstraint ALTERNATIVES -======\n");
+ return alternatives;
+}
+
+
+void FixedRelativeConstraint::generateSeparationConstraints(
+ const vpsc::Dim dim, vpsc::Variables& vars, vpsc::Constraints& ccs,
+ vpsc::Rectangles& bbs)
+{
+ COLA_UNUSED(vars);
+ COLA_UNUSED(bbs);
+
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ RelativeOffset *offset = static_cast<RelativeOffset *> (*o);
+ if (dim != offset->dim)
+ {
+ continue;
+ }
+
+ assertValidVariableIndex(vars, offset->varIndex);
+ assertValidVariableIndex(vars, offset->varIndex2);
+ vpsc::Constraint *c =
+ new vpsc::Constraint(vars[offset->varIndex],
+ vars[offset->varIndex2], offset->distOffset, true);
+ c->creator = this;
+ ccs.push_back(c);
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// PageBoundaryConstraint code
+//-----------------------------------------------------------------------------
+
+class PageBoundaryShapeOffsets : public SubConstraintInfo
+{
+ public:
+ PageBoundaryShapeOffsets(unsigned ind, double xOffset, double yOffset) :
+ SubConstraintInfo(ind)
+ {
+ halfDim[0] = xOffset;
+ halfDim[1] = yOffset;
+ }
+ double halfDim[2]; // half width and height values;
+};
+
+
+PageBoundaryConstraints::PageBoundaryConstraints(double xLow, double xHigh,
+ double yLow, double yHigh, double weight)
+ : CompoundConstraint(vpsc::HORIZONTAL)
+{
+ COLA_ASSERT(xLow < xHigh);
+ COLA_ASSERT(yLow < yHigh);
+
+ leftMargin[vpsc::XDIM] = xLow;
+ rightMargin[vpsc::XDIM] = xHigh;
+ leftMargin[vpsc::YDIM] = yLow;
+ rightMargin[vpsc::YDIM] = yHigh;
+
+ for (unsigned i = 0; i < 2; ++i)
+ {
+ actualLeftMargin[i] = leftMargin[i];
+ actualRightMargin[i] = rightMargin[i];
+ leftWeight[i] = weight;
+ rightWeight[i] = weight;
+ vl[i] = nullptr;
+ vr[i] = nullptr;
+ }
+}
+
+
+void PageBoundaryConstraints::addShape(unsigned id, double halfW, double halfH)
+{
+ _subConstraintInfo.push_back(new PageBoundaryShapeOffsets(id, halfW, halfH));
+}
+
+
+void PageBoundaryConstraints::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " PageBoundaryConstraints *pageBoundary%llu = "
+ "new PageBoundaryConstraints(%g, %g, %g, %g, %g);\n",
+ (unsigned long long) this, leftMargin[vpsc::XDIM],
+ rightMargin[vpsc::XDIM], leftMargin[vpsc::YDIM],
+ rightMargin[vpsc::YDIM], leftWeight[0]);
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ PageBoundaryShapeOffsets *offsets =
+ static_cast<PageBoundaryShapeOffsets *> (*o);
+ fprintf(fp, " pageBoundary%llu->addShape(%u, %g, %g);\n",
+ (unsigned long long) this, offsets->varIndex,
+ offsets->halfDim[XDIM], offsets->halfDim[YDIM]);
+ }
+ fprintf(fp, " ccs.push_back(pageBoundary%llu);\n\n",
+ (unsigned long long) this);
+}
+
+
+std::string PageBoundaryConstraints::toString(void) const
+{
+ std::ostringstream stream;
+ stream << "PageBoundaryConstraints(";
+ stream << "xLow: " << leftMargin[vpsc::XDIM];
+ stream << ", xHigh: " << rightMargin[vpsc::XDIM];
+ stream << ", yLow: " << leftMargin[vpsc::YDIM];
+ stream << ", yHigh: " << rightMargin[vpsc::YDIM];
+ stream << ", weight: " << leftWeight[0];
+ stream << "): {";
+ bool first = true;
+ for (SubConstraintInfoList::const_iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ if (!first)
+ {
+ stream << ", ";
+ }
+ PageBoundaryShapeOffsets *offsets =
+ static_cast<PageBoundaryShapeOffsets *> (*o);
+ stream << "(rect: " << offsets->varIndex;
+ stream << ", halfWidth: " << offsets->halfDim[XDIM];
+ stream << ", halfHeight: " << offsets->halfDim[YDIM];
+ stream <<")";
+ first = false;
+ }
+ stream << "}";
+ return stream.str();
+}
+
+SubConstraintAlternatives
+PageBoundaryConstraints::getCurrSubConstraintAlternatives(vpsc::Variables vs[])
+{
+ COLA_UNUSED(vs);
+
+ // Page boundary constraints do not need to be evaluated at the
+ // time of makeFeasible, so we return an empty list here.
+ _currSubConstraintIndex = _subConstraintInfo.size();
+ return SubConstraintAlternatives();
+}
+
+
+void PageBoundaryConstraints::updatePosition(const vpsc::Dim dim)
+{
+ if (vl[dim])
+ {
+ actualLeftMargin[dim] = vl[dim]->finalPosition;
+ }
+
+ if (vr[dim])
+ {
+ actualRightMargin[dim] = vr[dim]->finalPosition;
+ }
+}
+
+
+double PageBoundaryConstraints::getActualLeftMargin(const vpsc::Dim dim)
+{
+ return actualLeftMargin[dim];
+}
+
+
+double PageBoundaryConstraints::getActualRightMargin(const vpsc::Dim dim)
+{
+ return actualRightMargin[dim];
+}
+
+
+void PageBoundaryConstraints::generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ // create 2 dummy vars, based on the dimension we are in
+ if (leftWeight[dim])
+ {
+ vars.push_back(vl[dim] = new vpsc::Variable(vars.size(),
+ leftMargin[dim], leftWeight[dim]));
+ vl[dim]->fixedDesiredPosition = true;
+ }
+
+ if (rightWeight[dim])
+ {
+ vars.push_back(vr[dim] = new vpsc::Variable(vars.size(),
+ rightMargin[dim], rightWeight[dim]));
+ vr[dim]->fixedDesiredPosition = true;
+ }
+}
+
+
+void PageBoundaryConstraints::generateSeparationConstraints(
+ const vpsc::Dim dim, vpsc::Variables& vs, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs)
+{
+ COLA_UNUSED(bbs);
+ // For each of the "real" variables, create a constraint that puts
+ // that var between our two new dummy vars, depending on the dimension.
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ PageBoundaryShapeOffsets *info =
+ static_cast<PageBoundaryShapeOffsets *> (*o);
+ assertValidVariableIndex(vs, info->varIndex);
+ if (vl[dim])
+ {
+ vpsc::Constraint *constraint = new vpsc::Constraint(vl[dim],
+ vs[info->varIndex], info->halfDim[dim]);
+ constraint->creator = this;
+ cs.push_back(constraint);
+ }
+
+ if (vr[dim])
+ {
+ vpsc::Constraint *constraint = new vpsc::Constraint(
+ vs[info->varIndex], vr[dim], info->halfDim[dim]);
+ constraint->creator = this;
+ cs.push_back(constraint);
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Support code
+//-----------------------------------------------------------------------------
+
+
+struct GenerateVariables
+{
+ GenerateVariables(const vpsc::Dim dim, vpsc::Variables& vars)
+ : dim(dim),
+ vars(vars)
+ {
+ }
+ void operator() (CompoundConstraint *c)
+ {
+ c->generateVariables(dim, vars);
+ }
+
+ const vpsc::Dim dim;
+ vpsc::Variables& vars;
+};
+
+
+struct GenerateSeparationConstraints
+{
+ GenerateSeparationConstraints(const vpsc::Dim dim, vpsc::Variables& vars,
+ vpsc::Constraints& cs, vpsc::Rectangles& bbs)
+ : dim(dim),
+ vars(vars),
+ cs(cs),
+ bbs(bbs)
+ {
+ }
+ void operator() (CompoundConstraint *c)
+ {
+ c->generateSeparationConstraints(dim, vars, cs, bbs);
+ }
+ const vpsc::Dim dim;
+ vpsc::Variables& vars;
+ vpsc::Constraints& cs;
+ vpsc::Rectangles& bbs;
+};
+
+
+void generateVariablesAndConstraints(CompoundConstraints& ccs,
+ const vpsc::Dim dim, vpsc::Variables& vars, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs)
+{
+ for_each(ccs.begin(), ccs.end(),
+ GenerateVariables(dim, vars));
+ for_each(ccs.begin(), ccs.end(),
+ GenerateSeparationConstraints(dim, vars, cs, bbs));
+}
+
+
+void generateVariables(CompoundConstraints& ccs, const vpsc::Dim dim,
+ vpsc::Variables& vars)
+{
+ for_each(ccs.begin(), ccs.end(),
+ GenerateVariables(dim, vars));
+}
+
+
+CompoundConstraint::CompoundConstraint(vpsc::Dim primaryDim,
+ unsigned int priority) :
+ _primaryDim(primaryDim),
+ _secondaryDim((vpsc::Dim) ((primaryDim + 1) % 2)),
+ _priority(priority),
+ _combineSubConstraints(false),
+ _currSubConstraintIndex(0)
+{
+}
+
+
+CompoundConstraint::~CompoundConstraint()
+{
+ // Free memory from the subConstraintInfo list.
+ for_each(_subConstraintInfo.begin(), _subConstraintInfo.end(), delete_object());
+ _subConstraintInfo.clear();
+}
+
+
+vpsc::Dim CompoundConstraint::dimension(void) const
+{
+ return _primaryDim;
+}
+
+
+unsigned int CompoundConstraint::priority(void) const
+{
+ return _priority;
+}
+
+
+void CompoundConstraint::printCreationCode(FILE *fp) const
+{
+ COLA_UNUSED(fp);
+
+ // Do nothing. Subclasses can implement this.
+}
+
+void CompoundConstraint::updateVarIDsWithMapping(const VariableIDMap& idMap,
+ bool forward)
+{
+ for (SubConstraintInfoList::iterator o = _subConstraintInfo.begin();
+ o != _subConstraintInfo.end(); ++o)
+ {
+ (*o)->updateVarIDsWithMapping(idMap, forward);
+ }
+}
+
+
+std::list<unsigned> CompoundConstraint::subConstraintObjIndexes(void) const
+{
+ std::list<unsigned> idList;
+ for (size_t i = 0; i < _subConstraintInfo.size(); ++i)
+ {
+ idList.push_back(_subConstraintInfo[i]->varIndex);
+ }
+ return idList;
+}
+
+
+bool CompoundConstraint::subConstraintsRemaining(void) const
+{
+ return _currSubConstraintIndex < _subConstraintInfo.size();
+}
+
+
+void CompoundConstraint::markAllSubConstraintsAsInactive(void)
+{
+ for (size_t i = 0; i < _subConstraintInfo.size(); ++i)
+ {
+ _subConstraintInfo[i]->satisfied = false;
+ }
+ _currSubConstraintIndex = 0;
+}
+
+
+void CompoundConstraint::markCurrSubConstraintAsActive(const bool satisfiable)
+{
+ _subConstraintInfo[_currSubConstraintIndex]->satisfied = satisfiable;
+
+ _currSubConstraintIndex++;
+}
+
+
+void CompoundConstraint::assertValidVariableIndex(const vpsc::Variables& vars,
+ const unsigned index)
+{
+ if (index >= vars.size())
+ {
+ throw InvalidVariableIndexException(this, index);
+ }
+}
+
+
+bool CompoundConstraint::shouldCombineSubConstraints(void) const
+{
+ return _combineSubConstraints;
+}
+
+
+UnsatisfiableConstraintInfo::UnsatisfiableConstraintInfo(
+ const vpsc::Constraint *c)
+ : leftVarIndex(c->left->id),
+ rightVarIndex(c->right->id),
+ separation(c->gap),
+ equality(c->equality),
+ cc((CompoundConstraint *)c->creator)
+{
+}
+
+// Variable mapping.
+
+VariableIDMap::VariableIDMap()
+{
+}
+
+VariableIDMap::~VariableIDMap()
+{
+}
+
+typedef std::pair<unsigned, unsigned> IDPair;
+typedef std::list<IDPair> IDPairList;
+
+bool VariableIDMap::addMappingForVariable(const unsigned from,
+ const unsigned to)
+{
+ bool found = false;
+ for (IDPairList::iterator it = m_mapping.begin(); it != m_mapping.end();
+ ++it)
+ {
+ IDPair& ids = *it;
+
+ if (ids.first == from)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ m_mapping.push_back(std::make_pair(from, to));
+ return true;
+ }
+ //fprintf(stderr, "VariableIDMap: mapping already exists for var %u\n", from);
+ return false;
+}
+
+void VariableIDMap::printCreationCode(FILE *fp) const
+{
+ fprintf(fp, " cola::VariableIDMap idMap;\n");
+ for (IDPairList::const_iterator it = m_mapping.begin();
+ it != m_mapping.end(); ++it)
+ {
+ fprintf(fp, " idMap.addMappingForVariable(%u, %u);\n",
+ it->first, it->second);
+ }
+ fprintf(fp, " \n");
+}
+
+unsigned VariableIDMap::mappingForVariable(const unsigned var,
+ bool forward) const
+{
+ for (IDPairList::const_iterator it = m_mapping.begin();
+ it != m_mapping.end(); ++it)
+ {
+ const IDPair& ids = *it;
+
+ if (forward)
+ {
+ if (ids.first == var)
+ {
+ return ids.second;
+ }
+ }
+ else // (!forward)
+ {
+ if (ids.second == var)
+ {
+ return ids.first;
+ }
+ }
+ }
+
+ //fprintf(stderr, "Warning: mapping not found for var %u\n", var);
+
+ // Just return original variable index.
+ return var;
+}
+
+void VariableIDMap::clear(void)
+{
+ m_mapping.clear();
+}
+
+
+} // namespace cola
+
diff --git a/src/3rdparty/adaptagrams/libcola/compound_constraints.h b/src/3rdparty/adaptagrams/libcola/compound_constraints.h
new file mode 100644
index 0000000..4d24152
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/compound_constraints.h
@@ -0,0 +1,829 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef _COMPOUND_CONSTRAINTS_H
+#define _COMPOUND_CONSTRAINTS_H
+
+#include <vector>
+#include <list>
+#include <set>
+#include <utility>
+
+#include "libvpsc/rectangle.h"
+#include "libvpsc/constraint.h"
+#include "libcola/sparse_matrix.h"
+#include "libcola/unused.h"
+
+namespace vpsc {
+ class Constraint;
+ class Variable;
+
+// Avoid SWIG redefinition warnings.
+#ifndef SWIG
+ typedef std::vector<vpsc::Constraint *> Constraints;
+ typedef std::vector<vpsc::Variable *> Variables;
+#endif
+}
+namespace cola {
+
+class Cluster;
+class RootCluster;
+
+
+// A component of a CompoundConstraint.
+class SubConstraint
+{
+ public:
+ SubConstraint(vpsc::Dim dim, vpsc::Constraint constraint,
+ double cost = 0)
+ : dim(dim),
+ constraint(constraint),
+ cost(cost)
+ {
+ }
+ bool operator<(const SubConstraint& rhs) const
+ {
+ return cost < rhs.cost;
+ }
+
+ vpsc::Dim dim;
+ vpsc::Constraint constraint;
+ double cost;
+};
+
+
+// A list of alternative SubConstraints.
+typedef std::list<SubConstraint> SubConstraintAlternatives;
+
+static const double freeWeight = 0.0001;
+
+static const unsigned int DEFAULT_CONSTRAINT_PRIORITY = 30000;
+static const unsigned int PRIORITY_NONOVERLAP =
+ DEFAULT_CONSTRAINT_PRIORITY - 2000;
+
+/**
+ * @brief Holds a mapping between two sets of Variable indices.
+ *
+ * This can be used to rewrite the Rectangles to which a set of
+ * CompoundConstraints apply to. This is useful when creating another
+ * instance of the problem, but using the same CompoundConstraints list.
+ * You should not usually need to use this yourself. It is utilised by
+ * addons such as topology::AvoidTopologyAddon.
+ *
+ * If a mapping for a particular value is not set, it is considered to be
+ * equal on both sides of the mapping.
+ */
+class VariableIDMap
+{
+ public:
+ VariableIDMap();
+ ~VariableIDMap();
+
+ /**
+ * @brief Adds a mapping between a pair of variables.
+ *
+ * @param[in] from The variable index to map from.
+ * @param[in] to The variable index to map to.
+ * @return True if the mapping was successfully added.
+ */
+ bool addMappingForVariable(const unsigned from, const unsigned to);
+ unsigned mappingForVariable(const unsigned var,
+ bool forward = true) const;
+ void clear(void);
+ void printCreationCode(FILE *fp) const;
+
+ private:
+ std::list<std::pair<unsigned, unsigned> > m_mapping;
+};
+
+class SubConstraintInfo
+{
+ public:
+ SubConstraintInfo(unsigned ind) :
+ varIndex(ind),
+ satisfied(false)
+ {
+ }
+ virtual ~SubConstraintInfo()
+ {
+ }
+ virtual void updateVarIDsWithMapping(const VariableIDMap& idMap,
+ bool forward);
+
+ unsigned varIndex;
+ bool satisfied;
+};
+
+typedef std::vector<SubConstraintInfo *> SubConstraintInfoList;
+
+
+/**
+ * @brief An abstract base class for all high-level compound constraints.
+ *
+ * A compound constraint is a conceptual, diagramming application oriented
+ * type of constraint, which can be translated into a set of simple
+ * separation constraints, possibly extra dummy variables, and perhaps
+ * even some extra terms for the quadratic objective function used
+ * in the gradient projection solver.
+ */
+class CompoundConstraint {
+public:
+ CompoundConstraint(vpsc::Dim primaryDim,
+ unsigned int priority = DEFAULT_CONSTRAINT_PRIORITY);
+ /**
+ * @brief Implemented by the compound constraint to generate any
+ * additional required variables in the given dimension.
+ *
+ * Generate any additional variables required by this compound constraint
+ * when operating in the given dimension dim and add them to vars. These
+ * variables should be cleaned up by the caller after the VPSC problem is
+ * solved.
+ *
+ * The variables' ideal position and weight should be set by the compound
+ * constraint and they should be added to the end of vars.
+ *
+ * @param[in] dim The current active dimension.
+ * @param[in,out] vars The list of variables for the overall problem
+ * instance to which any variables generated should
+ * be appended.
+ */
+ virtual void generateVariables(const vpsc::Dim dim,
+ vpsc::Variables& vars) = 0;
+ /**
+ * @brief Implemented by the compound constraint to generate the low-level
+ * separation constraints in the given dimension.
+ *
+ * These constraints will be added to the list of constraints cs.
+ *
+ * @param[in] dim The current active dimension.
+ * @param[in] vars The list of variables for the overall problem
+ * instance.
+ * @param[in,out] cs The list of constraints to which the generated
+ * constraints will be added.
+ * @param[in] bbs The list of bounding boxes for all rectangles
+ * in the current problem. It has the same order as
+ * vars.
+ */
+ virtual void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& var, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs) = 0;
+ /**
+ * @brief Implemented by the compound constraint to send position
+ * information back to the interface.
+ *
+ * This will be called for each compound constraint once the VPSC
+ * instance is solved to allow them to pass information such as
+ * variable values back to the graphical user interface.
+ *
+ * @param[in] dim The current active dimension.
+ */
+ virtual void updatePosition(const vpsc::Dim dim)
+ {
+ COLA_UNUSED(dim);
+ }
+
+ /**
+ * @brief Returns a textual description of the compound constraint.
+ *
+ * @return A string describing the compound constraint.
+ */
+ virtual std::string toString(void) const = 0;
+
+// To prevent C++ objects from being destroyed in garbage collected languages
+// when the libraries are called from SWIG, we hide the declarations of the
+// destructors and prevent generation of default destructors.
+#ifndef SWIG
+ virtual ~CompoundConstraint();
+#endif
+
+ vpsc::Dim dimension(void) const;
+ unsigned int priority(void) const;
+ virtual void updateVarIDsWithMapping(const VariableIDMap& idMap,
+ bool forward = true);
+ virtual void updateShapeOffsetsForDifferentCentres(
+ const std::vector<double>& offsets, bool forward = true)
+ {
+ COLA_UNUSED(offsets);
+ COLA_UNUSED(forward);
+ }
+
+ // The following methods are only needed for initially solving feasibility
+ // of the constraints, and do not need to be implemented for most compound
+ // constraints.
+ virtual void markAllSubConstraintsAsInactive(void);
+ virtual bool subConstraintsRemaining(void) const;
+ virtual void markCurrSubConstraintAsActive(const bool satisfiable);
+ virtual SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]) = 0;
+ std::list<unsigned> subConstraintObjIndexes(void) const;
+ virtual void printCreationCode(FILE *fp) const;
+ bool shouldCombineSubConstraints(void) const;
+
+protected:
+ void assertValidVariableIndex(const vpsc::Variables& vars,
+ const unsigned index);
+
+ // The dimension that this compound constraint operates.
+ vpsc::Dim _primaryDim;
+ // The alternate dimension.
+ vpsc::Dim _secondaryDim;
+ // The priority used to assign order for solving constraints.
+ unsigned int _priority;
+ // Describes whether to process sub constraints individually, or all
+ // at once, during the makeFeasible opteration.
+ bool _combineSubConstraints;
+
+ // Info about the sub constraints within this compound constraint.
+ SubConstraintInfoList _subConstraintInfo;
+ // The index of the current subConstraint being made feasible.
+ size_t _currSubConstraintIndex;
+};
+//! @brief A vector of pointers to CompoundConstraint objects.
+typedef std::vector<CompoundConstraint *> CompoundConstraints;
+
+
+/**
+ * @brief Generate all the variables and constraints for a collection of
+ * CompoundConstraints.
+ */
+void generateVariablesAndConstraints(CompoundConstraints& ccs,
+ const vpsc::Dim dim, vpsc::Variables& vars, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs);
+
+
+/**
+ * @brief Generate just all the variables for a collection of
+ * CompoundConstraints.
+ */
+void generateVariables(CompoundConstraints& ccs, const vpsc::Dim dim,
+ vpsc::Variables& vars);
+
+
+/**
+ * @brief A boundary constraint specifies a bounding line that a set of nodes
+ * must be either to the left or right of.
+ *
+ * A boundary constraint gives a bounding line in a particular dimension (with
+ * position stored in a variable) and a set of nodes required to be to the left
+ * of that line and nodes required to be to the right of the line. Separations
+ * are determined by offsets passed to addShape().
+ */
+class BoundaryConstraint : public CompoundConstraint
+{
+ public:
+ /**
+ * @brief Constructs a new BoundaryConstraint in the specified
+ * dimension.
+ *
+ * @param[in] dim The dimension the constraints will operate in.
+ */
+ BoundaryConstraint(const vpsc::Dim dim);
+ /**
+ * @brief Mark a node as being part of this boundary constraint.
+ *
+ * @param[in] index The index of the node in the Rectangles vector.
+ * @param[in] offset The minimum amount to separate the node from the
+ * boundary line. Negative if left-of, positive if
+ * right-of. Will usually be equal to half a node's
+ * size plus a buffer amount.
+ */
+ void addShape(const unsigned int index, const double offset);
+
+ /**
+ * @brief Returns a textual description of the compound constraint.
+ *
+ * @return A string describing the compound constraint.
+ */
+ std::string toString(void) const;
+
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs);
+ void updatePosition(const vpsc::Dim dim);
+ void printCreationCode(FILE *fp) const;
+
+ //! Holds the position of the boundary line, once layout is complete.
+ double position;
+
+ vpsc::Variable* variable;
+};
+
+
+/**
+ * @brief An alignment constraint specifies a alignment line that a set of
+ * nodes must be constrained to by an exact amount.
+ *
+ * This is represented as a variable representing the position of a vertical
+ * or horizontal and a then group of nodes and offsets for those nodes such
+ * that the nodes must be spaced exactly at those offsets from the alignment
+ * position.
+ *
+ * Optionally, the alignment may be given a suggested position and/or marked
+ * as "fixed". When fixed, the position variable will be given a higher
+ * weight to attempt to keep it at that position.
+ */
+class AlignmentConstraint : public CompoundConstraint
+{
+ public:
+ /**
+ * @brief Constructs a new AlignmentConstraint in the specified
+ * dimension.
+ *
+ * @param[in] dim The dimension the constraints will operate in.
+ */
+ AlignmentConstraint(const vpsc::Dim dim, double position = 0.0);
+ /**
+ * @brief Mark a node as being part of this alignment constraint.
+ *
+ * @param[in] index The index of the node in the Rectangles vector.
+ * @param[in] offset The exact amount to separate the node from the
+ * alignment line. Negative if left-of, positive if
+ * right-of. Will usually be equal to half a node's
+ * size if aligning to the side of a node, or zero
+ * if aligning with the centre of a node.
+ */
+ void addShape(const unsigned int index, const double offset);
+ /**
+ * @brief Mark the alignment as ideally having a fixed position.
+ *
+ * This causes the position variable for the alignment to be given
+ * the ideal position pos and a higher weight.
+ *
+ * @param[in] pos The ideal position value for the alignment.
+ */
+ void fixPos(double pos);
+ /**
+ * @brief Mark the alignment as not having a fixed position.
+ *
+ * This is the default.
+ */
+ void unfixPos(void);
+ /**
+ * @brief Indicates if the alignment position is marked as fixed.
+ *
+ * @returns True if the alignment position is marked as fixed, or
+ * false otherwise.
+ */
+ bool isFixed(void) const;
+
+ /**
+ * @brief Returns a textual description of the compound constraint.
+ *
+ * @return A string describing the compound constraint.
+ */
+ std::string toString(void) const;
+
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs);
+ void updatePosition(const vpsc::Dim dim);
+ double position(void) const;
+ void printCreationCode(FILE *fp) const;
+ void updateShapeOffsetsForDifferentCentres(
+ const std::vector<double>& offsets, bool forward = true);
+
+ /// Generic pointer to an indicator object being used to represent
+ /// this compound constraint in the GUI.
+ void *indicator;
+
+ vpsc::Variable* variable;
+ private:
+ // The position of the alignment line
+ double _position;
+ bool _isFixed;
+};
+
+
+/**
+ * @brief A separation constraint specifies a simple horizontal or vertical
+ * spacing constraint between 2 nodes or alignment constraints.
+ *
+ * The non-equality constraint is lPos + g <= rPos
+ * and the equality constraint is lPos + g = rPos
+ *
+ * @note With an equality, you can effectively reverse the ordering of the
+ * two variables by making the gap a negative number. This is not so
+ * for the non-equality case, there you need to keep the same gap value
+ * but reverse the order of the variables passed to the constructor.
+ */
+class SeparationConstraint : public CompoundConstraint
+{
+ public:
+ /**
+ * @brief Constructs a new SeparationConstraint between two nodes in
+ * the specified dimension.
+ *
+ * The constraint will keep the centre of the left node to the left of
+ * the right node by exactly or more than the specified gap.
+ *
+ * @param[in] dim The dimension the constraint will operate in.
+ * @param[in] l The index of the left node.
+ * @param[in] r The index of the right node.
+ * @param[in] g The minimum or exact distance to separate the
+ * two nodes.
+ * @param[in] equality Whether or not the constraint is an exact
+ * distance.
+ */
+ SeparationConstraint(const vpsc::Dim dim, unsigned l, unsigned r,
+ double g, bool equality = false);
+ /**
+ * @brief Constructs a new SeparationConstraint between two alignment
+ * constraints in the specified dimension.
+ *
+ * The constraint will keep the centre of the left alignment line to
+ * the left of the right alignment line by exactly or more than the
+ * specified gap.
+ *
+ * @param[in] dim The dimension the constraint will operate in.
+ * @param[in] l A pointer to the left AlignmentConstraint.
+ * @param[in] r A pointer to the right AlignmentConstraint.
+ * @param[in] g The minimum or exact distance to separate the
+ * two alignment constraints.
+ * @param[in] equality Whether or not the constraint is an exact
+ * distance.
+ */
+ SeparationConstraint(const vpsc::Dim dim, AlignmentConstraint *l,
+ AlignmentConstraint *r, double g, bool equality = false);
+
+ /**
+ * @brief Returns a textual description of the compound constraint.
+ *
+ * @return A string describing the compound constraint.
+ */
+ std::string toString(void) const;
+
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vs, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs);
+ void setSeparation(double gap);
+ unsigned left(void) const;
+ unsigned right(void) const;
+ void printCreationCode(FILE *fp) const;
+
+ double gap;
+ bool equality;
+ vpsc::Constraint *vpscConstraint;
+};
+
+
+// XXX: This is experimental
+//
+// Orthogonal edges must have their end points aligned horizontally or
+// vertically
+class OrthogonalEdgeConstraint : public CompoundConstraint
+{
+ public:
+ OrthogonalEdgeConstraint(const vpsc::Dim dim, unsigned l, unsigned r);
+
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vs, vpsc::Constraints& cs,
+ vpsc::Rectangles& bbs);
+ void generateTopologyConstraints(const vpsc::Dim k,
+ vpsc::Rectangles const& rs,
+ std::vector<vpsc::Variable*> const& vars,
+ std::vector<vpsc::Constraint*>& cs);
+ void printCreationCode(FILE *fp) const;
+ std::string toString(void) const;
+
+ unsigned left;
+ unsigned right;
+ vpsc::Constraint* vpscConstraint;
+ private:
+ void rectBounds(const vpsc::Dim k, vpsc::Rectangle const *r,
+ double& cmin, double& cmax, double& centre, double& l) const;
+};
+
+
+/**
+ * @brief A multi-separation constraint Specifies a set of horizontal or
+ * vertical equal spacing constraints between pairs of alignment
+ * constraints.
+ *
+ * This is a way of arranging a group of alignment lines to be equally
+ * distributed, or given a uniform minimum spacing.
+ */
+class MultiSeparationConstraint : public CompoundConstraint
+{
+ public:
+ /**
+ * @brief Constructs a new empty MultiSeparationConstraint with a
+ * minimum or exact spacing.
+ *
+ * @param[in] dim The dimension the constraints will operate in.
+ * @param[in] minSep The minimum or exact distance to separate the
+ * alignment constraints.
+ * @param[in] equality Whether or not the constraints will be an exact
+ * distance.
+ */
+ MultiSeparationConstraint(const vpsc::Dim dim, double minSep = 0,
+ bool equality = false);
+ /**
+ * @brief Mark a pair of alignment constraints as being part of this
+ * multi separation constraint.
+ *
+ * You will often specify spacing beteen a set of alignments (e.g.,
+ * {1, 2, 3, 4}) by calling this method with each neighbouring pair
+ * (e.g., {(1, 2), (2, 3), (3, 4)}), but you can also specify
+ * non-neighbouring alignment constraints, if you wish them to have
+ * equal exact or minimum separation.
+ *
+ * @param[in] ac1 A pointer to the left AlignmentConstraint object
+ * of the pair.
+ * @param[in] ac2 A pointer to the right AlignmentConstraint object
+ * of the pair.
+ */
+ void addAlignmentPair(AlignmentConstraint *ac1,
+ AlignmentConstraint *ac2);
+ /**
+ * @brief Alter the minimum or exact spacing between each pair of
+ * alignment constraints.
+ *
+ * @param[in] sep The minimum or exact distance to separate the
+ * alignment constraints.
+ */
+ void setSeparation(double sep);
+
+ /**
+ * @brief Returns a textual description of the compound constraint.
+ *
+ * @return A string describing the compound constraint.
+ */
+ std::string toString(void) const;
+
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vs, vpsc::Constraints& gcs,
+ vpsc::Rectangles& bbs);
+ void printCreationCode(FILE *fp) const;
+
+ vpsc::Constraints cs;
+
+ /// Generic pointer to an indicator object being used to represent
+ /// this compound constraint in the GUI.
+ void *indicator;
+
+ double sep;
+ bool equality;
+};
+
+
+/**
+ * @brief A distribution constraint specifies an ordered set of alignment
+ * constraints and a fixed separation required between them.
+ *
+ * This compound constraint it used to keep a set of alignment constraints
+ * equally distributed.
+ *
+ * If no separation distance is set, then it is detemined from the distance
+ * between the two outer alignments, divided by the number of alignments - 1.
+ */
+class DistributionConstraint : public CompoundConstraint {
+ public:
+ /**
+ * @brief Constructs a new empty DistributionConstraint with a
+ * minimum or exact spacing.
+ *
+ * @param[in] dim The dimension the constraints will operate in.
+ */
+ DistributionConstraint(const vpsc::Dim dim);
+ /**
+ * @brief Mark a pair of alignment constraints as being part of this
+ * distribution constraint.
+ *
+ * You should specify spacing beteen a set of alignments (e.g.,
+ * {1, 2, 3, 4}) by calling this method with each neighbouring pair
+ * (e.g., {(1, 2), (2, 3), (3, 4)}).
+ *
+ * @param[in] ac1 A pointer to the left AlignmentConstraint object
+ * of the pair.
+ * @param[in] ac2 A pointer to the right AlignmentConstraint object
+ * of the pair.
+ */
+ void addAlignmentPair(AlignmentConstraint *ac1,
+ AlignmentConstraint *ac2);
+ /**
+ * @brief Alter the exact spacing between each pair of alignment
+ * constraints.
+ *
+ * @param[in] sep The exact distance to separate the alignment
+ * constraints.
+ */
+ void setSeparation(double sep);
+
+ /**
+ * @brief Returns a textual description of the compound constraint.
+ *
+ * @return A string describing the compound constraint.
+ */
+ std::string toString(void) const;
+
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& gcs,
+ vpsc::Rectangles& bbs);
+ void printCreationCode(FILE *fp) const;
+
+ vpsc::Constraints cs;
+
+ /// Generic pointer to an indicator object being used to represent
+ /// this compound constraint in the GUI.
+ void *indicator;
+
+ double sep;
+};
+
+/**
+ * @brief A fixed-relative constraint specifies that a group of nodes are
+ * constrained to be fixed in position relative to each other.
+ *
+ * These nodes are fixed relative to each other in both the x- and y-dimensions
+ * but still free to move as a group.
+ *
+ * Optionally, this compound constraint can be marked as desiring a fixed
+ * position. If this is specified, the group of nodes will attempt to stay
+ * close to its current position.
+ */
+class FixedRelativeConstraint : public CompoundConstraint {
+ public:
+ /**
+ * @brief Constructs a new FixedRelativeConstraint between a set of
+ * nodes, optionally with a fixed position.
+ *
+ * @param[in] rs The list of bounding boxes for the rectangles
+ * for all nodes in the current problem.
+ * @param[in] shapeIds A vector of indices into the rc vector for the
+ * nodes that will be fixed relative to each other.
+ * @param[in] fixedPosition Whether of not the nodes should ideally be
+ * fixed to the current position. The default
+ * is not fixed.
+ */
+ FixedRelativeConstraint(const vpsc::Rectangles& rs,
+ std::vector<unsigned> shapeIds,
+ const bool fixedPosition = false);
+
+ /**
+ * @brief Returns a textual description of the compound constraint.
+ *
+ * @return A string describing the compound constraint.
+ */
+ std::string toString(void) const;
+
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& gcs,
+ vpsc::Rectangles& bbs);
+ void printCreationCode(FILE *fp) const;
+ void updateVarIDsWithMapping(const VariableIDMap& idMap,
+ bool forward = true);
+
+ private:
+ bool m_fixed_position;
+ std::vector<unsigned> m_shape_vars;
+};
+
+
+/**
+ * @brief A page boundary contraint specifies constraints that attempt to keep
+ * the given nodes within a defined rectangular region.
+ *
+ * This compound constraint creates dummy variables for each of the four edges
+ * of the page and constraints between all nodes and these dummy vars such
+ * that nodes are contained between the edges. The variables for the page
+ * edges have a high weight but will "balloon out" if other constraints force
+ * nodes to stick out past the ideal edge positions.
+ */
+class PageBoundaryConstraints : public CompoundConstraint {
+ public:
+ /**
+ * @brief Constructs a new PageBoundaryConstraints object with given
+ * page boundary positions and weight.
+ *
+ * @param[in] xLow The position of the left edge of the page.
+ * @param[in] xHigh The position of the right edge of the page.
+ * @param[in] yLow The position of the bottom edge of the page.
+ * @param[in] yHigh The position of the top edge of the page.
+ * @param[in] weight The weight to give the positions variables
+ * for the page edges. The default is 100.0.
+ */
+ PageBoundaryConstraints(double xLow, double xHigh,
+ double yLow, double yHigh, double weight = 100.0);
+ /**
+ * @brief Mark a node as being contained within this page boundary.
+ *
+ * @param[in] index The index of the node in the Rectangles vector.
+ * @param[in] halfW Half of the width of the node. Needed because
+ * node position variables represent their centre.
+ * @param[in] halfH Half of the height of the node.
+ */
+ void addShape(unsigned index, double halfW, double halfH);
+
+ /**
+ * @brief Returns a textual description of the compound constraint.
+ *
+ * @return A string describing the compound constraint.
+ */
+ std::string toString(void) const;
+
+ SubConstraintAlternatives getCurrSubConstraintAlternatives(
+ vpsc::Variables vs[]);
+ void generateVariables(const vpsc::Dim dim, vpsc::Variables& vars);
+ void generateSeparationConstraints(const vpsc::Dim dim,
+ vpsc::Variables& vars, vpsc::Constraints& gcs,
+ vpsc::Rectangles& bbs);
+ void updatePosition(const vpsc::Dim dim);
+ double getActualLeftMargin(const vpsc::Dim dim);
+ double getActualRightMargin(const vpsc::Dim dim);
+ void printCreationCode(FILE *fp) const;
+
+ private:
+ double leftMargin[2];
+ double rightMargin[2];
+ double actualLeftMargin[2];
+ double actualRightMargin[2];
+ double leftWeight[2];
+ double rightWeight[2];
+ vpsc::Variable *vl[2], *vr[2];
+};
+
+
+/**
+ * @brief Info about constraints that could not be satisfied in gradient
+ * projection process.
+ */
+class UnsatisfiableConstraintInfo {
+ public:
+ UnsatisfiableConstraintInfo(const vpsc::Constraint* c);
+
+ //! The index of the left variable.
+ unsigned leftVarIndex;
+ //! The index of the right variable.
+ unsigned rightVarIndex;
+ //! The separation.
+ double separation;
+ //! Whether the separation is an exact distance or not.
+ bool equality;
+ //! The index of the CompoundConstraint that created this.
+ cola::CompoundConstraint *cc;
+
+ std::string toString(void) const
+ {
+ std::stringstream stream;
+ stream << "Unsatisfiable constraint: var(" << leftVarIndex << ") ";
+ if (separation < 0)
+ {
+ stream << "- " << -separation;
+ }
+ else
+ {
+ stream << "+ " << separation;
+ }
+ stream << " " << ((equality) ? "== " : "<= ");
+ stream << "var(" << rightVarIndex << ")";
+ if (cc)
+ {
+ stream << "\n From " << cc->toString();
+ }
+
+ return stream.str();
+ }
+};
+//! @brief A vector of pointers to UnsatisfiableConstraintInfo objects.
+typedef std::vector<UnsatisfiableConstraintInfo *> UnsatisfiableConstraintInfos;
+
+} // namespace cola
+#endif // _COMPOUND_CONSTRAINTS_H
diff --git a/src/3rdparty/adaptagrams/libcola/conjugate_gradient.cpp b/src/3rdparty/adaptagrams/libcola/conjugate_gradient.cpp
new file mode 100644
index 0000000..adb7fa6
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/conjugate_gradient.cpp
@@ -0,0 +1,137 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006 Nathan Hurst <njh@njhurst.com>
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Nathan Hurst
+ * Tim Dwyer
+ *
+*/
+
+
+#include <cmath>
+#include <cstdlib>
+#include <cassert>
+#include <valarray>
+
+#include "libvpsc/assertions.h"
+#include "libcola/commondefs.h"
+#include "libcola/conjugate_gradient.h"
+
+/* lifted wholely from wikipedia. Well, apart from the bug in the wikipedia version. */
+
+using std::valarray;
+
+static void
+matrix_times_vector(valarray<double> const &matrix, /* m * n */
+ valarray<double> const &vec, /* n */
+ valarray<double> &result) /* m */
+{
+ unsigned n = vec.size();
+ unsigned m = result.size();
+ COLA_ASSERT(m*n == matrix.size());
+# if defined(_MSC_VER)
+ // magmy: The following lines show how operator[] is defined for valarray under MSVC
+ // _Ty valarray<_Ty>::operator[](size_t _Off) const;
+ // _Ty &valarray<_Ty>::operator[](size_t _Off);
+ // As a consequence, it is not possible to take the address of a constant valarray[n].
+ // This looks like a bug in the Microsoft's <valarray> file.
+ // Below is a workaround
+ double const *mp = &const_cast<valarray<double> &>(matrix)[0];
+# else
+ const double* mp = &matrix[0];
+# endif
+ for (unsigned i = 0; i < m; i++) {
+ double res = 0;
+ for (unsigned j = 0; j < n; j++)
+ res += *mp++ * vec[j];
+ result[i] = res;
+ }
+}
+
+/*
+static double Linfty(valarray<double> const &vec) {
+ return std::max(vec.max(), -vec.min());
+}
+*/
+
+double
+inner(valarray<double> const &x,
+ valarray<double> const &y) {
+ double total = 0;
+ for(unsigned i = 0; i < x.size(); i++)
+ total += x[i]*y[i];
+ return total;// (x*y).sum(); <- this is more concise, but ineff
+}
+
+double compute_cost(valarray<double> const &A,
+ valarray<double> const &b,
+ valarray<double> const &x,
+ const unsigned n) {
+ // computes cost = 2 b x - x A x
+ double cost = 2. * inner(b,x);
+ valarray<double> Ax(n);
+ for (unsigned i=0; i<n; i++) {
+ Ax[i] = 0;
+ for (unsigned j=0; j<n; j++) {
+ Ax[i] += A[i*n+j]*x[j];
+ }
+ }
+ return cost - inner(x,Ax);
+}
+void
+conjugate_gradient(valarray<double> const &A,
+ valarray<double> &x,
+ valarray<double> const &b,
+ unsigned const n, double const tol,
+ unsigned const max_iterations) {
+ //printf("Conjugate Gradient...\n");
+ valarray<double> Ap(n), p(n), r(n);
+ matrix_times_vector(A,x,Ap);
+ r=b-Ap;
+ double r_r = inner(r,r);
+ unsigned k = 0;
+ double tol_squared = tol*tol;
+#ifdef EXAMINE_COST
+ double previousCost=compute_cost(A,b,x,n),cost;
+#endif
+ while(k < max_iterations && r_r > tol_squared) {
+ k++;
+ double r_r_new = r_r;
+ if(k == 1)
+ p = r;
+ else {
+ r_r_new = inner(r,r);
+ if(r_r_new<tol_squared) break;
+ p = r + (r_r_new/r_r)*p;
+ }
+ matrix_times_vector(A, p, Ap);
+ double alpha_k = r_r_new / inner(p, Ap);
+ x += alpha_k*p;
+#ifdef EXAMINE_COST
+ cost=compute_cost(A,b,x,n);
+ printf(" CG[%d] %.15f %.15f\n",k,previousCost,cost);
+ previousCost=cost;
+#endif
+ r -= alpha_k*Ap;
+ r_r = r_r_new;
+ }
+ //printf(" CG finished after %d iterations\n",k);
+ //printf("njh: %d iters, Linfty = %g L2 = %g\n", k,
+ //std::max(-r.min(), r.max()), sqrt(r_r));
+ // x is solution
+}
diff --git a/src/3rdparty/adaptagrams/libcola/conjugate_gradient.h b/src/3rdparty/adaptagrams/libcola/conjugate_gradient.h
new file mode 100644
index 0000000..e21cd16
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/conjugate_gradient.h
@@ -0,0 +1,36 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef _CONJUGATE_GRADIENT_H
+#define _CONJUGATE_GRADIENT_H
+
+#include <valarray>
+
+double
+inner(std::valarray<double> const &x,
+ std::valarray<double> const &y);
+
+void
+conjugate_gradient(std::valarray<double> const &A,
+ std::valarray<double> &x,
+ std::valarray<double> const &b,
+ unsigned const n, double const tol,
+ unsigned const max_iterations);
+#endif // _CONJUGATE_GRADIENT_H
diff --git a/src/3rdparty/adaptagrams/libcola/connected_components.cpp b/src/3rdparty/adaptagrams/libcola/connected_components.cpp
new file mode 100644
index 0000000..fc65dc9
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/connected_components.cpp
@@ -0,0 +1,160 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+
+#include <map>
+#include <list>
+
+#include "libvpsc/rectangle.h"
+#include "libvpsc/assertions.h"
+#include "libcola/commondefs.h"
+#include "libcola/connected_components.h"
+
+using namespace std;
+using namespace vpsc;
+namespace cola {
+ Component::~Component() {
+ /*
+ for(unsigned i=0;i<scx.size();i++) {
+ delete scx[i];
+ }
+ for(unsigned i=0;i<scy.size();i++) {
+ delete scy[i];
+ }
+ */
+ }
+ void Component::moveRectangles(double x, double y) {
+ for(unsigned i=0;i<rects.size();i++) {
+ rects[i]->moveCentreX(rects[i]->getCentreX()+x);
+ rects[i]->moveCentreY(rects[i]->getCentreY()+y);
+ }
+ }
+ Rectangle* Component::getBoundingBox()
+ {
+ Rectangle boundingBox;
+ for (unsigned i = 0; i < rects.size(); ++i)
+ {
+ boundingBox = boundingBox.unionWith(*(rects[i]));
+ }
+ return new Rectangle(boundingBox);
+ }
+
+ namespace ccomponents {
+ struct Node {
+ unsigned id;
+ bool visited;
+ vector<Node*> neighbours;
+ list<Node*>::iterator listPos;
+ Rectangle* r;
+ };
+ // Depth first search traversal of graph to find connected component
+ void dfs(Node* v,
+ list<Node*>& remaining,
+ Component* component,
+ map<unsigned,pair<Component*,unsigned> > &cmap) {
+ v->visited=true;
+ remaining.erase(v->listPos);
+ cmap[v->id]=make_pair(component,static_cast<unsigned>(component->node_ids.size()));
+ component->node_ids.push_back(v->id);
+ component->rects.push_back(v->r);
+ for(unsigned i=0;i<v->neighbours.size();i++) {
+ Node* u=v->neighbours[i];
+ if(!u->visited) {
+ dfs(u,remaining,component,cmap);
+ }
+ }
+ }
+ }
+
+ using namespace ccomponents;
+
+ // for a graph of n nodes, return connected components
+ void connectedComponents(
+ const vector<Rectangle*> &rs,
+ const vector<Edge> &es,
+ //const SeparationConstraints &scx,
+ //const SeparationConstraints &scy,
+ vector<Component*> &components) {
+ unsigned n=rs.size();
+ vector<Node> vs(n);
+ list<Node*> remaining;
+ for(unsigned i=0;i<n;i++) {
+ vs[i].id=i;
+ vs[i].visited=false;
+ vs[i].r=rs[i];
+ vs[i].listPos = remaining.insert(remaining.end(),&vs[i]);
+ }
+ vector<Edge>::const_iterator ei;
+ for(ei=es.begin();ei!=es.end();ei++) {
+ vs[ei->first].neighbours.push_back(&vs[ei->second]);
+ vs[ei->second].neighbours.push_back(&vs[ei->first]);
+ }
+ map<unsigned,pair<Component*,unsigned> > cmap;
+ while(!remaining.empty()) {
+ Component* component=new Component;
+ Node* v=*remaining.begin();
+ dfs(v,remaining,component,cmap);
+ components.push_back(component);
+ }
+ for(ei=es.begin();ei!=es.end();ei++) {
+ pair<Component*,unsigned> u=cmap[ei->first],
+ v=cmap[ei->second];
+ COLA_ASSERT(u.first==v.first);
+ u.first->edges.push_back(make_pair(u.second,v.second));
+ }
+ /*
+ SeparationConstraints::const_iterator ci;
+ for(ci=scx.begin();ci!=scx.end();ci++) {
+ SeparationConstraint *c=*ci;
+ pair<Component*,unsigned> u=cmap[c->left],
+ v=cmap[c->right];
+ COLA_ASSERT(u.first==v.first);
+ u.first->scx.push_back(
+ new SeparationConstraint(u.second,v.second,c->gap));
+ }
+ for(ci=scy.begin();ci!=scy.end();ci++) {
+ SeparationConstraint *c=*ci;
+ pair<Component*,unsigned> u=cmap[c->left],
+ v=cmap[c->right];
+ COLA_ASSERT(u.first==v.first);
+ u.first->scy.push_back(
+ new SeparationConstraint(u.second,v.second,c->gap));
+ }
+ */
+ }
+ void separateComponents(const vector<Component*> &components) {
+ unsigned n=components.size();
+ vector<Rectangle*> bbs(n);
+ valarray<double> origX(n);
+ valarray<double> origY(n);
+ for(unsigned i=0;i<n;i++) {
+ bbs[i]=components[i]->getBoundingBox();
+ origX[i]=bbs[i]->getCentreX();
+ origY[i]=bbs[i]->getCentreY();
+ }
+ removeoverlaps(bbs);
+ for(unsigned i=0;i<n;i++) {
+ components[i]->moveRectangles(
+ bbs[i]->getCentreX()-origX[i],
+ bbs[i]->getCentreY()-origY[i]);
+ delete bbs[i];
+ }
+ }
+}
diff --git a/src/3rdparty/adaptagrams/libcola/connected_components.h b/src/3rdparty/adaptagrams/libcola/connected_components.h
new file mode 100644
index 0000000..578eab2
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/connected_components.h
@@ -0,0 +1,54 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef CONNECTED_COMPONENTS_H
+#define CONNECTED_COMPONENTS_H
+#include "libcola/cola.h"
+#include <vector>
+
+namespace cola {
+// a graph component with a list of node_ids giving indices for some larger list of nodes
+// for the nodes in this component,
+// and a list of edges - node indices relative to this component
+class Component {
+public:
+ std::vector<unsigned> node_ids;
+ std::vector<vpsc::Rectangle*> rects;
+ std::vector<cola::Edge> edges;
+ //CompoundConstraints cx, cy;
+ ~Component();
+ void moveRectangles(double x, double y);
+ vpsc::Rectangle* getBoundingBox();
+};
+// for a graph of n nodes, return connected components
+void connectedComponents(
+ const std::vector<vpsc::Rectangle*> &rs,
+ const std::vector<cola::Edge> &es,
+ //const CompoundConstraints &cx,
+ //const CompoundConstraints &cy,
+ std::vector<Component*> &components);
+
+// move the contents of each component so that the components do not
+// overlap.
+void separateComponents(const std::vector<Component*> &components);
+
+} // namespace cola
+
+#endif // CONNECTED_COMPONENTS_H
diff --git a/src/3rdparty/adaptagrams/libcola/convex_hull.cpp b/src/3rdparty/adaptagrams/libcola/convex_hull.cpp
new file mode 100644
index 0000000..3ecbfea
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/convex_hull.cpp
@@ -0,0 +1,129 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#include <valarray>
+#include <cfloat>
+#include <algorithm>
+
+#include "libvpsc/assertions.h"
+#include "libcola/convex_hull.h"
+
+
+namespace hull {
+using namespace std;
+/**
+ * CrossProduct of three points: If the result is 0, the points are collinear;
+ * if it is positive, the three points (in order) constitute a "left turn",
+ * otherwise a "right turn".
+ */
+inline double crossProduct(
+ double x0, double y0,
+ double x1, double y1,
+ double x2, double y2) {
+ return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
+}
+struct CounterClockwiseOrder {
+ CounterClockwiseOrder(
+ const unsigned p,
+ std::valarray<double> const & X, std::valarray<double> const & Y)
+ :px(X[p]), py(Y[p]), X(X), Y(Y) {};
+ bool operator() (unsigned i, unsigned j) {
+ // o=crossProduct(px,py,X[i],Y[i],X[j],Y[j]);
+ double xi=X[i]-px;
+ double xj=X[j]-px;
+ // since py is the min y pos, yi and yj must be positive
+ double yi=Y[i]-py;
+ double yj=Y[j]-py;
+
+ // use cross product rule
+ double o = xi*yj-xj*yi;
+ if(o!=0) {
+ return o>0;
+ }
+ // in case of ties choose point farthest from p
+ return (xi*xi+yi*yi) < (xj*xj+yj*yj);
+ }
+ const double px;
+ const double py;
+ std::valarray<double> const & X;
+ std::valarray<double> const & Y;
+};
+void convex(const unsigned n, const double* X, const double* Y, vector<unsigned> & h) {
+ const valarray<double> XA(X,n);
+ const valarray<double> YA(Y,n);
+ convex(XA,YA,h);
+}
+/**
+ * Implementation of Graham's scan convex hull finding algorithm.
+ * X and Y give the horizontal and vertical positions of the pointset.
+ * The result is returned in hull as a list of indices referencing points in X and Y.
+ */
+void convex(valarray<double> const & X, valarray<double> const & Y, vector<unsigned> & h) {
+ unsigned n=X.size();
+ COLA_ASSERT(n==Y.size());
+ unsigned p0=0;
+ // find point p0 with min Y position, choose leftmost in case of tie.
+ // This is our "pivot" point
+ double minY=DBL_MAX,minX=DBL_MAX;
+ for(unsigned i=0;i<n;i++) {
+ if ( (Y[i] < minY) || ((Y[i] == minY) && (X[i] < minX)) )
+ {
+ p0=i;
+ minY=Y[i];
+ minX=X[i];
+ }
+ }
+ // sort remaining points by the angle line p0-p1 (p1 in points) makes
+ // with x-axis
+ vector<unsigned> points;
+ for(unsigned i=0;i<n;i++) {
+ if(i!=p0) points.push_back(i);
+ }
+ CounterClockwiseOrder order(p0,X,Y);
+ sort(points.begin(),points.end(),order);
+ // now we maintain a stack in h, adding points while each successive
+ // point is a "left turn", backtracking if we make a right turn.
+ h.clear();
+ h.push_back(p0);
+ h.push_back(points[0]);
+ for(unsigned i=1;i<points.size();i++) {
+ double o=crossProduct(
+ X[h[h.size()-2]],Y[h[h.size()-2]],
+ X[h[h.size()-1]],Y[h[h.size()-1]],
+ X[points[i]],Y[points[i]]);
+ if(o==0) {
+ h.pop_back();
+ h.push_back(points[i]);
+ } else if(o>0) {
+ h.push_back(points[i]);
+ } else {
+ while(o<=0 && h.size()>2) {
+ h.pop_back();
+ o=crossProduct(
+ X[h[h.size()-2]],Y[h[h.size()-2]],
+ X[h[h.size()-1]],Y[h[h.size()-1]],
+ X[points[i]],Y[points[i]]);
+ }
+ h.push_back(points[i]);
+ }
+ }
+}
+
+} // namespace hull
diff --git a/src/3rdparty/adaptagrams/libcola/convex_hull.h b/src/3rdparty/adaptagrams/libcola/convex_hull.h
new file mode 100644
index 0000000..e17c6a8
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/convex_hull.h
@@ -0,0 +1,31 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef CONVEX_HULL_H
+#define CONVEX_HULL_H
+#include <vector>
+#include <valarray>
+
+namespace hull {
+void convex(const unsigned n, const double* X, const double* Y, std::vector<unsigned> & hull);
+void convex(const std::valarray<double> & X, const std::valarray<double> & Y, std::vector<unsigned> & hull);
+}
+
+#endif // CONVEX_HULL_H
diff --git a/src/3rdparty/adaptagrams/libcola/doc/description.doc b/src/3rdparty/adaptagrams/libcola/doc/description.doc
new file mode 100644
index 0000000..cf8cdda
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/doc/description.doc
@@ -0,0 +1,50 @@
+/*!
+
+\if LIBCOLA_DOC
+@mainpage libcola: Force-directed Network Layout ubject to Separation Constraints
+\endif
+\if ADAPTAGRAMS_DOC
+@page libcola libcola &mdash; Overview
+\endif
+
+libcola is a cross-platform C++ library for constraint graph layout. Specifically, force-directed layout using the stress-majorization method subject to separation constraints. Applications include layout with non-overlapping nodes and clusters, directed graph layout and layout preserving the crossing properties of a given starting layout.
+
+libcola is part of the
+<a href="http://www.adaptagrams.org/">Adaptagrams project</a>.
+There are no official releases yet, though the code is stable and
+available from the Adaptagrams
+<a href="https://github.com/mjwybrow/adaptagrams">GitHub
+repository</a>.
+
+The API is documented using Doxygen. The documentation you are currently
+reading can be obtained by running doxygen in the cola directory.
+
+libcola is written and maintained by
+<a href="http://users.monash.edu/~mwybrow/">Michael Wybrow</a> and
+<a href="http://ialab.it.monash.edu/~dwyer/">Tim Dwyer</a>,
+members of <a href="http://ialab.it.monash.edu/">Immersive Analytics Lab</a> at Monash University, Australia.
+
+The algorithms used for ConstrainedFDLayout are described in the following papers. If you use libcola, please cite the relevant paper.
+- Tim Dwyer, Kim Marriott, and Michael Wybrow. Topology preserving
+ constrained graph layout. In Proc. 16th Intl. Symp. Graph Drawing
+ (GD'08), volume 5417 of Lecture Notes in Computer Science, pages
+ 230-241. Springer, 2009.
+- Tim Dwyer, Kim Marriott, and Michael Wybrow. Dunnart: A
+ constraint-based network diagram authoring tool. In Proc. 16th Intl.
+ Symp. Graph Drawing (GD'08), volume 5417 of Lecture Notes in Computer
+ Science, pages 420-431. Springer, 2009.
+- Tim Dwyer, Kim Marriott, Falk Schreiber, Peter J. Stuckey,
+ Michael Woodward, and Michael Wybrow. Exploration of networks using
+ overview+detail with constraint-based cooperative layout. IEEE
+ Transactions on Visualization and Computer Graphics, 14(6):1293-1300,
+ 2008.
+
+The method used in ConstrainedMajorizationLayout is described in:
+- Tim Dwyer and Kim Marriott. Constrained stress majorization using diagonally
+ scaled gradient projection. In Proc. 15th Intl. Symp. Graph Drawing (GD
+ '07), volume 4875 of Lecture Notes in Computer Science. Springer, 2008.
+
+
+*/
+
+
diff --git a/src/3rdparty/adaptagrams/libcola/exceptions.h b/src/3rdparty/adaptagrams/libcola/exceptions.h
new file mode 100644
index 0000000..516e69e
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/exceptions.h
@@ -0,0 +1,54 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef SEEN_LIBCOLA_EXCEPTIONS_H
+#define SEEN_LIBCOLA_EXCEPTIONS_H
+#include <string>
+#include <sstream>
+
+namespace cola {
+class CompoundConstraint;
+
+struct InvalidConstraint {
+ InvalidConstraint(CompoundConstraint *c):constraint(c) {}
+ CompoundConstraint *constraint;
+};
+
+
+class InvalidVariableIndexException
+{
+public:
+ InvalidVariableIndexException(CompoundConstraint *c, unsigned i)
+ : constraint(c),
+ index(i)
+ { }
+ std::string what() const throw()
+ {
+ std::stringstream s;
+ s << "Invalid variable index: " << index;
+ return s.str();
+ }
+ CompoundConstraint *constraint;
+ unsigned index;
+};
+
+
+} // namespace cola
+#endif //SEEN_LIBCOLA_EXCEPTIONS_H
diff --git a/src/3rdparty/adaptagrams/libcola/gradient_projection.cpp b/src/3rdparty/adaptagrams/libcola/gradient_projection.cpp
new file mode 100644
index 0000000..b53e876
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/gradient_projection.cpp
@@ -0,0 +1,482 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+/**********************************************************
+ *
+ * Solve a quadratic function f(X) = X' A X + b X
+ * subject to a set of separation constraints cs
+ *
+ **********************************************************/
+
+#include <iostream>
+#include <cmath>
+#include <ctime>
+
+#include <libvpsc/solve_VPSC.h>
+#include <libvpsc/variable.h>
+#include <libvpsc/constraint.h>
+#include <libvpsc/assertions.h>
+
+#include "libcola/cluster.h"
+#include "libcola/gradient_projection.h"
+#include "libcola/straightener.h"
+#include "libcola/commondefs.h"
+//#define CHECK_CONVERGENCE_BY_COST 1
+
+
+using namespace std;
+using namespace vpsc;
+namespace cola {
+GradientProjection::GradientProjection(
+ const Dim k,
+ std::valarray<double> *denseQ,
+ const double tol,
+ const unsigned max_iterations,
+ CompoundConstraints const *ccs,
+ UnsatisfiableConstraintInfos *unsatisfiableConstraints,
+ NonOverlapConstraintsMode nonOverlapConstraints,
+ RootCluster* clusterHierarchy,
+ vpsc::Rectangles* rs,
+ const bool scaling,
+ SolveWithMosek solveWithMosek)
+ : k(k),
+ denseSize(static_cast<unsigned>((floor(sqrt(static_cast<double>(denseQ->size())))))),
+ denseQ(denseQ),
+ rs(rs),
+ ccs(ccs),
+ unsatisfiableConstraints(unsatisfiableConstraints),
+ nonOverlapConstraints(nonOverlapConstraints),
+ clusterHierarchy(clusterHierarchy),
+ tolerance(tol),
+ max_iterations(max_iterations),
+ sparseQ(nullptr),
+ solveWithMosek(solveWithMosek),
+ scaling(scaling)
+{
+ //printf("GP Instance: scaling=%d, mosek=%d\n",scaling,solveWithMosek);
+ for(unsigned i=0;i<denseSize;i++) {
+ vars.push_back(new vpsc::Variable(i,1,1));
+ }
+ if(scaling) {
+ scaledDenseQ.resize(denseSize*denseSize);
+ for(unsigned i=0;i<denseSize;i++) {
+ vars[i]->scale=1./sqrt(fabs((*denseQ)[i*denseSize+i]));
+ // XXX: Scale can sometimes be set to infinity here when
+ // there are nodes not connected to any other node.
+ // Thus we just set the scale for such a variable to 1.
+ if (!std::isfinite(vars[i]->scale))
+ {
+ vars[i]->scale = 1;
+ }
+ }
+ // the following computes S'QS for Q=denseQ
+ // and S is diagonal matrix of scale factors
+ for(unsigned i=0;i<denseSize;i++) {
+ for(unsigned j=0;j<denseSize;j++) {
+ scaledDenseQ[i*denseSize+j]=(*denseQ)[i*denseSize+j]*vars[i]->scale
+ *vars[j]->scale;
+ }
+ }
+ this->denseQ = &scaledDenseQ;
+ }
+ //dumpSquareMatrix(*this->denseQ);
+ //dumpSquareMatrix(scaledDenseQ);
+
+ if(ccs) {
+ for(CompoundConstraints::const_iterator c=ccs->begin();
+ c!=ccs->end();++c) {
+ (*c)->generateVariables(k, vars);
+ OrthogonalEdgeConstraint* e=dynamic_cast<OrthogonalEdgeConstraint*>(*c);
+ if(e) {
+ orthogonalEdges.push_back(e);
+ }
+ }
+ for(CompoundConstraints::const_iterator c=ccs->begin();
+ c!=ccs->end();++c) {
+ (*c)->generateSeparationConstraints(k, vars, gcs, *rs);
+ }
+ }
+ /*
+ if(clusterHierarchy) {
+ clusterHierarchy->createVars(k,*rs,vars);
+ }
+ */
+ numStaticVars=vars.size();
+ //solver=setupVPSC();
+}
+static inline double dotProd(valarray<double> const & a, valarray<double> const & b) {
+ double p = 0;
+ for (unsigned i=0; i<a.size(); i++) {
+ p += a[i]*b[i];
+ }
+ return p;
+}
+double GradientProjection::computeCost(
+ valarray<double> const &b,
+ valarray<double> const &x) const {
+ // computes cost = 2 b x - x A x
+ double cost = 2. * dotProd(b,x);
+ valarray<double> Ax(x.size());
+ for (unsigned i=0; i<denseSize; i++) {
+ Ax[i] = 0;
+ for (unsigned j=0; j<denseSize; j++) {
+ Ax[i] += (*denseQ)[i*denseSize+j]*x[j];
+ }
+ }
+ if(sparseQ) {
+ valarray<double> r(x.size());
+ sparseQ->rightMultiply(x,r);
+ Ax+=r;
+ }
+ return cost - dotProd(x,Ax);
+}
+
+double GradientProjection::computeSteepestDescentVector(
+ valarray<double> const &b,
+ valarray<double> const &x,
+ valarray<double> &g) const {
+ // find steepest descent direction
+ // g = 2 ( b - A x )
+ // where: A = denseQ + sparseQ
+ // g = 2 ( b - denseQ x) - 2 sparseQ x
+ //
+ // except the 2s don't matter because we compute
+ // the optimal stepsize anyway
+ COLA_ASSERT(x.size()==b.size() && b.size()==g.size());
+ g = b;
+ for (unsigned i=0; i<denseSize; i++) {
+ for (unsigned j=0; j<denseSize; j++) {
+ g[i] -= (*denseQ)[i*denseSize+j]*x[j];
+ }
+ }
+ // sparse part:
+ if(sparseQ) {
+ valarray<double> r(x.size());
+ sparseQ->rightMultiply(x,r);
+ g-=r;
+ }
+ return computeStepSize(g,g);
+}
+// compute optimal step size along descent vector d relative to
+// a gradient related vector g
+// stepsize = ( g' d ) / ( d' A d )
+double GradientProjection::computeStepSize(
+ valarray<double> const & g, valarray<double> const & d) const {
+ COLA_ASSERT(g.size()==d.size());
+ valarray<double> Ad;
+ if(sparseQ) {
+ Ad.resize(g.size());
+ sparseQ->rightMultiply(d,Ad);
+ }
+ double const numerator = dotProd(g, d);
+ double denominator = 0;
+ for (unsigned i=0; i<g.size(); i++) {
+ double r = sparseQ ? Ad[i] : 0;
+ if(i<denseSize) { for (unsigned j=0; j<denseSize; j++) {
+ r += (*denseQ)[i*denseSize+j] * d[j];
+ } }
+ denominator += r * d[i];
+ }
+ if(denominator==0) {
+ return 0;
+ }
+ return numerator/(2.*denominator);
+}
+
+bool GradientProjection::runSolver(valarray<double> & result) {
+ bool activeConstraints = false;
+ switch(solveWithMosek) {
+ case Off:
+ activeConstraints = solver->satisfy();
+ for (unsigned i=0;i<vars.size();i++) {
+ result[i]=vars[i]->finalPosition;
+ }
+ break;
+ case Inner:
+#ifdef MOSEK_AVAILABLE
+ float *ba=new float[vars.size()];
+ float *coords=new float[vars.size()];
+ for(unsigned i=0;i<vars.size();i++) {
+ ba[i]=vars[i]->desiredPosition;
+ }
+ mosek_quad_solve_sep(menv,ba,coords);
+ for(unsigned i=0;i<vars.size();i++) {
+ //printf("x[%d]=%f\n",i,coords[i]);
+ result[i]=coords[i];
+ }
+ delete [] ba;
+ delete [] coords;
+ break;
+#endif
+ default:
+ break;
+ }
+ return activeConstraints;
+}
+
+/*
+ * Use gradient-projection to solve an instance of
+ * the Variable Placement with Separation Constraints problem.
+ */
+unsigned GradientProjection::solve(
+ valarray<double> const &linearCoefficients,
+ valarray<double> &x) {
+ COLA_ASSERT(linearCoefficients.size()==x.size());
+ COLA_ASSERT(x.size()==denseSize);
+ COLA_ASSERT(numStaticVars>=denseSize);
+ COLA_ASSERT(sparseQ==nullptr ||
+ (sparseQ!=nullptr && (vars.size()==sparseQ->rowSize())) );
+
+ if(max_iterations==0) return 0;
+
+ bool converged=false;
+
+ solver = setupVPSC();
+#ifdef MOSEK_AVAILABLE
+ if(solveWithMosek==Outer) {
+ float* ba=new float[vars.size()];
+ float* xa=new float[vars.size()];
+ for(unsigned i=0;i<vars.size();i++) {
+ ba[i]=-linearCoefficients[i];
+ }
+ mosek_quad_solve_sep(menv,ba,xa);
+ for(unsigned i=0;i<vars.size();i++) {
+ //printf("mosek result x[%d]=%f\n",i,xa[i]);
+ x[i]=xa[i];
+ }
+ delete [] ba;
+ delete [] xa;
+ return 1;
+ }
+#endif
+ // it may be that we have to consider dummy vars, which the caller didn't know
+ // about. Thus vars.size() may not equal x.size()
+ unsigned n = vars.size();
+ valarray<double> b(n);
+ result.resize(n);
+
+ // load desired positions into vars, note that we keep desired positions
+ // already calculated for dummy vars
+ for (unsigned i=0;i<x.size();i++) {
+ COLA_ASSERT(!std::isnan(x[i]));
+ COLA_ASSERT(std::isfinite(x[i]));
+ b[i]=i<linearCoefficients.size()?linearCoefficients[i]:0;
+ result[i]=x[i];
+ if(scaling) {
+ b[i]*=vars[i]->scale;
+ result[i]/=vars[i]->scale;
+ }
+ if(!vars[i]->fixedDesiredPosition) vars[i]->desiredPosition=result[i];
+ }
+ runSolver(result);
+
+ valarray<double> g(n); /* gradient */
+ valarray<double> previous(n); /* stored positions */
+ valarray<double> d(n); /* actual descent vector */
+
+#ifdef CHECK_CONVERGENCE_BY_COST
+ double previousCost = DBL_MAX;
+#endif
+ unsigned counter=0;
+ double stepSize;
+ for (; counter<max_iterations&&!converged; counter++) {
+ previous=result;
+ stepSize=0;
+ double alpha=computeSteepestDescentVector(b,result,g);
+
+ //printf("Iteration[%d]\n",counter);
+ // move to new unconstrained position
+ for (unsigned i=0; i<n; i++) {
+ // dividing by variable weight is a cheap trick to make these
+ // weights mean something in terms of the descent vector
+ double step=alpha*g[i]/vars[i]->weight;
+ result[i]+=step;
+ //printf(" after unconstrained step: x[%d]=%f\n",i,result[i]);
+ stepSize+=step*step;
+ COLA_ASSERT(!std::isnan(result[i]));
+ COLA_ASSERT(std::isfinite(result[i]));
+ if(!vars[i]->fixedDesiredPosition) vars[i]->desiredPosition=result[i];
+ }
+
+ //project to constraint boundary
+ bool constrainedOptimum = false;
+ constrainedOptimum=runSolver(result);
+ stepSize=0;
+ for (unsigned i=0;i<n;i++) {
+ double step = previous[i]-result[i];
+ stepSize+=step*step;
+ }
+ //constrainedOptimum=false;
+ // beta seems, more often than not, to be >1!
+ if(constrainedOptimum) {
+ // The following step limits the step-size in the feasible
+ // direction
+ d = result - previous;
+ const double beta = 0.5*computeStepSize(g, d);
+ // beta > 1.0 takes us back outside the feasible region
+ // beta < 0 clearly not useful and may happen due to numerical imp.
+ //printf("beta=%f\n",beta);
+ if(beta>0&&beta<0.99999) {
+ stepSize=0;
+ for (unsigned i=0; i<n; i++) {
+ double step=beta*d[i];
+ result[i]=previous[i]+step;
+ stepSize+=step*step;
+ }
+ }
+ }
+#ifdef CHECK_CONVERGENCE_BY_COST
+ /* This would be the slow way to detect convergence */
+ //if(counter%2) {
+ double cost = computeCost(b,result);
+ printf(" gp[%d] %.15f %.15f\n",counter,previousCost,cost);
+ //COLA_ASSERT(previousCost>cost);
+ if(fabs(previousCost - cost) < tolerance) {
+ converged = true;
+ }
+ previousCost = cost;
+ //}
+#else
+ if(stepSize<tolerance) converged = true;
+#endif
+ }
+ //printf("GP[%d] converged after %d iterations.\n",k,counter);
+ for(unsigned i=0;i<x.size();i++) {
+ x[i]=result[i];
+ if(scaling) {
+ x[i]*=vars[i]->scale;
+ }
+ }
+ destroyVPSC(solver);
+ return counter;
+}
+// Setup an instance of the Variable Placement with Separation Constraints
+// for one iteration.
+// Generate transient local constraints --- such as non-overlap constraints
+// --- that are only relevant to one iteration, and merge these with the
+// global constraint list (including alignment constraints,
+// dir-edge constraints, containment constraints, etc).
+IncSolver* GradientProjection::setupVPSC() {
+ if(nonOverlapConstraints!=None) {
+ if(clusterHierarchy) {
+ //printf("Setup up cluster constraints, dim=%d--------------\n",k);
+ //clusterHierarchy->generateNonOverlapConstraints(k,nonOverlapConstraints,*rs,vars,lcs);
+ } else {
+ for(vector<OrthogonalEdgeConstraint*>::iterator i=orthogonalEdges.begin();i!=orthogonalEdges.end();i++) {
+ OrthogonalEdgeConstraint* e=*i;
+ e->generateTopologyConstraints(k,*rs,vars,lcs);
+ }
+ if(k==HORIZONTAL) {
+ // Make rectangles a little bit wider when processing horizontally so that any overlap
+ // resolved horizontally is strictly non-overlapping when processing vertically
+ Rectangle::setXBorder(0.0001);
+ // use rs->size() rather than n because some of the variables may
+ // be dummy vars with no corresponding rectangle
+ generateXConstraints(*rs,vars,lcs,nonOverlapConstraints==Both?true:false);
+ Rectangle::setXBorder(0);
+ } else {
+ generateYConstraints(*rs,vars,lcs);
+ }
+ }
+ }
+ cs=gcs;
+ cs.insert(cs.end(),lcs.begin(),lcs.end());
+ switch(solveWithMosek) {
+ case Off:
+ break;
+#ifdef MOSEK_AVAILABLE
+ case Inner:
+ menv = mosek_init_sep_ls(vars.size(),cs);
+ break;
+ case Outer:
+ unsigned n = vars.size();
+ float* lap = new float[n*(n+1)/2];
+ unsigned k=0;
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=i;j<n;j++) {
+ lap[k]=(*denseQ)[i*n+j];
+ k++;
+ }
+ }
+ menv = mosek_init_sep(lap,n,cs,1);
+ delete [] lap;
+ break;
+#endif
+ default:
+ break;
+ }
+ return new IncSolver(vars,cs);
+}
+void GradientProjection::destroyVPSC(IncSolver *vpsc) {
+ if(ccs) {
+ for(CompoundConstraints::const_iterator c=ccs->begin();
+ c!=ccs->end();++c) {
+ (*c)->updatePosition(vpsc::XDIM);
+ (*c)->updatePosition(vpsc::YDIM);
+ }
+ }
+ if(unsatisfiableConstraints) {
+ unsatisfiableConstraints->clear();
+ for(Constraints::iterator i=cs.begin();i!=cs.end();i++) {
+ Constraint* c=*i;
+ if(c->unsatisfiable) {
+ UnsatisfiableConstraintInfo *ci = new UnsatisfiableConstraintInfo(c);
+ unsatisfiableConstraints->push_back(ci);
+ }
+ }
+ }
+ if(clusterHierarchy) {
+ clusterHierarchy->computeBoundary(*rs);
+ }
+ if(sparseQ) {
+ for(unsigned i=numStaticVars;i<vars.size();i++) {
+ delete vars[i];
+ }
+ vars.resize(numStaticVars);
+ sparseQ=nullptr;
+ }
+ for(vector<Constraint*>::iterator i=lcs.begin();i!=lcs.end();i++) {
+ delete *i;
+ }
+ lcs.clear();
+ delete vpsc;
+#ifdef MOSEK_AVAILABLE
+ if(solveWithMosek!=Off) mosek_delete(menv);
+#endif
+}
+void GradientProjection::straighten(
+ cola::SparseMatrix const * Q,
+ vector<SeparationConstraint*> const & cs,
+ vector<straightener::Node*> const & snodes)
+{
+ COLA_ASSERT(Q->rowSize()==snodes.size());
+ COLA_ASSERT(vars.size()==numStaticVars);
+ sparseQ = Q;
+ for(unsigned i=numStaticVars;i<snodes.size();i++) {
+ Variable* v=new vpsc::Variable(i,snodes[i]->pos[k],1);
+ COLA_ASSERT(v->desiredPosition==snodes[i]->pos[k]);
+ vars.push_back(v);
+ }
+ COLA_ASSERT(lcs.size()==0);
+ for(vector<SeparationConstraint*>::const_iterator i=cs.begin();i!=cs.end();i++) {
+ (*i)->generateSeparationConstraints(k, vars, lcs, *rs);
+ }
+}
+} // namespace cola
diff --git a/src/3rdparty/adaptagrams/libcola/gradient_projection.h b/src/3rdparty/adaptagrams/libcola/gradient_projection.h
new file mode 100644
index 0000000..0e85780
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/gradient_projection.h
@@ -0,0 +1,165 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef _GRADIENT_PROJECTION_H
+#define _GRADIENT_PROJECTION_H
+
+#include <iostream>
+#include <cmath>
+#include <valarray>
+
+#include "libvpsc/solve_VPSC.h"
+#include "libvpsc/variable.h"
+#include "libvpsc/constraint.h"
+#include "libvpsc/rectangle.h"
+#include "libcola/commondefs.h"
+#include "libcola/compound_constraints.h"
+#include "libcola/cluster.h"
+#include "libcola/sparse_matrix.h"
+#ifdef MOSEK_AVAILABLE
+#include "libvpsc/mosek_quad_solve.h"
+#endif
+
+namespace straightener {
+ class Node;
+}
+namespace cola {
+
+enum SolveWithMosek { Off, Inner, Outer };
+
+class GradientProjection {
+public:
+ /**
+ * GradientProjection solves a linear system
+ * Qx=b
+ * subject to separation constraints.
+ * The usual use-case is with a dense square matrix (denseQ).
+ * However, certain CompoundConstraints and also clusters add dummy
+ * variables and simple goal terms which populate a sparse matrix
+ * sparseQ (constructed in this constructor).
+ * A motivated person could rewrite the constructor to allow
+ * arbitrary sparse terms (if they had a use for it).
+ */
+ GradientProjection(
+ const vpsc::Dim k,
+ std::valarray<double> *denseQ,
+ const double tol,
+ const unsigned max_iterations,
+ CompoundConstraints const *ccs,
+ UnsatisfiableConstraintInfos *unsatisfiableConstraints,
+ NonOverlapConstraintsMode nonOverlapConstraints = None,
+ RootCluster* clusterHierarchy = nullptr,
+ vpsc::Rectangles* rs = nullptr,
+ const bool scaling = false,
+ SolveWithMosek solveWithMosek = Off);
+ static void dumpSquareMatrix(std::valarray<double> const &L) {
+ unsigned n=static_cast<unsigned>(floor(sqrt(static_cast<double>(L.size()))));
+ printf("Matrix %dX%d\n{",n,n);
+ for(unsigned i=0;i<n;i++) {
+ printf("{");
+ for(unsigned j=0;j<n;j++) {
+ char c=j==n-1?'}':',';
+ printf("%f%c",1. * L[i*n+j],c);
+ }
+ char c=i==n-1?'}':',';
+ printf("%c\n",c);
+ }
+ }
+
+ unsigned getNumStaticVars() const {
+ return numStaticVars;
+ }
+ ~GradientProjection() {
+ //destroyVPSC(solver);
+ for(vpsc::Constraints::iterator i(gcs.begin()); i!=gcs.end(); i++) {
+ delete *i;
+ }
+ gcs.clear();
+ for(unsigned i=0;i<vars.size();i++) {
+ delete vars[i];
+ }
+ }
+ unsigned solve(std::valarray<double> const & b, std::valarray<double> & x);
+ void unfixPos(unsigned i) {
+ if(vars[i]->fixedDesiredPosition) {
+ vars[i]->weight=1;
+ vars[i]->fixedDesiredPosition=false;
+ }
+ }
+ void fixPos(const unsigned i,const double pos) {
+ vars[i]->weight=100000.;
+ vars[i]->desiredPosition=pos;
+ vars[i]->fixedDesiredPosition=true;
+ }
+ vpsc::Dim getDimension() const {
+ return k;
+ }
+ void straighten(
+ cola::SparseMatrix const * Q,
+ std::vector<SeparationConstraint*> const & ccs,
+ std::vector<straightener::Node*> const & snodes);
+ std::valarray<double> const & getFullResult() const {
+ return result;
+ }
+private:
+ vpsc::IncSolver* setupVPSC();
+ double computeCost(std::valarray<double> const &b,
+ std::valarray<double> const &x) const;
+ double computeSteepestDescentVector(
+ std::valarray<double> const &b, std::valarray<double> const &place,
+ std::valarray<double> &g) const;
+ double computeScaledSteepestDescentVector(
+ std::valarray<double> const &b, std::valarray<double> const &place,
+ std::valarray<double> &g) const;
+ double computeStepSize(
+ std::valarray<double> const & g, std::valarray<double> const & d) const;
+ bool runSolver(std::valarray<double> & result);
+ void destroyVPSC(vpsc::IncSolver *vpsc);
+ vpsc::Dim k;
+ unsigned numStaticVars; // number of variables that persist
+ // throughout iterations
+ const unsigned denseSize; // denseQ has denseSize^2 entries
+ std::valarray<double> *denseQ; // dense square graph laplacian matrix
+ std::valarray<double> scaledDenseQ; // scaled dense square graph laplacian matrix
+ std::vector<vpsc::Rectangle*>* rs;
+ CompoundConstraints const *ccs;
+ UnsatisfiableConstraintInfos *unsatisfiableConstraints;
+ NonOverlapConstraintsMode nonOverlapConstraints;
+ Cluster* clusterHierarchy;
+ double tolerance;
+ unsigned max_iterations;
+ cola::SparseMatrix const * sparseQ; // sparse components of goal function
+ vpsc::Variables vars; // all variables
+ // computations
+ vpsc::Constraints gcs; /* global constraints - persist throughout all
+ iterations */
+ vpsc::Constraints lcs; /* local constraints - only for current iteration */
+ vpsc::Constraints cs; /* working list of constraints: gcs +lcs */
+ std::valarray<double> result;
+#ifdef MOSEK_AVAILABLE
+ MosekEnv* menv;
+#endif
+ vpsc::IncSolver* solver;
+ SolveWithMosek solveWithMosek;
+ const bool scaling;
+ std::vector<OrthogonalEdgeConstraint*> orthogonalEdges;
+};
+} // namespace cola
+#endif /* _GRADIENT_PROJECTION_H */
diff --git a/src/3rdparty/adaptagrams/libcola/libcola.pc.in b/src/3rdparty/adaptagrams/libcola/libcola.pc.in
new file mode 100644
index 0000000..f9d0688
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/libcola.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libcola
+Description: A library for constraint graph layout
+URL: http://www.adaptagrams.org/
+Version: @VERSION@
+Libs: -L${libdir} -lcola
+Cflags: -I${includedir}/libcola
diff --git a/src/3rdparty/adaptagrams/libcola/output_svg.cpp b/src/3rdparty/adaptagrams/libcola/output_svg.cpp
new file mode 100644
index 0000000..cd564e6
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/output_svg.cpp
@@ -0,0 +1,389 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <list>
+
+#include "libcola/output_svg.h"
+#include "libcola/cola.h"
+#include "libcola/straightener.h"
+
+using namespace cola;
+using vpsc::Rectangle;
+using std::endl;
+using std::cout;
+using std::ios;
+using std::max;
+using std::min;
+using std::ofstream;
+using std::vector;
+using std::list;
+
+void OutputFile::generate() {
+ unsigned E=es.size();
+ bool cleanupRoutes=false;
+ if(routes==nullptr) {
+ cleanupRoutes=true;
+ routes = new vector<straightener::Route*>(E);
+ for(unsigned i=0;i<E;i++) {
+ straightener::Route* r=new straightener::Route(2);
+ r->xs[0]=rs[es[i].first]->getCentreX();
+ r->ys[0]=rs[es[i].first]->getCentreY();
+ r->xs[1]=rs[es[i].second]->getCentreX();
+ r->ys[1]=rs[es[i].second]->getCentreY();
+ (*routes)[i]=r;
+ }
+ }
+
+#if defined (CAIRO_HAS_SVG_SURFACE) && defined (CAIRO_HAS_PDF_SURFACE)
+ double width,height,r=2;
+ if(rects) r=rs[0]->width()/2;
+ double xmin=DBL_MAX, ymin=xmin;
+ double xmax=-DBL_MAX, ymax=xmax;
+ for (unsigned i=0;i<rs.size();i++) {
+ double x=rs[i]->getCentreX(), y=rs[i]->getCentreY();
+ xmin=min(xmin,x);
+ ymin=min(ymin,y);
+ xmax=max(xmax,x);
+ ymax=max(ymax,y);
+ }
+ xmax+=2*r;
+ ymax+=2*r;
+ xmin-=2*r;
+ ymin-=2*r;
+ width=xmax-xmin;
+ height=ymax-ymin;
+
+ Cairo::RefPtr<Cairo::Context> cr;
+ openCairo(cr,width,height);
+
+ /* set background colour
+ cr->save(); // save the state of the context
+ cr->set_source_rgb(0.86, 0.85, 0.47);
+ cr->paint(); // fill image with the color
+ cr->restore(); // color is back to black now
+ */
+
+ cr->set_line_width(1.);
+ cr->set_font_size(8);
+ cr->save();
+ if(rc) for(Clusters::const_iterator c=rc->clusters.begin();c!=rc->clusters.end();c++) {
+ draw_cluster_boundary(cr,**c,xmin,ymin);
+ }
+ if(curvedEdges)
+ draw_curved_edges(cr,es,xmin,ymin);
+ else
+ draw_edges(cr,*routes,xmin,ymin);
+ Cairo::TextExtents te;
+ for (unsigned i=0;i<rs.size();i++) {
+ if(!rects) {
+ double x=rs[i]->getCentreX()-xmin, y=rs[i]->getCentreY()-ymin;
+ cr->arc(x,y,r, 0.0, 2.0 * M_PI);
+ cr->fill();
+ } else {
+ double x=rs[i]->getMinX()-xmin+0.5, y=rs[i]->getMinY()-ymin+0.5;
+ std::string str;
+ if(labels.size()==rs.size()) {
+ str=labels[i];
+ } else {
+ std::stringstream s; s<<i;
+ str=s.str();
+ }
+ cr->get_text_extents(str,te);
+ /*
+ double llx = x-te.width/2.-1;
+ double lly = y-te.height/2.-1;
+ cr->rectangle(llx,lly,te.width+2,te.height+2);
+ */
+ cr->rectangle(x,y,
+ rs[i]->width()-1,rs[i]->height()-1);
+ cr->stroke_preserve();
+ cr->save();
+ cr->set_source_rgba(245./255., 233./255., 177./255., 0.6);
+ cr->fill();
+ cr->restore();
+ if(labels.size()==rs.size()) {
+ cr->move_to(x-te.x_bearing+te.width/2.,y-te.y_bearing+te.height/2.);
+ cr->show_text(str);
+ }
+ cr->stroke();
+ }
+ }
+
+ cr->show_page();
+
+ std::cout << "Wrote file \"" << fname << "\"" << std::endl;
+
+#else
+ std::cout <<
+ "WARNING: cola::OutputFile::generate(): No SVG file produced." <<
+ std::endl <<
+ " You must have cairomm (and cairo with SVG support) " <<
+ "this to work." << std::endl;
+#endif
+
+ if(cleanupRoutes) {
+ for(unsigned i=0;i<E;i++) {
+ delete (*routes)[i];
+ }
+ delete routes;
+ }
+}
+
+#ifdef HAVE_CAIROMM
+void OutputFile::draw_cluster_boundary(Cairo::RefPtr<Cairo::Context> const &cr,
+ Cluster &c,
+ const double xmin,
+ const double ymin) {
+ c.computeBoundary(rs);
+ cr->save();
+ // background
+ cr->set_source_rgb(0.7, 0.7, 224./255.);
+ cr->move_to(c.hullX[0]-xmin,c.hullY[0]-ymin);
+ for(unsigned i=1;i<c.hullX.size();i++) {
+ cr->line_to(c.hullX[i]-xmin,c.hullY[i]-ymin);
+ }
+ cr->line_to(c.hullX[0]-xmin,c.hullY[0]-ymin);
+ cr->fill();
+ cr->restore();
+ // outline
+ cr->move_to(c.hullX[0]-xmin,c.hullY[0]-ymin);
+ for(unsigned i=1;i<c.hullX.size();i++) {
+ cr->line_to(c.hullX[i]-xmin,c.hullY[i]-ymin);
+ }
+ cr->line_to(c.hullX[0]-xmin,c.hullY[0]-ymin);
+ cr->stroke();
+}
+
+void OutputFile::draw_edges(Cairo::RefPtr<Cairo::Context> &cr,
+ vector<straightener::Route*> const & es, double const xmin, double const ymin) {
+ cr->save();
+ // background
+ cr->set_source_rgba(0,0,1,0.5);
+ for (unsigned i=0;i<es.size();i++) {
+ const straightener::Route* r=es[i];
+ cr->move_to(r->xs[0]-xmin,r->ys[0]-ymin);
+ for (unsigned j=1;j<r->n;j++) {
+ cr->line_to(r->xs[j]-xmin,r->ys[j]-ymin);
+ }
+ cr->stroke();
+ }
+ cr->restore();
+}
+
+namespace bundles {
+struct CEdge {
+ unsigned startID, endID;
+ double x0,y0,x1,y1,x2,y2,x3,y3;
+};
+struct CBundle;
+struct CNode {
+ double x,y;
+ vector<CEdge*> edges;
+ list<CBundle*> bundles;
+};
+double vangle(double ax,double ay, double bx, double by) {
+ double ab=ax*bx+ay*by;
+ double len=sqrt(ax*ax+ay*ay)*sqrt(bx*bx+by*by);
+ double angle=acos(ab/len);
+ //printf("ab=%f len=%f angle=%f\n",ab,len,angle);
+ return angle;
+}
+struct CBundle {
+ unsigned w;
+ double x0, y0;
+ double sx,sy;
+ vector<CEdge*> edges;
+ CBundle(CNode const &u) : w(u.edges.size()), x0(u.x), y0(u.y), sx(w*u.x), sy(w*u.y) { }
+ void addEdge(CEdge *e) {
+ if(x0==e->x0 && y0==e->y0) {
+ sx+=e->x3; sy+=e->y3;
+ } else {
+ sx+=e->x0; sy+=e->y0;
+ }
+ edges.push_back(e);
+ }
+ double x1() const {
+ return sx/(w+edges.size());
+ }
+ double y1() const {
+ return sy/(w+edges.size());
+ }
+ double angle(CBundle* const &b) const {
+ double ax=x1()-x0;
+ double ay=y1()-y0;
+ double bx=b->x1()-b->x0;
+ double by=b->y1()-b->y0;
+ return vangle(ax,ay,bx,by);
+ }
+ double yangle() const {
+ double x=x1()-x0;
+ double y=y1()-y0;
+ double o=x<0?1:-1;
+ return vangle(0,1,x,y)*o+M_PI;
+ }
+ void merge(CBundle* b) {
+ for(unsigned i=0;i<b->edges.size();i++) {
+ addEdge(b->edges[i]);
+ }
+ }
+ void dump() {
+ printf("Bundle: ");
+ for(unsigned i=0;i<edges.size();i++) {
+ printf("(%d,%d) ",edges[i]->startID,edges[i]->endID);
+ }
+ }
+};
+struct clockwise {
+ bool operator() (CBundle* const &a, CBundle* const &b) {
+ return a->yangle()<b->yangle();
+ }
+};
+} //namespace bundles
+
+/*
+ * draw edges bundled. That is, edges are drawn as splines, with the control points
+ * between adjacent edges outgoing from a particular node shared if the angle between them
+ * is less than pi/8
+ */
+void OutputFile::draw_curved_edges(Cairo::RefPtr<Cairo::Context> &cr,
+ vector<cola::Edge> const & es,
+ const double xmin,
+ const double ymin) {
+ using namespace bundles;
+ vector<CNode> nodes(rs.size());
+ vector<CEdge> edges(es.size());
+ for (unsigned i=0;i<es.size();i++) {
+ CEdge *e=&edges[i];
+ unsigned start=es[i].first;
+ unsigned end=es[i].second;
+ e->startID=start;
+ e->endID=end;
+ nodes[start].x=rs[start]->getCentreX()-xmin;
+ nodes[start].y=rs[start]->getCentreY()-ymin;
+ nodes[end].x=rs[end]->getCentreX()-xmin;
+ nodes[end].y=rs[end]->getCentreY()-ymin;
+ e->x0=nodes[start].x;
+ e->x1=nodes[start].x;
+ e->x2=nodes[end].x;
+ e->x3=nodes[end].x;
+ e->y0=nodes[start].y;
+ e->y1=nodes[start].y;
+ e->y2=nodes[end].y;
+ e->y3=nodes[end].y;
+ nodes[end].edges.push_back(e);
+ nodes[start].edges.push_back(e);
+ }
+
+ for (unsigned i=0;i<nodes.size();i++) {
+ CNode u=nodes[i];
+ if(u.edges.size()<2) continue;
+ for (unsigned j=0;j<u.edges.size();j++) {
+ CBundle* b=new CBundle(u);
+ b->addEdge(u.edges[j]);
+ u.bundles.push_back(b);
+ }
+ u.bundles.sort(clockwise());
+ /*
+ printf("Sorted: \n");
+ list<CBundle*>::iterator i,j;
+ for(list<CBundle*>::iterator i=u.bundles.begin();i!=u.bundles.end();i++) {
+ CBundle* a=*i;
+ a->dump();
+ printf(" angle=%f\n",a->yangle());
+ }
+ printf("---------\n");
+ */
+ while(true) {
+ double minAngle=DBL_MAX;
+ list<CBundle*>::iterator mini,minj,i,j;
+ for(i=u.bundles.begin();i!=u.bundles.end();i++) {
+ j=i;
+ if(++j==u.bundles.end()) {
+ j=u.bundles.begin();
+ }
+ CBundle* a=*i;
+ CBundle* b=*j;
+ double angle=b->yangle()-a->yangle();
+ if(angle<0) angle+=2*M_PI;
+ //printf("between ");
+ //a->dump(); b->dump();
+ //printf(" angle=%f\n",angle);
+ if(angle<minAngle) {
+ minAngle=angle;
+ mini=i;
+ minj=j;
+ }
+ }
+ if(minAngle>cos(M_PI/8.)) break;
+ CBundle* a=*mini;
+ CBundle* b=*minj;
+ //a->dump();
+ //b->dump();
+ b->merge(a);
+ //printf("***Merged on %f***: ",minAngle);
+ //b->dump();
+ //printf("\n");
+ u.bundles.erase(mini);
+ if(u.bundles.size() < 2) break;
+ }
+ for(list<CBundle*>::iterator i=u.bundles.begin();i!=u.bundles.end();i++) {
+ CBundle* b=*i;
+ for(unsigned i=0;i<b->edges.size();i++) {
+ CEdge* e=b->edges[i];
+ if(e->x0==u.x&&e->y0==u.y) {
+ e->x1=b->x1();
+ e->y1=b->y1();
+ } else {
+ e->x2=b->x1();
+ e->y2=b->y1();
+ }
+ }
+ }
+ }
+
+ cr->save();
+ // background
+ cr->set_source_rgba(0,0,1,0.2);
+ for (unsigned i=0;i<edges.size();i++) {
+ CEdge &e=edges[i];
+ cr->move_to(e.x0,e.y0);
+ cr->curve_to(e.x1,e.y1,e.x2,e.y2,e.x3,e.y3);
+ cr->stroke();
+ }
+ cr->restore();
+}
+void OutputFile::openCairo(Cairo::RefPtr<Cairo::Context> &cr, double width, double height) {
+ if(fname.rfind("pdf") == (fname.length()-3) ) {
+ printf("writing pdf file: %s\n",fname.c_str());
+ Cairo::RefPtr<Cairo::PdfSurface> pdfsurface =
+ Cairo::PdfSurface::create(fname, width, height);
+ cr = Cairo::Context::create(pdfsurface);
+ } else {
+ printf("writing svg file: %s\n",fname.c_str());
+ Cairo::RefPtr<Cairo::SvgSurface> svgsurface =
+ Cairo::SvgSurface::create(fname, width, height);
+ cr = Cairo::Context::create(svgsurface);
+ }
+}
+
+#endif // HAVE_CAIROMM
diff --git a/src/3rdparty/adaptagrams/libcola/output_svg.h b/src/3rdparty/adaptagrams/libcola/output_svg.h
new file mode 100644
index 0000000..d68f161
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/output_svg.h
@@ -0,0 +1,80 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef _OUTPUT_SVG_H
+#define _OUTPUT_SVG_H
+
+#include "libcola/config.h"
+#include "libcola/cola.h"
+
+#ifdef HAVE_CAIROMM
+#include <cairomm/context.h>
+#include <cairomm/surface.h>
+#endif
+
+class OutputFile {
+public:
+ std::vector<vpsc::Rectangle*> const &rs;
+ std::vector<cola::Edge> const &es;
+ std::vector<straightener::Route*> *routes;
+ cola::RootCluster const * rc;
+ std::string const fname;
+ bool rects;
+ bool curvedEdges;
+ OutputFile(std::vector<vpsc::Rectangle*> const &rs,
+ std::vector<cola::Edge> const &es,
+ cola::RootCluster const * rc,
+ std::string const fname,
+ const bool rects=false,
+ const bool curvedEdges=false)
+ : rs(rs),
+ es(es),
+ routes(nullptr),
+ rc(rc),
+ fname(fname),
+ rects(rects),
+ curvedEdges(curvedEdges) {}
+ void generate();
+ void setLabels(std::vector<std::string> ls) {
+ labels.resize(ls.size());
+ std::copy(ls.begin(),ls.end(),labels.begin());
+ }
+ void setLabels(const unsigned n, const char **ls) {
+ labels.resize(n);
+ for(unsigned i=0;i<n;i++) {
+ labels[i]=ls[i];
+ }
+ }
+private:
+#ifdef HAVE_CAIROMM
+ void draw_cluster_boundary(Cairo::RefPtr<Cairo::Context> const &cr,
+ cola::Cluster &c, const double xmin, const double ymin);
+ void draw_edges(Cairo::RefPtr<Cairo::Context> &cr,
+ std::vector<straightener::Route*> const & es,
+ double const xmin, double const ymin);
+ void draw_curved_edges(Cairo::RefPtr<Cairo::Context> &cr,
+ std::vector<cola::Edge> const & es,
+ const double xmin,
+ const double ymin);
+ void openCairo(Cairo::RefPtr<Cairo::Context> &cr, double width, double height);
+#endif // HAVE_CAIROMM
+ std::vector<std::string> labels;
+};
+#endif // _OUTPUT_SVG_H
diff --git a/src/3rdparty/adaptagrams/libcola/pseudorandom.cpp b/src/3rdparty/adaptagrams/libcola/pseudorandom.cpp
new file mode 100644
index 0000000..6577b3a
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/pseudorandom.cpp
@@ -0,0 +1,48 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2015 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+*/
+
+#include "libcola/pseudorandom.h"
+
+namespace cola {
+
+PseudoRandom::PseudoRandom(double s)
+ : a(214013),
+ c(2531011),
+ m(2147483648),
+ range(32767),
+ seed(s)
+{
+}
+
+double PseudoRandom::getNext(void)
+{
+ seed = (seed * a + c) % m;
+ return (seed >> 16) / range;
+}
+
+double PseudoRandom::getNextBetween(double min, double max)
+{
+ return min + getNext() * (max - min);
+}
+
+
+}
+
diff --git a/src/3rdparty/adaptagrams/libcola/pseudorandom.h b/src/3rdparty/adaptagrams/libcola/pseudorandom.h
new file mode 100644
index 0000000..bb3b269
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/pseudorandom.h
@@ -0,0 +1,44 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2015 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+*/
+
+#ifndef COLA_PSEUDORANDOM_H
+#define COLA_PSEUDORANDOM_H
+
+namespace cola {
+
+class PseudoRandom
+{
+public:
+ PseudoRandom(double s = 1);
+
+ double getNext(void);
+ double getNextBetween(double min, double max);
+
+private:
+ int a;
+ int c;
+ unsigned int m;
+ double range;
+ unsigned int seed;
+};
+
+}
+#endif // COLA_PSEUDORANDOM_H
diff --git a/src/3rdparty/adaptagrams/libcola/shapepair.cpp b/src/3rdparty/adaptagrams/libcola/shapepair.cpp
new file mode 100644
index 0000000..5673322
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/shapepair.cpp
@@ -0,0 +1,47 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Michael Wybrow
+ *
+*/
+
+#include "libvpsc/assertions.h"
+
+#include "libcola/shapepair.h"
+
+namespace cola {
+
+ShapePair::ShapePair(unsigned ind1, unsigned ind2)
+{
+ COLA_ASSERT(ind1 != ind2);
+ // Assign the lesser value to m_index1.
+ m_index1 = (ind1 < ind2) ? ind1 : ind2;
+ // Assign the greater value to m_index2.
+ m_index2 = (ind1 > ind2) ? ind1 : ind2;
+}
+
+bool ShapePair::operator<(const ShapePair& rhs) const
+{
+ if (m_index1 != rhs.m_index1)
+ {
+ return m_index1 < rhs.m_index1;
+ }
+ return m_index2 < rhs.m_index2;
+}
+
+};
diff --git a/src/3rdparty/adaptagrams/libcola/shapepair.h b/src/3rdparty/adaptagrams/libcola/shapepair.h
new file mode 100644
index 0000000..7c122cb
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/shapepair.h
@@ -0,0 +1,49 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Michael Wybrow
+ *
+*/
+
+#ifndef COLA_SHAPEPAIR_H
+#define COLA_SHAPEPAIR_H
+
+namespace cola {
+
+// A pair of indexes.
+// Specified unordered but stored ordered so it can be compared and
+// stored in a set.
+//
+class ShapePair
+{
+ public:
+ ShapePair(unsigned ind1, unsigned ind2);
+ bool operator<(const ShapePair& rhs) const;
+ unsigned short index1(void) const {return m_index1;}
+ unsigned short index2(void) const {return m_index2;}
+
+ private:
+ unsigned short m_index1;
+ unsigned short m_index2;
+};
+
+
+};
+
+#endif
+
diff --git a/src/3rdparty/adaptagrams/libcola/shortest_paths.h b/src/3rdparty/adaptagrams/libcola/shortest_paths.h
new file mode 100644
index 0000000..22b54e3
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/shortest_paths.h
@@ -0,0 +1,245 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2014 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+*/
+
+#ifndef SHORTEST_PATHS_H
+#define SHORTEST_PATHS_H
+
+#include <vector>
+#include <valarray>
+#include <cfloat>
+#include <cassert>
+#include <algorithm>
+#include <iostream>
+#include <limits>
+
+#include "libcola/commondefs.h"
+#include <libvpsc/pairing_heap.h>
+#include <libvpsc/assertions.h>
+
+template <class T>
+struct PairNode;
+
+namespace shortest_paths {
+
+template <typename T>
+struct Node {
+ unsigned id;
+ T d;
+ Node* p; // predecessor
+ std::vector<Node<T>*> neighbours;
+ std::vector<T> nweights;
+ PairNode<Node<T>*>* qnode;
+};
+template <typename T>
+struct CompareNodes {
+ bool operator() (Node<T> *const &u, Node<T> *const &v) const {
+ if(u==v) return false; // with g++ 4.1.2 unless I have this explicit check
+ // it returns true for this case when using -O3 optimization
+ // CRAZY!
+ if(u->d < v->d) {
+ return true;
+ }
+ return false;
+ }
+};
+
+typedef std::pair<unsigned,unsigned> Edge;
+template <typename T>
+/**
+ * returns the adjacency matrix, 0 entries for non-adjacent nodes
+ * @param n total number of nodes
+ * @param D n*n matrix of shortest paths
+ * @param es edge pairs
+ * @param eweights edge weights, if empty then all weights will be taken as 1
+ */
+void neighbours(unsigned const n, T** D, std::vector<Edge> const & es,
+ std::valarray<T> const & eweights = std::valarray<T>());
+/**
+ * find all pairs shortest paths, n^3 dynamic programming approach
+ * @param n total number of nodes
+ * @param D n*n matrix of shortest paths
+ * @param es edge pairs
+ * @param eweights edge weights, if empty then all weights will be taken as 1
+ */
+template <typename T>
+void floyd_warshall(unsigned const n, T** D, std::vector<Edge> const & es,
+ std::valarray<T> const & eweights = std::valarray<T>());
+
+/**
+ * find all pairs shortest paths, faster, uses dijkstra
+ * @param n total number of nodes
+ * @param D n*n matrix of shortest paths
+ * @param es edge pairs
+ * @param eweights edge weights, if empty then all weights will be taken as 1
+ */
+template <typename T>
+void johnsons(unsigned const n, T** D, std::vector<Edge> const & es,
+ std::valarray<T> const & eweights = std::valarray<T>());
+/**
+ * find shortest path lengths from node s to all other nodes
+ * @param s starting node
+ * @param n total number of nodes
+ * @param d n vector of path lengths
+ * @param es edge pairs
+ * @param eweights edge weights, if empty then all weights will be taken as 1
+ */
+template <typename T>
+void dijkstra(unsigned const s, unsigned const n, T* d,
+ std::vector<Edge> const & es,
+ std::valarray<T> const & eweights = std::valarray<T>());
+
+
+//-----------------------------------------------------------------------------
+// Implementation:
+
+// O(n^3) time dynamic programming approach. Slow, but fool proof.
+// Use for testing.
+template <typename T>
+void floyd_warshall(
+ unsigned const n,
+ T** D,
+ std::vector<Edge> const & es,
+ std::valarray<T> const & eweights)
+{
+ COLA_ASSERT((eweights.size() == 0) || (eweights.size() == es.size()));
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=0;j<n;j++) {
+ if(i==j) D[i][j]=0;
+ else D[i][j]=std::numeric_limits<T>::max();
+ }
+ }
+ for(unsigned i=0;i<es.size();i++) {
+ unsigned u=es[i].first, v=es[i].second;
+ COLA_ASSERT(u<n&&v<n);
+ D[u][v] = D[v][u] = (eweights.size() > 0) ? eweights[i] : 1;
+ }
+ for(unsigned k=0; k<n; k++) {
+ for(unsigned i=0; i<n; i++) {
+ for(unsigned j=0; j<n; j++) {
+ D[i][j]=std::min(D[i][j],D[i][k]+D[k][j]);
+ }
+ }
+ }
+}
+// Simply returns the adjacency graph
+template <typename T>
+void neighbours(
+ unsigned const n,
+ T** D,
+ std::vector<Edge> const & es,
+ std::valarray<T> const & eweights)
+{
+ COLA_ASSERT((eweights.size() == 0) || (eweights.size() == es.size()));
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=0;j<n;j++) {
+ D[i][j]=0;
+ }
+ }
+ for(unsigned i=0;i<es.size();i++) {
+ unsigned u=es[i].first, v=es[i].second;
+ COLA_ASSERT(u<n&&v<n);
+ D[u][v] = D[v][u] = (eweights.size() > 0) ? eweights[i] : 1;
+ }
+}
+template <typename T>
+void dijkstra_init(
+ std::vector<Node<T> > & vs,
+ std::vector<Edge> const& es,
+ std::valarray<T> const & eweights) {
+ COLA_ASSERT((eweights.size() == 0) || (eweights.size() == es.size()));
+#ifndef NDEBUG
+ const unsigned n=vs.size();
+#endif
+ for(unsigned i=0;i<es.size();i++) {
+ unsigned u=es[i].first, v=es[i].second;
+ COLA_ASSERT(u<n);
+ COLA_ASSERT(v<n);
+ T w = (eweights.size() > 0) ? eweights[i] : 1;
+ vs[u].neighbours.push_back(&vs[v]);
+ vs[u].nweights.push_back(w);
+ vs[v].neighbours.push_back(&vs[u]);
+ vs[v].nweights.push_back(w);
+ }
+}
+template <typename T>
+void dijkstra(
+ unsigned const s,
+ std::vector<Node<T> > & vs,
+ T* d)
+{
+ const unsigned n=vs.size();
+ COLA_ASSERT(s<n);
+ for(unsigned i=0;i<n;i++) {
+ vs[i].id=i;
+ vs[i].d=std::numeric_limits<T>::max();
+ vs[i].p=nullptr;
+ }
+ vs[s].d=0;
+ PairingHeap<Node<T>*,CompareNodes<T> > Q;
+ for(unsigned i=0;i<n;i++) {
+ vs[i].qnode = Q.insert(&vs[i]);
+ }
+ while(!Q.isEmpty()) {
+ Node<T> *u=Q.extractMin();
+ d[u->id]=u->d;
+ for(unsigned i=0;i<u->neighbours.size();i++) {
+ Node<T> *v=u->neighbours[i];
+ T w=u->nweights[i];
+ if(u->d!=std::numeric_limits<T>::max()
+ && v->d > u->d+w) {
+ v->p=u;
+ v->d=u->d+w;
+ Q.decreaseKey(v->qnode,v);
+ }
+ }
+ }
+}
+template <typename T>
+void dijkstra(
+ unsigned const s,
+ unsigned const n,
+ T* d,
+ std::vector<Edge> const & es,
+ std::valarray<T> const & eweights)
+{
+ COLA_ASSERT((eweights.size() == 0) || (eweights.size() == es.size()));
+ COLA_ASSERT(s<n);
+ std::vector<Node<T> > vs(n);
+ dijkstra_init(vs,es,eweights);
+ dijkstra(s,vs,d);
+}
+
+template <typename T>
+void johnsons(
+ unsigned const n,
+ T** D,
+ std::vector<Edge> const & es,
+ std::valarray<T> const & eweights)
+{
+ std::vector<Node<T> > vs(n);
+ dijkstra_init(vs,es,eweights);
+ for(unsigned k=0;k<n;k++) {
+ dijkstra(k,vs,D[k]);
+ }
+}
+
+} //namespace shortest_paths
+#endif //SHORTEST_PATHS_H
diff --git a/src/3rdparty/adaptagrams/libcola/sparse_matrix.h b/src/3rdparty/adaptagrams/libcola/sparse_matrix.h
new file mode 100644
index 0000000..f4ec858
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/sparse_matrix.h
@@ -0,0 +1,140 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+*/
+
+/*
+ * Yale Sparse Matrix implementation (from Wikipedia definition).
+ * It stores an initial sparse n×n matrix M in row form using three arrays, A,
+ * IA, JA. NZ denotes the number of nonzero entries in matrix M. The array A
+ * then is of length NZ and holds all nonzero entries of M. The array IA stores
+ * at IA(i) the position of the first element of row i in the sparse array A.
+ * The length of row i is determined by IA(i+1) - IA(i). Therefore IA needs to
+ * be of length N + 1. In array JA, the column index of the element A(j) is
+ * stored. JA is of length NZ.
+ */
+#ifndef _SPARSE_MATRIX_H
+#define _SPARSE_MATRIX_H
+
+#include <valarray>
+#include <map>
+#include <cstdio>
+
+#include "libvpsc/assertions.h"
+
+namespace cola {
+struct SparseMap {
+ SparseMap(unsigned n = 0) : n(n) {};
+ unsigned n;
+ typedef std::pair<unsigned, unsigned> SparseIndex;
+ typedef std::map<SparseIndex,double> SparseLookup;
+ typedef SparseLookup::const_iterator ConstIt;
+ SparseLookup lookup;
+ double& operator[](const SparseIndex& k) {
+ return lookup[k];
+ }
+ double& operator()(const unsigned i, const unsigned j) {
+ return lookup[std::make_pair(i,j)];
+ }
+ double getIJ(const unsigned i, const unsigned j) const {
+ COLA_ASSERT(i<n);
+ COLA_ASSERT(j<n);
+ ConstIt v=lookup.find(std::make_pair(i,j));
+ if(v!=lookup.end()) {
+ return v->second;
+ }
+ return 0;
+ }
+ size_t nonZeroCount() const {
+ return lookup.size();
+ }
+ void resize(unsigned n) {
+ this->n = n;
+ }
+ void clear() {
+ lookup.clear();
+ }
+};
+/*
+ * Yale Sparse Matrix implementation (from Wikipedia definition).
+ * It stores an initial sparse n×n matrix M in row form using three arrays, A,
+ * IA, JA. NZ denotes the number of nonzero entries in matrix M. The array A
+ * then is of length NZ and holds all nonzero entries of M. The array IA stores
+ * at IA(i) the position of the first element of row i in the sparse array A.
+ * The length of row i is determined by IA(i+1) - IA(i). Therefore IA needs to
+ * be of length N + 1. In array JA, the column index of the element A(j) is
+ * stored. JA is of length NZ.
+ */
+class SparseMatrix {
+public:
+ SparseMatrix(SparseMap const & m)
+ : n(m.n), NZ((unsigned)m.nonZeroCount()), sparseMap(m),
+ A(std::valarray<double>(NZ)), IA(std::valarray<unsigned>(n+1)), JA(std::valarray<unsigned>(NZ)) {
+ unsigned cnt=0;
+ int lastrow=-1;
+ for(SparseMap::ConstIt i=m.lookup.begin(); i!=m.lookup.end(); i++) {
+ SparseMap::SparseIndex p = i->first;
+ COLA_ASSERT(p.first<n);
+ COLA_ASSERT(p.second<n);
+ A[cnt]=i->second;
+ if((int)p.first!=lastrow) {
+ for(unsigned r=lastrow+1;r<=p.first;r++) {
+ IA[r]=cnt;
+ }
+ lastrow=p.first;
+ }
+ JA[cnt]=p.second;
+ cnt++;
+ }
+ for(unsigned r=lastrow+1;r<=n;r++) {
+ IA[r]=NZ;
+ }
+ }
+ void rightMultiply(std::valarray<double> const & v, std::valarray<double> & r) const {
+ COLA_ASSERT(v.size()>=n);
+ COLA_ASSERT(r.size()>=n);
+ for(unsigned i=0;i<n;i++) {
+ r[i]=0;
+ for(unsigned j=IA[i];j<IA[i+1];j++) {
+ r[i]+=A[j]*v[JA[j]];
+ }
+ }
+ }
+ double getIJ(const unsigned i, const unsigned j) const {
+ return sparseMap.getIJ(i,j);
+ }
+ void print() const {
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=0;j<n;j++) {
+ printf("%f ",getIJ(i,j));
+ }
+ printf("\n");
+ }
+ }
+ unsigned rowSize() const {
+ return n;
+ }
+private:
+ const unsigned n,NZ;
+ SparseMap const & sparseMap;
+ std::valarray<double> A;
+ std::valarray<unsigned> IA, JA;
+};
+} //namespace cola
+#endif /* _SPARSE_MATRIX_H */
diff --git a/src/3rdparty/adaptagrams/libcola/straightener.cpp b/src/3rdparty/adaptagrams/libcola/straightener.cpp
new file mode 100644
index 0000000..dc22d18
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/straightener.cpp
@@ -0,0 +1,798 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2005-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Author(s): Tim Dwyer
+ *
+*/
+
+/*
+ * Functions to automatically generate constraints for the
+ * rectangular node overlap removal problem.
+ */
+
+#include <set>
+#include <list>
+#include <cassert>
+#include <iostream>
+#include <cmath>
+
+#include "libvpsc/assertions.h"
+#include "libcola/commondefs.h"
+#include "libcola/cola.h"
+#include "libcola/compound_constraints.h"
+#include "libcola/straightener.h"
+
+//#define STRAIGHTENER_DEBUG 1
+
+using std::list;
+using std::make_pair;
+using std::pair;
+using std::set;
+using std::vector;
+using std::copy;
+
+namespace straightener {
+
+ // is point p on line a-b?
+ static bool pointOnLine(double px,double py, double ax, double ay, double bx, double by, double& tx) {
+ double dx=bx-ax;
+ double dy=by-ay;
+ double ty=0;
+ if(fabs(dx)<0.0001&&fabs(dy)<0.0001) {
+ // runty line!
+ tx=px-ax;
+ ty=py-ay;
+ } else {
+ if(fabs(dx)<0.0001) {
+ //vertical line
+ if(fabs(px-ax)<0.01) {
+ tx=(py-ay)/dy;
+ }
+ } else {
+ tx=(px-ax)/dx;
+ }
+ if(fabs(dy)<0.0001) {
+ //horizontal line
+ if(fabs(py-ay)<0.01) {
+ ty=tx;
+ }
+ } else {
+ ty=(py-ay)/dy;
+ }
+ }
+ //printf(" tx=%f,ty=%f\n",tx,ty);
+ if(fabs(tx-ty)<0.001 && tx>=0 && tx<=1) {
+ return true;
+ }
+ return false;
+ }
+ void Route::rerouteAround(vpsc::Rectangle* rect) {
+ // the first and last points should not be inside this
+ // rectangle - note that we should not be routing around
+ // rectangles directly connected to this route
+ COLA_ASSERT(!rect->inside(xs[0],ys[0]));
+ COLA_ASSERT(!rect->inside(xs[n-1],ys[n-1]));
+ // first, we examine each point and if it is inside the rectangle, we
+ // project to the nearest edge of the rectangle
+ for(unsigned i=1;i<n-1;i++) {
+ double &x=xs[i], &y=ys[i];
+ if(rect->inside(x,y)) {
+ enum ProjectSide {LEFT, BOTTOM, RIGHT, TOP};
+ unsigned projectSide = LEFT;
+ double minDist = x - rect->getMinX();
+ double dist = y - rect->getMinY();
+ if(dist<minDist) {
+ projectSide = BOTTOM;
+ minDist = dist;
+ }
+ dist = rect->getMaxX() - x;
+ if(dist<minDist) {
+ projectSide = RIGHT;
+ minDist = dist;
+ }
+ dist = rect->getMaxY() - y;
+ if(dist<minDist) {
+ projectSide = TOP;
+ minDist = dist;
+ }
+ switch(projectSide) {
+ case LEFT:
+ x=rect->getMinX();
+ break;
+ case BOTTOM:
+ y=rect->getMinY();
+ break;
+ case RIGHT:
+ x=rect->getMaxX();
+ break;
+ case TOP:
+ y=rect->getMaxY();
+ break;
+ }
+
+ }
+ }
+ // the new route is copied into rxs, rys.
+ vector<double> rxs, rys;
+ double prevX=xs[0], prevY=ys[0];
+ rxs.push_back(prevX);
+ rys.push_back(prevY);
+
+ // check each segment in turn to see if it intersects
+ // with the rectangle.
+ // If an intersecting segment is found:
+ // 1) the segment passes right through the rectangle
+ // - we insert new segments routed around the rectangle
+ // 2) the segment terminates inside the rectangle
+ // - we follow connected segments until we find the exit
+ // point, then we insert a route around the rectangle
+ // 3) the segment just touches one side
+ //
+ for(unsigned i=1;i<n;i++) {
+ // we have projected all points to the boundary already so we shouldn't find any inside
+ COLA_ASSERT(!rect->inside(xs[i],ys[i]));
+ vpsc::RectangleIntersections ri;
+ rect->lineIntersections(prevX,prevY,
+ xs[i],ys[i],ri);
+ if(ri.intersects) {
+ int count=ri.countIntersections();
+ COLA_ASSERT(count>0); // can't be 0 because we have detected an intersection
+ COLA_ASSERT(count<4); // assumes no zero width or height rects which would be
+ // the only way for a line segment to touch all 4 sides at once
+ if(count==3) { // runs along one side
+ COLA_ASSERT(!rect->inside(xs[i],ys[i]));
+ } else if(count==2) { // passes right through
+ COLA_ASSERT(!rect->inside(xs[i],ys[i]));
+ double x1=0, y1=0, x2=0, y2=0;
+ ri.nearest(prevX, prevY, x1, y1);
+ ri.nearest(xs[i], ys[i], x2, y2);
+ rect->routeAround(x1, y1, x2, y2, rxs, rys);
+ } else if(count==1) {
+ // single intersection, earlier projection step ensures it is on the
+ // perimeter, so nothing to do
+ }
+ }
+ prevX=xs[i];
+ prevY=ys[i];
+ COLA_ASSERT(!rect->inside(prevX,prevY));
+ rxs.push_back(prevX);
+ rys.push_back(prevY);
+ }
+ delete [] xs;
+ delete [] ys;
+ n=rxs.size();
+ COLA_ASSERT(rys.size()==n);
+ xs = new double[n];
+ ys = new double[n];
+ copy(rxs.begin(),rxs.end(),xs);
+ copy(rys.begin(),rys.end(),ys);
+ }
+ /**
+ * sets up the path information for an edge,
+ * i.e. nodes are added to the path list in the order they appear on the
+ * edge, from startNode to endNode.
+ * activePath contains at least the first and last node in the edge.
+ * If allActive is true then
+ * activePath list is also set up with a subset of nodes from path, each of
+ * which is active (a start/end node or involved in a violated constraint).
+ */
+ void Edge::nodePath(vector<Node*>& nodes, bool allActive = true) {
+ list<unsigned> ds(dummyNodes.size());
+ copy(dummyNodes.begin(),dummyNodes.end(),ds.begin());
+ //printf("Edge::nodePath: (%d,%d) dummyNodes:%d\n",startNode,endNode,ds.size());
+ path.clear();
+ activePath.clear();
+ path.push_back(startNode);
+ activePath.push_back(0);
+ for(unsigned i=1;i<route->n;i++) {
+ //printf(" checking segment %d-%d\n",i-1,i);
+ set<pair<double,unsigned> > pntsOnLineSegment;
+ for(list<unsigned>::iterator j=ds.begin();j!=ds.end();) {
+ double px=nodes[*j]->pos[0];
+ double py=nodes[*j]->pos[1];
+ double ax=route->xs[i-1];
+ double ay=route->ys[i-1];
+ double bx=route->xs[i];
+ double by=route->ys[i];
+ double t=0;
+ list<unsigned>::iterator copyit=j++;
+ //printf(" px=%f, py=%f, ax=%f, ay=%f, bx=%f, by=%f\n",px,py,ax,ay,bx,by);
+ if(pointOnLine(px,py,ax,ay,bx,by,t)) {
+ //printf(" got node %d\n",*copyit);
+ pntsOnLineSegment.insert(make_pair(t,*copyit));
+ ds.erase(copyit);
+ }
+ }
+ for(set<pair<double,unsigned> >::iterator j=pntsOnLineSegment.begin();j!=pntsOnLineSegment.end();j++) {
+ if(allActive && nodes[j->second]->active) {
+ activePath.push_back(path.size());
+ }
+ path.push_back(j->second);
+ }
+ //printf("\n");
+ }
+ activePath.push_back(path.size());
+ path.push_back(endNode);
+ COLA_ASSERT(ds.empty());
+ }
+ void Edge::createRouteFromPath(std::vector<Node *> const & nodes) {
+ Route* r=new Route(path.size());
+#ifdef STRAIGHTENER_DEBUG
+ //printf("Route:");
+#endif
+ for(unsigned i=0;i<path.size();i++) {
+ r->xs[i]=nodes[path[i]]->pos[0];
+ r->ys[i]=nodes[path[i]]->pos[1];
+#ifdef STRAIGHTENER_DEBUG
+ //printf("(%f,%f)",r->xs[i],r->ys[i]);
+#endif
+ }
+#ifdef STRAIGHTENER_DEBUG
+ //printf("\n");
+#endif
+ setRoute(r);
+ }
+
+ typedef enum {Open, Close} EventType;
+ struct Event {
+ EventType type;
+ Node *v;
+ Edge *e;
+ double pos;
+ Event(EventType t, Node *v, double p) : type(t),v(v),e(nullptr),pos(p) {};
+ Event(EventType t, Edge *e, double p) : type(t),v(nullptr),e(e),pos(p) {};
+ };
+ /*
+ * the following relation defines a strict weak ordering over events, i.e.:
+ * irreflexivity: CompareEvents(e,e) == false
+ * antisymetry: CompareEvents(a,b) => !CompareEvents(b,a)
+ * transitivity: CompareEvents(a,b) && CompareEvents(b,c) => CompareEvents(a,c)
+ * transitivity of equivalence:
+ * !CompareEvents(a,b) && !CompareEvents(b,a) && !CompareEvents(b,c) && !CompareEvents(c,b)
+ * => !CompareEvents(a,c) && !CompareEvents(c,a)
+ */
+ struct CompareEvents {
+ bool operator() (Event *const &a, Event *const &b) const {
+ if(a->pos < b->pos) {
+ return true;
+ } else if(a->pos==b->pos) {
+ // All opens should come before closes when at the same position
+ if(a->type==Open && b->type==Close) return true;
+ if(a->type==Close && b->type==Open) return false;
+ // Edge opens at the same position as node opens, edge comes first
+ if(a->type==Open && b->type==Open) {
+ if(a->e && b->v) return true;
+ if(b->e && a->v) return false;
+ }
+ // Edge closes at the same position as node closes, node comes first
+ if(a->type==Close && b->type==Close) {
+ if(a->e && b->v) return false;
+ if(b->e && a->v) return true;
+ }
+ }
+ return false;
+ }
+ };
+
+ /**
+ * Search along scan line at conjpos for open edges to the left of v
+ * as far as l, and to the right of v as far as r.
+ * The result is a list of nodes L (including l,v,r and a bunch of
+ * new dummy nodes for each edge intersected - excluding edges
+ * connected to v).
+ * The new dummy nodes are also added to the end of the canonical
+ * node list: nodes.
+ */
+ void sortNeighbours(const vpsc::Dim dim, Node * v, Node * l, Node * r,
+ const double conjpos, vector<Edge*> const & openEdges,
+ vector<Node *>& L,vector<Node *>& nodes) {
+ double minpos=-DBL_MAX, maxpos=DBL_MAX;
+ if(l!=nullptr) {
+ L.push_back(l);
+ minpos=l->scanpos;
+ }
+ typedef pair<double,Edge*> PosEdgePair;
+ set<PosEdgePair> sortedEdges;
+ for(unsigned i=0;i<openEdges.size();i++) {
+ Edge *e=openEdges[i];
+ vector<double> bs;
+ if(dim==vpsc::HORIZONTAL) {
+ e->xpos(conjpos,bs);
+ } else {
+ e->ypos(conjpos,bs);
+ }
+ //std::cerr << "edge(intersections="<<bs.size()<<":("<<e->startNode<<","<<e->endNode<<"))"<<std::endl;
+ for(vector<double>::iterator it=bs.begin();it!=bs.end();it++) {
+ sortedEdges.insert(make_pair(*it,e));
+ }
+ }
+ for(set<PosEdgePair>::iterator i=sortedEdges.begin();i!=sortedEdges.end();i++) {
+ double pos=i->first;
+ if(pos < minpos) continue;
+ if(pos > v->scanpos) break;
+ // if edge is connected (start or end) to v then skip
+ // need to record start and end positions of edge segment!
+ Edge* e=i->second;
+ if(e->startNode==v->id||e->endNode==v->id) continue;
+ //if(l!=nullptr&&(e->startNode==l->id||e->endNode==l->id)) continue;
+ //cerr << "edge("<<e->startNode<<","<<e->endNode<<",pts="<<e->pts<<")"<<endl;
+ // here, we probably want to search for existing dummy
+ // nodes associated with the same edge within some
+ // range of (pos,conjpos), rather than creating new ones.
+ // Would require some sort of quad-tree structure
+ Node* d=dim==vpsc::HORIZONTAL?
+ new Node(nodes.size(),pos,conjpos,e):
+ new Node(nodes.size(),conjpos,pos,e);
+ L.push_back(d);
+ nodes.push_back(d);
+ }
+ L.push_back(v);
+
+ if(r!=nullptr) {
+ maxpos=r->scanpos;
+ }
+ for(set<PosEdgePair>::iterator i=sortedEdges.begin();i!=sortedEdges.end();i++) {
+ if(i->first < v->scanpos) continue;
+ if(i->first > maxpos) break;
+ double pos=i->first;
+ // if edge is connected (start or end) to v then skip
+ // need to record start and end positions of edge segment!
+ Edge* e=i->second;
+ if(e->startNode==v->id||e->endNode==v->id) continue;
+ //if(r!=nullptr&&(e->startNode==r->id||e->endNode==r->id)) continue;
+ //cerr << "edge("<<e->startNode<<","<<e->endNode<<",pts="<<e->pts<<")"<<endl;
+ Node* d=dim==vpsc::HORIZONTAL?
+ new Node(nodes.size(),pos,conjpos,e):
+ new Node(nodes.size(),conjpos,pos,e);
+ L.push_back(d);
+ nodes.push_back(d);
+ }
+ if(r!=nullptr) {
+ L.push_back(r);
+ }
+ }
+ static double overlap(vpsc::Dim k, Node const *u, Node const *v) {
+ if (u->pos[k] <= v->pos[k] && v->getMin(k) < u->getMax(k))
+ return u->getMax(k) - v->getMin(k);
+ if (v->pos[k] <= u->pos[k] && u->getMin(k) < v->getMax(k))
+ return v->getMax(k) - u->getMin(k);
+ return 0;
+ }
+
+ static cola::SeparationConstraint* createConstraint(
+ Node* u, Node* v, vpsc::Dim dim) {
+ double g=u->length[dim]+v->length[dim];
+ g/=2;
+ double sep=v->pos[dim]-u->pos[dim];
+ if(sep < g) {
+ u->active = true;
+ v->active = true;
+ }
+ //cerr << "Constraint: "<< u->id << "+"<<g<<"<="<<v->id<<endl;
+ return new cola::SeparationConstraint(dim, u->id, v->id, g);
+ }
+
+ template <typename T>
+ Event* createEvent(
+ const vpsc::Dim dim,
+ const EventType type,
+ T *v,
+ double border) {
+ double pos = (type==Open) ? v->getMin((vpsc::Dim)!dim)-border
+ : v->getMax((vpsc::Dim)!dim)+border ;
+ return new Event(type,v,pos);
+ }
+ /**
+ * Generates constraints to prevent node/edge and edge/edge intersections.
+ * Can be invoked to generate either horizontal or vertical constraints
+ * depending on dim parameter.
+ * For horizontal constraints, a vertical scan (from top to bottom) is
+ * conducted, looking for node/edge boundaries, and then searching along
+ * the horizontal limit of that boundary for intersections with other
+ * nodes/edges.
+ */
+ void generateConstraints(
+ const vpsc::Dim dim,
+ vector<Node*> & nodes,
+ vector<Edge*> const & edges,
+ vector<cola::SeparationConstraint*>& cs,
+ bool xSkipping = true) {
+ vector<Event*> events;
+ double nodeFudge=-0.01, edgeFudge=0;
+#ifdef STRAIGHTENER_DEBUG
+ cout << (dim==vpsc::HORIZONTAL
+ ?"scanning top to bottom..."
+ :"scanning left to right...")
+ << endl;
+#endif
+ for(unsigned i=0;i<nodes.size();i++) {
+ Node *v=nodes[i];
+ if(v->scan) {
+ v->scanpos=v->pos[dim];
+ events.push_back(createEvent(dim,Open,v,nodeFudge));
+ events.push_back(createEvent(dim,Close,v,nodeFudge));
+ }
+ }
+ for(unsigned i=0;i<edges.size();i++) {
+ Edge *e=edges[i];
+ events.push_back(createEvent(dim,Open,e,edgeFudge));
+ events.push_back(createEvent(dim,Close,e,edgeFudge));
+ }
+ std::sort(events.begin(),events.end(),CompareEvents());
+
+ NodeSet openNodes;
+ vector<Edge*> openEdges;
+ // scan opening and closing events in order
+ for(unsigned i=0;i<events.size();i++) {
+ Event *e=events[i];
+ Node *v=e->v;
+ if(v!=nullptr) {
+ v->open = true;
+#ifdef STRAIGHTENER_DEBUG
+ printf("NEvent@%f,nid=%d,(%f,%f),w=%f,h=%f,openn=%d,opene=%d\n",e->pos,v->id,v->pos[0],v->pos[1],v->length[0],v->length[1],(int)openNodes.size(),(int)openEdges.size());
+#endif
+ Node *l=nullptr, *r=nullptr;
+ if(!openNodes.empty()) {
+ // it points to the first node to the right of v
+ NodeSet::iterator it=openNodes.lower_bound(v);
+ // step left to find the first node to the left of v
+ while(it--!=openNodes.begin()) {
+ if(!xSkipping
+ || dim!=vpsc::HORIZONTAL
+ || overlap(vpsc::HORIZONTAL,*it,v) <= 0
+ || overlap(vpsc::HORIZONTAL,*it,v) <= overlap(vpsc::VERTICAL,*it,v)) {
+ l=*it;
+ break;
+ }
+#ifdef STRAIGHTENER_DEBUG
+ printf("l=%d\n",l->id);
+#endif
+ }
+ it=openNodes.upper_bound(v);
+ while(it!=openNodes.end()) {
+ if(!xSkipping
+ || dim!=vpsc::HORIZONTAL
+ || overlap(vpsc::HORIZONTAL,v,*it) <= 0
+ || overlap(vpsc::HORIZONTAL,v,*it) <= overlap(vpsc::VERTICAL,v,*it)) {
+ r=*it;
+ break;
+ }
+ it++;
+ }
+ }
+ vector<Node*> L;
+ sortNeighbours(dim,v,l,r,e->pos,openEdges,L,nodes);
+#ifdef STRAIGHTENER_DEBUG
+ printf("L=[");
+ for(unsigned i=0;i<L.size();i++) {
+ printf("%d ",L[i]->id);
+ }
+ printf("]\n");
+#endif
+ // for each dummy node w in L:
+ // if w left of v create constraints l<w, w<v
+ // if w right of v create constraints v<w, w<r
+ for(vector<Node*>::iterator i=L.begin();i!=L.end();i++) {
+ Node* w=*i;
+ if(w->dummy) {
+ // node is on an edge
+ Edge *edge=w->edge;
+ if(w->pos[dim]<v->pos[dim]) { // w left of v
+ if(l!=nullptr&&!edge->isEnd(l->id)) {
+ cs.push_back(createConstraint(l,w,dim));
+ }
+ if(!edge->isEnd(v->id)) {
+ cs.push_back(createConstraint(w,v,dim));
+ }
+ } else { // w right of v
+ if(!edge->isEnd(v->id)) {
+ cs.push_back(createConstraint(v,w,dim));
+ }
+ if(r!=nullptr&&!edge->isEnd(r->id)) {
+ cs.push_back(createConstraint(w,r,dim));
+ }
+ }
+ }
+ }
+ if(e->type==Close) {
+ if(l!=nullptr) cs.push_back(createConstraint(l,v,dim));
+ if(r!=nullptr) cs.push_back(createConstraint(v,r,dim));
+ }
+ }
+ if(e->type==Open) {
+ if(v!=nullptr) {
+ openNodes.insert(v);
+ } else {
+#ifdef STRAIGHTENER_DEBUG
+ printf("EdgeOpen@%f,eid=%d,(u,v)=(%d,%d)\n", e->pos,e->e->id,e->e->startNode,e->e->endNode);
+#endif
+ e->e->openInd=openEdges.size();
+ openEdges.push_back(e->e);
+ }
+ } else {
+ // Close
+ if(v!=nullptr) {
+ openNodes.erase(v);
+ v->open=false;
+ } else {
+#ifdef STRAIGHTENER_DEBUG
+ printf("EdgeClose@%f,eid=%d,(u,v)=(%d,%d)\n", e->pos,e->e->id,e->e->startNode,e->e->endNode);
+#endif
+ unsigned i=e->e->openInd;
+ COLA_ASSERT(openEdges.size()>0);
+ openEdges[i]=openEdges[openEdges.size()-1];
+ openEdges[i]->openInd=i;
+ openEdges.resize(openEdges.size()-1);
+ }
+ }
+ delete e;
+ }
+ }
+ /**
+ * set up straightener clusters.
+ * For each cola::cluster c:
+ * create a straightener::cluster sc
+ * set each node in c to belong to sc
+ * set scanpos based on avg pos in scan dir
+ * create a chain of dummy nodes for cluster boundary
+ */
+ void generateClusterBoundaries(
+ const vpsc::Dim dim,
+ vector<straightener::Node*> & nodes,
+ vector<straightener::Edge*> & edges,
+ vector<vpsc::Rectangle*> const & rs,
+ cola::Cluster const & clusterHierarchy,
+ vector<straightener::Cluster*>& sclusters) {
+ sclusters.clear();
+ for(vector<cola::Cluster*>::const_iterator i
+ =clusterHierarchy.clusters.begin();
+ i!=clusterHierarchy.clusters.end(); i++) {
+ if(cola::ConvexCluster* c=dynamic_cast<cola::ConvexCluster*>(*i)) {
+ straightener::Cluster* sc=new straightener::Cluster(c);
+ // compute scanpos based on average position in scan direction
+ sc->scanpos=0;
+ for(set<unsigned>::iterator it= c->nodes.begin();
+ it != c->nodes.end(); ++it) {
+ straightener::Node* u = nodes[*it];
+ sc->scanpos+=u->pos[dim];
+ u->cluster = sc;
+ }
+ sc->scanpos/=c->nodes.size();
+ sclusters.push_back(sc);
+ c->computeBoundary(rs);
+ // create a chain of dummy nodes for the boundary
+ Node* first = new Node(nodes.size(),c->hullX[0],c->hullY[0]);
+ nodes.push_back(first);
+ Node* u = first;
+ unsigned i=1;
+ for(;i<c->hullX.size();i++) {
+ Node* v = new Node(nodes.size(),c->hullX[i],c->hullY[i]);
+ nodes.push_back(v);
+ Edge* e = new Edge(edges.size(),u->id,v->id,
+ c->hullX[i-1],c->hullY[i-1],c->hullX[i],c->hullY[i]);
+ edges.push_back(e);
+ sc->boundary.push_back(e);
+ u=v;
+ }
+ edges.push_back(
+ new Edge(edges.size(),u->id,first->id,
+ c->hullX[i-1],c->hullY[i-1],c->hullX[0],c->hullY[0]));
+ }
+ }
+ }
+
+ void Cluster::updateActualBoundary()
+ {
+ unsigned n=0;
+ for(std::vector<Edge*>::const_iterator e=boundary.begin();
+ e!=boundary.end();e++) {
+ n+=(*e)->getRoute()->n;
+ }
+ colaCluster->hullX.resize(n);
+ colaCluster->hullY.resize(n);
+ unsigned i=0;
+ for(std::vector<Edge*>::const_iterator e=boundary.begin();
+ e!=boundary.end();e++) {
+ Route const * r=(*e)->getRoute();
+ for(unsigned j=0;j<r->n;j++) {
+ colaCluster->hullX[i]=r->xs[j];
+ colaCluster->hullY[i++]=r->ys[j];
+ }
+ }
+ }
+ Straightener::Straightener(
+ const double strength,
+ const vpsc::Dim dim,
+ std::vector<vpsc::Rectangle*> const & rs,
+ cola::FixedList const & fixed,
+ std::vector<Edge*> const & edges,
+ vpsc::Variables const & vs,
+ vpsc::Variables & lvs,
+ vpsc::Constraints & lcs,
+ std::valarray<double> &oldCoords,
+ std::valarray<double> &oldG)
+ : strength(strength),
+ dim(dim),
+ fixed(fixed),
+ edges(edges),
+ vs(vs),
+ lvs(lvs)
+ {
+ unsigned n=rs.size();
+ for (unsigned i=0;i<n;i++) {
+ nodes.push_back(new straightener::Node(i,rs[i]));
+ }
+ vector<cola::SeparationConstraint*> cs;
+ straightener::generateConstraints(dim,nodes,edges,cs);
+ // after generateConstraints we have new dummy nodes at the end of snodes and
+ // constraints in cs
+ // need to create variables for dummy nodes in lvs and constraints in lcs
+ N=nodes.size();
+ g.resize(N);
+ coords.resize(N);
+ for(unsigned i=0;i<n;i++) {
+ g[i]=oldG[i];
+ coords[i]=oldCoords[i];
+ }
+ for (unsigned i=n;i<N;i++) {
+ double desiredPos = nodes[i]->pos[dim];
+ lvs.push_back(new vpsc::Variable(i,desiredPos,1));
+ g[i]=0;
+ coords[i]=desiredPos;
+ }
+ for (vector<cola::SeparationConstraint*>::iterator i=cs.begin();i!=cs.end();i++) {
+ unsigned lv=(*i)->left();
+ unsigned rv=(*i)->right();
+ double gap=(*i)->gap;
+ vpsc::Variable* l = lv<n?vs[lv]:lvs[lv-n];
+ vpsc::Variable* r = rv<n?vs[rv]:lvs[rv-n];
+ lcs.push_back(new vpsc::Constraint(l,r,gap));
+ }
+ for(unsigned i=0;i<edges.size();i++) {
+ edges[i]->nodePath(nodes,false);
+ }
+ for_each(cs.begin(),cs.end(),cola::delete_object());
+ }
+ Straightener::~Straightener() {
+ for_each(nodes.begin(),nodes.end(),cola::delete_object());
+ }
+ void Straightener::computeForces(cola::SparseMap &H) {
+ // hessian matrix:
+ // diagonal: sum dy2/l^3
+ // off-diag: -dy2/l^3
+ for(unsigned i=0;i<edges.size();i++) {
+ //printf("Straightening path:\n");
+ //edges[i]->print();
+ vector<unsigned>& path=edges[i]->path;
+ COLA_ASSERT(path.size()>0);
+ for(unsigned j=1;j<path.size();j++) {
+ unsigned u=path[j-1], v=path[j];
+ double x1=nodes[u]->pos[0], x2=nodes[v]->pos[0],
+ y1=nodes[u]->pos[1], y2=nodes[v]->pos[1];
+ double dx=x1-x2, dy=y1-y2;
+ double dx2=dx*dx, dy2=dy*dy;
+ double l=sqrt(dx2+dy2);
+ if(l<0.0000001) continue;
+ double f=dim==vpsc::HORIZONTAL?dx:dy;
+ f*=strength/l;
+ if(!fixed.check(u)) { g[u]+=f; }
+ if(!fixed.check(v)) { g[v]-=f; }
+ double h=dim==vpsc::HORIZONTAL?dy2:dx2;
+ h*=strength/(l*l*l);
+ H(u,u)+=h;
+ H(v,v)+=h;
+ H(u,v)-=h;
+ H(v,u)-=h;
+ }
+ }
+ }
+ double Straightener::computeStress(std::valarray<double> const &coords) {
+ double stress=0;
+ for(unsigned i=0;i<edges.size();i++) {
+ vector<unsigned>& path=edges[i]->path;
+ COLA_ASSERT(path.size()>0);
+ for(unsigned j=1;j<path.size();j++) {
+ unsigned u=path[j-1], v=path[j];
+ double x1,x2,y1,y2;
+ if(dim==vpsc::HORIZONTAL) {
+ x1=coords[u];
+ x2=coords[v];
+ y1=nodes[u]->pos[1];
+ y2=nodes[v]->pos[1];
+ } else {
+ x1=nodes[u]->pos[0];
+ x2=nodes[v]->pos[0];
+ y1=coords[u];
+ y2=coords[v];
+ }
+ double dx=x1-x2, dy=y1-y2;
+ double dx2=dx*dx, dy2=dy*dy;
+ double l=sqrt(dx2+dy2);
+ stress+=l;
+ }
+ }
+ return strength*stress;
+ }
+ double Straightener::computeStress2(std::valarray<double> const &coords)
+ {
+ COLA_UNUSED(coords);
+
+ double stress=0;
+ for(unsigned i=0;i<edges.size();i++) {
+ double d = edges[i]->idealLength;
+ double weight=1/(d*d);
+ //printf("pathLength=%f\n",pathLength(edges[i],nodes));
+ double sqrtf=fabs(d-pathLength(edges[i],nodes));
+ stress+=weight*sqrtf*sqrtf;
+ }
+ return strength*stress;
+ }
+ void Straightener::updateNodePositions() {
+ // real nodes
+ for (unsigned i=0;i<N;i++) {
+ Node *n=nodes[i];
+ n->pos[dim]=coords[i];
+ }
+ // dummy bend nodes
+ //printf("got %d dummy nodes\n", (int) lvs.size());
+ dummyNodesX.resize(lvs.size());
+ dummyNodesY.resize(lvs.size());
+ for (unsigned i=0;i<lvs.size();i++) {
+ COLA_ASSERT(i+vs.size() < nodes.size());
+ Node *n=nodes[i+vs.size()];
+ dummyNodesX[i]=n->pos[0];
+ dummyNodesY[i]=n->pos[1];
+ }
+ }
+ void Straightener::finalizeRoutes() {
+ for(unsigned i=0;i<edges.size();i++) {
+ edges[i]->createRouteFromPath(nodes);
+ edges[i]->dummyNodes.clear();
+ edges[i]->path.clear();
+ }
+ }
+ void setEdgeLengths(double **D, vector<Edge*> & edges) {
+ for(unsigned i=0;i<edges.size();i++) {
+ Edge* e=edges[i];
+ e->idealLength=D[e->startNode][e->endNode];
+ }
+ }
+ double pathLength(Edge const * e, vector<Node*> const & nodes) {
+ double length=0;
+ vector<unsigned> const & path=e->path;
+ for(unsigned i=1;i<path.size();i++) {
+ Node *u=nodes[path[i-1]], *v=nodes[path[i]];
+ double dx=u->pos[0]-v->pos[0];
+ double dy=u->pos[1]-v->pos[1];
+ length+=sqrt(dx*dx+dy*dy);
+ }
+ return length;
+ }
+ double computeStressFromRoutes(double strength, vector<Edge*> & edges) {
+ double stress=0;
+ for(unsigned i=0;i<edges.size();i++) {
+ Edge* e=edges[i];
+ double d = e->idealLength;
+ double weight=1/(d*d);
+ double sqrtf=fabs(d-e->getRoute()->routeLength());
+ stress+=weight*sqrtf*sqrtf;
+ }
+ return strength*stress;
+ }
+}
+
diff --git a/src/3rdparty/adaptagrams/libcola/straightener.h b/src/3rdparty/adaptagrams/libcola/straightener.h
new file mode 100644
index 0000000..846f4f9
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/straightener.h
@@ -0,0 +1,389 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef STRAIGHTENER_H
+#define STRAIGHTENER_H
+
+#include <set>
+#include <cfloat>
+#include <iostream>
+#include <iterator>
+
+#include "libvpsc/rectangle.h"
+#include "libcola/commondefs.h"
+
+namespace cola {
+ class Cluster;
+ class ConvexCluster;
+ class SeparationConstraint;
+}
+namespace straightener {
+
+struct Route {
+ Route(unsigned n) : n(n), xs(new double[n]), ys(new double[n]) {}
+ ~Route() {
+ delete [] xs;
+ delete [] ys;
+ }
+ void print() {
+ std::cout << "double xs[]={";
+ std::copy(xs,xs+n-1,std::ostream_iterator<double>(std::cout,","));
+ std::cout << xs[n-1] << "};" << std::endl << "double ys[]={";
+ std::copy(ys,ys+n-1,std::ostream_iterator<double>(std::cout,","));
+ std::cout << ys[n-1] << "};" << std::endl;
+ }
+ void boundingBox(double &xmin,double &ymin,double &xmax,double &ymax) {
+ xmin=ymin=DBL_MAX;
+ xmax=ymax=-DBL_MAX;
+ for(unsigned i=0;i<n;i++) {
+ xmin=std::min(xmin,xs[i]);
+ xmax=std::max(xmax,xs[i]);
+ ymin=std::min(ymin,ys[i]);
+ ymax=std::max(ymax,ys[i]);
+ }
+ }
+ double routeLength () const {
+ double length=0;
+ for(unsigned i=1;i<n;i++) {
+ double dx=xs[i-1]-xs[i];
+ double dy=ys[i-1]-ys[i];
+ length+=sqrt(dx*dx+dy*dy);
+ }
+ return length;
+ }
+ void rerouteAround(vpsc::Rectangle *rect);
+ unsigned n;
+ double *xs;
+ double *ys;
+};
+class Node;
+struct DebugPoint {
+ double x,y;
+};
+struct DebugLine {
+ DebugLine(double x0,double y0,double x1,double y1,unsigned colour)
+ : x0(x0),y0(y0),x1(x1),y1(y1),colour(colour) {}
+ double x0,y0,x1,y1;
+ unsigned colour;
+};
+class ScanObject {
+public:
+ const unsigned id;
+ double getMin(vpsc::Dim d) const {
+ return min[d];
+ }
+ double getMax(vpsc::Dim d) const {
+ return max[d];
+ }
+ ScanObject(unsigned id) : id(id) {}
+protected:
+ double min[2], max[2];
+};
+class Edge : public ScanObject {
+public:
+ unsigned openInd; // position in openEdges
+ unsigned startNode, endNode;
+ double idealLength;
+ std::vector<unsigned> dummyNodes;
+ std::vector<unsigned> path;
+ std::vector<unsigned> activePath;
+ std::vector<DebugPoint> debugPoints;
+ std::vector<DebugLine> debugLines;
+ void print() {
+ printf("Edge[%d]=(%d,%d)\n",id,startNode,endNode);
+ route->print();
+ }
+ // if the edge route intersects with any of the rectangles in rects then reroute
+ // those parts of the route around the rectangle boundaries
+ void rerouteAround(std::vector<vpsc::Rectangle*> const &rects) {
+ unsigned rid=0;
+ for(std::vector<vpsc::Rectangle*>::const_iterator r=rects.begin();r!=rects.end();r++,rid++) {
+ if(rid!=startNode && rid!=endNode) {
+ route->rerouteAround(*r);
+ }
+ }
+ updateBoundingBox();
+ }
+ // Edge with a non-trivial route
+ Edge(unsigned id, unsigned start, unsigned end, Route* route)
+ : ScanObject(id), startNode(start), endNode(end), route(route)
+ {
+ updateBoundingBox();
+ }
+ // Edge with a trivial route
+ Edge(unsigned id, unsigned start, unsigned end,
+ double x1, double y1, double x2, double y2)
+ : ScanObject(id), startNode(start), endNode(end) {
+ route = new Route(2);
+ route->xs[0]=x1; route->ys[0]=y1;
+ route->xs[1]=x2; route->ys[1]=y2;
+ updateBoundingBox();
+ }
+ ~Edge() {
+ delete route;
+ }
+ bool isEnd(unsigned n) const {
+ if(startNode==n||endNode==n) return true;
+ return false;
+ }
+ void nodePath(std::vector<Node*>& nodes, bool allActive);
+ void createRouteFromPath(std::vector<Node *> const & nodes);
+ void xpos(double y, std::vector<double>& xs) const {
+ // search line segments for intersection points with y pos
+ for(unsigned i=1;i<route->n;i++) {
+ double ax=route->xs[i-1], bx=route->xs[i], ay=route->ys[i-1], by=route->ys[i];
+ double r=(y-ay)/(by-ay);
+ // as long as y is between ay and by then r>0
+ if(r>=0&&r<=1) {
+ xs.push_back(ax+(bx-ax)*r);
+ }
+ }
+ }
+ void ypos(double x, std::vector<double>& ys) const {
+ // search line segments for intersection points with x pos
+ for(unsigned i=1;i<route->n;i++) {
+ double ax=route->xs[i-1], bx=route->xs[i], ay=route->ys[i-1], by=route->ys[i];
+ double r=(x-ax)/(bx-ax);
+ // as long as y is between ax and bx then r>0
+ if(r>0&&r<=1) {
+ ys.push_back(ay+(by-ay)*r);
+ }
+ }
+ }
+ Route const * getRoute() const {
+ return route;
+ }
+ void setRoute(Route * r) {
+ delete route;
+ route=r;
+ updateBoundingBox();
+ }
+private:
+ void updateBoundingBox() {
+ route->boundingBox(min[0],min[1],max[0],max[1]);
+ }
+ Route* route;
+};
+class Straightener {
+public:
+ Straightener(
+ const double strength,
+ const vpsc::Dim dim,
+ std::vector<vpsc::Rectangle*> const & rs,
+ cola::FixedList const & fixed,
+ std::vector<Edge*> const & edges,
+ vpsc::Variables const & vs,
+ vpsc::Variables & lvs,
+ vpsc::Constraints & lcs,
+ std::valarray<double> & oldCoords,
+ std::valarray<double> & oldG);
+ ~Straightener();
+ void updateNodePositions();
+ void finalizeRoutes();
+ void computeForces(cola::SparseMap &H);
+ void computeForces2(cola::SparseMap &H);
+ double computeStress(std::valarray<double> const &coords);
+ double computeStress2(std::valarray<double> const &coords);
+ std::valarray<double> dummyNodesX;
+ std::valarray<double> dummyNodesY;
+ std::valarray<double> g;
+ std::valarray<double> coords;
+ unsigned N;
+private:
+ double strength;
+ const vpsc::Dim dim;
+ cola::FixedList const & fixed;
+ std::vector<Edge*> const & edges;
+ vpsc::Variables const & vs;
+ vpsc::Variables & lvs;
+ std::vector<Node*> nodes;
+ double len(const unsigned u, const unsigned v,
+ double& dx, double& dy,
+ double& dx2, double& dy2);
+ double gRule1(const unsigned a, const unsigned b);
+ double gRule2(const unsigned a, const unsigned b, const unsigned c);
+ double hRuleD1(const unsigned u, const unsigned v, const double sqrtf);
+ double hRuleD2(const unsigned u, const unsigned v, const unsigned w, const double sqrtf);
+ double hRule2(const unsigned u, const unsigned v, const unsigned w, const double sqrtf);
+ double hRule3(const unsigned u, const unsigned v, const unsigned w, const double sqrtf);
+ double hRule4(const unsigned a, const unsigned b, const unsigned c, const unsigned d);
+ double hRule56(const unsigned u, const unsigned v,
+ const unsigned a, const unsigned b, const unsigned c);
+ double hRule7(const unsigned a, const unsigned b,
+ const unsigned c, const unsigned d, const double sqrtf);
+ double hRule8(const unsigned u, const unsigned v, const unsigned w,
+ const unsigned a, const unsigned b, const unsigned c);
+};
+class Cluster {
+public:
+ cola::ConvexCluster* colaCluster;
+ Cluster(cola::ConvexCluster* c) : colaCluster(c) {}
+ double scanpos;
+ std::vector<Edge*> boundary;
+ void updateActualBoundary();
+};
+class Node : public ScanObject {
+public:
+ Cluster* cluster;
+ // Nodes may optionally belong to a cluster.
+ // Neg cluster_id means no cluster - i.e. top-level membership.
+ double pos[2];
+ double scanpos;
+ double length[2];
+ Edge* edge;
+ bool dummy; // nodes on edge paths (but not ends) are dummy
+ bool scan; // triggers scan events
+ bool active; // node is active if it is not dummy or is dummy and involved in
+ // a violated constraint
+ bool open; // a node is opened (if scan is true) when the scanline first reaches
+ // its boundary and closed when the scanline leaves it.
+ Node(unsigned id, vpsc::Rectangle const * r) :
+ ScanObject(id),cluster(nullptr),
+ edge(nullptr),dummy(false),scan(true),active(true),open(false) {
+ for(unsigned i=0;i<2;i++) {
+ pos[i]=r->getCentreD(i);
+ min[i]=r->getMinD(i);
+ max[i]=r->getMaxD(i);
+ length[i]=r->length(i);
+ }
+ }
+ Node(unsigned id, const double x, const double y) :
+ ScanObject(id),cluster(nullptr),
+ edge(nullptr),dummy(false),scan(false),active(true),open(false) {
+ pos[vpsc::HORIZONTAL]=x;
+ pos[vpsc::VERTICAL]=y;
+ for(unsigned i=0;i<2;i++) {
+ length[i]=4;
+ min[i]=pos[i]-length[i]/2.0;
+ max[i]=pos[i]+length[i]/2.0;
+ }
+ }
+ double euclidean_distance(Node const * v) const {
+ double dx=pos[0]-v->pos[0];
+ double dy=pos[1]-v->pos[1];
+ return sqrt(dx*dx+dy*dy);
+ }
+
+private:
+ friend void sortNeighbours(const vpsc::Dim dim, Node * v, Node * l, Node * r,
+ const double conjpos, std::vector<Edge*> const & openEdges,
+ std::vector<Node *>& L, std::vector<Node *>& nodes);
+ Node(const unsigned id, const double x, const double y, Edge* e) :
+ ScanObject(id),cluster(nullptr),
+ edge(e),dummy(true),scan(false),active(false) {
+ pos[vpsc::HORIZONTAL]=x;
+ pos[vpsc::VERTICAL]=y;
+ for(unsigned i=0;i<2;i++) {
+ length[i]=4;
+ min[i]=pos[i]-length[i]/2.0;
+ max[i]=pos[i]+length[i]/2.0;
+ }
+ e->dummyNodes.push_back(id);
+ }
+};
+struct CmpNodePos {
+ bool operator() (const Node* u, const Node* v) const {
+ double upos = u->scanpos;
+ double vpos = v->scanpos;
+ bool tiebreaker = u < v;
+ if (u->cluster != v->cluster) {
+ if(u->cluster!=nullptr) {
+ upos = u->cluster->scanpos;
+ }
+ if(v->cluster!=nullptr) {
+ vpos = v->cluster->scanpos;
+ }
+ tiebreaker = u->cluster < v->cluster;
+ }
+ if (upos < vpos) {
+ return true;
+ }
+ if (vpos < upos) {
+ return false;
+ }
+ return tiebreaker;
+ }
+};
+typedef std::set<Node*,CmpNodePos> NodeSet;
+// defines references to three variables for which the goal function
+// will be altered to prefer points u-b-v are in a linear arrangement
+// such that b is placed at u+t(v-u).
+struct LinearConstraint {
+ LinearConstraint(
+ Node const & u,
+ Node const & v,
+ Node const & b,
+ double w)
+ : u(u.id),v(v.id),b(b.id),w(w)
+ {
+ // from cosine rule: ub.uv/|uv|=|ub|cos(theta)
+ double uvx = v.pos[0] - u.pos[0],
+ uvy = v.pos[1] - u.pos[1],
+ ubx = b.pos[0] - u.pos[0],
+ uby = b.pos[1] - u.pos[1],
+ duv2 = uvx * uvx + uvy * uvy;
+ if(duv2 < 0.0001) {
+ t=0;
+ } else {
+ t = (uvx * ubx + uvy * uby)/duv2;
+ }
+ duu=(1-t)*(1-t);
+ duv=t*(1-t);
+ dub=t-1;
+ dvv=t*t;
+ dvb=-t;
+ dbb=1;
+ //printf("New LC: t=%f\n",t);
+ }
+ unsigned u;
+ unsigned v;
+ unsigned b;
+ double w; // weight
+ double t;
+ // 2nd partial derivatives of the goal function
+ // (X[b] - (1-t) X[u] - t X[v])^2
+ double duu;
+ double duv;
+ double dub;
+ double dvv;
+ double dvb;
+ double dbb;
+};
+void setEdgeLengths(double **D, std::vector<Edge*> & edges);
+double pathLength(Edge const * e, std::vector<Node*> const & nodes);
+double computeStressFromRoutes(double strength, std::vector<Edge*> & edges);
+typedef std::vector<LinearConstraint*> LinearConstraints;
+void generateConstraints(
+ const vpsc::Dim dim,
+ std::vector<Node*> & nodes,
+ std::vector<Edge*> const & edges,
+ std::vector<cola::SeparationConstraint*>& cs,
+ bool xSkipping);
+void nodePath(Edge& e, std::vector<Node*>& nodes, std::vector<unsigned>& path);
+void generateClusterBoundaries(
+ const vpsc::Dim dim,
+ std::vector<Node*> & nodes,
+ std::vector<Edge*> & edges,
+ std::vector<vpsc::Rectangle*> const & rs,
+ cola::Cluster const & clusterHierarchy,
+ std::vector<straightener::Cluster*>& sclusters);
+
+} // namespace straightener
+#endif
diff --git a/src/3rdparty/adaptagrams/libcola/tests/FixedRelativeConstraint01.cpp b/src/3rdparty/adaptagrams/libcola/tests/FixedRelativeConstraint01.cpp
new file mode 100755
index 0000000..378219e
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/FixedRelativeConstraint01.cpp
@@ -0,0 +1,51 @@
+#include <vector>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ double defaultEdgeLength=40;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+ std::vector<unsigned> fixedShapes;
+
+ double textW = 100;
+ double textH = 10;
+ double circleW = 5;
+ double circleH = 5;
+
+ rect = new vpsc::Rectangle(303-circleW, 303+circleW, 300-circleH, 300+circleH);
+ rs.push_back(rect);
+ fixedShapes.push_back(rs.size() - 1);
+
+ rect = new vpsc::Rectangle(310-circleW, 310+circleW, 302-circleH, 302+circleH);
+ rs.push_back(rect);
+ fixedShapes.push_back(rs.size() - 1);
+
+ rect = new vpsc::Rectangle(313-circleW, 313+circleW, 297-circleH, 297+circleH);
+ rs.push_back(rect);
+ fixedShapes.push_back(rs.size() - 1);
+
+ rect = new vpsc::Rectangle(300-textW, 300+textW, 300-textH, 300+textH);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(310-textW, 310+textW, 305-textH, 305+textH);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(317-textW, 317+textW, 295-textH, 295+textH);
+ rs.push_back(rect);
+
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength);
+ alg.setAvoidNodeOverlaps(true);
+
+ ccs.push_back(new FixedRelativeConstraint(rs, fixedShapes, true));
+ alg.setConstraints(ccs);
+
+ alg.makeFeasible();
+
+ // Can be used to output a "libcola-debug.svg" file:
+ //alg.outputInstanceToSVG();
+ alg.freeAssociatedObjects();
+
+ return 0;
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/Makefile.am b/src/3rdparty/adaptagrams/libcola/tests/Makefile.am
new file mode 100644
index 0000000..a73ff82
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/Makefile.am
@@ -0,0 +1,68 @@
+AM_CPPFLAGS = -I$(top_srcdir) $(CAIROMM_CFLAGS)
+
+LDADD = \
+ $(top_builddir)/libvpsc/libvpsc.la \
+ $(top_builddir)/libtopology/libtopology.la \
+ $(top_builddir)/libcola/libcola.la \
+ $(top_builddir)/libavoid/libavoid.la \
+ $(CAIROMM_LIBS)
+
+check_PROGRAMS = random_graph page_bounds constrained unsatisfiable invalid makefeasible rectclustershapecontainment FixedRelativeConstraint01 StillOverlap01 StillOverlap02 shortest_paths rectangularClusters01 overlappingClusters01 overlappingClusters02 overlappingClusters04 initialOverlap
+#check_PROGRAMS = unconstrained constrained containment shortest_paths connected_components large_graph convex_hull scale_free trees random_graph large_graph topology boundary planar #resize
+#check_PROGRAMS = topology boundary planar resize resizealignment
+
+# problem_SOURCES = problem.cpp
+
+initialOverlap_SOURCES = initialOverlap.cpp
+
+overlappingClusters01_SOURCES = overlappingClusters01.cpp
+overlappingClusters02_SOURCES = overlappingClusters02.cpp
+overlappingClusters04_SOURCES = overlappingClusters04.cpp
+
+rectangularClusters01_SOURCES = rectangularClusters01.cpp
+
+StillOverlap01_SOURCES = StillOverlap01.cpp
+StillOverlap02_SOURCES = StillOverlap02.cpp
+
+FixedRelativeConstraint01_SOURCES = FixedRelativeConstraint01.cpp
+
+rectclustershapecontainment_SOURCES = rectclustershapecontainment.cpp
+
+random_graph_SOURCES = random_graph.cpp
+
+page_bounds_SOURCES = page_bounds.cpp
+
+constrained_SOURCES = constrained.cpp
+
+unsatisfiable_SOURCES = unsatisfiable.cpp
+
+invalid_SOURCES = invalid.cpp
+
+makefeasible_LDADD = $(LDADD) $(top_srcdir)/libavoid/libavoid.la
+makefeasible_SOURCES = makefeasible02.cpp
+
+shortest_paths_SOURCES = shortest_paths.cpp
+#unconstrained_SOURCES = unconstrained.cpp
+#containment_SOURCES = containment.cpp
+#topology_SOURCES = topology.cpp
+#boundary_SOURCES = boundary.cpp
+#resize_SOURCES = resize.cpp
+#resizealignment_SOURCES = resizealignment.cpp
+#planar_SOURCES = planar.cpp
+#connected_components_SOURCES = connected_components.cpp
+# test Requires boost
+#sparse_matrix_SOURCES = sparse_matrix.cpp
+#convex_hull_SOURCES = convex_hull.cpp
+#convex_hull_LDADD = $(LDADD) -lcairo -lcairomm-1.0
+#aarontest_SOURCES = aarontest.cpp
+#aarontest_LDADD = $(top_srcdir)/libcola/libcola.la $(top_builddir)/libvpsc/libvpsc.la -lcairo -lcairomm-1.0
+#qo1_SOURCES = qo1.c
+#qo1_LDADD = -L$(mosek_home)/bin -lmosek -lguide -limf
+#small_graph_SOURCES = small_graph.cpp
+#large_graph_SOURCES = large_graph.cpp
+#gml_graph_LDADD = $(common_LDADD) /usr/lib/libboost_regex.so
+#gml_graph_SOURCES = gml_graph.cpp
+#scale_free_SOURCES = scale_free.cpp
+#trees_SOURCES = trees.cpp
+
+TESTS = $(check_PROGRAMS)
diff --git a/src/3rdparty/adaptagrams/libcola/tests/StillOverlap01.cpp b/src/3rdparty/adaptagrams/libcola/tests/StillOverlap01.cpp
new file mode 100755
index 0000000..1b87767
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/StillOverlap01.cpp
@@ -0,0 +1,221 @@
+#include <vector>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ double defaultEdgeLength=40;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ rect = new vpsc::Rectangle(210, 240, 83.5, 113.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(210, 240, 125.5, 155.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(377, 407, 43.5, 73.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(251, 281, 43.5, 73.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(110, 140, 43.5, 73.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(29, 79, 55.5, 105.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(427, 477, 32.5, 82.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(300, 350, 32.5, 82.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(171, 221, 32.5, 82.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(33, 83, 115.5, 165.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(522, 572, 115.5, 165.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(519, 569, 35.5, 85.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(192, 258, 123.5, 173.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(192, 258, 65.5, 115.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(359, 425, -16.5, 33.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(233, 299, -16.5, 33.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(154, 220, 33.5, 83.5);
+ rs.push_back(rect);
+
+ AlignmentConstraint *alignment140600592030544 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592030544->addShape(1, 0);
+ alignment140600592030544->addShape(0, 0);
+ ccs.push_back(alignment140600592030544);
+
+ AlignmentConstraint *alignment140600592030848 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592030848->addShape(2, 0);
+ ccs.push_back(alignment140600592030848);
+
+ AlignmentConstraint *alignment140600592031040 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592031040->addShape(3, 0);
+ ccs.push_back(alignment140600592031040);
+
+ AlignmentConstraint *alignment140600592031168 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592031168->addShape(4, 0);
+ ccs.push_back(alignment140600592031168);
+
+ AlignmentConstraint *alignment140600592031296 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592031296->addShape(5, 0);
+ ccs.push_back(alignment140600592031296);
+
+ AlignmentConstraint *alignment140600592031456 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592031456->addShape(6, 0);
+ ccs.push_back(alignment140600592031456);
+
+ AlignmentConstraint *alignment140600592031616 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592031616->addShape(7, 0);
+ ccs.push_back(alignment140600592031616);
+
+ AlignmentConstraint *alignment140600592031776 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592031776->addShape(8, 0);
+ ccs.push_back(alignment140600592031776);
+
+ AlignmentConstraint *alignment140600592031936 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592031936->addShape(9, 0);
+ ccs.push_back(alignment140600592031936);
+
+ AlignmentConstraint *alignment140600592032240 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592032240->addShape(10, 0);
+ ccs.push_back(alignment140600592032240);
+
+ AlignmentConstraint *alignment140600592032400 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592032400->addShape(11, 0);
+ ccs.push_back(alignment140600592032400);
+
+ SeparationConstraint *separation140600592044112 = new SeparationConstraint(vpsc::XDIM, alignment140600592031296, alignment140600592031936, 4, false);
+ ccs.push_back(separation140600592044112);
+
+ SeparationConstraint *separation140600592045280 = new SeparationConstraint(vpsc::XDIM, alignment140600592031936, alignment140600592031168, 67, false);
+ ccs.push_back(separation140600592045280);
+
+ SeparationConstraint *separation140600592045376 = new SeparationConstraint(vpsc::XDIM, alignment140600592031168, alignment140600592031776, 71, false);
+ ccs.push_back(separation140600592045376);
+
+ SeparationConstraint *separation140600592045520 = new SeparationConstraint(vpsc::XDIM, alignment140600592031776, alignment140600592030544, 29, false);
+ ccs.push_back(separation140600592045520);
+
+ SeparationConstraint *separation140600592045696 = new SeparationConstraint(vpsc::XDIM, alignment140600592030544, alignment140600592031040, 41, false);
+ ccs.push_back(separation140600592045696);
+
+ SeparationConstraint *separation140600592045872 = new SeparationConstraint(vpsc::XDIM, alignment140600592031040, alignment140600592031616, 59, false);
+ ccs.push_back(separation140600592045872);
+
+ SeparationConstraint *separation140600592043472 = new SeparationConstraint(vpsc::XDIM, alignment140600592031616, alignment140600592030848, 67, false);
+ ccs.push_back(separation140600592043472);
+
+ SeparationConstraint *separation140600592043648 = new SeparationConstraint(vpsc::XDIM, alignment140600592030848, alignment140600592031456, 60, false);
+ ccs.push_back(separation140600592043648);
+
+ SeparationConstraint *separation140600592043824 = new SeparationConstraint(vpsc::XDIM, alignment140600592031456, alignment140600592032400, 92, false);
+ ccs.push_back(separation140600592043824);
+
+ SeparationConstraint *separation140600592046048 = new SeparationConstraint(vpsc::XDIM, alignment140600592032400, alignment140600592032240, 3, false);
+ ccs.push_back(separation140600592046048);
+
+ AlignmentConstraint *alignment140600592044208 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140600592044208->addShape(0, 0);
+ ccs.push_back(alignment140600592044208);
+
+ AlignmentConstraint *alignment140600592044368 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140600592044368->addShape(5, 0);
+ ccs.push_back(alignment140600592044368);
+
+ AlignmentConstraint *alignment140600592044528 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140600592044528->addShape(1, 0);
+ alignment140600592044528->addShape(9, 0);
+ alignment140600592044528->addShape(10, 0);
+ ccs.push_back(alignment140600592044528);
+
+ AlignmentConstraint *alignment140600592044752 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140600592044752->addShape(6, 0);
+ alignment140600592044752->addShape(4, 0);
+ alignment140600592044752->addShape(7, 0);
+ alignment140600592044752->addShape(8, 0);
+ alignment140600592044752->addShape(3, 0);
+ alignment140600592044752->addShape(11, 0);
+ alignment140600592044752->addShape(2, 0);
+ ccs.push_back(alignment140600592044752);
+
+ SeparationConstraint *separation140600592045088 = new SeparationConstraint(vpsc::YDIM, alignment140600592044752, alignment140600592044368, 22.1429, false);
+ ccs.push_back(separation140600592045088);
+
+ SeparationConstraint *separation140600590330720 = new SeparationConstraint(vpsc::YDIM, alignment140600592044368, alignment140600592044208, 18, false);
+ ccs.push_back(separation140600590330720);
+
+ SeparationConstraint *separation140600590330896 = new SeparationConstraint(vpsc::YDIM, alignment140600592044208, alignment140600592044528, 42, false);
+ ccs.push_back(separation140600590330896);
+
+ AlignmentConstraint *alignment140600590331072 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600590331072->addShape(0, 0);
+ alignment140600590331072->addShape(12, 0);
+ ccs.push_back(alignment140600590331072);
+
+ SeparationConstraint *separation140600590331376 = new SeparationConstraint(vpsc::YDIM, 0, 12, 50, true);
+ ccs.push_back(separation140600590331376);
+
+ AlignmentConstraint *alignment140600590331520 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600590331520->addShape(1, 0);
+ alignment140600590331520->addShape(13, 0);
+ ccs.push_back(alignment140600590331520);
+
+ SeparationConstraint *separation140600590331744 = new SeparationConstraint(vpsc::YDIM, 1, 13, -50, true);
+ ccs.push_back(separation140600590331744);
+
+ AlignmentConstraint *alignment140600590331888 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600590331888->addShape(2, 0);
+ alignment140600590331888->addShape(14, 0);
+ ccs.push_back(alignment140600590331888);
+
+ SeparationConstraint *separation140600590332112 = new SeparationConstraint(vpsc::YDIM, 2, 14, -50, true);
+ ccs.push_back(separation140600590332112);
+
+ AlignmentConstraint *alignment140600592043200 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140600592043200->addShape(3, 0);
+ alignment140600592043200->addShape(15, 0);
+ ccs.push_back(alignment140600592043200);
+
+ SeparationConstraint *separation140600590332784 = new SeparationConstraint(vpsc::YDIM, 3, 15, -50, true);
+ ccs.push_back(separation140600590332784);
+
+ AlignmentConstraint *alignment140600590332880 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140600590332880->addShape(4, 0);
+ alignment140600590332880->addShape(16, 0);
+ ccs.push_back(alignment140600590332880);
+
+ SeparationConstraint *separation140600590333104 = new SeparationConstraint(vpsc::XDIM, 4, 16, 62, true);
+ ccs.push_back(separation140600590333104);
+
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength);
+ alg.setAvoidNodeOverlaps(true);
+ RootCluster *cluster140600590333360 = new RootCluster();
+ alg.setClusterHierarchy(cluster140600590333360);
+ alg.setConstraints(ccs);
+ alg.makeFeasible();
+ alg.run();
+ alg.outputInstanceToSVG("test-StillOverlap01");
+ alg.freeAssociatedObjects();
+ return 0;
+};
+
diff --git a/src/3rdparty/adaptagrams/libcola/tests/StillOverlap02.cpp b/src/3rdparty/adaptagrams/libcola/tests/StillOverlap02.cpp
new file mode 100755
index 0000000..c45eef6
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/StillOverlap02.cpp
@@ -0,0 +1,1863 @@
+#include <vector>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ double defaultEdgeLength=40;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ rect = new vpsc::Rectangle(80.8448, 110.845, -23.9565, 6.04346);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-121.155, 128.845, -212.957, -142.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(209.095, 239.095, -389.957, -359.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(209.095, 239.095, -240.957, -210.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(274.428, 304.428, -130.957, -100.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(140.845, 170.845, -78.9565, -48.9565);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(80.8448, 110.845, -55.9565, -25.9565);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(501.428, 531.428, -232.623, -202.623);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(501.428, 531.428, -140.623, -110.623);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(485.428, 515.428, -33.3565, -3.35654);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(737.928, 767.928, -133.957, -103.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(140.845, 170.845, 314.043, 344.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(375.428, 405.428, 191.443, 221.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(443.428, 473.428, 202.243, 232.243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(558.428, 588.428, 136.777, 166.777);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(634.214, 664.214, 136.777, 166.777);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(764.214, 794.214, 136.777, 166.777);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(819.095, 849.095, 156.443, 186.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(853.595, 883.595, 76.0435, 106.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(711.928, 741.928, 202.243, 232.243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(542.428, 572.428, 280.443, 310.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(296.428, 326.428, 440.943, 470.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(202.428, 232.428, 693.943, 723.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(407.428, 473.428, 685.943, 735.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(375.428, 405.428, 693.943, 723.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(542.428, 572.428, 632.443, 662.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(517.428, 547.428, 444.443, 474.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(566.928, 596.928, 444.443, 474.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(879.345, 909.345, 280.443, 310.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(879.345, 909.345, 478.443, 508.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(836.095, 866.095, 332.443, 362.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(797.928, 827.928, 436.443, 466.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(55.8448, 85.8448, 507.443, 537.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(375.428, 405.428, 1026.76, 1056.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(375.428, 405.428, 1074.76, 1104.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-102.489, -72.4885, 1051.76, 1081.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(797.928, 827.928, 802.515, 832.515);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(839.928, 1079.93, 198.443, 268.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(768, 1008, 844.515, 914.515);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(626.928, 656.928, 972.765, 1002.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(426.956, 456.956, 972.765, 1002.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(224.428, 254.428, 972.765, 1002.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(375.428, 405.428, 870.765, 900.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(255.428, 285.428, 870.765, 900.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(744.928, 774.928, 332.443, 362.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(30, 354, -347.957, -302.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-183.905, 137.095, 68.0435, 252.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(375.428, 405.428, 530.443, 560.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(375.428, 405.428, 332.443, 362.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1.84481, 31.8448, 870.765, 900.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(127.095, 157.095, 870.765, 900.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(991.345, 1021.34, 478.443, 508.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(991.345, 1021.34, 600.443, 630.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(38.8448, 68.8448, 693.943, 723.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-58.1552, -28.1552, 768.765, 798.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(130.845, 180.845, -399.957, -349.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(130.845, 180.845, -250.957, -200.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-112.489, -62.4885, -43.3565, 6.64346);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(289.428, 339.428, 192.243, 242.243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(532.428, 582.428, 192.243, 242.243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(567.428, 617.428, -150.623, -100.623);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(843.595, 893.595, -150.623, -100.623);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(616.928, 666.928, -43.3565, 6.64346);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(787.928, 837.928, -43.3565, 6.64346);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(869.345, 919.345, 520.443, 570.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(289.428, 339.428, 322.443, 372.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(130.845, 180.845, 430.943, 480.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(869.345, 919.345, 374.443, 424.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(286.428, 336.428, 683.943, 733.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(130.845, 180.845, 520.443, 570.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(130.845, 180.845, 1116.76, 1166.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(676.928, 726.928, 962.765, 1012.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(520.428, 570.428, 962.765, 1012.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(336.428, 386.428, 962.765, 1012.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(676.928, 726.928, 860.765, 910.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(130.845, 180.845, 1064.76, 1114.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(425.428, 475.428, 860.765, 910.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(305.428, 355.428, 860.765, 910.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(787.928, 837.928, 1064.76, 1114.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(532.428, 582.428, 520.443, 570.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(787.928, 837.928, 192.243, 242.243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(295.428, 345.428, 520.443, 570.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(475.428, 525.428, 683.943, 733.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(113.095, 163.095, 683.943, 733.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-19.1552, 30.8448, 520.443, 570.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(295.428, 345.428, 572.443, 622.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(295.428, 345.428, 631.943, 681.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(289.428, 339.428, -43.3565, 6.64346);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(177.428, 227.428, 860.765, 910.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(289.428, 339.428, -250.957, -200.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(532.428, 582.428, 322.443, 372.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(787.928, 837.928, 622.443, 672.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(556.928, 606.928, 860.765, 910.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(139.095, 189.095, 66.0435, 116.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-68.1552, -18.1552, 683.943, 733.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(425.428, 475.428, 758.765, 808.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(177.428, 227.428, 758.765, 808.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(51.8448, 101.845, 860.765, 910.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-68.1552, -18.1552, 860.765, 910.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(305.428, 355.428, 758.765, 808.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(616.928, 666.928, 218.443, 268.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(981.345, 1031.34, 520.443, 570.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(981.345, 1031.34, 656.943, 706.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(592.428, 839.428, 486.443, 556.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(626.928, 656.928, 596.443, 626.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(616.928, 666.928, 656.943, 706.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(616.928, 666.928, 750.515, 800.515);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(626.928, 656.928, 717.515, 747.515);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(209.095, 239.095, 76.0435, 106.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(62.8448, 128.845, 16.0435, 66.0435);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(191.095, 257.095, -449.957, -399.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(191.095, 257.095, -300.957, -250.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(194.428, 260.428, -140.957, -90.9565);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(184.845, 250.845, -88.9565, -38.9565);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(62.8448, 128.845, -115.957, -65.9565);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(483.428, 549.428, -292.623, -242.623);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(483.428, 549.428, -200.623, -150.623);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(467.428, 533.428, -93.3565, -43.3565);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(719.928, 785.928, -93.9565, -43.9565);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(122.845, 188.845, 254.043, 304.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(357.428, 423.428, 131.443, 181.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(425.428, 491.428, 142.243, 192.243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(540.428, 606.428, 76.7768, 126.777);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(616.214, 682.214, 76.7768, 126.777);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(684.214, 750.214, 126.777, 176.777);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(863.095, 929.095, 146.443, 196.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(897.595, 963.595, 66.0435, 116.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(693.928, 759.928, 242.243, 292.243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(586.428, 652.428, 270.443, 320.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(278.428, 344.428, 380.943, 430.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(184.428, 250.428, 633.943, 683.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(357.428, 423.428, 633.943, 683.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(524.428, 590.428, 572.443, 622.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(437.428, 503.428, 434.443, 484.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(610.928, 676.928, 434.443, 484.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(923.345, 989.345, 270.443, 320.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(923.345, 989.345, 468.443, 518.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(880.095, 946.095, 322.443, 372.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(841.928, 907.928, 426.443, 476.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(37.8448, 103.845, 447.443, 497.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(357.428, 423.428, 1066.76, 1116.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(357.428, 423.428, 1014.76, 1064.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-58.4885, 7.51148, 1041.76, 1091.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(841.928, 907.928, 792.515, 842.515);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(608.928, 674.928, 912.765, 962.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(408.956, 474.956, 912.765, 962.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(268.428, 334.428, 962.765, 1012.76);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(357.428, 423.428, 810.765, 860.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(237.428, 303.428, 810.765, 860.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(664.928, 730.928, 322.443, 372.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(357.428, 423.428, 470.443, 520.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(357.428, 423.428, 272.443, 322.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-16.1552, 49.8448, 810.765, 860.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(109.095, 175.095, 810.765, 860.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1035.34, 1101.34, 468.443, 518.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1035.34, 1101.34, 590.443, 640.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(20.8448, 86.8448, 633.943, 683.943);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-14.1552, 51.8448, 758.765, 808.765);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(670.928, 736.928, 586.443, 636.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(670.928, 736.928, 707.515, 757.515);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(191.095, 257.095, 16.0435, 66.0435);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(58.8448, 128.845, -192.957, -142.957);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(839.928, 909.928, 218.443, 268.443);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(768.5, 838.5, 844.515, 894.515);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(67.0948, 137.095, 150.043, 200.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(67.0948, 137.095, 202.043, 252.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-36.9052, 13.0948, 182.043, 252.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(15.0948, 65.0948, 182.043, 252.043);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(592.428, 662.428, 486.443, 536.443);
+ rs.push_back(rect);
+
+ AlignmentConstraint *alignment1114387328 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114387328->addShape(4, 0);
+ ccs.push_back(alignment1114387328);
+
+ AlignmentConstraint *alignment1103856272 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103856272->addShape(0, 0);
+ alignment1103856272->addShape(6, 0);
+ ccs.push_back(alignment1103856272);
+
+ AlignmentConstraint *alignment1102536224 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1102536224->addShape(7, 0);
+ alignment1102536224->addShape(8, 0);
+ ccs.push_back(alignment1102536224);
+
+ AlignmentConstraint *alignment1113412976 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1113412976->addShape(10, 0);
+ ccs.push_back(alignment1113412976);
+
+ AlignmentConstraint *alignment1103859296 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103859296->addShape(13, 0);
+ ccs.push_back(alignment1103859296);
+
+ AlignmentConstraint *alignment1108560576 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1108560576->addShape(14, 0);
+ ccs.push_back(alignment1108560576);
+
+ AlignmentConstraint *alignment1102536400 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1102536400->addShape(15, 0);
+ ccs.push_back(alignment1102536400);
+
+ AlignmentConstraint *alignment1102857472 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1102857472->addShape(16, 0);
+ ccs.push_back(alignment1102857472);
+
+ AlignmentConstraint *alignment1103856000 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103856000->addShape(17, 0);
+ ccs.push_back(alignment1103856000);
+
+ AlignmentConstraint *alignment1103638512 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103638512->addShape(19, 0);
+ ccs.push_back(alignment1103638512);
+
+ AlignmentConstraint *alignment1103638608 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103638608->addShape(22, 0);
+ ccs.push_back(alignment1103638608);
+
+ AlignmentConstraint *alignment1095948608 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1095948608->addShape(26, 0);
+ ccs.push_back(alignment1095948608);
+
+ AlignmentConstraint *alignment1095948704 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1095948704->addShape(30, 0);
+ ccs.push_back(alignment1095948704);
+
+ AlignmentConstraint *alignment1109826288 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1109826288->addShape(32, 0);
+ ccs.push_back(alignment1109826288);
+
+ AlignmentConstraint *alignment1109826384 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1109826384->addShape(40, 0);
+ ccs.push_back(alignment1109826384);
+
+ AlignmentConstraint *alignment1110086352 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1110086352->addShape(41, 0);
+ ccs.push_back(alignment1110086352);
+
+ AlignmentConstraint *alignment1110086480 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1110086480->addShape(43, 0);
+ ccs.push_back(alignment1110086480);
+
+ AlignmentConstraint *alignment1100384896 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100384896->addShape(44, 0);
+ ccs.push_back(alignment1100384896);
+
+ AlignmentConstraint *alignment1100385056 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100385056->addShape(33, 0);
+ alignment1100385056->addShape(42, 0);
+ alignment1100385056->addShape(48, 0);
+ alignment1100385056->addShape(12, 0);
+ alignment1100385056->addShape(47, 0);
+ alignment1100385056->addShape(34, 0);
+ alignment1100385056->addShape(24, 0);
+ ccs.push_back(alignment1100385056);
+
+ AlignmentConstraint *alignment1114389776 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114389776->addShape(49, 0);
+ ccs.push_back(alignment1114389776);
+
+ AlignmentConstraint *alignment1114389936 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114389936->addShape(50, 0);
+ ccs.push_back(alignment1114389936);
+
+ AlignmentConstraint *alignment1103858368 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103858368->addShape(53, 0);
+ ccs.push_back(alignment1103858368);
+
+ AlignmentConstraint *alignment1103858496 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103858496->addShape(35, 0);
+ alignment1103858496->addShape(57, 0);
+ ccs.push_back(alignment1103858496);
+
+ AlignmentConstraint *alignment1103858720 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103858720->addShape(60, 0);
+ ccs.push_back(alignment1103858720);
+
+ AlignmentConstraint *alignment1103857616 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103857616->addShape(61, 0);
+ alignment1103857616->addShape(18, 0);
+ ccs.push_back(alignment1103857616);
+
+ AlignmentConstraint *alignment1103857840 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103857840->addShape(64, 0);
+ alignment1103857840->addShape(28, 0);
+ alignment1103857840->addShape(67, 0);
+ alignment1103857840->addShape(29, 0);
+ ccs.push_back(alignment1103857840);
+
+ AlignmentConstraint *alignment1103858032 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103858032->addShape(68, 0);
+ alignment1103858032->addShape(21, 0);
+ ccs.push_back(alignment1103858032);
+
+ AlignmentConstraint *alignment1103741312 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103741312->addShape(72, 0);
+ ccs.push_back(alignment1103741312);
+
+ AlignmentConstraint *alignment1103741440 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103741440->addShape(73, 0);
+ ccs.push_back(alignment1103741440);
+
+ AlignmentConstraint *alignment1103741600 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103741600->addShape(71, 0);
+ alignment1103741600->addShape(74, 0);
+ ccs.push_back(alignment1103741600);
+
+ AlignmentConstraint *alignment1103741824 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103741824->addShape(66, 0);
+ alignment1103741824->addShape(56, 0);
+ alignment1103741824->addShape(70, 0);
+ alignment1103741824->addShape(69, 0);
+ alignment1103741824->addShape(5, 0);
+ alignment1103741824->addShape(11, 0);
+ alignment1103741824->addShape(55, 0);
+ alignment1103741824->addShape(75, 0);
+ ccs.push_back(alignment1103741824);
+
+ AlignmentConstraint *alignment1103742144 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103742144->addShape(9, 0);
+ alignment1103742144->addShape(82, 0);
+ ccs.push_back(alignment1103742144);
+
+ AlignmentConstraint *alignment1103743632 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103743632->addShape(83, 0);
+ ccs.push_back(alignment1103743632);
+
+ AlignmentConstraint *alignment1113416080 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1113416080->addShape(84, 0);
+ ccs.push_back(alignment1113416080);
+
+ AlignmentConstraint *alignment1113416240 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1113416240->addShape(81, 0);
+ alignment1113416240->addShape(85, 0);
+ alignment1113416240->addShape(86, 0);
+ ccs.push_back(alignment1113416240);
+
+ AlignmentConstraint *alignment1103744288 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103744288->addShape(87, 0);
+ alignment1103744288->addShape(89, 0);
+ alignment1103744288->addShape(58, 0);
+ alignment1103744288->addShape(65, 0);
+ ccs.push_back(alignment1103744288);
+
+ AlignmentConstraint *alignment1103744448 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103744448->addShape(79, 0);
+ alignment1103744448->addShape(59, 0);
+ alignment1103744448->addShape(90, 0);
+ alignment1103744448->addShape(25, 0);
+ alignment1103744448->addShape(20, 0);
+ ccs.push_back(alignment1103744448);
+
+ AlignmentConstraint *alignment1103744704 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103744704->addShape(80, 0);
+ alignment1103744704->addShape(91, 0);
+ alignment1103744704->addShape(63, 0);
+ alignment1103744704->addShape(31, 0);
+ alignment1103744704->addShape(78, 0);
+ alignment1103744704->addShape(36, 0);
+ ccs.push_back(alignment1103744704);
+
+ AlignmentConstraint *alignment1103744992 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1103744992->addShape(27, 0);
+ alignment1103744992->addShape(92, 0);
+ ccs.push_back(alignment1103744992);
+
+ AlignmentConstraint *alignment1114376272 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114376272->addShape(93, 0);
+ ccs.push_back(alignment1114376272);
+
+ AlignmentConstraint *alignment1114376400 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114376400->addShape(95, 0);
+ alignment1114376400->addShape(76, 0);
+ ccs.push_back(alignment1114376400);
+
+ AlignmentConstraint *alignment1114376624 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114376624->addShape(96, 0);
+ alignment1114376624->addShape(88, 0);
+ ccs.push_back(alignment1114376624);
+
+ AlignmentConstraint *alignment1114376816 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114376816->addShape(97, 0);
+ ccs.push_back(alignment1114376816);
+
+ AlignmentConstraint *alignment1114376944 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114376944->addShape(94, 0);
+ alignment1114376944->addShape(54, 0);
+ alignment1114376944->addShape(98, 0);
+ ccs.push_back(alignment1114376944);
+
+ AlignmentConstraint *alignment1114377168 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114377168->addShape(77, 0);
+ alignment1114377168->addShape(99, 0);
+ ccs.push_back(alignment1114377168);
+
+ AlignmentConstraint *alignment1114377360 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114377360->addShape(51, 0);
+ alignment1114377360->addShape(101, 0);
+ alignment1114377360->addShape(102, 0);
+ alignment1114377360->addShape(52, 0);
+ ccs.push_back(alignment1114377360);
+
+ AlignmentConstraint *alignment1114377600 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114377600->addShape(107, 0);
+ alignment1114377600->addShape(62, 0);
+ alignment1114377600->addShape(105, 0);
+ alignment1114377600->addShape(106, 0);
+ alignment1114377600->addShape(104, 0);
+ alignment1114377600->addShape(39, 0);
+ alignment1114377600->addShape(100, 0);
+ ccs.push_back(alignment1114377600);
+
+ AlignmentConstraint *alignment1114378048 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114378048->addShape(3, 0);
+ alignment1114378048->addShape(2, 0);
+ alignment1114378048->addShape(108, 0);
+ ccs.push_back(alignment1114378048);
+
+ SeparationConstraint *separation1114378272 = new SeparationConstraint(vpsc::XDIM, alignment1103858496, alignment1114376944, 44.3333, false);
+ ccs.push_back(separation1114378272);
+
+ SeparationConstraint *separation1114378416 = new SeparationConstraint(vpsc::XDIM, alignment1114376944, alignment1113416080, 24.6667, false);
+ ccs.push_back(separation1114378416);
+
+ SeparationConstraint *separation1114378592 = new SeparationConstraint(vpsc::XDIM, alignment1113416080, alignment1114389776, 11, false);
+ ccs.push_back(separation1114378592);
+
+ SeparationConstraint *separation1114378768 = new SeparationConstraint(vpsc::XDIM, alignment1114389776, alignment1103858368, 23, false);
+ ccs.push_back(separation1114378768);
+
+ SeparationConstraint *separation1114378944 = new SeparationConstraint(vpsc::XDIM, alignment1103858368, alignment1109826288, 17, false);
+ ccs.push_back(separation1114378944);
+
+ SeparationConstraint *separation1114379120 = new SeparationConstraint(vpsc::XDIM, alignment1109826288, alignment1114376816, 6, false);
+ ccs.push_back(separation1114379120);
+
+ SeparationConstraint *separation1114379296 = new SeparationConstraint(vpsc::XDIM, alignment1114376816, alignment1103856272, 19, false);
+ ccs.push_back(separation1114379296);
+
+ SeparationConstraint *separation1114379472 = new SeparationConstraint(vpsc::XDIM, alignment1103856272, alignment1103743632, 14, false);
+ ccs.push_back(separation1114379472);
+
+ SeparationConstraint *separation1114379648 = new SeparationConstraint(vpsc::XDIM, alignment1103743632, alignment1114389936, 4, false);
+ ccs.push_back(separation1114379648);
+
+ SeparationConstraint *separation1114379824 = new SeparationConstraint(vpsc::XDIM, alignment1114389936, alignment1103741824, 13.75, false);
+ ccs.push_back(separation1114379824);
+
+ SeparationConstraint *separation1114380000 = new SeparationConstraint(vpsc::XDIM, alignment1103741824, alignment1114376272, 8.25, false);
+ ccs.push_back(separation1114380000);
+
+ SeparationConstraint *separation1114380176 = new SeparationConstraint(vpsc::XDIM, alignment1114376272, alignment1114376624, 23, false);
+ ccs.push_back(separation1114380176);
+
+ SeparationConstraint *separation1114380352 = new SeparationConstraint(vpsc::XDIM, alignment1114376624, alignment1103638608, 15, false);
+ ccs.push_back(separation1114380352);
+
+ SeparationConstraint *separation1114380528 = new SeparationConstraint(vpsc::XDIM, alignment1103638608, alignment1114378048, 6.66667, false);
+ ccs.push_back(separation1114380528);
+
+ SeparationConstraint *separation1114380704 = new SeparationConstraint(vpsc::XDIM, alignment1114378048, alignment1110086352, 15.3333, false);
+ ccs.push_back(separation1114380704);
+
+ SeparationConstraint *separation1114380880 = new SeparationConstraint(vpsc::XDIM, alignment1110086352, alignment1110086480, 8, false);
+ ccs.push_back(separation1114380880);
+
+ SeparationConstraint *separation1114381056 = new SeparationConstraint(vpsc::XDIM, alignment1110086480, alignment1114387328, 5, false);
+ ccs.push_back(separation1114381056);
+
+ SeparationConstraint *separation1116666144 = new SeparationConstraint(vpsc::XDIM, alignment1114387328, alignment1103858032, 22, false);
+ ccs.push_back(separation1116666144);
+
+ SeparationConstraint *separation1103743760 = new SeparationConstraint(vpsc::XDIM, alignment1103858032, alignment1103744288, 3, false);
+ ccs.push_back(separation1103743760);
+
+ SeparationConstraint *separation1103743904 = new SeparationConstraint(vpsc::XDIM, alignment1103744288, alignment1113416240, 6, false);
+ ccs.push_back(separation1103743904);
+
+ SeparationConstraint *separation1103744080 = new SeparationConstraint(vpsc::XDIM, alignment1113416240, alignment1114377168, 10, false);
+ ccs.push_back(separation1103744080);
+
+ SeparationConstraint *separation1114381232 = new SeparationConstraint(vpsc::XDIM, alignment1114377168, alignment1103741440, 17, false);
+ ccs.push_back(separation1114381232);
+
+ SeparationConstraint *separation1114381376 = new SeparationConstraint(vpsc::XDIM, alignment1103741440, alignment1100385056, 29, false);
+ ccs.push_back(separation1114381376);
+
+ SeparationConstraint *separation1114381552 = new SeparationConstraint(vpsc::XDIM, alignment1100385056, alignment1109826384, 41, false);
+ ccs.push_back(separation1114381552);
+
+ SeparationConstraint *separation1114381728 = new SeparationConstraint(vpsc::XDIM, alignment1109826384, alignment1114376400, 4, false);
+ ccs.push_back(separation1114381728);
+
+ SeparationConstraint *separation1114370064 = new SeparationConstraint(vpsc::XDIM, alignment1114376400, alignment1103859296, 3, false);
+ ccs.push_back(separation1114370064);
+
+ SeparationConstraint *separation1114370240 = new SeparationConstraint(vpsc::XDIM, alignment1103859296, alignment1103742144, 7, false);
+ ccs.push_back(separation1114370240);
+
+ SeparationConstraint *separation1114370416 = new SeparationConstraint(vpsc::XDIM, alignment1103742144, alignment1102536224, 16, false);
+ ccs.push_back(separation1114370416);
+
+ SeparationConstraint *separation1114370592 = new SeparationConstraint(vpsc::XDIM, alignment1102536224, alignment1095948608, 16, false);
+ ccs.push_back(separation1114370592);
+
+ SeparationConstraint *separation1114370768 = new SeparationConstraint(vpsc::XDIM, alignment1095948608, alignment1103741312, 13, false);
+ ccs.push_back(separation1114370768);
+
+ SeparationConstraint *separation1114370944 = new SeparationConstraint(vpsc::XDIM, alignment1103741312, alignment1103744448, 12, false);
+ ccs.push_back(separation1114370944);
+
+ SeparationConstraint *separation1114371120 = new SeparationConstraint(vpsc::XDIM, alignment1103744448, alignment1108560576, 16, false);
+ ccs.push_back(separation1114371120);
+
+ SeparationConstraint *separation1114371296 = new SeparationConstraint(vpsc::XDIM, alignment1108560576, alignment1103744992, 8.5, false);
+ ccs.push_back(separation1114371296);
+
+ SeparationConstraint *separation1114371472 = new SeparationConstraint(vpsc::XDIM, alignment1103744992, alignment1103858720, 10.5, false);
+ ccs.push_back(separation1114371472);
+
+ SeparationConstraint *separation1114371648 = new SeparationConstraint(vpsc::XDIM, alignment1103858720, alignment1114377600, 23.7143, false);
+ ccs.push_back(separation1114371648);
+
+ SeparationConstraint *separation1114371824 = new SeparationConstraint(vpsc::XDIM, alignment1114377600, alignment1102536400, 7.28571, false);
+ ccs.push_back(separation1114371824);
+
+ SeparationConstraint *separation1114372000 = new SeparationConstraint(vpsc::XDIM, alignment1102536400, alignment1103741600, 49, false);
+ ccs.push_back(separation1114372000);
+
+ SeparationConstraint *separation1114372176 = new SeparationConstraint(vpsc::XDIM, alignment1103741600, alignment1103638512, 25, false);
+ ccs.push_back(separation1114372176);
+
+ SeparationConstraint *separation1114372352 = new SeparationConstraint(vpsc::XDIM, alignment1103638512, alignment1113412976, 26, false);
+ ccs.push_back(separation1114372352);
+
+ SeparationConstraint *separation1114372528 = new SeparationConstraint(vpsc::XDIM, alignment1113412976, alignment1100384896, 7, false);
+ ccs.push_back(separation1114372528);
+
+ SeparationConstraint *separation1114372704 = new SeparationConstraint(vpsc::XDIM, alignment1100384896, alignment1102857472, 15, false);
+ ccs.push_back(separation1114372704);
+
+ SeparationConstraint *separation1114372880 = new SeparationConstraint(vpsc::XDIM, alignment1102857472, alignment1103744704, 21.8333, false);
+ ccs.push_back(separation1114372880);
+
+ SeparationConstraint *separation1114373056 = new SeparationConstraint(vpsc::XDIM, alignment1103744704, alignment1103856000, 21.1667, false);
+ ccs.push_back(separation1114373056);
+
+ SeparationConstraint *separation1114373232 = new SeparationConstraint(vpsc::XDIM, alignment1103856000, alignment1095948704, 17, false);
+ ccs.push_back(separation1114373232);
+
+ SeparationConstraint *separation1114373408 = new SeparationConstraint(vpsc::XDIM, alignment1095948704, alignment1103857616, 17.5, false);
+ ccs.push_back(separation1114373408);
+
+ SeparationConstraint *separation1114373584 = new SeparationConstraint(vpsc::XDIM, alignment1103857616, alignment1103857840, 25.75, false);
+ ccs.push_back(separation1114373584);
+
+ SeparationConstraint *separation1114373760 = new SeparationConstraint(vpsc::XDIM, alignment1103857840, alignment1114377360, 52.25, false);
+ ccs.push_back(separation1114373760);
+
+ AlignmentConstraint *alignment1114373936 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114373936->addShape(0, 0);
+ ccs.push_back(alignment1114373936);
+
+ AlignmentConstraint *alignment1114374096 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114374096->addShape(4, 0);
+ ccs.push_back(alignment1114374096);
+
+ AlignmentConstraint *alignment1114374256 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114374256->addShape(5, 0);
+ ccs.push_back(alignment1114374256);
+
+ AlignmentConstraint *alignment1114374416 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114374416->addShape(6, 0);
+ ccs.push_back(alignment1114374416);
+
+ AlignmentConstraint *alignment1114374576 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114374576->addShape(7, 0);
+ ccs.push_back(alignment1114374576);
+
+ AlignmentConstraint *alignment1114374736 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114374736->addShape(10, 0);
+ ccs.push_back(alignment1114374736);
+
+ AlignmentConstraint *alignment1114374896 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114374896->addShape(11, 0);
+ ccs.push_back(alignment1114374896);
+
+ AlignmentConstraint *alignment1114375056 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114375056->addShape(12, 0);
+ ccs.push_back(alignment1114375056);
+
+ AlignmentConstraint *alignment1114375216 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114375216->addShape(15, 0);
+ alignment1114375216->addShape(16, 0);
+ alignment1114375216->addShape(14, 0);
+ ccs.push_back(alignment1114375216);
+
+ AlignmentConstraint *alignment1114375488 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114375488->addShape(17, 0);
+ ccs.push_back(alignment1114375488);
+
+ AlignmentConstraint *alignment1114375616 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114375616->addShape(26, 0);
+ alignment1114375616->addShape(27, 0);
+ ccs.push_back(alignment1114375616);
+
+ AlignmentConstraint *alignment1114375840 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114375840->addShape(28, 0);
+ alignment1114375840->addShape(20, 0);
+ ccs.push_back(alignment1114375840);
+
+ AlignmentConstraint *alignment1114429984 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114429984->addShape(31, 0);
+ ccs.push_back(alignment1114429984);
+
+ AlignmentConstraint *alignment1114430112 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114430112->addShape(32, 0);
+ ccs.push_back(alignment1114430112);
+
+ AlignmentConstraint *alignment1114430272 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114430272->addShape(33, 0);
+ ccs.push_back(alignment1114430272);
+
+ AlignmentConstraint *alignment1114430432 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114430432->addShape(35, 0);
+ ccs.push_back(alignment1114430432);
+
+ AlignmentConstraint *alignment1114430592 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114430592->addShape(36, 0);
+ ccs.push_back(alignment1114430592);
+
+ AlignmentConstraint *alignment1114430752 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114430752->addShape(51, 0);
+ alignment1114430752->addShape(29, 0);
+ ccs.push_back(alignment1114430752);
+
+ AlignmentConstraint *alignment1114430976 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114430976->addShape(52, 0);
+ ccs.push_back(alignment1114430976);
+
+ AlignmentConstraint *alignment1114431104 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114431104->addShape(55, 0);
+ alignment1114431104->addShape(2, 0);
+ ccs.push_back(alignment1114431104);
+
+ AlignmentConstraint *alignment1114431328 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114431328->addShape(61, 0);
+ alignment1114431328->addShape(60, 0);
+ alignment1114431328->addShape(8, 0);
+ ccs.push_back(alignment1114431328);
+
+ AlignmentConstraint *alignment1114431568 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114431568->addShape(66, 0);
+ alignment1114431568->addShape(21, 0);
+ ccs.push_back(alignment1114431568);
+
+ AlignmentConstraint *alignment1114431760 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114431760->addShape(67, 0);
+ ccs.push_back(alignment1114431760);
+
+ AlignmentConstraint *alignment1114431888 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114431888->addShape(70, 0);
+ ccs.push_back(alignment1114431888);
+
+ AlignmentConstraint *alignment1114432048 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114432048->addShape(71, 0);
+ alignment1114432048->addShape(73, 0);
+ alignment1114432048->addShape(40, 0);
+ alignment1114432048->addShape(72, 0);
+ alignment1114432048->addShape(41, 0);
+ alignment1114432048->addShape(39, 0);
+ ccs.push_back(alignment1114432048);
+
+ AlignmentConstraint *alignment1114432464 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114432464->addShape(78, 0);
+ alignment1114432464->addShape(75, 0);
+ alignment1114432464->addShape(34, 0);
+ ccs.push_back(alignment1114432464);
+
+ AlignmentConstraint *alignment1114432688 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114432688->addShape(13, 0);
+ alignment1114432688->addShape(19, 0);
+ alignment1114432688->addShape(58, 0);
+ alignment1114432688->addShape(80, 0);
+ alignment1114432688->addShape(59, 0);
+ ccs.push_back(alignment1114432688);
+
+ AlignmentConstraint *alignment1114433040 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114433040->addShape(85, 0);
+ ccs.push_back(alignment1114433040);
+
+ AlignmentConstraint *alignment1114433200 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114433200->addShape(86, 0);
+ ccs.push_back(alignment1114433200);
+
+ AlignmentConstraint *alignment1114433360 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114433360->addShape(87, 0);
+ alignment1114433360->addShape(9, 0);
+ alignment1114433360->addShape(62, 0);
+ alignment1114433360->addShape(63, 0);
+ alignment1114433360->addShape(57, 0);
+ ccs.push_back(alignment1114433360);
+
+ AlignmentConstraint *alignment1114433696 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114433696->addShape(56, 0);
+ alignment1114433696->addShape(3, 0);
+ alignment1114433696->addShape(89, 0);
+ ccs.push_back(alignment1114433696);
+
+ AlignmentConstraint *alignment1114433920 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114433920->addShape(65, 0);
+ alignment1114433920->addShape(48, 0);
+ alignment1114433920->addShape(30, 0);
+ alignment1114433920->addShape(90, 0);
+ alignment1114433920->addShape(44, 0);
+ ccs.push_back(alignment1114433920);
+
+ AlignmentConstraint *alignment1114434272 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114434272->addShape(91, 0);
+ alignment1114434272->addShape(25, 0);
+ ccs.push_back(alignment1114434272);
+
+ AlignmentConstraint *alignment1114434496 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114434496->addShape(68, 0);
+ alignment1114434496->addShape(94, 0);
+ alignment1114434496->addShape(83, 0);
+ alignment1114434496->addShape(22, 0);
+ alignment1114434496->addShape(53, 0);
+ alignment1114434496->addShape(24, 0);
+ alignment1114434496->addShape(82, 0);
+ ccs.push_back(alignment1114434496);
+
+ AlignmentConstraint *alignment1114436928 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114436928->addShape(97, 0);
+ alignment1114436928->addShape(43, 0);
+ alignment1114436928->addShape(49, 0);
+ alignment1114436928->addShape(77, 0);
+ alignment1114436928->addShape(42, 0);
+ alignment1114436928->addShape(74, 0);
+ alignment1114436928->addShape(76, 0);
+ alignment1114436928->addShape(50, 0);
+ alignment1114436928->addShape(88, 0);
+ alignment1114436928->addShape(92, 0);
+ alignment1114436928->addShape(98, 0);
+ ccs.push_back(alignment1114436928);
+
+ AlignmentConstraint *alignment1114369232 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114369232->addShape(96, 0);
+ alignment1114369232->addShape(95, 0);
+ alignment1114369232->addShape(99, 0);
+ alignment1114369232->addShape(54, 0);
+ ccs.push_back(alignment1114369232);
+
+ AlignmentConstraint *alignment1114369456 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114369456->addShape(100, 0);
+ ccs.push_back(alignment1114369456);
+
+ AlignmentConstraint *alignment1114369616 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114369616->addShape(81, 0);
+ alignment1114369616->addShape(101, 0);
+ alignment1114369616->addShape(69, 0);
+ alignment1114369616->addShape(79, 0);
+ alignment1114369616->addShape(64, 0);
+ alignment1114369616->addShape(47, 0);
+ alignment1114369616->addShape(84, 0);
+ ccs.push_back(alignment1114369616);
+
+ AlignmentConstraint *alignment1114437392 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114437392->addShape(104, 0);
+ ccs.push_back(alignment1114437392);
+
+ AlignmentConstraint *alignment1100848528 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100848528->addShape(102, 0);
+ alignment1100848528->addShape(105, 0);
+ ccs.push_back(alignment1100848528);
+
+ AlignmentConstraint *alignment1100848752 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100848752->addShape(106, 0);
+ ccs.push_back(alignment1100848752);
+
+ AlignmentConstraint *alignment1100848880 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100848880->addShape(107, 0);
+ ccs.push_back(alignment1100848880);
+
+ AlignmentConstraint *alignment1100849040 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100849040->addShape(18, 0);
+ alignment1100849040->addShape(93, 0);
+ alignment1100849040->addShape(108, 0);
+ ccs.push_back(alignment1100849040);
+
+ SeparationConstraint *separation1100849264 = new SeparationConstraint(vpsc::YDIM, alignment1114431104, alignment1114433696, 30.1667, false);
+ ccs.push_back(separation1100849264);
+
+ SeparationConstraint *separation1100849360 = new SeparationConstraint(vpsc::YDIM, alignment1114433696, alignment1114374576, 8.33333, false);
+ ccs.push_back(separation1100849360);
+
+ SeparationConstraint *separation1100849536 = new SeparationConstraint(vpsc::YDIM, alignment1114374576, alignment1114431328, 18.3333, false);
+ ccs.push_back(separation1100849536);
+
+ SeparationConstraint *separation1100849712 = new SeparationConstraint(vpsc::YDIM, alignment1114431328, alignment1114374736, 6.66667, false);
+ ccs.push_back(separation1100849712);
+
+ SeparationConstraint *separation1100849888 = new SeparationConstraint(vpsc::YDIM, alignment1114374736, alignment1114374096, 3, false);
+ ccs.push_back(separation1100849888);
+
+ SeparationConstraint *separation1100850064 = new SeparationConstraint(vpsc::YDIM, alignment1114374096, alignment1114374256, 3, false);
+ ccs.push_back(separation1100850064);
+
+ SeparationConstraint *separation1100850240 = new SeparationConstraint(vpsc::YDIM, alignment1114374256, alignment1114374416, 23, false);
+ ccs.push_back(separation1100850240);
+
+ SeparationConstraint *separation1100850416 = new SeparationConstraint(vpsc::YDIM, alignment1114374416, alignment1114433360, 11.6, false);
+ ccs.push_back(separation1100850416);
+
+ SeparationConstraint *separation1100850592 = new SeparationConstraint(vpsc::YDIM, alignment1114433360, alignment1114373936, 9.4, false);
+ ccs.push_back(separation1100850592);
+
+ SeparationConstraint *separation1100850768 = new SeparationConstraint(vpsc::YDIM, alignment1114373936, alignment1100849040, 18.6667, false);
+ ccs.push_back(separation1100850768);
+
+ SeparationConstraint *separation1100850944 = new SeparationConstraint(vpsc::YDIM, alignment1100849040, alignment1114375216, 14.6667, false);
+ ccs.push_back(separation1100850944);
+
+ SeparationConstraint *separation1100851120 = new SeparationConstraint(vpsc::YDIM, alignment1114375216, alignment1114375488, 19.6667, false);
+ ccs.push_back(separation1100851120);
+
+ SeparationConstraint *separation1100851296 = new SeparationConstraint(vpsc::YDIM, alignment1114375488, alignment1114375056, 32, false);
+ ccs.push_back(separation1100851296);
+
+ SeparationConstraint *separation1100851472 = new SeparationConstraint(vpsc::YDIM, alignment1114375056, alignment1114432688, 10.8, false);
+ ccs.push_back(separation1100851472);
+
+ SeparationConstraint *separation1100851648 = new SeparationConstraint(vpsc::YDIM, alignment1114432688, alignment1114369456, 26.2, false);
+ ccs.push_back(separation1100851648);
+
+ SeparationConstraint *separation1100851824 = new SeparationConstraint(vpsc::YDIM, alignment1114369456, alignment1114375840, 7.5, false);
+ ccs.push_back(separation1100851824);
+
+ SeparationConstraint *separation1100852000 = new SeparationConstraint(vpsc::YDIM, alignment1114375840, alignment1114374896, 15.5, false);
+ ccs.push_back(separation1100852000);
+
+ SeparationConstraint *separation1100852176 = new SeparationConstraint(vpsc::YDIM, alignment1114374896, alignment1114433920, 18.4, false);
+ ccs.push_back(separation1100852176);
+
+ SeparationConstraint *separation1100852352 = new SeparationConstraint(vpsc::YDIM, alignment1114433920, alignment1114431760, 4.6, false);
+ ccs.push_back(separation1100852352);
+
+ SeparationConstraint *separation1100852528 = new SeparationConstraint(vpsc::YDIM, alignment1114431760, alignment1114429984, 25, false);
+ ccs.push_back(separation1100852528);
+
+ SeparationConstraint *separation1100852704 = new SeparationConstraint(vpsc::YDIM, alignment1114429984, alignment1114431568, 4.5, false);
+ ccs.push_back(separation1100852704);
+
+ SeparationConstraint *separation1100852880 = new SeparationConstraint(vpsc::YDIM, alignment1114431568, alignment1114375616, 3.5, false);
+ ccs.push_back(separation1100852880);
+
+ SeparationConstraint *separation1100853056 = new SeparationConstraint(vpsc::YDIM, alignment1114375616, alignment1114430752, 8, false);
+ ccs.push_back(separation1100853056);
+
+ SeparationConstraint *separation1100853232 = new SeparationConstraint(vpsc::YDIM, alignment1114430752, alignment1114430112, 29, false);
+ ccs.push_back(separation1100853232);
+
+ SeparationConstraint *separation1100853408 = new SeparationConstraint(vpsc::YDIM, alignment1114430112, alignment1114369616, 10.1429, false);
+ ccs.push_back(separation1100853408);
+
+ SeparationConstraint *separation1100853584 = new SeparationConstraint(vpsc::YDIM, alignment1114369616, alignment1114433040, 24.8571, false);
+ ccs.push_back(separation1100853584);
+
+ SeparationConstraint *separation1100853760 = new SeparationConstraint(vpsc::YDIM, alignment1114433040, alignment1114437392, 14, false);
+ ccs.push_back(separation1100853760);
+
+ SeparationConstraint *separation1100853936 = new SeparationConstraint(vpsc::YDIM, alignment1114437392, alignment1114430976, 4, false);
+ ccs.push_back(separation1100853936);
+
+ SeparationConstraint *separation1100854112 = new SeparationConstraint(vpsc::YDIM, alignment1114430976, alignment1114434272, 6.5, false);
+ ccs.push_back(separation1100854112);
+
+ SeparationConstraint *separation1100854288 = new SeparationConstraint(vpsc::YDIM, alignment1114434272, alignment1114433200, 9.5, false);
+ ccs.push_back(separation1100854288);
+
+ SeparationConstraint *separation1100854464 = new SeparationConstraint(vpsc::YDIM, alignment1114433200, alignment1100848528, 25, false);
+ ccs.push_back(separation1100854464);
+
+ SeparationConstraint *separation1100854640 = new SeparationConstraint(vpsc::YDIM, alignment1100848528, alignment1114434496, 9.42857, false);
+ ccs.push_back(separation1100854640);
+
+ SeparationConstraint *separation1100854816 = new SeparationConstraint(vpsc::YDIM, alignment1114434496, alignment1100848880, 23.5714, false);
+ ccs.push_back(separation1100854816);
+
+ SeparationConstraint *separation1100854992 = new SeparationConstraint(vpsc::YDIM, alignment1100848880, alignment1100848752, 43, false);
+ ccs.push_back(separation1100854992);
+
+ SeparationConstraint *separation1100855168 = new SeparationConstraint(vpsc::YDIM, alignment1100848752, alignment1114369232, 8.25, false);
+ ccs.push_back(separation1100855168);
+
+ SeparationConstraint *separation1100855344 = new SeparationConstraint(vpsc::YDIM, alignment1114369232, alignment1114430592, 33.75, false);
+ ccs.push_back(separation1100855344);
+
+ SeparationConstraint *separation1100855520 = new SeparationConstraint(vpsc::YDIM, alignment1114430592, alignment1114436928, 36.3636, false);
+ ccs.push_back(separation1100855520);
+
+ SeparationConstraint *separation1100855696 = new SeparationConstraint(vpsc::YDIM, alignment1114436928, alignment1114432048, 54.1364, false);
+ ccs.push_back(separation1100855696);
+
+ SeparationConstraint *separation1100855872 = new SeparationConstraint(vpsc::YDIM, alignment1114432048, alignment1114430272, 40.5, false);
+ ccs.push_back(separation1100855872);
+
+ SeparationConstraint *separation1100856048 = new SeparationConstraint(vpsc::YDIM, alignment1114430272, alignment1114430432, 25, false);
+ ccs.push_back(separation1100856048);
+
+ SeparationConstraint *separation1100856224 = new SeparationConstraint(vpsc::YDIM, alignment1114430432, alignment1114432464, 17, false);
+ ccs.push_back(separation1100856224);
+
+ SeparationConstraint *separation1100856400 = new SeparationConstraint(vpsc::YDIM, alignment1114432464, alignment1114431888, 33, false);
+ ccs.push_back(separation1100856400);
+
+ AlignmentConstraint *alignment1100856576 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100856576->addShape(0, 0);
+ alignment1100856576->addShape(109, 0);
+ ccs.push_back(alignment1100856576);
+
+ SeparationConstraint *separation1100856800 = new SeparationConstraint(vpsc::YDIM, 0, 109, 50, true);
+ ccs.push_back(separation1100856800);
+
+ AlignmentConstraint *alignment1100856944 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100856944->addShape(2, 0);
+ alignment1100856944->addShape(110, 0);
+ ccs.push_back(alignment1100856944);
+
+ SeparationConstraint *separation1100857168 = new SeparationConstraint(vpsc::YDIM, 2, 110, -50, true);
+ ccs.push_back(separation1100857168);
+
+ AlignmentConstraint *alignment1100857312 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100857312->addShape(3, 0);
+ alignment1100857312->addShape(111, 0);
+ ccs.push_back(alignment1100857312);
+
+ SeparationConstraint *separation1100857536 = new SeparationConstraint(vpsc::YDIM, 3, 111, -50, true);
+ ccs.push_back(separation1100857536);
+
+ AlignmentConstraint *alignment1100857680 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100857680->addShape(4, 0);
+ alignment1100857680->addShape(112, 0);
+ ccs.push_back(alignment1100857680);
+
+ SeparationConstraint *separation1100857904 = new SeparationConstraint(vpsc::XDIM, 4, 112, -62, true);
+ ccs.push_back(separation1100857904);
+
+ AlignmentConstraint *alignment1100858048 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100858048->addShape(5, 0);
+ alignment1100858048->addShape(113, 0);
+ ccs.push_back(alignment1100858048);
+
+ SeparationConstraint *separation1100858272 = new SeparationConstraint(vpsc::XDIM, 5, 113, 62, true);
+ ccs.push_back(separation1100858272);
+
+ AlignmentConstraint *alignment1100858416 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100858416->addShape(6, 0);
+ alignment1100858416->addShape(114, 0);
+ ccs.push_back(alignment1100858416);
+
+ SeparationConstraint *separation1100858640 = new SeparationConstraint(vpsc::YDIM, 6, 114, -50, true);
+ ccs.push_back(separation1100858640);
+
+ AlignmentConstraint *alignment1100858784 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100858784->addShape(7, 0);
+ alignment1100858784->addShape(115, 0);
+ ccs.push_back(alignment1100858784);
+
+ SeparationConstraint *separation1100859008 = new SeparationConstraint(vpsc::YDIM, 7, 115, -50, true);
+ ccs.push_back(separation1100859008);
+
+ AlignmentConstraint *alignment1100859152 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100859152->addShape(8, 0);
+ alignment1100859152->addShape(116, 0);
+ ccs.push_back(alignment1100859152);
+
+ SeparationConstraint *separation1100859376 = new SeparationConstraint(vpsc::YDIM, 8, 116, -50, true);
+ ccs.push_back(separation1100859376);
+
+ AlignmentConstraint *alignment1100859520 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100859520->addShape(9, 0);
+ alignment1100859520->addShape(117, 0);
+ ccs.push_back(alignment1100859520);
+
+ SeparationConstraint *separation1100859744 = new SeparationConstraint(vpsc::YDIM, 9, 117, -50, true);
+ ccs.push_back(separation1100859744);
+
+ AlignmentConstraint *alignment1100859888 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100859888->addShape(10, 0);
+ alignment1100859888->addShape(118, 0);
+ ccs.push_back(alignment1100859888);
+
+ SeparationConstraint *separation1100860112 = new SeparationConstraint(vpsc::YDIM, 10, 118, 50, true);
+ ccs.push_back(separation1100860112);
+
+ AlignmentConstraint *alignment1100860256 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100860256->addShape(11, 0);
+ alignment1100860256->addShape(119, 0);
+ ccs.push_back(alignment1100860256);
+
+ SeparationConstraint *separation1100860480 = new SeparationConstraint(vpsc::YDIM, 11, 119, -50, true);
+ ccs.push_back(separation1100860480);
+
+ AlignmentConstraint *alignment1100860624 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100860624->addShape(12, 0);
+ alignment1100860624->addShape(120, 0);
+ ccs.push_back(alignment1100860624);
+
+ SeparationConstraint *separation1100860848 = new SeparationConstraint(vpsc::YDIM, 12, 120, -50, true);
+ ccs.push_back(separation1100860848);
+
+ AlignmentConstraint *alignment1100860992 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100860992->addShape(13, 0);
+ alignment1100860992->addShape(121, 0);
+ ccs.push_back(alignment1100860992);
+
+ SeparationConstraint *separation1100861216 = new SeparationConstraint(vpsc::YDIM, 13, 121, -50, true);
+ ccs.push_back(separation1100861216);
+
+ AlignmentConstraint *alignment1100861360 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100861360->addShape(14, 0);
+ alignment1100861360->addShape(122, 0);
+ ccs.push_back(alignment1100861360);
+
+ SeparationConstraint *separation1100861584 = new SeparationConstraint(vpsc::YDIM, 14, 122, -50, true);
+ ccs.push_back(separation1100861584);
+
+ AlignmentConstraint *alignment1100861728 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100861728->addShape(15, 0);
+ alignment1100861728->addShape(123, 0);
+ ccs.push_back(alignment1100861728);
+
+ SeparationConstraint *separation1100861952 = new SeparationConstraint(vpsc::YDIM, 15, 123, -50, true);
+ ccs.push_back(separation1100861952);
+
+ AlignmentConstraint *alignment1100862096 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100862096->addShape(16, 0);
+ alignment1100862096->addShape(124, 0);
+ ccs.push_back(alignment1100862096);
+
+ SeparationConstraint *separation1100862320 = new SeparationConstraint(vpsc::XDIM, 16, 124, -62, true);
+ ccs.push_back(separation1100862320);
+
+ AlignmentConstraint *alignment1100862464 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100862464->addShape(17, 0);
+ alignment1100862464->addShape(125, 0);
+ ccs.push_back(alignment1100862464);
+
+ SeparationConstraint *separation1100862688 = new SeparationConstraint(vpsc::XDIM, 17, 125, 62, true);
+ ccs.push_back(separation1100862688);
+
+ AlignmentConstraint *alignment1100862832 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100862832->addShape(18, 0);
+ alignment1100862832->addShape(126, 0);
+ ccs.push_back(alignment1100862832);
+
+ SeparationConstraint *separation1100863056 = new SeparationConstraint(vpsc::XDIM, 18, 126, 62, true);
+ ccs.push_back(separation1100863056);
+
+ AlignmentConstraint *alignment1100863200 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100863200->addShape(19, 0);
+ alignment1100863200->addShape(127, 0);
+ ccs.push_back(alignment1100863200);
+
+ SeparationConstraint *separation1100863424 = new SeparationConstraint(vpsc::YDIM, 19, 127, 50, true);
+ ccs.push_back(separation1100863424);
+
+ AlignmentConstraint *alignment1100863568 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100863568->addShape(20, 0);
+ alignment1100863568->addShape(128, 0);
+ ccs.push_back(alignment1100863568);
+
+ SeparationConstraint *separation1100863792 = new SeparationConstraint(vpsc::XDIM, 20, 128, 62, true);
+ ccs.push_back(separation1100863792);
+
+ AlignmentConstraint *alignment1100863936 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100863936->addShape(21, 0);
+ alignment1100863936->addShape(129, 0);
+ ccs.push_back(alignment1100863936);
+
+ SeparationConstraint *separation1100864160 = new SeparationConstraint(vpsc::YDIM, 21, 129, -50, true);
+ ccs.push_back(separation1100864160);
+
+ AlignmentConstraint *alignment1100864304 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100864304->addShape(22, 0);
+ alignment1100864304->addShape(130, 0);
+ ccs.push_back(alignment1100864304);
+
+ SeparationConstraint *separation1100864528 = new SeparationConstraint(vpsc::YDIM, 22, 130, -50, true);
+ ccs.push_back(separation1100864528);
+
+ AlignmentConstraint *alignment1100864672 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100864672->addShape(24, 0);
+ alignment1100864672->addShape(131, 0);
+ ccs.push_back(alignment1100864672);
+
+ SeparationConstraint *separation1100864896 = new SeparationConstraint(vpsc::YDIM, 24, 131, -50, true);
+ ccs.push_back(separation1100864896);
+
+ AlignmentConstraint *alignment1100865040 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100865040->addShape(25, 0);
+ alignment1100865040->addShape(132, 0);
+ ccs.push_back(alignment1100865040);
+
+ SeparationConstraint *separation1100865264 = new SeparationConstraint(vpsc::YDIM, 25, 132, -50, true);
+ ccs.push_back(separation1100865264);
+
+ AlignmentConstraint *alignment1100865408 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100865408->addShape(26, 0);
+ alignment1100865408->addShape(133, 0);
+ ccs.push_back(alignment1100865408);
+
+ SeparationConstraint *separation1100865632 = new SeparationConstraint(vpsc::XDIM, 26, 133, -62, true);
+ ccs.push_back(separation1100865632);
+
+ AlignmentConstraint *alignment1100865776 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100865776->addShape(27, 0);
+ alignment1100865776->addShape(134, 0);
+ ccs.push_back(alignment1100865776);
+
+ SeparationConstraint *separation1100866000 = new SeparationConstraint(vpsc::XDIM, 27, 134, 62, true);
+ ccs.push_back(separation1100866000);
+
+ AlignmentConstraint *alignment1100866144 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100866144->addShape(28, 0);
+ alignment1100866144->addShape(135, 0);
+ ccs.push_back(alignment1100866144);
+
+ SeparationConstraint *separation1100866368 = new SeparationConstraint(vpsc::XDIM, 28, 135, 62, true);
+ ccs.push_back(separation1100866368);
+
+ AlignmentConstraint *alignment1100866512 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100866512->addShape(29, 0);
+ alignment1100866512->addShape(136, 0);
+ ccs.push_back(alignment1100866512);
+
+ SeparationConstraint *separation1100866736 = new SeparationConstraint(vpsc::XDIM, 29, 136, 62, true);
+ ccs.push_back(separation1100866736);
+
+ AlignmentConstraint *alignment1100866880 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100866880->addShape(30, 0);
+ alignment1100866880->addShape(137, 0);
+ ccs.push_back(alignment1100866880);
+
+ SeparationConstraint *separation1100867104 = new SeparationConstraint(vpsc::XDIM, 30, 137, 62, true);
+ ccs.push_back(separation1100867104);
+
+ AlignmentConstraint *alignment1100867248 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100867248->addShape(31, 0);
+ alignment1100867248->addShape(138, 0);
+ ccs.push_back(alignment1100867248);
+
+ SeparationConstraint *separation1100867472 = new SeparationConstraint(vpsc::XDIM, 31, 138, 62, true);
+ ccs.push_back(separation1100867472);
+
+ AlignmentConstraint *alignment1100867616 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100867616->addShape(32, 0);
+ alignment1100867616->addShape(139, 0);
+ ccs.push_back(alignment1100867616);
+
+ SeparationConstraint *separation1100867840 = new SeparationConstraint(vpsc::YDIM, 32, 139, -50, true);
+ ccs.push_back(separation1100867840);
+
+ AlignmentConstraint *alignment1100867984 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100867984->addShape(33, 0);
+ alignment1100867984->addShape(140, 0);
+ ccs.push_back(alignment1100867984);
+
+ SeparationConstraint *separation1100868208 = new SeparationConstraint(vpsc::YDIM, 33, 140, 50, true);
+ ccs.push_back(separation1100868208);
+
+ AlignmentConstraint *alignment1100868352 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100868352->addShape(34, 0);
+ alignment1100868352->addShape(141, 0);
+ ccs.push_back(alignment1100868352);
+
+ SeparationConstraint *separation1100868576 = new SeparationConstraint(vpsc::YDIM, 34, 141, -50, true);
+ ccs.push_back(separation1100868576);
+
+ AlignmentConstraint *alignment1100868720 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100868720->addShape(35, 0);
+ alignment1100868720->addShape(142, 0);
+ ccs.push_back(alignment1100868720);
+
+ SeparationConstraint *separation1100868944 = new SeparationConstraint(vpsc::XDIM, 35, 142, 62, true);
+ ccs.push_back(separation1100868944);
+
+ AlignmentConstraint *alignment1100869088 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100869088->addShape(36, 0);
+ alignment1100869088->addShape(143, 0);
+ ccs.push_back(alignment1100869088);
+
+ SeparationConstraint *separation1100869312 = new SeparationConstraint(vpsc::XDIM, 36, 143, 62, true);
+ ccs.push_back(separation1100869312);
+
+ AlignmentConstraint *alignment1100869456 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100869456->addShape(39, 0);
+ alignment1100869456->addShape(144, 0);
+ ccs.push_back(alignment1100869456);
+
+ SeparationConstraint *separation1100869680 = new SeparationConstraint(vpsc::YDIM, 39, 144, -50, true);
+ ccs.push_back(separation1100869680);
+
+ AlignmentConstraint *alignment1100869824 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100869824->addShape(40, 0);
+ alignment1100869824->addShape(145, 0);
+ ccs.push_back(alignment1100869824);
+
+ SeparationConstraint *separation1100870048 = new SeparationConstraint(vpsc::YDIM, 40, 145, -50, true);
+ ccs.push_back(separation1100870048);
+
+ AlignmentConstraint *alignment1100870192 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100870192->addShape(41, 0);
+ alignment1100870192->addShape(146, 0);
+ ccs.push_back(alignment1100870192);
+
+ SeparationConstraint *separation1100870416 = new SeparationConstraint(vpsc::XDIM, 41, 146, 62, true);
+ ccs.push_back(separation1100870416);
+
+ AlignmentConstraint *alignment1100870560 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100870560->addShape(42, 0);
+ alignment1100870560->addShape(147, 0);
+ ccs.push_back(alignment1100870560);
+
+ SeparationConstraint *separation1100870784 = new SeparationConstraint(vpsc::YDIM, 42, 147, -50, true);
+ ccs.push_back(separation1100870784);
+
+ AlignmentConstraint *alignment1114434864 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114434864->addShape(43, 0);
+ alignment1114434864->addShape(148, 0);
+ ccs.push_back(alignment1114434864);
+
+ SeparationConstraint *separation1114435088 = new SeparationConstraint(vpsc::YDIM, 43, 148, -50, true);
+ ccs.push_back(separation1114435088);
+
+ AlignmentConstraint *alignment1114435232 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1114435232->addShape(44, 0);
+ alignment1114435232->addShape(149, 0);
+ ccs.push_back(alignment1114435232);
+
+ SeparationConstraint *separation1114435456 = new SeparationConstraint(vpsc::XDIM, 44, 149, -62, true);
+ ccs.push_back(separation1114435456);
+
+ AlignmentConstraint *alignment1114435600 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114435600->addShape(47, 0);
+ alignment1114435600->addShape(150, 0);
+ ccs.push_back(alignment1114435600);
+
+ SeparationConstraint *separation1114435824 = new SeparationConstraint(vpsc::YDIM, 47, 150, -50, true);
+ ccs.push_back(separation1114435824);
+
+ AlignmentConstraint *alignment1114435968 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114435968->addShape(48, 0);
+ alignment1114435968->addShape(151, 0);
+ ccs.push_back(alignment1114435968);
+
+ SeparationConstraint *separation1114436192 = new SeparationConstraint(vpsc::YDIM, 48, 151, -50, true);
+ ccs.push_back(separation1114436192);
+
+ AlignmentConstraint *alignment1114436336 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114436336->addShape(49, 0);
+ alignment1114436336->addShape(152, 0);
+ ccs.push_back(alignment1114436336);
+
+ SeparationConstraint *separation1114436560 = new SeparationConstraint(vpsc::YDIM, 49, 152, -50, true);
+ ccs.push_back(separation1114436560);
+
+ AlignmentConstraint *alignment1114436704 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1114436704->addShape(50, 0);
+ alignment1114436704->addShape(153, 0);
+ ccs.push_back(alignment1114436704);
+
+ SeparationConstraint *separation1100875040 = new SeparationConstraint(vpsc::YDIM, 50, 153, -50, true);
+ ccs.push_back(separation1100875040);
+
+ AlignmentConstraint *alignment1100875184 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100875184->addShape(51, 0);
+ alignment1100875184->addShape(154, 0);
+ ccs.push_back(alignment1100875184);
+
+ SeparationConstraint *separation1100875408 = new SeparationConstraint(vpsc::XDIM, 51, 154, 62, true);
+ ccs.push_back(separation1100875408);
+
+ AlignmentConstraint *alignment1100875552 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100875552->addShape(52, 0);
+ alignment1100875552->addShape(155, 0);
+ ccs.push_back(alignment1100875552);
+
+ SeparationConstraint *separation1100875776 = new SeparationConstraint(vpsc::XDIM, 52, 155, 62, true);
+ ccs.push_back(separation1100875776);
+
+ AlignmentConstraint *alignment1100875920 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100875920->addShape(53, 0);
+ alignment1100875920->addShape(156, 0);
+ ccs.push_back(alignment1100875920);
+
+ SeparationConstraint *separation1100876144 = new SeparationConstraint(vpsc::YDIM, 53, 156, -50, true);
+ ccs.push_back(separation1100876144);
+
+ AlignmentConstraint *alignment1100876288 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100876288->addShape(54, 0);
+ alignment1100876288->addShape(157, 0);
+ ccs.push_back(alignment1100876288);
+
+ SeparationConstraint *separation1100876512 = new SeparationConstraint(vpsc::XDIM, 54, 157, 62, true);
+ ccs.push_back(separation1100876512);
+
+ AlignmentConstraint *alignment1100876656 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100876656->addShape(104, 0);
+ alignment1100876656->addShape(158, 0);
+ ccs.push_back(alignment1100876656);
+
+ SeparationConstraint *separation1100876880 = new SeparationConstraint(vpsc::XDIM, 104, 158, 62, true);
+ ccs.push_back(separation1100876880);
+
+ AlignmentConstraint *alignment1100877024 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment1100877024->addShape(107, 0);
+ alignment1100877024->addShape(159, 0);
+ ccs.push_back(alignment1100877024);
+
+ SeparationConstraint *separation1100877248 = new SeparationConstraint(vpsc::XDIM, 107, 159, 62, true);
+ ccs.push_back(separation1100877248);
+
+ AlignmentConstraint *alignment1100877392 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment1100877392->addShape(108, 0);
+ alignment1100877392->addShape(160, 0);
+ ccs.push_back(alignment1100877392);
+
+ SeparationConstraint *separation1100877616 = new SeparationConstraint(vpsc::YDIM, 108, 160, -50, true);
+ ccs.push_back(separation1100877616);
+
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength);
+ alg.setAvoidNodeOverlaps(true);
+ RootCluster *cluster1100877760 = new RootCluster();
+ cluster1100877760->addChildNode(0);
+ cluster1100877760->addChildNode(2);
+ cluster1100877760->addChildNode(3);
+ cluster1100877760->addChildNode(4);
+ cluster1100877760->addChildNode(5);
+ cluster1100877760->addChildNode(6);
+ cluster1100877760->addChildNode(7);
+ cluster1100877760->addChildNode(8);
+ cluster1100877760->addChildNode(9);
+ cluster1100877760->addChildNode(10);
+ cluster1100877760->addChildNode(11);
+ cluster1100877760->addChildNode(12);
+ cluster1100877760->addChildNode(13);
+ cluster1100877760->addChildNode(14);
+ cluster1100877760->addChildNode(15);
+ cluster1100877760->addChildNode(16);
+ cluster1100877760->addChildNode(17);
+ cluster1100877760->addChildNode(18);
+ cluster1100877760->addChildNode(19);
+ cluster1100877760->addChildNode(20);
+ cluster1100877760->addChildNode(21);
+ cluster1100877760->addChildNode(22);
+ cluster1100877760->addChildNode(23);
+ cluster1100877760->addChildNode(24);
+ cluster1100877760->addChildNode(25);
+ cluster1100877760->addChildNode(26);
+ cluster1100877760->addChildNode(27);
+ cluster1100877760->addChildNode(28);
+ cluster1100877760->addChildNode(29);
+ cluster1100877760->addChildNode(30);
+ cluster1100877760->addChildNode(31);
+ cluster1100877760->addChildNode(32);
+ cluster1100877760->addChildNode(33);
+ cluster1100877760->addChildNode(34);
+ cluster1100877760->addChildNode(35);
+ cluster1100877760->addChildNode(36);
+ cluster1100877760->addChildNode(39);
+ cluster1100877760->addChildNode(40);
+ cluster1100877760->addChildNode(41);
+ cluster1100877760->addChildNode(42);
+ cluster1100877760->addChildNode(43);
+ cluster1100877760->addChildNode(44);
+ cluster1100877760->addChildNode(47);
+ cluster1100877760->addChildNode(48);
+ cluster1100877760->addChildNode(49);
+ cluster1100877760->addChildNode(50);
+ cluster1100877760->addChildNode(51);
+ cluster1100877760->addChildNode(52);
+ cluster1100877760->addChildNode(53);
+ cluster1100877760->addChildNode(54);
+ cluster1100877760->addChildNode(55);
+ cluster1100877760->addChildNode(56);
+ cluster1100877760->addChildNode(57);
+ cluster1100877760->addChildNode(58);
+ cluster1100877760->addChildNode(59);
+ cluster1100877760->addChildNode(60);
+ cluster1100877760->addChildNode(61);
+ cluster1100877760->addChildNode(62);
+ cluster1100877760->addChildNode(63);
+ cluster1100877760->addChildNode(64);
+ cluster1100877760->addChildNode(65);
+ cluster1100877760->addChildNode(66);
+ cluster1100877760->addChildNode(67);
+ cluster1100877760->addChildNode(68);
+ cluster1100877760->addChildNode(69);
+ cluster1100877760->addChildNode(70);
+ cluster1100877760->addChildNode(71);
+ cluster1100877760->addChildNode(72);
+ cluster1100877760->addChildNode(73);
+ cluster1100877760->addChildNode(74);
+ cluster1100877760->addChildNode(75);
+ cluster1100877760->addChildNode(76);
+ cluster1100877760->addChildNode(77);
+ cluster1100877760->addChildNode(78);
+ cluster1100877760->addChildNode(79);
+ cluster1100877760->addChildNode(80);
+ cluster1100877760->addChildNode(81);
+ cluster1100877760->addChildNode(82);
+ cluster1100877760->addChildNode(83);
+ cluster1100877760->addChildNode(84);
+ cluster1100877760->addChildNode(85);
+ cluster1100877760->addChildNode(86);
+ cluster1100877760->addChildNode(87);
+ cluster1100877760->addChildNode(88);
+ cluster1100877760->addChildNode(89);
+ cluster1100877760->addChildNode(90);
+ cluster1100877760->addChildNode(91);
+ cluster1100877760->addChildNode(92);
+ cluster1100877760->addChildNode(93);
+ cluster1100877760->addChildNode(94);
+ cluster1100877760->addChildNode(95);
+ cluster1100877760->addChildNode(96);
+ cluster1100877760->addChildNode(97);
+ cluster1100877760->addChildNode(98);
+ cluster1100877760->addChildNode(99);
+ cluster1100877760->addChildNode(100);
+ cluster1100877760->addChildNode(101);
+ cluster1100877760->addChildNode(102);
+ cluster1100877760->addChildNode(104);
+ cluster1100877760->addChildNode(105);
+ cluster1100877760->addChildNode(106);
+ cluster1100877760->addChildNode(107);
+ cluster1100877760->addChildNode(108);
+ cluster1100877760->addChildNode(109);
+ cluster1100877760->addChildNode(110);
+ cluster1100877760->addChildNode(111);
+ cluster1100877760->addChildNode(112);
+ cluster1100877760->addChildNode(113);
+ cluster1100877760->addChildNode(114);
+ cluster1100877760->addChildNode(115);
+ cluster1100877760->addChildNode(116);
+ cluster1100877760->addChildNode(117);
+ cluster1100877760->addChildNode(118);
+ cluster1100877760->addChildNode(119);
+ cluster1100877760->addChildNode(120);
+ cluster1100877760->addChildNode(121);
+ cluster1100877760->addChildNode(122);
+ cluster1100877760->addChildNode(123);
+ cluster1100877760->addChildNode(124);
+ cluster1100877760->addChildNode(125);
+ cluster1100877760->addChildNode(126);
+ cluster1100877760->addChildNode(127);
+ cluster1100877760->addChildNode(128);
+ cluster1100877760->addChildNode(129);
+ cluster1100877760->addChildNode(130);
+ cluster1100877760->addChildNode(131);
+ cluster1100877760->addChildNode(132);
+ cluster1100877760->addChildNode(133);
+ cluster1100877760->addChildNode(134);
+ cluster1100877760->addChildNode(135);
+ cluster1100877760->addChildNode(136);
+ cluster1100877760->addChildNode(137);
+ cluster1100877760->addChildNode(138);
+ cluster1100877760->addChildNode(139);
+ cluster1100877760->addChildNode(140);
+ cluster1100877760->addChildNode(141);
+ cluster1100877760->addChildNode(142);
+ cluster1100877760->addChildNode(143);
+ cluster1100877760->addChildNode(144);
+ cluster1100877760->addChildNode(145);
+ cluster1100877760->addChildNode(146);
+ cluster1100877760->addChildNode(147);
+ cluster1100877760->addChildNode(148);
+ cluster1100877760->addChildNode(149);
+ cluster1100877760->addChildNode(150);
+ cluster1100877760->addChildNode(151);
+ cluster1100877760->addChildNode(152);
+ cluster1100877760->addChildNode(153);
+ cluster1100877760->addChildNode(154);
+ cluster1100877760->addChildNode(155);
+ cluster1100877760->addChildNode(156);
+ cluster1100877760->addChildNode(157);
+ cluster1100877760->addChildNode(158);
+ cluster1100877760->addChildNode(159);
+ cluster1100877760->addChildNode(160);
+ RectangularCluster *cluster1100878032 = new RectangularCluster();
+ cluster1100878032->addChildNode(161);
+ cluster1100877760->addChildCluster(cluster1100878032);
+ RectangularCluster *cluster1100878416 = new RectangularCluster();
+ cluster1100878416->addChildNode(162);
+ cluster1100877760->addChildCluster(cluster1100878416);
+ RectangularCluster *cluster1100878800 = new RectangularCluster();
+ cluster1100878800->addChildNode(163);
+ cluster1100877760->addChildCluster(cluster1100878800);
+ RectangularCluster *cluster1100879168 = new RectangularCluster();
+ cluster1100877760->addChildCluster(cluster1100879168);
+ RectangularCluster *cluster1100879488 = new RectangularCluster();
+ cluster1100879488->addChildNode(164);
+ cluster1100879488->addChildNode(165);
+ cluster1100879488->addChildNode(166);
+ cluster1100879488->addChildNode(167);
+ cluster1100877760->addChildCluster(cluster1100879488);
+ RectangularCluster *cluster1100879920 = new RectangularCluster();
+ cluster1100879920->addChildNode(168);
+ cluster1100877760->addChildCluster(cluster1100879920);
+ alg.setClusterHierarchy(cluster1100877760);
+ alg.setConstraints(ccs);
+ alg.makeFeasible();
+ alg.run();
+ alg.outputInstanceToSVG("test-StillOverlap02");
+ alg.freeAssociatedObjects();
+ return 0;
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/boundary.cpp b/src/3rdparty/adaptagrams/libcola/tests/boundary.cpp
new file mode 100644
index 0000000..18e962d
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/boundary.cpp
@@ -0,0 +1,121 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/** \file boundary.cpp
+ *
+ * a clustered graph using libtopology to preserve the cluster boundary.
+ */
+/*
+* Authors:
+* Tim Dwyer <tgdwyer@gmail.com>
+*/
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+#include <vector>
+#include <valarray>
+#include <algorithm>
+#include <float.h>
+#include "graphlayouttest.h"
+#include <libtopology/topology_graph.h>
+#include <libproject/project.h>
+using namespace std;
+using namespace topology;
+
+Node* addNode( Nodes& vs, vpsc::Rectangle* r) {
+ Node *v = new Node(vs.size(), r);
+ vs.push_back(v);
+ return v;
+}
+void addToPath(EdgePoints& ps, Node *v, EdgePoint::RectIntersect i) {
+ ps.push_back(new EdgePoint(v,i));
+}
+struct SetDesiredPos : public PreIteration {
+ SetDesiredPos(Locks& locks) : PreIteration(locks) {}
+};
+struct Test : TestConvergence {
+ Test(const double d,const unsigned i,topology::Nodes& vs, topology::Edges& es,const string fname) : TestConvergence(d,i), vs(vs), es(es), fname(fname) {}
+ bool operator()(const double new_stress, valarray<double> & X, valarray<double> & Y) {
+ bool converged= TestConvergence::operator()(new_stress,X,Y);
+ if(converged) {
+ cerr << "stress="<<new_stress<<" iteration="<<iterations<<endl;
+ stringstream ss;
+ ss << fname << "-" << setfill('0') << setw(3) << iterations << ".svg";
+ cerr << "writing file: " << ss.str() << endl;
+ writeFile(vs,es,ss.str());
+ }
+ return converged;
+ }
+ double lastStress;
+ topology::Nodes& vs;
+ topology::Edges& es;
+ const string fname;
+};
+void clusterBoundary() {
+ vector<cola::Edge> es;
+ vector<vpsc::Rectangle*> rs;
+ rs.push_back(new vpsc::Rectangle(395,449,155,189));
+ rs.push_back(new vpsc::Rectangle(309,363,155,189));
+ double idealLength=60;
+ // set up topology graph
+ topology::Nodes vs;
+ for(vector<Rectangle*>::iterator i = rs.begin(); i!=rs.end();++i) {
+ addNode(vs,*i);
+ }
+ Edges tes;
+ EdgePoints ps;
+ addToPath(ps,vs[1],EdgePoint::BL);
+ addToPath(ps,vs[0],EdgePoint::BR);
+ addToPath(ps,vs[0],EdgePoint::TR);
+ addToPath(ps,vs[1],EdgePoint::TL);
+ ps.push_back(ps[0]);
+ tes.push_back(new topology::Edge(idealLength, ps));
+
+ writeFile(vs,tes,"boundary-000.svg");
+
+ Locks locks;
+ locks.push_back(Lock(0,rs[0]->getCentreX(), rs[0]->getCentreY()+10));
+ locks.push_back(Lock(1,rs[1]->getCentreX(), rs[1]->getCentreY()));
+ SetDesiredPos preIteration(locks);
+
+ Test test(0.00001,100,vs,tes,"boundary");
+ cola::ConstrainedFDLayout alg(rs,es,idealLength,nullptr,test,&preIteration);
+
+ alg.setTopology(&vs,&tes);
+ alg.run(true,true);
+ double finalStress=alg.computeStress();
+ printf("finalStress=%f\n",finalStress);
+
+ //assert(finalStress<1e-5);
+ for_each(rs.begin(),rs.end(),cola::delete_object());
+ for_each(tes.begin(),tes.end(),cola::delete_object());
+ for_each(vs.begin(),vs.end(),cola::delete_object());
+}
+int main() {
+ clusterBoundary();
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=80 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/connected_components.cpp b/src/3rdparty/adaptagrams/libcola/tests/connected_components.cpp
new file mode 100644
index 0000000..d5df479
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/connected_components.cpp
@@ -0,0 +1,69 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <iostream>
+#include <vector>
+#include <set>
+#include <libvpsc/rectangle.h>
+#include <libcola/cola.h>
+#include <libcola/connected_components.h>
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+
+int main() {
+ const unsigned V = 7;
+ unsigned c1[]={0,1,2,3};
+ set<unsigned> expected_c1(c1,c1+4);
+ unsigned c2[]={4,5,6};
+ set<unsigned> expected_c2(c2,c2+3);
+
+ Edge edge_array[] = { Edge(0, 1), Edge(1, 2), Edge(3, 2), Edge(1, 3),
+ Edge(4, 5), Edge(5, 6), Edge(6, 4) };
+ const std::size_t E = sizeof(edge_array) / sizeof(Edge);
+ vector<Edge> es(edge_array,edge_array+E);
+ vector<Component*> cs;
+ vpsc::Rectangles rs;
+ double width=100,height=100;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+5,y,y+5));
+ }
+ connectedComponents(rs,es,cs);
+ set<unsigned> result_c1(cs[0]->node_ids.begin(),cs[0]->node_ids.end());
+ set<unsigned> result_c2(cs[1]->node_ids.begin(),cs[1]->node_ids.end());
+ assert(expected_c1==result_c1);
+ assert(expected_c2==result_c2);
+ for(unsigned i=0;i<cs.size();i++) {
+ printf("Component %d:\n",i);
+ for(unsigned j=0;j<cs[i]->edges.size();j++) {
+ Edge& e=cs[i]->edges[j];
+ printf("(%d,%d) ",e.first,e.second);
+ }
+ cout << endl;
+ }
+ return 0;
+}
diff --git a/src/3rdparty/adaptagrams/libcola/tests/constrained.cpp b/src/3rdparty/adaptagrams/libcola/tests/constrained.cpp
new file mode 100644
index 0000000..20215f7
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/constrained.cpp
@@ -0,0 +1,99 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/** \file constrained.cpp
+ *
+ * runs constraint layout on a small graph. nodes 0 and 3 are constrained
+ * to a vertical line
+ *
+ *
+ * Authors:
+ * Tim Dwyer <tgdwyer@gmail.com>
+ */
+#include <iostream>
+
+#include <vector>
+#include <algorithm>
+#include <float.h>
+#include <libcola/cola.h>
+#include <libcola/output_svg.h>
+inline double getRand(double range) {
+ return range*rand()/RAND_MAX;
+}
+
+using namespace std;
+using namespace cola;
+/**
+* \brief Determines when to terminate layout of a particular graph based
+* on a given relative tolerance.
+*/
+int main() {
+
+ const unsigned V = 4;
+ typedef pair < unsigned, unsigned >Edge;
+ Edge edge_array[] = { Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(1, 3) };
+ unsigned E = sizeof(edge_array) / sizeof(Edge);
+ vector<Edge> es(edge_array,edge_array+E);
+ double width=100;
+ double height=100;
+ vector<vpsc::Rectangle*> rs;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+5,y,y+5));
+ }
+ CompoundConstraints ccs;
+ AlignmentConstraint ac(vpsc::XDIM);
+ ccs.push_back(&ac);
+ ac.addShape(0,0);
+ ac.addShape(3,0);
+ // apply steepest descent layout
+ ConstrainedFDLayout alg2(rs,es,width/2);
+ alg2.setConstraints(ccs);
+ alg2.run();
+ assert(alg2.computeStress()<0.0013);
+ // the following pair of nodes should line-up
+ assert(fabs(rs[0]->getCentreX()-rs[3]->getCentreX())<0.001);
+ // reset rectangles to random positions
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs[i]->moveCentre(x,y);
+ }
+ // apply scaled majorization layout
+ ConstrainedMajorizationLayout alg(rs,es,nullptr,width/2);
+ alg.setConstraints(&ccs);
+ alg.setScaling(true);
+ alg.run();
+ // the following pair of nodes should line-up
+ assert(fabs(rs[0]->getCentreX()-rs[3]->getCentreX())<0.001);
+ cout<<rs[0]->getCentreX()<<","<<rs[3]->getCentreX()<<endl;
+ OutputFile output(rs,es,nullptr,"constrained.svg");
+ output.rects=true;
+ output.generate();
+
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
diff --git a/src/3rdparty/adaptagrams/libcola/tests/containment.cpp b/src/3rdparty/adaptagrams/libcola/tests/containment.cpp
new file mode 100644
index 0000000..488700e
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/containment.cpp
@@ -0,0 +1,89 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/** \file containment.cpp
+ *
+ * simple test of clustered graph layout
+ *
+ * Authors:
+ * Tim Dwyer <tgdwyer@gmail.com>
+ */
+#include <iostream>
+
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <float.h>
+#include <iomanip>
+#include <libcola/cola.h>
+#include <libcola/output_svg.h>
+#include "graphlayouttest.h"
+
+using namespace cola;
+using namespace std;
+
+vector<vpsc::Rectangle*> rs;
+vector<Edge> es;
+RectangularCluster rc, rd;
+RootCluster root;
+unsigned iteration=0;
+
+int main() {
+
+ const unsigned V = 5;
+ typedef pair < unsigned, unsigned >Edge;
+ Edge edge_array[] = { Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(3, 4) };
+ const std::size_t E = sizeof(edge_array) / sizeof(Edge);
+ es.resize(E);
+ copy(edge_array,edge_array+E,es.begin());
+ double width=100;
+ double height=100;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+20,y,y+15));
+ }
+
+ const unsigned c[]={0,4}, d[]={1,2,3};
+ unsigned nc=sizeof(c)/sizeof(unsigned), nd=sizeof(d)/sizeof(unsigned);
+ CheckProgress test(0.0001,100);
+ ConstrainedMajorizationLayout alg(rs,es,&root,30,nullptr,test);
+ alg.setScaling(true);
+ rc.nodes.resize(nc);
+ copy(c,c+nc,rc.nodes.begin());
+ rd.nodes.resize(nd);
+ copy(d,d+nd,rd.nodes.begin());
+ root.clusters.push_back(&rc);
+ root.clusters.push_back(&rd);
+ alg.run();
+ alg.setAvoidOverlaps();
+ alg.run();
+ OutputFile of(rs,es,&root,"containment.svg",false,true);
+ of.generate();
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/containment2.cpp b/src/3rdparty/adaptagrams/libcola/tests/containment2.cpp
new file mode 100644
index 0000000..d499ffc
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/containment2.cpp
@@ -0,0 +1,157 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/** \file
+ * Interface between Inkscape code (SPItem) and graphlayout functions.
+ * Authors:
+ * Tim Dwyer <tgdwyer@gmail.com>
+ */
+#include <iostream>
+
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <float.h>
+#include <iomanip>
+#include <libcola/cola.h>
+#include <libcola/output_svg.h>
+#include "graphlayouttest.h"
+
+using namespace cola;
+using namespace std;
+
+vector<vpsc::Rectangle*> rs;
+vector<Edge> es;
+RootCluster root;
+unsigned iteration=0;
+
+/**
+* \brief Determines when to terminate layout of a particular graph based
+* on a given relative tolerance.
+*/
+int main() {
+
+ const unsigned V = 19;
+ const char* labels[]={
+ "Hamza Alghamdi",
+ "Nawaf Alhazmi",
+ "Marwan Al-Shehhi",
+ "Mohand Alshehri",
+ "Ahmed Alghamdi",
+ "Saeed Alghamdi",
+ "Salem Alhazmi",
+ "Hani Hanjour",
+ "Mohamed Atta",
+ "Ziad Jarrah",
+ "Ahmed Al Haznawi",
+ "Fayez Ahmed",
+ "Ahmed Alnami",
+ "Khalid Al-Mihdhar",
+ "Majed Moqed",
+ "Abdul Aziz Al-Omari",
+ "Waleed Alshehri",
+ "Wail Alshehri",
+ "Satam Suqami"};
+
+ typedef pair < unsigned, unsigned >Edge;
+ Edge edge_array[] = {
+ Edge(0,1), Edge(0,3), Edge(0,4), Edge(0,5), Edge(0,10),
+ Edge(1,5), Edge(1,6), Edge(1,7), Edge(1,12), Edge(1,13),
+ Edge(2,8), Edge(2,9), Edge(2,11), Edge(2,15),
+ Edge(3,11),
+ Edge(5,10), Edge(5,12),
+ Edge(7,13), Edge(7,14),
+ Edge(8,9), Edge(8,15),
+ Edge(9,10),
+ Edge(15,16),
+ Edge(16,17), Edge(16,18),
+ Edge(17,18)
+ };
+ double g=10;
+ CompoundConstraints scy;
+ scy.push_back(new SeparationConstraint(0,10,g));
+ scy.push_back(new SeparationConstraint(0,3,g));
+ scy.push_back(new SeparationConstraint(0,4,g));
+ scy.push_back(new SeparationConstraint(0,12,g));
+ scy.push_back(new SeparationConstraint(0,5,g));
+ scy.push_back(new SeparationConstraint(1,12,g));
+ scy.push_back(new SeparationConstraint(1,5,g));
+ scy.push_back(new SeparationConstraint(1,13,g));
+ scy.push_back(new SeparationConstraint(1,6,g));
+ scy.push_back(new SeparationConstraint(1,7,g));
+ scy.push_back(new SeparationConstraint(2,8,g));
+ scy.push_back(new SeparationConstraint(2,9,g));
+ scy.push_back(new SeparationConstraint(2,15,g));
+ scy.push_back(new SeparationConstraint(2,11,g));
+ scy.push_back(new SeparationConstraint(5,12,g));
+ scy.push_back(new SeparationConstraint(7,13,g));
+ scy.push_back(new SeparationConstraint(7,14,g));
+ scy.push_back(new SeparationConstraint(16,17,g));
+ scy.push_back(new SeparationConstraint(16,18,g));
+ const std::size_t E = sizeof(edge_array) / sizeof(Edge);
+ es.resize(E);
+ copy(edge_array,edge_array+E,es.begin());
+ double width=100;
+ double height=100;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+17,y,y+10));
+ }
+
+ RectangularCluster c;
+ c.nodes.push_back(0);
+ c.nodes.push_back(1);
+ RectangularCluster d;
+ d.nodes.push_back(3);
+ d.nodes.push_back(11);
+ RectangularCluster e;
+ e.nodes.push_back(8);
+ e.nodes.push_back(9);
+ e.nodes.push_back(10);
+ e.nodes.push_back(15);
+ e.nodes.push_back(16);
+ RectangularCluster f;
+ f.nodes.push_back(17);
+ f.nodes.push_back(18);
+ root.clusters.push_back(&c);
+ root.clusters.push_back(&d);
+ root.clusters.push_back(&e);
+ root.clusters.push_back(&f);
+ OutputFile of(rs,es,&root,"containment2.svg",true,true);
+ //of.setLabels(V,labels);
+ CheckProgress test(0.0001,100);
+ ConstrainedMajorizationLayout alg(rs,es,&root,30,nullptr,test);
+ alg.setScaling(false);
+ //alg.setYSeparationConstraints(&scy);
+ //alg.run();
+ alg.setAvoidOverlaps();
+ alg.run();
+ of.generate();
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/convex_hull.cpp b/src/3rdparty/adaptagrams/libcola/tests/convex_hull.cpp
new file mode 100644
index 0000000..38b6629
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/convex_hull.cpp
@@ -0,0 +1,180 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/**
+ * Really basic regression test of convex hull implementation
+ * declared in libcola/convex_hull.h
+ */
+#include <valarray>
+#include <algorithm>
+#include <libcola/convex_hull.h>
+#include "graphlayouttest.h"
+
+#include <string>
+#include <iostream>
+#include <cairomm/context.h>
+#include <cairomm/surface.h>
+
+/* M_PI is defined in math.h in the case of Microsoft Visual C++ */
+#if defined(_MSC_VER)
+#define _USE_MATH_DEFINES
+#include <math.h>
+#endif
+using namespace std;
+
+typedef vector<unsigned> Hull;
+/**
+ * generates a random set of n points in X and Y.
+ */
+void randTest(unsigned n, valarray<double>& X, valarray<double>& Y) {
+ X.resize(n);
+ Y.resize(n);
+ srand(time(nullptr));
+ for(unsigned i=0;i<n;i++) {
+ X[i]=getRand(1.);
+ Y[i]=getRand(1.);
+ }
+}
+/**
+ * generates a set of 8 points (actually the vertices of two rectangles)
+ * which lineup horizontally. The expected hull are the lower-left and
+ * top-left corners of the left rectangle and the top-right/lower-right
+ * corners of the right rectangle.
+ */
+void tworects(valarray<double>& X, valarray<double>& Y, Hull& expectedHull) {
+ const unsigned n=8;
+ X.resize(n);
+ Y.resize(n);
+ X[0]=330.011898, Y[0]=203.250425;
+ X[1]=330.011898, Y[1]=237.250425;
+ X[2]=276.011898, Y[2]=237.250425;
+ X[3]=276.011898, Y[3]=203.250425;
+ X[4]=459.998300, Y[4]=203.250425;
+ X[5]=459.998300, Y[5]=237.250425;
+ X[6]=405.998300, Y[6]=237.250425;
+ X[7]=405.998300, Y[7]=203.250425;
+ unsigned hull[]={3,4,5,2};
+ unsigned m=sizeof(hull)/sizeof(unsigned);
+ expectedHull.resize(m);
+ copy(hull,hull+m,expectedHull.begin());
+}
+
+int drawCairo(const string& fname,
+ const valarray<double>& X, const valarray<double>& Y,
+ const Hull& hull);
+
+int main(int argc, char** argv) {
+ valarray<double> X, Y;
+ Hull h,expectedHull;
+ tworects(X,Y,expectedHull);
+ hull::convex(X,Y,h);
+ printf("hull size=%d\n",h.size());
+ pair<Hull::iterator,Hull::iterator> r
+ =mismatch(h.begin(),h.end(),expectedHull.begin());
+ assert(r.first==h.end());
+ drawCairo("convex_tworects.svg",X,Y,h);
+
+ randTest(20,X,Y);
+ hull::convex(X,Y,h);
+ drawCairo("convex_hull_random.svg",X,Y,h);
+ return 0;
+}
+
+/***********CAIRO CODE***************************************************/
+double width = 600;
+double height = 400;
+double border=10;
+void dot(Cairo::RefPtr<Cairo::Context> & cr, double x, double y) {
+ cr->arc(x, y,
+ 2., 0.0, 2.0 * M_PI);
+ cr->stroke();
+}
+
+double xcoord(double x) {
+ return border+x*width;
+}
+double ycoord(double y) {
+ return border+y*height;
+}
+int drawCairo(const string& fname,
+ const valarray<double>& Xin, const valarray<double>& Yin,
+ const Hull& hull) {
+#ifdef CAIRO_HAS_SVG_SURFACE
+ unsigned n=Xin.size();
+ assert(Yin.size()==n);
+
+ // normalise coords to range 0-1
+ valarray<double> X=Xin, Y=Yin;
+ X-=X.min();
+ Y-=Y.min();
+ X/=X.max();
+ Y/=Y.max();
+
+ Cairo::RefPtr<Cairo::SvgSurface> surface =
+ Cairo::SvgSurface::create(fname, width+2*border, height+2*border);
+
+ Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);
+
+ cr->save(); // save the state of the context
+ cr->set_source_rgba(0.0, 0.0, 0.0, 0.7);
+ // draw a circle at each coordinate
+ for(unsigned i=0;i<n;i++) {
+ dot(cr,xcoord(X[i]),ycoord(Y[i]));
+ }
+
+ cr->set_source_rgba(0.0, 0.0, 0.0, 0.3);
+ cr->move_to(xcoord(X[hull[0]]),ycoord(Y[hull[0]]));
+ for(unsigned i=1;i<hull.size();i++) {
+ cr->line_to(xcoord(X[hull[i]]),ycoord(Y[hull[i]]));
+ }
+ cr->line_to(xcoord(X[hull[0]]),ycoord(Y[hull[0]]));
+ cr->stroke();
+ cr->set_source_rgba(0.0, 0.0, 0.0, 1.);
+ for(vector<unsigned>::const_iterator i=hull.begin();i!=hull.end();++i) {
+ unsigned j=*i;
+ stringstream ss;
+ ss<<j;
+ printf("p[%d]=(%f,%f)\n",j,X[j],Y[j]);
+ cr->move_to(xcoord(X[j]),ycoord(Y[j]));
+ cr->show_text(ss.str());
+ cr->stroke();
+ }
+ cr->restore();
+
+ cr->show_page();
+
+ cout << "Wrote SVG file \"" << fname << "\"" << endl;
+ return 0;
+
+#else
+
+ cout << "You must compile cairo with SVG support for this example to work."
+ << endl;
+ return 1;
+
+#endif
+
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/cycle_detector.cpp b/src/3rdparty/adaptagrams/libcola/tests/cycle_detector.cpp
new file mode 100644
index 0000000..3b9a0a4
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/cycle_detector.cpp
@@ -0,0 +1,386 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <iostream>
+#include <vector>
+#include <assert.h>
+#include <libcola/cola.h>
+#include <libcola/cycle_detector.h>
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+using namespace cycle_detector;
+using vpsc::Rectangle;
+
+int main() {
+ CycleDetector *cd;
+ Edges case_a, case_b, case_c, case_d, case_e, case_f, case_g;
+
+ CyclicEdges *cycles = nullptr;
+ vector<Rectangle *> rs;
+ unsigned V;
+
+ // create case A
+ // case A consists of a basic graph where the start point is a source
+ cout << endl << "ENTERING CASE A" << endl;
+ V = 5;
+ case_a.push_back(Edge(0, 1));
+ case_a.push_back(Edge(1, 2));
+ case_a.push_back(Edge(2, 3));
+ case_a.push_back(Edge(3, 4));
+ case_a.push_back(Edge(4, 1));
+
+ // detect the cycles
+ cd = new CycleDetector(V, &case_a);
+ cycles = cd->detect_cycles();
+
+ if (cycles != nullptr) {
+ cout << "cycles->size(): " << cycles->size() << endl;
+ for (unsigned i = 0; i < case_a.size(); i++) {
+ // print out the cycles
+ if ((*cycles)[i]) cout << "Cyclic edge found: (" << case_a[i].first << ", " << case_a[i].second << ")" << endl;
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(10,10+5,10,10+5));
+ rs.push_back(new Rectangle(30,30+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,30,30+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_a, "cycle_detector_case_a.svg", false, true, cycles);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();
+ delete cycles;
+ }
+ else {
+ cout << "No cycles found" << endl;
+ }
+
+ // create case B
+ // case B is the same graph of case A but with more elements
+ cout << endl << "ENTERING CASE B" << endl;
+ V = 7;
+ case_b.push_back(Edge(0, 1));
+ case_b.push_back(Edge(1, 2));
+ case_b.push_back(Edge(2, 3));
+ case_b.push_back(Edge(3, 4));
+ case_b.push_back(Edge(4, 1));
+ case_b.push_back(Edge(5, 2));
+ case_b.push_back(Edge(6, 5));
+
+ // detect the cycles
+ cd->mod_graph(V, &case_b);
+ cycles = cd->detect_cycles();
+
+ if (cycles != nullptr) {
+ cout << "cycles->size(): " << cycles->size() << endl;
+ for (unsigned i = 0; i < case_b.size(); i++) {
+ // print out the cycles
+ if ((*cycles)[i]) cout << "Cyclic edge found: (" << case_b[i].first << ", " << case_b[i].second << ")" << endl;
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(10,10+5,10,10+5));
+ rs.push_back(new Rectangle(30,30+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,90,90+5));
+ rs.push_back(new Rectangle(65,65+5,90,90+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_b, "cycle_detector_case_b.svg", false, true, cycles);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();
+ delete cycles;
+ }
+
+ // create case C
+ // case C is a more complicated graph with nested cycles
+ cout << endl << "ENTERING CASE C" << endl;
+ V = 14;
+ case_c.push_back(Edge(0, 1));
+ case_c.push_back(Edge(0, 5));
+ case_c.push_back(Edge(0, 6));
+ case_c.push_back(Edge(2, 0));
+ case_c.push_back(Edge(3, 5));
+ case_c.push_back(Edge(4, 3));
+ case_c.push_back(Edge(5, 4));
+ case_c.push_back(Edge(5, 13));
+ case_c.push_back(Edge(6, 2));
+ case_c.push_back(Edge(6, 9));
+ case_c.push_back(Edge(7, 6));
+ case_c.push_back(Edge(8, 7));
+ case_c.push_back(Edge(9, 10));
+ case_c.push_back(Edge(9, 11));
+ case_c.push_back(Edge(9, 12));
+ case_c.push_back(Edge(10, 6));
+ case_c.push_back(Edge(12, 10));
+ case_c.push_back(Edge(13, 4));
+
+ // detect the cycles
+ //cd = new CycleDetector(V, &case_c);
+ cd->mod_graph(V, &case_c);
+ cycles = cd->detect_cycles();
+ if (cycles != nullptr) {
+ cout << "cycles->size(): " << cycles->size() << endl;
+ for (unsigned i = 0; i < case_c.size(); i++) {
+ // print out the cycles
+ if ((*cycles)[i]) cout << "Cyclic edge found: (" << case_c[i].first << ", " << case_c[i].second << ")" << endl;
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(10,10+5,10,10+5)); // node 0
+ rs.push_back(new Rectangle(20,20+5,40,40+5)); // node 1
+ rs.push_back(new Rectangle(40,40+5,30,30+5)); // node 2
+ rs.push_back(new Rectangle(30,30+5,60,60+5)); // node 3
+ rs.push_back(new Rectangle(60,60+5,60,60+5)); // node 4
+ rs.push_back(new Rectangle(10,10+5,90,90+5)); // node 5
+ rs.push_back(new Rectangle(80,80+5,15,15+5)); // node 6
+ rs.push_back(new Rectangle(110,110+5,15,15+5)); // node 7
+ rs.push_back(new Rectangle(140,140+5,15,15+5)); // node 8
+ rs.push_back(new Rectangle(110,110+5,60,60+5)); // node 9
+ rs.push_back(new Rectangle(100,100+5,85,85+5)); // node 10
+ rs.push_back(new Rectangle(140,140+5,50,50+5)); // node 11
+ rs.push_back(new Rectangle(140,140+5,70,70+5)); // node 12
+ rs.push_back(new Rectangle(45,45+5,90,90+5)); // node 13
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_c, "cycle_detector_case_c.svg", false, true, cycles);
+ for(int i = 0; i < V; i++) { delete rs[i]; }
+ rs.clear();
+ delete cycles;
+ }
+
+ // create case D
+ // case D consists of the same graph as case A but with a different starting location
+ cout << endl << "ENTERING CASE D" << endl;
+ V = 5;
+ case_d.push_back(Edge(0, 1));
+ case_d.push_back(Edge(1, 2));
+ case_d.push_back(Edge(2, 3));
+ case_d.push_back(Edge(3, 0));
+ case_d.push_back(Edge(4, 1));
+
+ // detect the cycles
+ cd->mod_graph(V, &case_d);
+ cycles = cd->detect_cycles();
+
+ if (cycles != nullptr) {
+ cout << "cycles->size(): " << cycles->size() << endl;
+ for (unsigned i = 0; i < case_d.size(); i++) {
+ // print out the cycles
+ if ((*cycles)[i]) cout << "Cyclic edge found: (" << case_d[i].first << ", " << case_d[i].second << ")" << endl;
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(65,65+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,60,60+5));
+ rs.push_back(new Rectangle(10,10+5,10,10+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_d, "cycle_detector_case_d.svg", false, true, cycles);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();
+ delete cycles;
+ }
+ else {
+ cout << "No cycles found" << endl;
+ }
+
+ // create case E
+ // case E is a reordering of case C
+ cout << endl << "ENTERING CASE E" << endl;
+ V = 14;
+ case_e.push_back(Edge(0, 6));
+ case_e.push_back(Edge(0, 9));
+ case_e.push_back(Edge(1, 4));
+ case_e.push_back(Edge(3, 10));
+ case_e.push_back(Edge(4, 3));
+ case_e.push_back(Edge(5, 0));
+ case_e.push_back(Edge(6, 7));
+ case_e.push_back(Edge(7, 0));
+ case_e.push_back(Edge(7, 2));
+ case_e.push_back(Edge(7, 10));
+ case_e.push_back(Edge(8, 5));
+ case_e.push_back(Edge(9, 12));
+ case_e.push_back(Edge(9, 11));
+ case_e.push_back(Edge(9, 13));
+ case_e.push_back(Edge(10, 1));
+ case_e.push_back(Edge(10, 4));
+ case_e.push_back(Edge(12, 0));
+ case_e.push_back(Edge(11, 12));
+
+ // detect the cycles
+ cd->mod_graph(V, &case_e);
+ cycles = cd->detect_cycles();
+ if (cycles != nullptr) {
+ cout << "cycles->size(): " << cycles->size() << endl;
+ for (unsigned i = 0; i < case_e.size(); i++) {
+ // print out the cycles
+ if ((*cycles)[i]) cout << "Cyclic edge found: (" << case_e[i].first << ", " << case_e[i].second << ")" << endl;
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(80,80+5,15,15+5)); // node 6
+ rs.push_back(new Rectangle(45,45+5,90,90+5)); // node 13
+ rs.push_back(new Rectangle(20,20+5,40,40+5)); // node 1
+ rs.push_back(new Rectangle(30,30+5,60,60+5)); // node 3
+ rs.push_back(new Rectangle(60,60+5,60,60+5)); // node 4
+ rs.push_back(new Rectangle(110,110+5,15,15+5)); // node 7
+ rs.push_back(new Rectangle(40,40+5,30,30+5)); // node 2
+ rs.push_back(new Rectangle(10,10+5,10,10+5)); // node 0
+ rs.push_back(new Rectangle(140,140+5,15,15+5)); // node 8
+ rs.push_back(new Rectangle(110,110+5,60,60+5)); // node 9
+ rs.push_back(new Rectangle(10,10+5,90,90+5)); // node 5
+ rs.push_back(new Rectangle(140,140+5,70,70+5)); // node 12
+ rs.push_back(new Rectangle(100,100+5,85,85+5)); // node 10
+ rs.push_back(new Rectangle(140,140+5,50,50+5)); // node 11
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_e, "cycle_detector_case_e.svg", false, true, cycles);
+ for(int i = 0; i < V; i++) { delete rs[i]; }
+ rs.clear();
+ delete cycles;
+ }
+
+ // create case F
+ // case F consists of the same graph with sinks
+ cout << endl << "ENTERING CASE F" << endl;
+ V = 3;
+ case_f.push_back(Edge(0, 1));
+ case_f.push_back(Edge(0, 2));
+ case_f.push_back(Edge(1, 2));
+
+ // detect the cycles
+ cd->mod_graph(V, &case_f);
+ cycles = cd->detect_cycles();
+
+ if (cycles != nullptr) {
+ // output a picture
+ rs.push_back(new Rectangle(10,10+5,10,10+5));
+ rs.push_back(new Rectangle(40,40+5,30,30+5));
+ rs.push_back(new Rectangle(15,15+5,60,60+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_f, "cycle_detector_case_f.svg", false, true, cycles);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();
+
+ cout << "No cycles found" << endl;
+ }
+
+ // This tests the cycle detectors ability to cycle through a chain of cyclic ancestors
+ cout << endl << "ENTERING CYCLIC ANCESTOR TEST" << endl;
+ Node a(1), b(2), c(3), d(4), e(5), f(6);
+ // set up the chain
+ f.cyclicAncestor = &e;
+ e.cyclicAncestor = &d;
+ d.cyclicAncestor = &c;
+ c.cyclicAncestor = &b;
+ b.cyclicAncestor = &a;
+ a.cyclicAncestor = &a;
+
+ Node *ca = cd->get_highest_ca(&f);
+ if (ca != nullptr) { cout << "Highest cyclic ancestor found at vertex(" << ca->id << ")" << endl; }
+
+ // create case G
+ // case G hows the ability to find nested cycles and to reassign cyclic ancestors
+ cout << endl << "ENTERING CASE G" << endl;
+ V = 7;
+ case_g.push_back(Edge(0, 1));
+ case_g.push_back(Edge(1, 2));
+ case_g.push_back(Edge(2, 3));
+ case_g.push_back(Edge(3, 4));
+ case_g.push_back(Edge(4, 5));
+ case_g.push_back(Edge(5, 6));
+ case_g.push_back(Edge(6, 5));
+ case_g.push_back(Edge(5, 4));
+ case_g.push_back(Edge(4, 3));
+ case_g.push_back(Edge(3, 2));
+ case_g.push_back(Edge(2, 1));
+ case_g.push_back(Edge(1, 0));
+ case_g.push_back(Edge(0, 6));
+
+ // detect the cycles
+ cd->mod_graph(V, &case_g);
+ cycles = cd->detect_cycles();
+
+ if (cycles != nullptr) {
+ cout << "cycles->size(): " << cycles->size() << endl;
+ for (unsigned i = 0; i < case_g.size(); i++) {
+ // print out the cycles
+ if ((*cycles)[i]) cout << "Cyclic edge found: (" << case_g[i].first << ", " << case_g[i].second << ")" << endl;
+ }
+
+ cout << endl;
+
+ // output a picture
+ cout << "No picture generated" << endl;
+
+ /*rs.push_back(new Rectangle(50,50+5,10,10+5));
+ rs.push_back(new Rectangle(50,50+5,30,30+5));
+ rs.push_back(new Rectangle(50,50+5,60,60+5));
+ rs.push_back(new Rectangle(10,10+5,70,70+5));
+ rs.push_back(new Rectangle(50,50+5,100,100+5));
+ rs.push_back(new Rectangle(10,10+5,40,40+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_a, "cycle_detector_case_g.svg", false, true, cycles);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();*/
+ delete cycles;
+ }
+ else {
+ cout << "No cycles found" << endl;
+ }
+
+ // END TEST
+ delete cd;
+
+ return 0;
+}
diff --git a/src/3rdparty/adaptagrams/libcola/tests/data/1138_bus.txt b/src/3rdparty/adaptagrams/libcola/tests/data/1138_bus.txt
new file mode 100644
index 0000000..fb63ec3
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/data/1138_bus.txt
@@ -0,0 +1,1458 @@
+4 0
+562 0
+9 1
+562 1
+10 2
+33 2
+34 2
+103 2
+474 2
+6 3
+26 3
+100 3
+101 3
+102 3
+8 4
+6 5
+36 5
+97 5
+102 5
+36 6
+100 6
+101 6
+102 6
+25 7
+34 7
+723 7
+9 8
+103 8
+103 9
+11 10
+37 10
+565 10
+33 12
+103 12
+412 13
+15 14
+16 14
+17 14
+18 14
+410 14
+20 19
+36 19
+101 19
+21 20
+22 20
+23 20
+24 20
+34 25
+27 26
+28 26
+29 26
+100 26
+31 30
+99 30
+99 31
+99 32
+103 33
+552 33
+103 34
+709 34
+710 35
+101 36
+38 37
+97 37
+411 37
+98 38
+40 39
+42 39
+44 39
+41 40
+43 40
+145 42
+485 43
+48 44
+47 45
+47 46
+53 47
+505 47
+49 48
+52 48
+50 49
+51 49
+124 51
+53 52
+54 52
+424 53
+444 53
+446 53
+62 55
+65 56
+69 57
+66 58
+67 59
+129 60
+128 61
+63 62
+64 62
+70 63
+130 63
+225 63
+1094 64
+66 65
+67 65
+73 65
+182 65
+225 65
+67 66
+68 66
+73 67
+89 67
+200 67
+69 68
+181 69
+195 69
+1062 69
+1064 69
+1073 69
+71 70
+72 71
+120 71
+74 73
+75 73
+77 73
+79 73
+118 73
+203 74
+809 74
+917 74
+76 75
+77 75
+126 75
+1049 76
+78 77
+451 77
+415 78
+416 78
+453 78
+80 79
+446 79
+451 79
+447 80
+449 80
+463 80
+93 81
+93 82
+94 83
+86 84
+125 84
+86 85
+240 85
+250 85
+252 85
+266 85
+268 85
+282 85
+290 85
+292 85
+293 85
+301 85
+314 85
+87 86
+104 88
+114 88
+90 89
+91 90
+107 90
+114 90
+115 90
+92 91
+93 92
+251 92
+263 92
+270 92
+287 92
+291 92
+292 92
+293 92
+321 92
+322 92
+323 92
+324 92
+325 92
+95 93
+263 93
+317 93
+324 93
+96 94
+261 94
+267 94
+299 94
+144 95
+703 95
+704 95
+267 96
+412 98
+724 99
+731 99
+101 100
+102 100
+102 101
+477 102
+105 104
+108 104
+107 106
+109 107
+1028 108
+110 109
+327 109
+366 109
+369 109
+366 110
+367 110
+700 110
+112 111
+369 111
+685 111
+113 112
+114 112
+689 112
+1008 113
+116 115
+125 115
+118 117
+122 118
+120 119
+121 120
+503 120
+122 121
+123 121
+124 122
+124 123
+126 123
+125 124
+128 124
+545 124
+128 125
+127 126
+132 129
+172 129
+212 129
+131 130
+132 130
+135 130
+143 131
+741 131
+133 132
+135 134
+138 134
+739 134
+140 135
+138 136
+140 136
+760 136
+140 137
+876 137
+881 137
+139 138
+828 139
+829 139
+257 141
+365 141
+143 142
+742 142
+744 142
+825 142
+826 143
+317 144
+702 144
+146 145
+147 146
+165 148
+172 149
+174 150
+179 151
+182 152
+206 153
+197 154
+212 155
+218 156
+225 157
+181 158
+204 158
+171 159
+232 159
+221 160
+742 160
+162 161
+168 161
+208 161
+222 161
+231 161
+185 162
+200 162
+226 162
+165 163
+165 164
+166 164
+174 164
+193 164
+191 165
+200 165
+217 165
+174 166
+179 167
+208 167
+186 168
+187 169
+193 169
+177 170
+216 170
+172 171
+221 171
+754 171
+183 172
+210 173
+215 173
+178 174
+176 175
+177 175
+206 175
+206 176
+213 177
+216 177
+202 178
+208 179
+182 180
+182 181
+204 181
+220 181
+183 182
+200 182
+225 182
+192 183
+212 183
+186 184
+186 185
+217 185
+187 186
+205 186
+208 186
+210 188
+215 188
+198 189
+194 190
+196 190
+197 190
+210 190
+198 191
+217 191
+219 191
+197 192
+198 192
+207 192
+215 193
+210 194
+211 196
+200 199
+201 199
+217 200
+202 201
+220 204
+215 205
+207 206
+223 206
+214 209
+216 209
+217 209
+211 210
+503 212
+216 213
+217 215
+219 218
+229 218
+221 220
+224 220
+224 221
+232 221
+742 221
+231 222
+1025 223
+227 226
+228 227
+230 227
+231 227
+231 230
+235 233
+306 233
+235 234
+242 234
+269 234
+271 234
+297 234
+298 234
+285 235
+260 236
+286 236
+308 236
+365 236
+701 236
+238 237
+269 237
+269 238
+280 238
+258 239
+241 240
+245 240
+252 240
+256 240
+265 240
+274 240
+278 240
+288 240
+290 240
+291 240
+292 240
+293 240
+298 240
+309 240
+320 240
+326 240
+243 241
+244 241
+271 243
+297 244
+309 245
+247 246
+254 246
+254 247
+281 248
+256 249
+262 249
+288 249
+316 249
+266 250
+309 251
+312 251
+254 253
+284 253
+257 254
+259 254
+262 254
+289 255
+316 255
+320 255
+260 257
+326 257
+277 258
+288 259
+267 261
+275 261
+313 261
+310 263
+275 264
+299 264
+306 265
+281 266
+283 266
+301 266
+269 267
+300 267
+283 268
+274 269
+278 269
+279 269
+317 269
+319 269
+273 272
+302 272
+314 272
+311 273
+284 276
+288 276
+308 277
+291 282
+290 287
+297 294
+296 295
+298 296
+695 299
+313 300
+311 302
+304 303
+314 303
+328 303
+314 304
+321 305
+322 307
+325 310
+314 311
+315 314
+318 314
+322 314
+321 315
+703 317
+328 318
+324 323
+334 329
+335 330
+336 331
+349 332
+349 333
+336 334
+336 335
+337 336
+338 336
+339 336
+339 337
+339 338
+340 339
+341 339
+341 340
+342 341
+343 341
+344 341
+369 341
+345 342
+345 343
+345 344
+346 345
+348 345
+366 345
+347 346
+348 347
+349 348
+365 350
+352 351
+407 351
+408 351
+362 352
+381 352
+381 353
+382 353
+374 354
+382 355
+397 355
+393 356
+394 356
+478 357
+473 358
+714 359
+478 360
+479 360
+402 361
+713 361
+363 362
+364 362
+372 362
+373 362
+387 362
+394 362
+406 362
+473 362
+698 365
+367 366
+371 366
+370 368
+371 370
+375 374
+376 374
+377 374
+378 374
+379 374
+380 374
+388 374
+403 374
+383 382
+384 382
+385 382
+386 382
+391 382
+388 387
+389 387
+390 387
+394 387
+400 387
+404 387
+394 391
+473 392
+478 392
+394 393
+397 394
+398 394
+404 394
+405 394
+406 394
+473 394
+405 395
+715 395
+716 395
+715 396
+716 396
+472 399
+401 400
+713 400
+408 403
+478 405
+482 405
+715 405
+716 405
+410 409
+411 409
+730 409
+475 410
+476 410
+485 410
+412 411
+477 411
+708 411
+723 411
+430 413
+432 413
+431 414
+432 414
+432 415
+461 415
+432 416
+461 416
+418 417
+544 417
+420 419
+421 419
+469 419
+424 422
+515 422
+465 423
+515 423
+425 424
+426 424
+465 424
+436 425
+518 425
+428 427
+429 427
+430 427
+431 427
+433 432
+509 432
+563 432
+509 434
+533 435
+437 436
+438 436
+440 436
+457 436
+439 438
+459 438
+441 440
+443 442
+469 442
+505 442
+515 442
+457 443
+445 444
+446 444
+448 446
+536 446
+463 447
+449 448
+450 449
+452 451
+454 453
+456 455
+563 455
+458 457
+459 457
+460 459
+462 461
+464 463
+544 463
+967 464
+466 465
+543 467
+542 468
+471 470
+477 470
+480 470
+491 470
+706 470
+707 470
+473 472
+709 474
+723 474
+481 475
+477 476
+707 477
+708 477
+479 478
+713 478
+725 478
+483 480
+484 480
+490 480
+491 480
+732 480
+482 481
+708 483
+732 483
+490 484
+730 485
+490 486
+490 487
+491 488
+491 489
+491 490
+733 490
+706 491
+706 492
+504 493
+512 494
+520 495
+521 496
+522 497
+499 498
+818 498
+913 498
+501 500
+504 500
+506 500
+520 500
+530 500
+535 500
+606 501
+608 501
+612 501
+936 501
+506 502
+512 502
+552 502
+504 503
+520 504
+525 504
+577 504
+507 506
+508 506
+514 506
+520 506
+521 506
+546 506
+618 507
+638 507
+780 507
+510 508
+514 508
+519 508
+533 508
+519 509
+913 510
+925 510
+519 511
+513 512
+539 512
+789 513
+794 513
+515 514
+516 514
+517 514
+535 514
+546 514
+992 516
+994 516
+956 518
+966 518
+521 520
+522 521
+581 522
+769 522
+778 522
+801 522
+532 523
+984 523
+1000 523
+567 524
+526 525
+530 525
+920 526
+932 526
+1067 526
+1072 526
+1073 526
+1123 526
+528 527
+808 527
+818 527
+577 529
+582 529
+779 529
+796 529
+802 529
+531 530
+533 530
+553 531
+646 531
+651 531
+662 531
+667 531
+671 531
+672 531
+676 531
+907 531
+911 531
+917 531
+1046 531
+534 533
+535 533
+541 533
+884 534
+536 535
+537 535
+538 535
+541 535
+808 537
+913 537
+947 537
+952 537
+963 537
+799 539
+542 540
+542 541
+544 541
+545 541
+543 542
+550 547
+562 548
+565 549
+551 550
+554 550
+565 550
+557 551
+559 551
+560 552
+709 552
+573 553
+908 553
+555 554
+556 554
+563 554
+565 554
+558 555
+578 555
+620 555
+902 555
+557 556
+978 557
+979 557
+985 557
+988 557
+990 557
+997 557
+999 557
+578 558
+979 559
+561 560
+565 560
+562 561
+566 562
+566 564
+566 565
+772 567
+794 567
+784 568
+578 569
+775 570
+782 571
+795 572
+580 574
+581 575
+783 575
+785 576
+801 576
+1089 576
+779 577
+579 578
+781 578
+782 578
+894 578
+926 578
+586 579
+775 580
+795 580
+796 580
+798 580
+779 582
+802 582
+584 583
+1067 583
+606 584
+612 584
+658 584
+596 585
+597 586
+613 586
+594 587
+596 587
+590 588
+594 589
+615 589
+600 590
+610 591
+603 592
+599 593
+596 595
+602 595
+606 595
+1104 598
+600 599
+781 599
+601 600
+632 600
+639 601
+603 602
+604 602
+1091 602
+611 603
+614 603
+606 604
+609 605
+609 607
+1100 607
+1067 608
+614 610
+1122 616
+628 617
+638 617
+619 618
+631 619
+623 620
+1060 620
+624 621
+640 621
+638 622
+641 622
+637 623
+634 624
+633 625
+634 625
+638 626
+630 627
+641 627
+636 628
+642 628
+630 629
+634 629
+795 629
+633 631
+640 631
+635 634
+1093 635
+651 643
+661 643
+649 644
+1059 644
+663 645
+1050 645
+1040 646
+677 647
+1041 647
+671 648
+1054 648
+652 649
+669 650
+1044 650
+652 651
+662 651
+665 651
+667 651
+675 651
+1053 651
+1047 652
+676 653
+1056 653
+656 654
+664 654
+677 655
+1054 656
+670 657
+671 657
+676 658
+1049 659
+1057 659
+676 660
+671 661
+1055 663
+681 664
+680 665
+1050 666
+678 668
+1057 668
+1120 669
+678 670
+672 671
+681 671
+1048 671
+1049 671
+1051 671
+1057 671
+1120 671
+674 673
+1045 673
+1049 674
+1042 675
+677 676
+1040 676
+1058 676
+1046 679
+1056 679
+1052 680
+688 682
+688 683
+690 684
+686 685
+687 685
+688 687
+693 687
+698 687
+699 687
+701 687
+692 688
+690 689
+693 689
+696 689
+691 690
+694 690
+694 692
+694 693
+697 696
+699 698
+706 705
+725 706
+708 707
+723 710
+733 710
+713 711
+713 712
+714 713
+733 713
+716 715
+723 717
+723 718
+723 719
+723 720
+723 721
+723 722
+724 723
+733 723
+727 726
+730 726
+730 727
+729 728
+730 728
+730 729
+742 734
+741 735
+742 736
+741 737
+743 738
+740 739
+741 739
+743 739
+748 740
+758 740
+742 741
+745 742
+755 743
+745 744
+747 746
+757 746
+756 747
+752 748
+750 749
+758 749
+756 751
+761 751
+756 753
+764 753
+763 754
+756 755
+760 759
+765 760
+766 760
+762 761
+767 765
+768 767
+771 767
+822 769
+771 770
+773 772
+794 772
+800 772
+801 772
+775 774
+780 774
+780 775
+795 775
+796 775
+1126 775
+792 776
+794 776
+799 776
+778 777
+779 778
+786 778
+796 779
+948 779
+782 781
+801 783
+785 784
+787 784
+795 784
+796 784
+801 784
+1127 785
+948 786
+788 787
+795 787
+1131 787
+1093 788
+790 789
+794 789
+798 791
+1109 791
+793 792
+824 792
+794 793
+799 793
+798 795
+797 796
+802 796
+804 796
+1118 796
+1113 797
+1136 801
+803 802
+1137 804
+820 805
+886 806
+896 807
+919 808
+810 809
+917 809
+908 811
+884 812
+939 812
+1121 812
+814 813
+908 813
+917 813
+816 815
+926 815
+817 816
+906 816
+819 818
+887 820
+896 820
+920 820
+879 821
+884 821
+934 821
+824 823
+836 827
+837 827
+873 827
+832 828
+838 828
+832 829
+839 829
+840 830
+868 830
+841 831
+868 831
+842 832
+843 833
+873 833
+844 834
+861 834
+845 835
+868 835
+858 837
+859 837
+847 846
+872 847
+853 848
+862 848
+863 848
+854 849
+872 849
+855 850
+857 850
+856 851
+868 851
+875 852
+872 857
+860 859
+862 861
+868 862
+864 863
+868 863
+868 865
+876 865
+877 866
+868 867
+870 867
+876 867
+869 868
+870 869
+876 869
+881 871
+881 872
+877 873
+875 874
+881 874
+877 876
+882 876
+881 878
+881 880
+936 883
+1122 883
+913 884
+917 884
+894 885
+926 885
+936 885
+895 886
+896 886
+923 887
+916 888
+890 889
+907 889
+916 889
+892 891
+898 891
+926 891
+920 893
+935 893
+1125 893
+1124 894
+896 895
+912 896
+916 896
+943 896
+913 897
+925 897
+899 898
+907 898
+912 900
+1128 900
+905 901
+986 902
+904 903
+938 903
+943 903
+921 905
+938 905
+922 906
+911 907
+916 907
+926 907
+909 908
+911 910
+934 913
+937 913
+962 913
+925 914
+990 915
+917 916
+929 916
+918 917
+1129 917
+939 918
+922 920
+923 920
+926 920
+932 920
+936 920
+929 921
+1132 921
+924 923
+927 926
+936 926
+928 927
+936 927
+930 929
+948 931
+933 932
+941 932
+946 934
+936 935
+1133 935
+953 939
+953 940
+943 942
+960 944
+964 945
+951 947
+954 947
+956 947
+957 947
+963 947
+950 949
+954 949
+955 949
+964 950
+968 950
+974 950
+959 951
+954 952
+958 953
+957 956
+966 956
+972 956
+972 959
+961 960
+962 960
+967 960
+965 961
+971 962
+967 964
+968 964
+970 965
+969 968
+971 970
+982 973
+976 975
+988 975
+1000 975
+988 977
+982 978
+981 980
+983 980
+997 980
+985 982
+986 984
+988 984
+998 986
+992 987
+994 987
+989 988
+991 990
+993 992
+996 994
+997 994
+996 995
+997 996
+1026 1001
+1034 1002
+1031 1003
+1038 1004
+1006 1005
+1012 1005
+1018 1005
+1020 1005
+1029 1005
+1034 1005
+1022 1007
+1009 1008
+1017 1008
+1018 1008
+1020 1008
+1021 1008
+1039 1008
+1039 1010
+1039 1011
+1022 1012
+1028 1012
+1029 1012
+1036 1012
+1037 1012
+1038 1012
+1038 1013
+1028 1014
+1023 1015
+1033 1015
+1028 1016
+1032 1018
+1020 1019
+1023 1022
+1024 1022
+1026 1022
+1033 1023
+1027 1024
+1026 1025
+1027 1026
+1034 1026
+1030 1029
+1033 1031
+1035 1031
+1035 1034
+1049 1042
+1049 1043
+1052 1043
+1046 1044
+1057 1045
+1053 1048
+1050 1049
+1051 1049
+1055 1050
+1055 1054
+1057 1054
+1060 1058
+1071 1061
+1084 1061
+1073 1062
+1074 1063
+1086 1063
+1076 1064
+1079 1064
+1067 1065
+1070 1066
+1068 1067
+1091 1067
+1085 1068
+1076 1069
+1112 1069
+1087 1070
+1074 1071
+1073 1072
+1074 1073
+1080 1073
+1085 1073
+1081 1074
+1076 1075
+1077 1076
+1079 1076
+1087 1076
+1094 1076
+1083 1077
+1084 1077
+1116 1078
+1086 1082
+1105 1088
+1111 1088
+1090 1089
+1092 1090
+1107 1090
+1097 1092
+1095 1094
+1099 1094
+1104 1094
+1112 1094
+1102 1095
+1106 1095
+1111 1095
+1099 1096
+1098 1097
+1100 1099
+1119 1100
+1111 1101
+1117 1103
+1118 1103
+1108 1105
+1113 1109
+1118 1110
+1114 1113
+1115 1113
+1119 1116
+1135 1121
+1134 1123
+1134 1128
+1135 1130
diff --git a/src/3rdparty/adaptagrams/libcola/tests/data/uetzNetworkGSC-all.gml b/src/3rdparty/adaptagrams/libcola/tests/data/uetzNetworkGSC-all.gml
new file mode 100644
index 0000000..99c4053
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/data/uetzNetworkGSC-all.gml
@@ -0,0 +1,26139 @@
+graph [
+ directed 1
+ node [
+ id 1
+ pajek_id 1
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1294.0522048684777
+ y 1122.6497967871214
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 2
+ pajek_id 2
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2055.718178872795
+ y 1059.2791761907554
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 3
+ pajek_id 3
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1256.6354129633914
+ y 1695.6123461841953
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 4
+ pajek_id 4
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1184.7211808078375
+ y 935.8910996786233
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 5
+ pajek_id 5
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2298.0954772536134
+ y 1437.502173559352
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 6
+ pajek_id 6
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1897.6814785435922
+ y 550.7159507323732
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 7
+ pajek_id 7
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1901.322129497895
+ y 1044.3438487090452
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 8
+ pajek_id 8
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2780.868057459027
+ y 880.0661109912785
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 9
+ pajek_id 9
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1538.3317441868267
+ y 1411.5744527134639
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 10
+ pajek_id 10
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 396.0152636117873
+ y 1131.0468905861571
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 11
+ pajek_id 11
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2807.6418756553476
+ y 1965.421804479885
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 12
+ pajek_id 12
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1483.7207919217562
+ y 1613.0999970511837
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 13
+ pajek_id 13
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 254.92863023355244
+ y 592.4142543364859
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 14
+ pajek_id 14
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2356.3555481078492
+ y 762.7982298395269
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 15
+ pajek_id 15
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 358.86149369612554
+ y 718.6522617063977
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 16
+ pajek_id 16
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1989.7728584457432
+ y 593.5406100260483
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 17
+ pajek_id 17
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1176.0589697518428
+ y 274.6599182522517
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 18
+ pajek_id 18
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 815.4286293876028
+ y 1519.2372285089286
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 19
+ pajek_id 19
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1292.8058349907271
+ y 1534.9166231756176
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 20
+ pajek_id 20
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1712.1139015143726
+ y 1743.9840389531971
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 21
+ pajek_id 21
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1159.0926195442978
+ y 60.0
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 22
+ pajek_id 22
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1698.8281996861965
+ y 938.1788913033595
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 23
+ pajek_id 23
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2117.1960623698105
+ y 377.3080137329175
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 24
+ pajek_id 24
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1988.5172976949088
+ y 1626.9118171301184
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 25
+ pajek_id 25
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1951.0677192239534
+ y 1227.8213042650113
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 26
+ pajek_id 26
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1209.2907663600151
+ y 571.9488583740487
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 27
+ pajek_id 27
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1553.217522639471
+ y 514.0779699887444
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 28
+ pajek_id 28
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1216.2131040787344
+ y 1306.3244872331861
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 29
+ pajek_id 29
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2495.910234238144
+ y 1509.2542926345884
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 30
+ pajek_id 30
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2589.368846133916
+ y 902.4410855851487
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 31
+ pajek_id 31
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1900.4466132863522
+ y 960.4878587369396
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 32
+ pajek_id 32
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1480.404193494587
+ y 503.45364906241434
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 33
+ pajek_id 33
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1786.4697371577445
+ y 2321.7848119927116
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 34
+ pajek_id 34
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1609.213005284541
+ y 1590.2108893694465
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 35
+ pajek_id 35
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 600.5008950141041
+ y 1277.5609673161835
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 36
+ pajek_id 36
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 60.0
+ y 768.8625017780407
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 37
+ pajek_id 37
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 382.9141452731493
+ y 1259.7726277058914
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 38
+ pajek_id 38
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 687.2063369120657
+ y 1082.3933671094655
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 39
+ pajek_id 39
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1027.5033292569951
+ y 1088.9830040963775
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 40
+ pajek_id 40
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1632.4747876484166
+ y 710.5037615118014
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 41
+ pajek_id 41
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 748.4550588733631
+ y 1062.8651339361004
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 42
+ pajek_id 42
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 963.8979533416527
+ y 1723.250139029375
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 43
+ pajek_id 43
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1411.3947986828978
+ y 1157.8550891438708
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 44
+ pajek_id 44
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2648.6214914664592
+ y 360.6532255567197
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 45
+ pajek_id 45
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1012.524198351514
+ y 1566.9080651878785
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 46
+ pajek_id 46
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1673.0588337518445
+ y 1520.3103374282064
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 47
+ pajek_id 47
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2292.062233641057
+ y 807.7075902196876
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 48
+ pajek_id 48
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2077.483685032171
+ y 1214.6266410102694
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 49
+ pajek_id 49
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1250.7982377330313
+ y 984.2480480318932
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 50
+ pajek_id 50
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 826.5624689443126
+ y 1458.2342219655006
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 51
+ pajek_id 51
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1043.503156998524
+ y 1914.4120411204835
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 52
+ pajek_id 52
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1097.4841298080655
+ y 608.9543419822743
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 53
+ pajek_id 53
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1151.8669553096083
+ y 1688.783506135614
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 54
+ pajek_id 54
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1100.1774339936296
+ y 449.9360013393336
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 55
+ pajek_id 55
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1797.1270429940496
+ y 517.7947984237063
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 56
+ pajek_id 56
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1958.7774891972645
+ y 951.067065374911
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 57
+ pajek_id 57
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1320.7173946510097
+ y 666.953428346941
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 58
+ pajek_id 58
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 409.511718757674
+ y 754.8270051102944
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 59
+ pajek_id 59
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 456.52944375010406
+ y 1644.5489937771122
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 60
+ pajek_id 60
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1650.4029796871373
+ y 1281.9794653489726
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 61
+ pajek_id 61
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2203.5059215970086
+ y 1103.986465771347
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 62
+ pajek_id 62
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1648.5790338469196
+ y 1619.5713910478498
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 63
+ pajek_id 63
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1441.449939123268
+ y 278.4421140050705
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 64
+ pajek_id 64
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1646.3755592037082
+ y 1867.8552090742746
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 65
+ pajek_id 65
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1690.4064173252282
+ y 1106.6596200585911
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 66
+ pajek_id 66
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1375.2079396723311
+ y 1567.1239230162141
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 67
+ pajek_id 67
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1381.6936762897983
+ y 930.9429010096588
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 68
+ pajek_id 68
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2246.515691754706
+ y 1228.672822112808
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 69
+ pajek_id 69
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2513.1221976499774
+ y 2123.5607442911432
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 70
+ pajek_id 70
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 325.1248018822786
+ y 1301.1300387216584
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 71
+ pajek_id 71
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 905.4567507395766
+ y 1635.3403866013616
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 72
+ pajek_id 72
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1409.3758774490468
+ y 2445.8494772528247
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 73
+ pajek_id 73
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 270.55209645867626
+ y 1976.484880612065
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 74
+ pajek_id 74
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1846.104723102188
+ y 2357.13888536703
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 75
+ pajek_id 75
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1931.8467589445268
+ y 1416.3573716456167
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 76
+ pajek_id 76
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 219.41564456563447
+ y 351.74606877700694
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 77
+ pajek_id 77
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1574.267945560331
+ y 994.005057804803
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 78
+ pajek_id 78
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2258.765897434142
+ y 975.7865089151361
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 79
+ pajek_id 79
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1003.0168039671166
+ y 818.3149905376152
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 80
+ pajek_id 80
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2162.351384651877
+ y 639.3742942428671
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 81
+ pajek_id 81
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1175.3498984884113
+ y 205.4073989675603
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 82
+ pajek_id 82
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1025.8732247508035
+ y 146.60499318409438
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 83
+ pajek_id 83
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 784.8316721743003
+ y 739.8886774008013
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 84
+ pajek_id 84
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2358.3905436512314
+ y 1757.8833117002607
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 85
+ pajek_id 85
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 187.0231231288874
+ y 464.9030131392583
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 86
+ pajek_id 86
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1680.1684155817545
+ y 989.3992861143759
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 87
+ pajek_id 87
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1592.5433115122046
+ y 1133.073079548351
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 88
+ pajek_id 88
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 984.0210982272379
+ y 1907.6496174273066
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 89
+ pajek_id 89
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1908.2544551347682
+ y 1953.0395792102486
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 90
+ pajek_id 90
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1760.6396933740039
+ y 454.1561397683437
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 91
+ pajek_id 91
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1510.4214829476575
+ y 255.4247158499462
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 92
+ pajek_id 92
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2156.911158437812
+ y 1737.2936541047445
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 93
+ pajek_id 93
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2330.4433111549088
+ y 1066.919264412134
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 94
+ pajek_id 94
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1489.0049739638976
+ y 1102.8420420131365
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 95
+ pajek_id 95
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1381.821327085725
+ y 1425.799958792195
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 96
+ pajek_id 96
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2026.5031721150344
+ y 1195.03677714938
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 97
+ pajek_id 97
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1566.5985533781122
+ y 2134.591986800821
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 98
+ pajek_id 98
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1866.8579043433465
+ y 496.54994132044186
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 99
+ pajek_id 99
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1709.8596572466934
+ y 1537.0985557194695
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 100
+ pajek_id 100
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1058.888749291412
+ y 1423.3219452240978
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 101
+ pajek_id 101
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1026.841049144297
+ y 1526.2197338662158
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 102
+ pajek_id 102
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1234.128325564796
+ y 1058.423971642138
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 103
+ pajek_id 103
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2269.604004829725
+ y 1961.2578434564753
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 104
+ pajek_id 104
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1204.604308471341
+ y 331.2782608195139
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 105
+ pajek_id 105
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1456.5954783621391
+ y 2393.969680005851
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 106
+ pajek_id 106
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1030.6221217055054
+ y 1655.7105879228054
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 107
+ pajek_id 107
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1825.2038903621162
+ y 1764.5225692398108
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 108
+ pajek_id 108
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 855.344393246044
+ y 1581.4397578617163
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 109
+ pajek_id 109
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2290.109859607357
+ y 1866.4142704202714
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 110
+ pajek_id 110
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2016.9300946422195
+ y 1800.0828289087844
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 111
+ pajek_id 111
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2311.298477488912
+ y 1203.9224047333146
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 112
+ pajek_id 112
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2173.9918013172064
+ y 1358.97529576786
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 113
+ pajek_id 113
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 402.8249532029572
+ y 2005.0535234158124
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 114
+ pajek_id 114
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1370.447752295795
+ y 1698.544524957459
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 115
+ pajek_id 115
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 824.5410187470699
+ y 2203.3482170965663
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 116
+ pajek_id 116
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1899.5312814624624
+ y 341.64788217907767
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 117
+ pajek_id 117
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1275.5334231652173
+ y 435.5539332588777
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 118
+ pajek_id 118
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1799.057369842763
+ y 898.644722551811
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 119
+ pajek_id 119
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 936.3882990544396
+ y 542.1677084693897
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 120
+ pajek_id 120
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2035.2157086365958
+ y 549.5503878259726
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 121
+ pajek_id 121
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2306.5008116638155
+ y 2172.8922465255055
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 122
+ pajek_id 122
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 794.0600584680333
+ y 1767.0092661358444
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 123
+ pajek_id 123
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 967.8528471899847
+ y 1305.606206649742
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 124
+ pajek_id 124
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2478.6497152538377
+ y 1203.6776389496872
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 125
+ pajek_id 125
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1997.321116636319
+ y 2192.367195588601
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 126
+ pajek_id 126
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1177.3434085029842
+ y 778.6424846605535
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 127
+ pajek_id 127
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1585.5048018331465
+ y 1455.2573996761384
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 128
+ pajek_id 128
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 472.28484900676176
+ y 718.0672675218485
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 129
+ pajek_id 129
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 794.0849295823707
+ y 1371.6459663216558
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 130
+ pajek_id 130
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2008.8851806591924
+ y 1293.0028606195688
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 131
+ pajek_id 131
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1441.295381525302
+ y 564.6073812973832
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 132
+ pajek_id 132
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1861.1042483735764
+ y 1523.2486386191717
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 133
+ pajek_id 133
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 957.7655245033009
+ y 114.39870152004505
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 134
+ pajek_id 134
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1961.9942877269461
+ y 124.43728726767961
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 135
+ pajek_id 135
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2317.512327717449
+ y 924.258173136443
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 136
+ pajek_id 136
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1800.1506277595804
+ y 2261.975902475042
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 137
+ pajek_id 137
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 595.234814691012
+ y 1025.317899636531
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 138
+ pajek_id 138
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 964.840641154222
+ y 247.01750927240698
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 139
+ pajek_id 139
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 588.9999815953205
+ y 2079.3235704527674
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 140
+ pajek_id 140
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2110.3560493557006
+ y 505.8109983485984
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 141
+ pajek_id 141
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1399.3112848730054
+ y 1227.804800096851
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 142
+ pajek_id 142
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1334.1378233999883
+ y 1813.8827309253875
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 143
+ pajek_id 143
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1805.918047276415
+ y 624.9341989045439
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 144
+ pajek_id 144
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1467.2887831794974
+ y 1491.092756875548
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 145
+ pajek_id 145
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1369.2679808531936
+ y 1127.5618294352796
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 146
+ pajek_id 146
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2025.2400562476682
+ y 1570.3163109170114
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 147
+ pajek_id 147
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2055.8364822532835
+ y 684.3901430356791
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 148
+ pajek_id 148
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2458.5244327113796
+ y 1391.3830145494958
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 149
+ pajek_id 149
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1552.825479830451
+ y 1252.8654366828728
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 150
+ pajek_id 150
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2642.703200490143
+ y 873.2840758651536
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 151
+ pajek_id 151
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2493.621315614442
+ y 1057.6778103427564
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 152
+ pajek_id 152
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2048.524265153669
+ y 2396.6375817898183
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 153
+ pajek_id 153
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1295.8980767195865
+ y 1281.8240646387455
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 154
+ pajek_id 154
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 948.0256773985192
+ y 874.4275219392624
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 155
+ pajek_id 155
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1060.558142370161
+ y 2121.7015632861817
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 156
+ pajek_id 156
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1588.0692311325395
+ y 2419.735277431223
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 157
+ pajek_id 157
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1399.2208755506806
+ y 668.8198477332975
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 158
+ pajek_id 158
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1580.2791211407448
+ y 894.9665199234698
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 159
+ pajek_id 159
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1585.445364428028
+ y 1518.9113878761736
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 160
+ pajek_id 160
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2149.623427593962
+ y 1585.663447804202
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 161
+ pajek_id 161
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1073.2288913412556
+ y 1374.5854206557112
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 162
+ pajek_id 162
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 493.61694579516404
+ y 1365.494793302807
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 163
+ pajek_id 163
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1286.2369050296045
+ y 1067.3473338636227
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 164
+ pajek_id 164
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 927.1316689881887
+ y 1385.503225606381
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 165
+ pajek_id 165
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2193.2522202024475
+ y 1206.1206658070653
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 166
+ pajek_id 166
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 772.1411120215096
+ y 1970.8119423759322
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 167
+ pajek_id 167
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1145.792529275603
+ y 1177.4939749954644
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 168
+ pajek_id 168
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 782.4194952141179
+ y 2042.5751921467117
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 169
+ pajek_id 169
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1254.116200428233
+ y 2594.759114678682
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 170
+ pajek_id 170
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2678.2734809510507
+ y 2096.8291622390625
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 171
+ pajek_id 171
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2400.4372550336543
+ y 1652.7179946898918
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 172
+ pajek_id 172
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1386.2112759254533
+ y 1638.7948048718672
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 173
+ pajek_id 173
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 943.8883491218697
+ y 1073.7919591358736
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 174
+ pajek_id 174
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1179.1603874552718
+ y 1122.3817446803446
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 175
+ pajek_id 175
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2233.8795632906877
+ y 1527.7817714192893
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 176
+ pajek_id 176
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2163.4669644146798
+ y 1260.955553479491
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 177
+ pajek_id 177
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1869.4250586602952
+ y 2472.448020780895
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 178
+ pajek_id 178
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1112.7457233061032
+ y 1329.0846670907608
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 179
+ pajek_id 179
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1118.8056866951574
+ y 852.6869706221119
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 180
+ pajek_id 180
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1307.2508861643091
+ y 2462.7701746985686
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 181
+ pajek_id 181
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1380.5745060829129
+ y 1076.2706855348051
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 182
+ pajek_id 182
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2036.4065621255
+ y 2529.571297575046
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 183
+ pajek_id 183
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1074.9510652351762
+ y 801.3658771409633
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 184
+ pajek_id 184
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 255.45722686156626
+ y 1805.532111761012
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 185
+ pajek_id 185
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2342.5052901155595
+ y 1982.0954207181567
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 186
+ pajek_id 186
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1178.1746215798703
+ y 871.8443836872366
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 187
+ pajek_id 187
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1537.0518689637947
+ y 1540.5124880929002
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 188
+ pajek_id 188
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1236.2077456256104
+ y 1534.272658840872
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 189
+ pajek_id 189
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1621.2397812102838
+ y 1400.4425940981625
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 190
+ pajek_id 190
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 766.3905805597286
+ y 886.402470142523
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 191
+ pajek_id 191
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2168.7884396974873
+ y 550.016818013951
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 192
+ pajek_id 192
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 993.9061877291988
+ y 1029.772643432917
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 193
+ pajek_id 193
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 463.0359831362713
+ y 1022.0861273460611
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 194
+ pajek_id 194
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 639.0038131671084
+ y 555.7612618656989
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 195
+ pajek_id 195
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1814.9683409976778
+ y 2445.753076164031
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 196
+ pajek_id 196
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1686.4439166148054
+ y 1938.4699461276296
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 197
+ pajek_id 197
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 930.0951591923147
+ y 1241.663890087508
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 198
+ pajek_id 198
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 520.2346633262122
+ y 1199.2357895089199
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 199
+ pajek_id 199
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1971.6382604373562
+ y 343.1014653785635
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 200
+ pajek_id 200
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2027.0179357401762
+ y 1349.107156613678
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 201
+ pajek_id 201
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2087.081528540994
+ y 802.4499939958602
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 202
+ pajek_id 202
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 625.0171226735023
+ y 1914.7856839077308
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 203
+ pajek_id 203
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1899.9652173985933
+ y 2072.1438307043504
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 204
+ pajek_id 204
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1606.0783659797662
+ y 1837.1508274695605
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 205
+ pajek_id 205
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 901.3919870421247
+ y 1513.1982896128998
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 206
+ pajek_id 206
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2538.1638433893568
+ y 1616.7551606942914
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 207
+ pajek_id 207
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1866.691494571614
+ y 2114.4934954074397
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 208
+ pajek_id 208
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1028.2574487173333
+ y 973.0790458888064
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 209
+ pajek_id 209
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1753.7616445481387
+ y 928.4269154425315
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 210
+ pajek_id 210
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 434.8320641528154
+ y 900.7941512774352
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 211
+ pajek_id 211
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1197.692612238198
+ y 1656.3283202472192
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 212
+ pajek_id 212
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2262.872473159019
+ y 855.5192882246674
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 213
+ pajek_id 213
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2005.7033668568552
+ y 1687.3129033516693
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 214
+ pajek_id 214
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2005.4330911080656
+ y 1248.6067376996575
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 215
+ pajek_id 215
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1497.6387156758587
+ y 409.988817350047
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 216
+ pajek_id 216
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1511.6499513985573
+ y 2019.1033155888222
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 217
+ pajek_id 217
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1832.9845660337855
+ y 1594.9330492361391
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 218
+ pajek_id 218
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2124.163466904739
+ y 1121.7594517130105
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 219
+ pajek_id 219
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2114.0594425877107
+ y 879.072087899176
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 220
+ pajek_id 220
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2060.685078868419
+ y 1835.1973884802942
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 221
+ pajek_id 221
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2250.360824827312
+ y 908.8247250753682
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 222
+ pajek_id 222
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1619.44524541997
+ y 1208.958636465997
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 223
+ pajek_id 223
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1420.5578431824722
+ y 1022.1078286320392
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 224
+ pajek_id 224
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1804.5906551872706
+ y 1356.7859367888193
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 225
+ pajek_id 225
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1182.3901258139676
+ y 1078.275091742608
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 226
+ pajek_id 226
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 939.5649257137159
+ y 750.6386331311932
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 227
+ pajek_id 227
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1227.5697565955718
+ y 1194.722525770867
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 228
+ pajek_id 228
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1677.315636418083
+ y 818.1002681824733
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 229
+ pajek_id 229
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1969.8218697907696
+ y 2124.400924405766
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 230
+ pajek_id 230
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1346.0361911089835
+ y 591.0926251849802
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 231
+ pajek_id 231
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1937.4480655403545
+ y 1484.3086656977262
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 232
+ pajek_id 232
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 913.1080893674856
+ y 2448.9010701058382
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 233
+ pajek_id 233
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 980.1355123328368
+ y 2143.0193206720637
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 234
+ pajek_id 234
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2468.507735819624
+ y 680.6867726745393
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 235
+ pajek_id 235
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 961.6345650781091
+ y 965.0860824711237
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 236
+ pajek_id 236
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 492.09673495414074
+ y 284.8975707321614
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 237
+ pajek_id 237
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1446.3792419244076
+ y 1813.9029462286976
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 238
+ pajek_id 238
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1813.9462106455926
+ y 947.4822230702299
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 239
+ pajek_id 239
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1428.5911518460912
+ y 1609.8340596280282
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 240
+ pajek_id 240
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1005.3650634855937
+ y 882.2530156601648
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 241
+ pajek_id 241
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1970.4155162426391
+ y 1125.8976010185038
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 242
+ pajek_id 242
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 240.57076448405542
+ y 1473.723263945339
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 243
+ pajek_id 243
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2046.1993784054494
+ y 950.6121816835345
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 244
+ pajek_id 244
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2808.307733786458
+ y 1514.739154198832
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 245
+ pajek_id 245
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1882.8938446652257
+ y 1459.0281000095843
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 246
+ pajek_id 246
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1723.9114037847546
+ y 2365.644132764209
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 247
+ pajek_id 247
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1936.717394034969
+ y 1594.3192138208242
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 248
+ pajek_id 248
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1971.7509493535508
+ y 1179.4845850946012
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 249
+ pajek_id 249
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1058.6250365444143
+ y 859.7134012319751
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 250
+ pajek_id 250
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1875.0949016123318
+ y 2018.8968281970356
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 251
+ pajek_id 251
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 802.2218018782783
+ y 830.0503347776802
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 252
+ pajek_id 252
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 813.0528123889172
+ y 1656.3453211681867
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 253
+ pajek_id 253
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1273.6722755380645
+ y 562.4903627029978
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 254
+ pajek_id 254
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 738.6225904711797
+ y 1832.437257453023
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 255
+ pajek_id 255
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2123.755229836545
+ y 2672.877537298277
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 256
+ pajek_id 256
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 766.238178017943
+ y 627.4085851267696
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 257
+ pajek_id 257
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1129.8317234871274
+ y 1757.6767114954823
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 258
+ pajek_id 258
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2009.7762232303267
+ y 2041.0971651622217
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 259
+ pajek_id 259
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1736.9465300050063
+ y 1793.4455313056224
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 260
+ pajek_id 260
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 648.0899197694613
+ y 1133.071910642336
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 261
+ pajek_id 261
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2673.608535682633
+ y 1969.3166527926637
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 262
+ pajek_id 262
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1190.4241821550581
+ y 1456.8778384709221
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 263
+ pajek_id 263
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1773.3304812765168
+ y 1171.6981943217245
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 264
+ pajek_id 264
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2455.8689870091684
+ y 1698.2588839027976
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 265
+ pajek_id 265
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1572.4184904317372
+ y 1079.9405584556314
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 266
+ pajek_id 266
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 930.5993117411441
+ y 932.4301787306301
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 267
+ pajek_id 267
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1241.016109181929
+ y 1641.851386078472
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 268
+ pajek_id 268
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1778.3112226979574
+ y 1527.5198182466306
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 269
+ pajek_id 269
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1997.6945206439827
+ y 1435.167335502786
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 270
+ pajek_id 270
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2928.2834579168007
+ y 1108.202244706911
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 271
+ pajek_id 271
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1549.1458457473145
+ y 592.3498910478805
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 272
+ pajek_id 272
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2567.1609182049815
+ y 349.9728983492399
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 273
+ pajek_id 273
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1790.3664691634244
+ y 2391.926302478362
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 274
+ pajek_id 274
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1156.9233946634465
+ y 1363.0451223083915
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 275
+ pajek_id 275
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 856.1024353157368
+ y 2058.0580043741106
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 276
+ pajek_id 276
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2007.3448524911623
+ y 955.2249749444019
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 277
+ pajek_id 277
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1867.826843063508
+ y 1168.1178614284738
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 278
+ pajek_id 278
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1849.7065836818551
+ y 1931.1333235795955
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 279
+ pajek_id 279
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1260.0763722109286
+ y 655.2169595822215
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 280
+ pajek_id 280
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1899.1104082490497
+ y 1614.8129891919102
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 281
+ pajek_id 281
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2378.43114046961
+ y 2184.529789498435
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 282
+ pajek_id 282
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2040.929028434561
+ y 2329.0083925520726
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 283
+ pajek_id 283
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1329.822091272441
+ y 817.7805081038614
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 284
+ pajek_id 284
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1916.5095601095395
+ y 1315.8369929397447
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 285
+ pajek_id 285
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1540.8732018426379
+ y 1757.2830276053164
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 286
+ pajek_id 286
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1497.5518877310492
+ y 2332.209587716714
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 287
+ pajek_id 287
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1820.876610989953
+ y 1705.7800792711614
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 288
+ pajek_id 288
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2053.621424690008
+ y 137.4950984709352
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 289
+ pajek_id 289
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2288.638168809773
+ y 1661.1373438648448
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 290
+ pajek_id 290
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2521.628031511117
+ y 1112.8442155271284
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 291
+ pajek_id 291
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2621.075261275747
+ y 1040.7003954194217
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 292
+ pajek_id 292
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1489.7226658046911
+ y 1212.598420726727
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 293
+ pajek_id 293
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1344.039251806568
+ y 765.4921416388333
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 294
+ pajek_id 294
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2783.106085646018
+ y 1011.1576483698651
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 295
+ pajek_id 295
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 666.034857878941
+ y 1196.1544941612838
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 296
+ pajek_id 296
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1069.4593629564115
+ y 1627.9059240200613
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 297
+ pajek_id 297
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1798.2247140891636
+ y 1428.1375539568382
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 298
+ pajek_id 298
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1934.1343683875075
+ y 2404.2315045912405
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 299
+ pajek_id 299
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2699.851785344458
+ y 427.8558563028148
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 300
+ pajek_id 300
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 834.2031874852718
+ y 250.70469068286297
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 301
+ pajek_id 301
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1004.0710874574961
+ y 1280.167160042513
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 302
+ pajek_id 302
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1750.4516583745296
+ y 1471.2162955489407
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 303
+ pajek_id 303
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2401.7820655598725
+ y 2272.1863557268275
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 304
+ pajek_id 304
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1814.6823768957051
+ y 2071.5062836539637
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 305
+ pajek_id 305
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2520.536274654057
+ y 992.8636618688267
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 306
+ pajek_id 306
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2265.0881548319567
+ y 2065.5837863656484
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 307
+ pajek_id 307
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1257.8172960656739
+ y 803.4108171125971
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 308
+ pajek_id 308
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 776.7856178664061
+ y 1694.4563434703907
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 309
+ pajek_id 309
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1440.886631358504
+ y 1532.750033969016
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 310
+ pajek_id 310
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1989.010230552772
+ y 259.2322753906619
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 311
+ pajek_id 311
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 793.6486929322533
+ y 1180.108345062422
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 312
+ pajek_id 312
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1917.539646877893
+ y 2281.8557999514537
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 313
+ pajek_id 313
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 867.9822424379655
+ y 1709.027298137467
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 314
+ pajek_id 314
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1484.2011650524655
+ y 1345.1479429348788
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 315
+ pajek_id 315
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1076.084829910138
+ y 996.0235144558553
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 316
+ pajek_id 316
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1693.090850412172
+ y 2090.5966253636116
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 317
+ pajek_id 317
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2037.1290633056465
+ y 369.80076511683393
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 318
+ pajek_id 318
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1007.8277192737382
+ y 1754.1325273022699
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 319
+ pajek_id 319
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2172.028629136008
+ y 1461.0364064098994
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 320
+ pajek_id 320
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2257.1227609527
+ y 1310.8862977736107
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 321
+ pajek_id 321
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1300.745991888025
+ y 2187.297908294803
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 322
+ pajek_id 322
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2204.6686322693918
+ y 1410.994870895594
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 323
+ pajek_id 323
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 864.8355633586339
+ y 1982.7204827008345
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 324
+ pajek_id 324
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 800.0003105548103
+ y 1923.7791435231852
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 325
+ pajek_id 325
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1024.7502660900132
+ y 1366.1758015615299
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 326
+ pajek_id 326
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2050.7149391093694
+ y 1257.3982758996383
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 327
+ pajek_id 327
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 960.7821525481202
+ y 1584.4968382633942
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 328
+ pajek_id 328
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1124.4061711877166
+ y 1046.726994002646
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 329
+ pajek_id 329
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1108.4893044148541
+ y 1194.3431578903087
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 330
+ pajek_id 330
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1100.133655193655
+ y 1137.6918022343907
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 331
+ pajek_id 331
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1760.6862781934046
+ y 1320.6513715309195
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 332
+ pajek_id 332
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1200.2523322538245
+ y 1002.7964728390644
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 333
+ pajek_id 333
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1181.4892595539825
+ y 1225.6989123360675
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 334
+ pajek_id 334
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1868.4127438749463
+ y 1117.6967188028786
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 335
+ pajek_id 335
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2168.6794851454647
+ y 1162.2427344452735
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 336
+ pajek_id 336
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1920.9638225147678
+ y 876.5150707247215
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 337
+ pajek_id 337
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2920.808088394186
+ y 892.3685934633982
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 338
+ pajek_id 338
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1645.909927183584
+ y 1471.9956590731072
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 339
+ pajek_id 339
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1447.1109049135396
+ y 1746.1534799232427
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 340
+ pajek_id 340
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1303.087697302223
+ y 1599.75182872408
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 341
+ pajek_id 341
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1404.1964183968635
+ y 1732.988309973422
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 342
+ pajek_id 342
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 188.7586938483705
+ y 732.4710661793797
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 343
+ pajek_id 343
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 237.5145668340565
+ y 798.209667685809
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 344
+ pajek_id 344
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 655.6090365411286
+ y 768.8237020380398
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 345
+ pajek_id 345
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1239.593772491194
+ y 142.24994629451373
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 346
+ pajek_id 346
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 668.4582174721975
+ y 1570.710895937615
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 347
+ pajek_id 347
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 704.1732692312117
+ y 1623.8128247520694
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 348
+ pajek_id 348
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1806.5024342076917
+ y 1845.9002776470725
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 349
+ pajek_id 349
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1572.0491307665409
+ y 1632.2321415433307
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 350
+ pajek_id 350
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2170.491596866099
+ y 252.15493902189132
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 351
+ pajek_id 351
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2236.6106720779644
+ y 313.9614539100346
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 352
+ pajek_id 352
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1956.787709026074
+ y 478.6286472297293
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 353
+ pajek_id 353
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1521.6247356278914
+ y 651.1377056441239
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 354
+ pajek_id 354
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2673.4749982408534
+ y 1517.3687949519558
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 355
+ pajek_id 355
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2462.8285772682266
+ y 853.132399611773
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 356
+ pajek_id 356
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2723.74809870115
+ y 928.6302426931661
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 357
+ pajek_id 357
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1370.7051182886262
+ y 1487.7369332080375
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 358
+ pajek_id 358
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 468.7736750192556
+ y 1245.6923887724063
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 359
+ pajek_id 359
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 769.1240346507418
+ y 1297.5083732935518
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 360
+ pajek_id 360
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1281.6747231335723
+ y 1222.571355135779
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 361
+ pajek_id 361
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2579.810673602955
+ y 486.0242869026378
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 362
+ pajek_id 362
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1625.153907135859
+ y 1657.7991036276171
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 363
+ pajek_id 363
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1685.4668204197178
+ y 1675.1432793501972
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 364
+ pajek_id 364
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1649.065379741583
+ y 1710.3631889761837
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 365
+ pajek_id 365
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1735.2434575622904
+ y 1652.0103910358575
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 366
+ pajek_id 366
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1546.6380216667462
+ y 1660.4291808801559
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 367
+ pajek_id 367
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1592.959070056042
+ y 1701.930864398132
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 368
+ pajek_id 368
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2000.4352383965368
+ y 1758.4816008564803
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 369
+ pajek_id 369
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1468.5107210693257
+ y 1274.5523522286858
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 370
+ pajek_id 370
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1343.841518355971
+ y 868.6992458482348
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 371
+ pajek_id 371
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 956.4416724575727
+ y 1542.5109738519532
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 372
+ pajek_id 372
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1033.5848153857899
+ y 2047.0346481519837
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 373
+ pajek_id 373
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1145.9845954789732
+ y 2010.3598901708774
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 374
+ pajek_id 374
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 966.9695596108811
+ y 2038.5494954424362
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 375
+ pajek_id 375
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1101.5378289239488
+ y 2056.772094668872
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 376
+ pajek_id 376
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1015.5518645355227
+ y 498.21676713384437
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 377
+ pajek_id 377
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1108.5018026732564
+ y 1836.2444968902573
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 378
+ pajek_id 378
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1050.8064474323255
+ y 1820.5838099325315
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 379
+ pajek_id 379
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1022.4653344068506
+ y 1715.6126995231655
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 380
+ pajek_id 380
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 973.3911705488091
+ y 1656.6045446044554
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 381
+ pajek_id 381
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 980.1312729019277
+ y 1790.1875755402975
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 382
+ pajek_id 382
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1165.9502913921285
+ y 1848.0553893620186
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 383
+ pajek_id 383
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1847.4512820966625
+ y 997.8047505299883
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 384
+ pajek_id 384
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1834.8709235195802
+ y 1082.3420824375842
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 385
+ pajek_id 385
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1926.272882956845
+ y 1130.2140856000237
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 386
+ pajek_id 386
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2019.5057069987238
+ y 1083.2924715168538
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 387
+ pajek_id 387
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 340.467937490798
+ y 1722.2588619668122
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 388
+ pajek_id 388
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 613.237652883032
+ y 1579.9427905965279
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 389
+ pajek_id 389
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1655.1932187894404
+ y 1782.2310536598284
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 390
+ pajek_id 390
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1637.2667690847445
+ y 952.3525949687174
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 391
+ pajek_id 391
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2630.804204930251
+ y 2213.7673865428937
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 392
+ pajek_id 392
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1080.8078508715175
+ y 1570.3664421378583
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 393
+ pajek_id 393
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2234.068836486567
+ y 1160.6502978141489
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 394
+ pajek_id 394
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1086.7948765031201
+ y 76.91119774421213
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 395
+ pajek_id 395
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2461.9112093928975
+ y 1766.6838415805391
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 396
+ pajek_id 396
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 113.1199288710568
+ y 369.28510273478156
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 397
+ pajek_id 397
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1776.1814775671203
+ y 1971.90651207382
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 398
+ pajek_id 398
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1707.0558465571435
+ y 1296.0087781780164
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 399
+ pajek_id 399
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1417.7718529314445
+ y 1350.7244506853776
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 400
+ pajek_id 400
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2125.52060844245
+ y 1048.4849048770884
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 401
+ pajek_id 401
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1552.3770468848625
+ y 2260.559438155617
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 402
+ pajek_id 402
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1874.1651337345234
+ y 1245.0945400298474
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 403
+ pajek_id 403
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1256.6383628219503
+ y 1450.7738470869801
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 404
+ pajek_id 404
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2259.967596935999
+ y 2120.7466929344328
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 405
+ pajek_id 405
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2500.5496931980915
+ y 1966.736685021926
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 406
+ pajek_id 406
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2347.7927648395157
+ y 2091.6701739856917
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 407
+ pajek_id 407
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2392.889146581768
+ y 2044.8922015795006
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 408
+ pajek_id 408
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2417.761515347872
+ y 1975.5515523680338
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 409
+ pajek_id 409
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1793.9182626491624
+ y 1627.666690778881
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 410
+ pajek_id 410
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 719.1430254147674
+ y 1486.956454607635
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 411
+ pajek_id 411
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 724.2454716778103
+ y 1551.3831943720716
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 412
+ pajek_id 412
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2447.6879968351877
+ y 1876.5514180960204
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 413
+ pajek_id 413
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2091.9643045079483
+ y 1974.8640522416667
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 414
+ pajek_id 414
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2028.15537010984
+ y 1956.056476995101
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 415
+ pajek_id 415
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1984.2252245737018
+ y 1908.623346940285
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 416
+ pajek_id 416
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2119.7472033124163
+ y 1865.6311815257598
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 417
+ pajek_id 417
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2130.68571853772
+ y 1928.6302578749373
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 418
+ pajek_id 418
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2122.510896875806
+ y 1780.9007711280406
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 419
+ pajek_id 419
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2066.857133577992
+ y 1911.002176703526
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 420
+ pajek_id 420
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2174.073650971839
+ y 1808.4465867530826
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 421
+ pajek_id 421
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2173.188445315479
+ y 1879.1912761247552
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 422
+ pajek_id 422
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2445.130066970032
+ y 1152.7800567449078
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 423
+ pajek_id 423
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2355.4692035510784
+ y 1402.5903362442382
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 424
+ pajek_id 424
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2415.2373515095965
+ y 1088.9498827129119
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 425
+ pajek_id 425
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2039.5995058528129
+ y 1430.5751740405808
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 426
+ pajek_id 426
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 322.6815092460105
+ y 2116.2903817807914
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 427
+ pajek_id 427
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 268.5119994462548
+ y 2056.087634484369
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 428
+ pajek_id 428
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1146.757825786496
+ y 364.2656095233129
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 429
+ pajek_id 429
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1489.2719624004453
+ y 693.8971583258162
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 430
+ pajek_id 430
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1827.8677422310066
+ y 766.7899007728367
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 431
+ pajek_id 431
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1798.3747778112622
+ y 1215.8365936661658
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 432
+ pajek_id 432
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 804.3580561584004
+ y 501.9583186324991
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 433
+ pajek_id 433
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 849.2647555481542
+ y 434.2847659573615
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 434
+ pajek_id 434
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2328.3994872753374
+ y 2321.663189777115
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 435
+ pajek_id 435
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 618.9825732416654
+ y 1813.9348120438804
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 436
+ pajek_id 436
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 700.4298252161705
+ y 1333.1902810428091
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 437
+ pajek_id 437
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1395.7113829826137
+ y 1284.9840905117753
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 438
+ pajek_id 438
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2630.3138122865585
+ y 1172.8988923967477
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 439
+ pajek_id 439
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2615.848167339149
+ y 1246.8020908359208
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 440
+ pajek_id 440
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 469.43123730699017
+ y 854.8438020056724
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 441
+ pajek_id 441
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2116.96992696925
+ y 1379.4358280316942
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 442
+ pajek_id 442
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2081.349871481623
+ y 1329.7245666590386
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 443
+ pajek_id 443
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2424.702556920728
+ y 768.839004481539
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 444
+ pajek_id 444
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 890.6313761901736
+ y 115.79231393666316
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 445
+ pajek_id 445
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 857.1356243649586
+ y 174.88311586144653
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 446
+ pajek_id 446
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 512.8629774244184
+ y 2201.527945647691
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 447
+ pajek_id 447
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 677.7488039882435
+ y 1909.537866326766
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 448
+ pajek_id 448
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1338.956871819991
+ y 1010.8829829830978
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 449
+ pajek_id 449
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1324.088243934198
+ y 1729.0798093126218
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 450
+ pajek_id 450
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1724.263819989563
+ y 504.51288018417335
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 451
+ pajek_id 451
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1910.6105654550115
+ y 630.6123921072538
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 452
+ pajek_id 452
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1710.4548801725487
+ y 647.7553354187357
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 453
+ pajek_id 453
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1702.9391298385015
+ y 563.411307161135
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 454
+ pajek_id 454
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1826.116078147204
+ y 450.3392482519506
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 455
+ pajek_id 455
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2011.5270490887758
+ y 760.825852289636
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 456
+ pajek_id 456
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2101.9753242282413
+ y 581.5866515110404
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 457
+ pajek_id 457
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2603.3686351996375
+ y 1409.84659720882
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 458
+ pajek_id 458
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2438.056345618056
+ y 1523.7553993407314
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 459
+ pajek_id 459
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2331.6849268576207
+ y 1134.766411504912
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 460
+ pajek_id 460
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1059.0576214306932
+ y 2264.1041145319637
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 461
+ pajek_id 461
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1458.141237363875
+ y 755.4394205573406
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 462
+ pajek_id 462
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 424.1436855406298
+ y 1477.224543730106
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 463
+ pajek_id 463
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 378.7154942468852
+ y 1401.5037756061158
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 464
+ pajek_id 464
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 314.0529479996145
+ y 1373.0410118674613
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 465
+ pajek_id 465
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 353.0119560198315
+ y 1455.904690398989
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 466
+ pajek_id 466
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 834.3766918623855
+ y 1291.1793247114124
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 467
+ pajek_id 467
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 893.5300096467302
+ y 1847.377115763661
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 468
+ pajek_id 468
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 716.2809799836317
+ y 2178.244847004791
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 469
+ pajek_id 469
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2541.4812097684
+ y 2043.553501917624
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 470
+ pajek_id 470
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1119.6037534804425
+ y 1102.2487155380616
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 471
+ pajek_id 471
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1007.8554543482325
+ y 1148.2192014655018
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 472
+ pajek_id 472
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2355.376017232971
+ y 1455.616264520982
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 473
+ pajek_id 473
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2394.6586276164862
+ y 1491.7526626843892
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 474
+ pajek_id 474
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2248.1811205504373
+ y 1647.7634009017388
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 475
+ pajek_id 475
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2337.1166010827837
+ y 1520.6716608448314
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 476
+ pajek_id 476
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2420.759607231811
+ y 1589.229118968443
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 477
+ pajek_id 477
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2314.5533268916042
+ y 1604.0297855841632
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 478
+ pajek_id 478
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2364.2202931300694
+ y 1575.671922904723
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 479
+ pajek_id 479
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2194.5964587031503
+ y 1638.225011658421
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 480
+ pajek_id 480
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1065.4992788010986
+ y 1464.6555423148318
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 481
+ pajek_id 481
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 968.0925172159282
+ y 1354.4290172504502
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 482
+ pajek_id 482
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1126.8845029318243
+ y 1435.5731026238109
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 483
+ pajek_id 483
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1213.8500385478933
+ y 1383.2655755080937
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 484
+ pajek_id 484
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1391.466199058675
+ y 2589.0242705868145
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 485
+ pajek_id 485
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1324.9339892036385
+ y 2618.7726752706
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 486
+ pajek_id 486
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1447.1572287025065
+ y 927.5802766521502
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 487
+ pajek_id 487
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2147.787079263979
+ y 2593.4264109946484
+ w 20.0
+ h 20.0
+ fill "#FFFF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 488
+ pajek_id 488
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2020.4864930201384
+ y 2667.000204943657
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 489
+ pajek_id 489
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2455.283559589994
+ y 2086.657483037342
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 490
+ pajek_id 490
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1682.851876497575
+ y 1583.6120931079872
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 491
+ pajek_id 491
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1161.1187083008704
+ y 1611.7393863381692
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 492
+ pajek_id 492
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1041.2626018954427
+ y 1598.954971993218
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 493
+ pajek_id 493
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2297.354570397635
+ y 534.3652679637769
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 494
+ pajek_id 494
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 526.5370388426392
+ y 485.54459385039985
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 495
+ pajek_id 495
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 560.2941765427282
+ y 402.56083072436417
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 496
+ pajek_id 496
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 377.08394387788996
+ y 1333.3317088869094
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 497
+ pajek_id 497
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 489.3047686961877
+ y 1939.8674034964001
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 498
+ pajek_id 498
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 527.233322511409
+ y 2017.0516767470162
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 499
+ pajek_id 499
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1605.5668452162006
+ y 1992.166283565707
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 500
+ pajek_id 500
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1546.0840293799524
+ y 1955.4015275314973
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 501
+ pajek_id 501
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2656.759269426316
+ y 1685.5061982513696
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 502
+ pajek_id 502
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1728.2354096255438
+ y 1051.4437767810607
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 503
+ pajek_id 503
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 317.98253615853616
+ y 835.2488823603016
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 504
+ pajek_id 504
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1227.6068253899532
+ y 1819.6331253463359
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 505
+ pajek_id 505
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1574.3747014862265
+ y 289.21933118032086
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 506
+ pajek_id 506
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1436.7167412577667
+ y 2136.3809474284844
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 507
+ pajek_id 507
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1928.2290848617536
+ y 1695.8756254197222
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 508
+ pajek_id 508
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2229.8166656736694
+ y 1842.5176093374575
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 509
+ pajek_id 509
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2191.4931676161536
+ y 1969.3723460631686
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 510
+ pajek_id 510
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2404.7934790895088
+ y 917.1422166878989
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 511
+ pajek_id 511
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2395.2429436891007
+ y 834.027810518057
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 512
+ pajek_id 512
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1638.416583359785
+ y 1075.9248111470263
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 513
+ pajek_id 513
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1117.2425662770952
+ y 945.1325831390579
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 514
+ pajek_id 514
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1071.8339051492999
+ y 667.2084929230319
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 515
+ pajek_id 515
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2080.1550476846883
+ y 2248.7722822540536
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 516
+ pajek_id 516
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 941.7035591125789
+ y 2315.12355349285
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 517
+ pajek_id 517
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 864.0401900606075
+ y 854.7476458360196
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 518
+ pajek_id 518
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1451.1619559522182
+ y 1947.3205327227465
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 519
+ pajek_id 519
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1481.5993172162407
+ y 1688.7490679204407
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 520
+ pajek_id 520
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 132.29183753554184
+ y 1549.9709751408773
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 521
+ pajek_id 521
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 201.92596700389458
+ y 1601.853692109065
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 522
+ pajek_id 522
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2153.1192264901847
+ y 822.9210553334786
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 523
+ pajek_id 523
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 640.2772506993291
+ y 1675.9420021748028
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 524
+ pajek_id 524
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1320.8511741047305
+ y 408.77871976114494
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 525
+ pajek_id 525
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2213.924926553872
+ y 2763.501088516637
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 526
+ pajek_id 526
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2074.4442713188187
+ y 2170.28081217305
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 527
+ pajek_id 527
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1907.281150461828
+ y 1756.8956641399836
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 528
+ pajek_id 528
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2125.030039415664
+ y 2128.3283642176266
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 529
+ pajek_id 529
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1748.248950250427
+ y 1911.7557662270228
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 530
+ pajek_id 530
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1150.8356799670266
+ y 1544.1121345992892
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 531
+ pajek_id 531
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1477.1689178603895
+ y 1147.0096180737971
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 532
+ pajek_id 532
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1458.9597650345672
+ y 1060.9858986563445
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 533
+ pajek_id 533
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1495.8280010142782
+ y 989.2245050486312
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 534
+ pajek_id 534
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 784.4777027529236
+ y 948.7566853266054
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 535
+ pajek_id 535
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2110.665526987148
+ y 1497.723078348779
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 536
+ pajek_id 536
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 3038.33263338064
+ y 1192.8113918381189
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 537
+ pajek_id 537
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1603.7304792610369
+ y 454.1950074099879
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 538
+ pajek_id 538
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1801.2035133048555
+ y 2119.4411185171184
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 539
+ pajek_id 539
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1950.4501795255455
+ y 2049.3079413070072
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 540
+ pajek_id 540
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1757.897607156828
+ y 2049.7669278996045
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 541
+ pajek_id 541
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1854.7360726993138
+ y 1393.7369312635797
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 542
+ pajek_id 542
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1415.8484373759234
+ y 1900.9653905466644
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 543
+ pajek_id 543
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1497.5005911357582
+ y 2480.683702039123
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 544
+ pajek_id 544
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 719.9288183455253
+ y 236.78163159716667
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 545
+ pajek_id 545
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2509.6237885742785
+ y 2373.522488677848
+ w 20.0
+ h 20.0
+ fill "#FF3333"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 546
+ pajek_id 546
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2436.169862983399
+ y 2416.0522801899683
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 547
+ pajek_id 547
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 647.1888372458554
+ y 1741.9224475898036
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 548
+ pajek_id 548
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 681.8502532202343
+ y 1799.6304470782582
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 549
+ pajek_id 549
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1985.5267000858494
+ y 2369.7344325668428
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 550
+ pajek_id 550
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1991.106100021963
+ y 2440.329057425812
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 551
+ pajek_id 551
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1931.1619344063192
+ y 2470.578249185151
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 552
+ pajek_id 552
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1875.3109201344084
+ y 2408.7968384052087
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 553
+ pajek_id 553
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1587.9274187718331
+ y 1318.0146867000844
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 554
+ pajek_id 554
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 930.2559142741628
+ y 1891.3731392078669
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 555
+ pajek_id 555
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1227.5755919224916
+ y 2306.541693351298
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 556
+ pajek_id 556
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1304.4750058932211
+ y 2321.289347146842
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 557
+ pajek_id 557
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 2217.1358311583554
+ y 1273.7535975697697
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ node [
+ id 558
+ pajek_id 558
+ label ""
+ labelgraphics [
+ anchor "c"
+ fontName "Tahoma"
+ alignment "left"
+ fontSize 13
+ fontStyle "plain"
+ color "#000000"
+ type "text"
+ ]
+ graphics [
+ x 1066.387215640596
+ y 1714.3761855178568
+ w 20.0
+ h 20.0
+ fill "#00FF00"
+ outline "#000000"
+ frameThickness 3.0
+ rounding 5.0
+ gradient 0.0
+ type "oval"
+ ]
+ ]
+ edge [
+ id 1
+ source 1
+ target 87
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 2
+ source 1
+ target 223
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 3
+ source 1
+ target 266
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 4
+ source 1
+ target 328
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 5
+ source 1
+ target 329
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 6
+ source 1
+ target 330
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 7
+ source 1
+ target 331
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 8
+ source 1
+ target 332
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 9
+ source 1
+ target 333
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 10
+ source 2
+ target 334
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 11
+ source 2
+ target 335
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 12
+ source 3
+ target 172
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 13
+ source 3
+ target 188
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 14
+ source 3
+ target 257
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 15
+ source 4
+ target 225
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 16
+ source 5
+ target 175
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 17
+ source 6
+ target 143
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 18
+ source 7
+ target 118
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 19
+ source 7
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 20
+ source 7
+ target 336
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 21
+ source 8
+ target 30
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 22
+ source 8
+ target 337
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 23
+ source 9
+ target 338
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 24
+ source 10
+ target 198
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 25
+ source 11
+ target 261
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 26
+ source 12
+ target 66
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 27
+ source 12
+ target 114
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 28
+ source 12
+ target 144
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 29
+ source 12
+ target 189
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 30
+ source 12
+ target 237
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 31
+ source 12
+ target 239
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 32
+ source 12
+ target 267
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 33
+ source 12
+ target 268
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 34
+ source 12
+ target 339
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 35
+ source 12
+ target 340
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 36
+ source 12
+ target 341
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 37
+ source 13
+ target 15
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 38
+ source 13
+ target 85
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 39
+ source 14
+ target 212
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 40
+ source 15
+ target 342
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 41
+ source 15
+ target 343
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 42
+ source 15
+ target 344
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 43
+ source 16
+ target 143
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 44
+ source 16
+ target 191
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 45
+ source 17
+ target 54
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 46
+ source 17
+ target 345
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 47
+ source 18
+ target 100
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 48
+ source 18
+ target 346
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 49
+ source 18
+ target 347
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 50
+ source 19
+ target 267
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 51
+ source 20
+ target 348
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 52
+ source 20
+ target 349
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 53
+ source 21
+ target 81
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 54
+ source 22
+ target 65
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 55
+ source 23
+ target 140
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 56
+ source 23
+ target 350
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 57
+ source 23
+ target 351
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 58
+ source 23
+ target 352
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 59
+ source 24
+ target 217
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 60
+ source 25
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 61
+ source 26
+ target 119
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 62
+ source 26
+ target 353
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 63
+ source 27
+ target 353
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 64
+ source 28
+ target 178
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 65
+ source 29
+ target 148
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 66
+ source 29
+ target 175
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 67
+ source 29
+ target 206
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 68
+ source 29
+ target 354
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 69
+ source 30
+ target 212
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 70
+ source 30
+ target 294
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 71
+ source 30
+ target 355
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 72
+ source 30
+ target 356
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 73
+ source 31
+ target 334
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 74
+ source 32
+ target 353
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 75
+ source 33
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 76
+ source 34
+ target 217
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 77
+ source 34
+ target 220
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 78
+ source 34
+ target 262
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 79
+ source 34
+ target 357
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 80
+ source 35
+ target 358
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 81
+ source 35
+ target 359
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 82
+ source 36
+ target 342
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 83
+ source 37
+ target 162
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 84
+ source 38
+ target 311
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 85
+ source 39
+ target 174
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 86
+ source 40
+ target 228
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 87
+ source 41
+ target 311
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 88
+ source 42
+ target 53
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 89
+ source 43
+ target 265
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 90
+ source 43
+ target 360
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 91
+ source 44
+ target 361
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 92
+ source 45
+ target 53
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 93
+ source 46
+ target 118
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 94
+ source 46
+ target 285
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 95
+ source 46
+ target 362
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 96
+ source 46
+ target 363
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 97
+ source 46
+ target 364
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 98
+ source 46
+ target 365
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 99
+ source 46
+ target 366
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 100
+ source 46
+ target 367
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 101
+ source 46
+ target 368
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 102
+ source 46
+ target 369
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 103
+ source 47
+ target 78
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 104
+ source 48
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 105
+ source 49
+ target 167
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 106
+ source 49
+ target 370
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 107
+ source 50
+ target 371
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 108
+ source 51
+ target 155
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 109
+ source 51
+ target 233
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 110
+ source 51
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 111
+ source 51
+ target 372
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 112
+ source 51
+ target 373
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 113
+ source 51
+ target 374
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 114
+ source 51
+ target 375
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 115
+ source 52
+ target 126
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 116
+ source 52
+ target 376
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 117
+ source 53
+ target 62
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 118
+ source 53
+ target 66
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 119
+ source 53
+ target 371
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 120
+ source 53
+ target 377
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 121
+ source 53
+ target 378
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 122
+ source 53
+ target 379
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 123
+ source 53
+ target 380
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 124
+ source 53
+ target 381
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 125
+ source 53
+ target 382
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 126
+ source 54
+ target 126
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 127
+ source 54
+ target 138
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 128
+ source 55
+ target 143
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 129
+ source 56
+ target 147
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 130
+ source 56
+ target 383
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 131
+ source 56
+ target 384
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 132
+ source 56
+ target 385
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 133
+ source 56
+ target 386
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 134
+ source 57
+ target 283
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 135
+ source 58
+ target 210
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 136
+ source 59
+ target 387
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 137
+ source 59
+ target 388
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 138
+ source 60
+ target 189
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 139
+ source 61
+ target 93
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 140
+ source 61
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 141
+ source 62
+ target 110
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 142
+ source 62
+ target 265
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 143
+ source 62
+ target 278
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 144
+ source 62
+ target 338
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 145
+ source 62
+ target 389
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 146
+ source 63
+ target 215
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 147
+ source 64
+ target 97
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 148
+ source 64
+ target 99
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 149
+ source 65
+ target 158
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 150
+ source 65
+ target 222
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 151
+ source 65
+ target 297
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 152
+ source 65
+ target 390
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 153
+ source 66
+ target 127
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 154
+ source 66
+ target 340
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 155
+ source 67
+ target 181
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 156
+ source 68
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 157
+ source 69
+ target 185
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 158
+ source 69
+ target 391
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 159
+ source 70
+ target 162
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 160
+ source 71
+ target 327
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 161
+ source 71
+ target 392
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 162
+ source 72
+ target 286
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 163
+ source 73
+ target 113
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 164
+ source 74
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 165
+ source 75
+ target 247
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 166
+ source 75
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 167
+ source 75
+ target 302
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 168
+ source 75
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 169
+ source 76
+ target 85
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 170
+ source 77
+ target 87
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 171
+ source 78
+ target 393
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 172
+ source 79
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 173
+ source 80
+ target 147
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 174
+ source 81
+ target 117
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 175
+ source 81
+ target 394
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 176
+ source 82
+ target 138
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 177
+ source 83
+ target 194
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 178
+ source 83
+ target 235
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 179
+ source 84
+ target 171
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 180
+ source 84
+ target 395
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 181
+ source 85
+ target 396
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 182
+ source 86
+ target 209
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 183
+ source 87
+ target 118
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 184
+ source 87
+ target 145
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 185
+ source 87
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 186
+ source 87
+ target 369
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 187
+ source 88
+ target 318
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 188
+ source 89
+ target 397
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 189
+ source 90
+ target 143
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 190
+ source 91
+ target 215
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 191
+ source 92
+ target 110
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 192
+ source 93
+ target 111
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 193
+ source 94
+ target 126
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 194
+ source 94
+ target 302
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 195
+ source 95
+ target 392
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 196
+ source 95
+ target 398
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 197
+ source 95
+ target 399
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 198
+ source 96
+ target 111
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 199
+ source 96
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 200
+ source 96
+ target 398
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 201
+ source 96
+ target 400
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 202
+ source 97
+ target 286
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 203
+ source 97
+ target 401
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 204
+ source 98
+ target 143
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 205
+ source 99
+ target 204
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 206
+ source 99
+ target 222
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 207
+ source 99
+ target 402
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 208
+ source 100
+ target 129
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 209
+ source 100
+ target 227
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 210
+ source 100
+ target 340
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 211
+ source 100
+ target 403
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 212
+ source 101
+ target 318
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 213
+ source 101
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 214
+ source 102
+ target 227
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 215
+ source 103
+ target 121
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 216
+ source 103
+ target 280
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 217
+ source 103
+ target 404
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 218
+ source 103
+ target 405
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 219
+ source 103
+ target 406
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 220
+ source 103
+ target 407
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 221
+ source 103
+ target 408
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 222
+ source 104
+ target 117
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 223
+ source 105
+ target 156
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 224
+ source 106
+ target 188
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 225
+ source 106
+ target 252
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 226
+ source 106
+ target 257
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 227
+ source 106
+ target 318
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 228
+ source 107
+ target 409
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 229
+ source 108
+ target 267
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 230
+ source 108
+ target 388
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 231
+ source 108
+ target 410
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 232
+ source 108
+ target 411
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 233
+ source 109
+ target 220
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 234
+ source 109
+ target 412
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 235
+ source 110
+ target 217
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 236
+ source 110
+ target 278
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 237
+ source 110
+ target 289
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 238
+ source 110
+ target 413
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 239
+ source 110
+ target 414
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 240
+ source 110
+ target 415
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 241
+ source 110
+ target 416
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 242
+ source 110
+ target 417
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 243
+ source 110
+ target 418
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 244
+ source 110
+ target 419
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 245
+ source 110
+ target 420
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 246
+ source 110
+ target 421
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 247
+ source 111
+ target 422
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 248
+ source 111
+ target 423
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 249
+ source 111
+ target 424
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 250
+ source 112
+ target 425
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 251
+ source 113
+ target 202
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 252
+ source 113
+ target 426
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 253
+ source 113
+ target 427
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 254
+ source 114
+ target 142
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 255
+ source 114
+ target 239
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 256
+ source 115
+ target 275
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 257
+ source 116
+ target 352
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 258
+ source 117
+ target 253
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 259
+ source 117
+ target 428
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 260
+ source 117
+ target 429
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 261
+ source 118
+ target 143
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 262
+ source 118
+ target 212
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 263
+ source 118
+ target 276
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 264
+ source 118
+ target 352
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 265
+ source 118
+ target 353
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 266
+ source 118
+ target 429
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 267
+ source 118
+ target 430
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 268
+ source 118
+ target 431
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 269
+ source 119
+ target 256
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 270
+ source 119
+ target 432
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 271
+ source 119
+ target 433
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 272
+ source 120
+ target 147
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 273
+ source 121
+ target 434
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 274
+ source 122
+ target 202
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 275
+ source 122
+ target 392
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 276
+ source 122
+ target 435
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 277
+ source 123
+ target 129
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 278
+ source 123
+ target 436
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 279
+ source 123
+ target 437
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 280
+ source 124
+ target 393
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 281
+ source 124
+ target 438
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 282
+ source 124
+ target 439
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 283
+ source 125
+ target 258
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 284
+ source 126
+ target 235
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 285
+ source 127
+ target 141
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 286
+ source 127
+ target 217
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 287
+ source 127
+ target 239
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 288
+ source 127
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 289
+ source 127
+ target 309
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 290
+ source 128
+ target 440
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 291
+ source 129
+ target 162
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 292
+ source 130
+ target 263
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 293
+ source 130
+ target 320
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 294
+ source 130
+ target 441
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 295
+ source 130
+ target 442
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 296
+ source 131
+ target 429
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 297
+ source 132
+ target 302
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 298
+ source 133
+ target 138
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 299
+ source 134
+ target 310
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 300
+ source 135
+ target 234
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 301
+ source 135
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 302
+ source 135
+ target 443
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 303
+ source 136
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 304
+ source 137
+ target 210
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 305
+ source 137
+ target 311
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 306
+ source 138
+ target 300
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 307
+ source 138
+ target 444
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 308
+ source 138
+ target 445
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 309
+ source 139
+ target 446
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 310
+ source 139
+ target 447
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 311
+ source 140
+ target 147
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 312
+ source 141
+ target 227
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 313
+ source 141
+ target 448
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 314
+ source 142
+ target 237
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 315
+ source 142
+ target 239
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 316
+ source 142
+ target 267
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 317
+ source 142
+ target 321
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 318
+ source 142
+ target 339
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 319
+ source 142
+ target 340
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 320
+ source 142
+ target 341
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 321
+ source 142
+ target 449
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 322
+ source 143
+ target 228
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 323
+ source 143
+ target 450
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 324
+ source 143
+ target 451
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 325
+ source 143
+ target 452
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 326
+ source 143
+ target 453
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 327
+ source 143
+ target 454
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 328
+ source 144
+ target 239
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 329
+ source 145
+ target 174
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 330
+ source 146
+ target 220
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 331
+ source 146
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 332
+ source 147
+ target 455
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 333
+ source 147
+ target 456
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 334
+ source 148
+ target 320
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 335
+ source 148
+ target 457
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 336
+ source 148
+ target 458
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 337
+ source 149
+ target 314
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 338
+ source 150
+ target 305
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 339
+ source 151
+ target 291
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 340
+ source 151
+ target 459
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 341
+ source 152
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 342
+ source 153
+ target 188
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 343
+ source 153
+ target 448
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 344
+ source 154
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 345
+ source 155
+ target 460
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 346
+ source 156
+ target 246
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 347
+ source 157
+ target 461
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 348
+ source 158
+ target 461
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 349
+ source 159
+ target 349
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 350
+ source 160
+ target 175
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 351
+ source 161
+ target 357
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 352
+ source 161
+ target 359
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 353
+ source 162
+ target 436
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 354
+ source 162
+ target 462
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 355
+ source 162
+ target 463
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 356
+ source 162
+ target 464
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 357
+ source 162
+ target 465
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 358
+ source 163
+ target 227
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 359
+ source 164
+ target 262
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 360
+ source 164
+ target 359
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 361
+ source 164
+ target 466
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 362
+ source 165
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 363
+ source 166
+ target 467
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 364
+ source 167
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 365
+ source 168
+ target 467
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 366
+ source 168
+ target 468
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 367
+ source 169
+ target 180
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 368
+ source 170
+ target 469
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 369
+ source 171
+ target 175
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 370
+ source 171
+ target 206
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 371
+ source 171
+ target 395
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 372
+ source 172
+ target 187
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 373
+ source 173
+ target 470
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 374
+ source 174
+ target 266
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 375
+ source 174
+ target 369
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 376
+ source 174
+ target 471
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 377
+ source 175
+ target 280
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 378
+ source 175
+ target 331
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 379
+ source 175
+ target 458
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 380
+ source 175
+ target 472
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 381
+ source 175
+ target 473
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 382
+ source 175
+ target 474
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 383
+ source 175
+ target 475
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 384
+ source 175
+ target 476
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 385
+ source 175
+ target 477
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 386
+ source 175
+ target 478
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 387
+ source 175
+ target 479
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 388
+ source 176
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 389
+ source 177
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 390
+ source 178
+ target 225
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 391
+ source 178
+ target 227
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 392
+ source 178
+ target 296
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 393
+ source 178
+ target 480
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 394
+ source 178
+ target 481
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 395
+ source 178
+ target 482
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 396
+ source 178
+ target 483
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 397
+ source 179
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 398
+ source 180
+ target 321
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 399
+ source 180
+ target 484
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 400
+ source 180
+ target 485
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 401
+ source 181
+ target 222
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 402
+ source 181
+ target 225
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 403
+ source 181
+ target 227
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 404
+ source 181
+ target 486
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 405
+ source 182
+ target 255
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 406
+ source 182
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 407
+ source 182
+ target 487
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 408
+ source 182
+ target 488
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 409
+ source 183
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 410
+ source 184
+ target 387
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 411
+ source 185
+ target 306
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 412
+ source 185
+ target 368
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 413
+ source 185
+ target 469
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 414
+ source 185
+ target 489
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 415
+ source 186
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 416
+ source 187
+ target 302
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 417
+ source 187
+ target 357
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 418
+ source 187
+ target 490
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 419
+ source 188
+ target 280
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 420
+ source 188
+ target 467
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 421
+ source 188
+ target 470
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 422
+ source 188
+ target 491
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 423
+ source 188
+ target 492
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 424
+ source 189
+ target 239
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 425
+ source 189
+ target 334
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 426
+ source 190
+ target 266
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 427
+ source 191
+ target 493
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 428
+ source 192
+ target 470
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 429
+ source 193
+ target 198
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 430
+ source 193
+ target 440
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 431
+ source 194
+ target 494
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 432
+ source 194
+ target 495
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 433
+ source 195
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 434
+ source 196
+ target 259
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 435
+ source 197
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 436
+ source 198
+ target 359
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 437
+ source 198
+ target 496
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 438
+ source 199
+ target 352
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 439
+ source 200
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 440
+ source 201
+ target 243
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 441
+ source 202
+ target 467
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 442
+ source 202
+ target 497
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 443
+ source 202
+ target 498
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 444
+ source 203
+ target 278
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 445
+ source 204
+ target 216
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 446
+ source 204
+ target 259
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 447
+ source 204
+ target 499
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 448
+ source 204
+ target 500
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 449
+ source 205
+ target 492
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 450
+ source 206
+ target 458
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 451
+ source 206
+ target 476
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 452
+ source 206
+ target 501
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 453
+ source 207
+ target 278
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 454
+ source 208
+ target 470
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 455
+ source 209
+ target 502
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 456
+ source 210
+ target 503
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 457
+ source 211
+ target 296
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 458
+ source 211
+ target 403
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 459
+ source 211
+ target 504
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 460
+ source 212
+ target 355
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 461
+ source 213
+ target 280
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 462
+ source 214
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 463
+ source 215
+ target 429
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 464
+ source 215
+ target 505
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 465
+ source 216
+ target 506
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 466
+ source 217
+ target 231
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 467
+ source 217
+ target 245
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 468
+ source 217
+ target 507
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 469
+ source 218
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 470
+ source 219
+ target 243
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 471
+ source 219
+ target 276
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 472
+ source 220
+ target 258
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 473
+ source 220
+ target 306
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 474
+ source 220
+ target 508
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 475
+ source 220
+ target 509
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 476
+ source 221
+ target 276
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 477
+ source 221
+ target 510
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 478
+ source 221
+ target 511
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 479
+ source 222
+ target 502
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 480
+ source 222
+ target 512
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 481
+ source 223
+ target 265
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 482
+ source 224
+ target 302
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 483
+ source 225
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 484
+ source 225
+ target 513
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 485
+ source 226
+ target 266
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 486
+ source 226
+ target 514
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 487
+ source 227
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 488
+ source 227
+ target 437
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 489
+ source 228
+ target 265
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 490
+ source 229
+ target 258
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 491
+ source 229
+ target 278
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 492
+ source 229
+ target 515
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 493
+ source 230
+ target 293
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 494
+ source 231
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 495
+ source 232
+ target 516
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 496
+ source 233
+ target 516
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 497
+ source 234
+ target 361
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 498
+ source 235
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 499
+ source 235
+ target 517
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 500
+ source 236
+ target 495
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 501
+ source 237
+ target 518
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 502
+ source 238
+ target 502
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 503
+ source 239
+ target 267
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 504
+ source 239
+ target 339
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 505
+ source 239
+ target 340
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 506
+ source 239
+ target 341
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 507
+ source 239
+ target 349
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 508
+ source 239
+ target 449
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 509
+ source 239
+ target 519
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 510
+ source 240
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 511
+ source 241
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 512
+ source 242
+ target 496
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 513
+ source 242
+ target 520
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 514
+ source 242
+ target 521
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 515
+ source 243
+ target 402
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 516
+ source 243
+ target 522
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 517
+ source 244
+ target 354
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 518
+ source 245
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 519
+ source 246
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 520
+ source 247
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 521
+ source 247
+ target 302
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 522
+ source 247
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 523
+ source 247
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 524
+ source 248
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 525
+ source 249
+ target 315
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 526
+ source 250
+ target 397
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 527
+ source 251
+ target 266
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 528
+ source 252
+ target 523
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 529
+ source 253
+ target 307
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 530
+ source 253
+ target 524
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 531
+ source 254
+ target 308
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 532
+ source 255
+ target 525
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 533
+ source 256
+ target 344
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 534
+ source 257
+ target 318
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 535
+ source 258
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 536
+ source 258
+ target 526
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 537
+ source 258
+ target 527
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 538
+ source 258
+ target 528
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 539
+ source 259
+ target 302
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 540
+ source 259
+ target 397
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 541
+ source 259
+ target 529
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 542
+ source 260
+ target 311
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 543
+ source 261
+ target 405
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 544
+ source 262
+ target 301
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 545
+ source 262
+ target 392
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 546
+ source 262
+ target 530
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 547
+ source 263
+ target 265
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 548
+ source 264
+ target 289
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 549
+ source 265
+ target 429
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 550
+ source 265
+ target 531
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 551
+ source 265
+ target 532
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 552
+ source 265
+ target 533
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 553
+ source 266
+ target 344
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 554
+ source 266
+ target 534
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 555
+ source 267
+ target 340
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 556
+ source 268
+ target 425
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 557
+ source 269
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 558
+ source 269
+ target 535
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 559
+ source 270
+ target 294
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 560
+ source 270
+ target 536
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 561
+ source 271
+ target 461
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 562
+ source 271
+ target 537
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 563
+ source 272
+ target 361
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 564
+ source 273
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 565
+ source 274
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 566
+ source 274
+ target 403
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 567
+ source 275
+ target 467
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 568
+ source 276
+ target 334
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 569
+ source 277
+ target 431
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 570
+ source 278
+ target 287
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 571
+ source 278
+ target 538
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 572
+ source 278
+ target 539
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 573
+ source 278
+ target 540
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 574
+ source 279
+ target 429
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 575
+ source 279
+ target 514
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 576
+ source 280
+ target 284
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 577
+ source 281
+ target 306
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 578
+ source 282
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 579
+ source 283
+ target 448
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 580
+ source 284
+ target 393
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 581
+ source 284
+ target 425
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 582
+ source 284
+ target 431
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 583
+ source 284
+ target 437
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 584
+ source 284
+ target 442
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 585
+ source 284
+ target 459
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 586
+ source 284
+ target 541
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 587
+ source 285
+ target 542
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 588
+ source 286
+ target 543
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 589
+ source 287
+ target 302
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 590
+ source 288
+ target 310
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 591
+ source 289
+ target 423
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 592
+ source 290
+ target 291
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 593
+ source 290
+ target 459
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 594
+ source 291
+ target 305
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 595
+ source 292
+ target 437
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 596
+ source 293
+ target 448
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 597
+ source 294
+ target 356
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 598
+ source 295
+ target 311
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 599
+ source 296
+ target 467
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 600
+ source 297
+ target 527
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 601
+ source 298
+ target 312
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 602
+ source 299
+ target 361
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 603
+ source 300
+ target 544
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 604
+ source 301
+ target 311
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 605
+ source 302
+ target 409
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 606
+ source 302
+ target 431
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 607
+ source 302
+ target 541
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 608
+ source 303
+ target 306
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 609
+ source 303
+ target 545
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 610
+ source 303
+ target 546
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 611
+ source 304
+ target 397
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 612
+ source 305
+ target 459
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 613
+ source 306
+ target 509
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 614
+ source 307
+ target 461
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 615
+ source 307
+ target 470
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 616
+ source 308
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 617
+ source 308
+ target 447
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 618
+ source 308
+ target 547
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 619
+ source 308
+ target 548
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 620
+ source 309
+ target 340
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 621
+ source 310
+ target 352
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 622
+ source 311
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 623
+ source 312
+ target 549
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 624
+ source 312
+ target 550
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 625
+ source 312
+ target 551
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 626
+ source 312
+ target 552
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 627
+ source 313
+ target 327
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 628
+ source 314
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 629
+ source 314
+ target 326
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 630
+ source 314
+ target 403
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 631
+ source 314
+ target 553
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 632
+ source 315
+ target 325
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 633
+ source 316
+ target 397
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 634
+ source 317
+ target 352
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 635
+ source 318
+ target 492
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 636
+ source 318
+ target 554
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 637
+ source 319
+ target 425
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 638
+ source 320
+ target 335
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 639
+ source 321
+ target 555
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 640
+ source 321
+ target 556
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 641
+ source 322
+ target 425
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 642
+ source 323
+ target 467
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 643
+ source 324
+ target 467
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 644
+ source 325
+ target 327
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 645
+ source 326
+ target 557
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+ edge [
+ id 646
+ source 327
+ target 558
+ pajek [
+ dir 0.0
+ weight 1.0
+ ]
+ graphics [
+ fill "#000000"
+ outline "#000000"
+ frameThickness 1.0
+ rounding 5.0
+ gradient 0.0
+ arrow "none"
+ thickness 1.0
+ ]
+ ]
+]
diff --git a/src/3rdparty/adaptagrams/libcola/tests/gml_graph.cpp b/src/3rdparty/adaptagrams/libcola/tests/gml_graph.cpp
new file mode 100644
index 0000000..6a280cf
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/gml_graph.cpp
@@ -0,0 +1,257 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <boost/regex.hpp>
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+
+typedef map<unsigned,unsigned> NodeIdMap;
+typedef map<string,list<unsigned> > Partitions;
+
+Edge readEdge(ifstream &f) {
+ string l;
+ int indent=1;
+ unsigned source, target;
+ boost::regex sourceRE(".*source\\s+(\\d+).*");
+ boost::regex targetRE(".*target\\s+(\\d+).*");
+ boost::smatch matches;
+ while(!getline(f,l).eof()) {
+ if(boost::regex_match(l,matches,sourceRE)) {
+ std::istringstream i(matches[1]);
+ i>>source;
+ }
+ if(boost::regex_match(l,matches,targetRE)) {
+ std::istringstream i(matches[1]);
+ i>>target;
+ }
+ if(l.find("[")!=string::npos) {
+ indent++;
+ }
+ if(l.find("]")!=string::npos) {
+ indent--;
+ if(indent==0) {
+ return make_pair(source,target);
+ }
+ }
+ }
+ cerr << "Incomplete edge definition!" << endl;
+ return make_pair(0,0);
+}
+
+unsigned readNode(ifstream &f, NodeIdMap &nodeIdMap,
+ Partitions &partitions) {
+ static unsigned nodeCtr=0;
+ int indent=1;
+ string l;
+ boost::regex idRE("\\s*id\\s+(\\d+).*");
+ boost::regex fillRE(".*fill\\s+\"#(.+)\".*");
+ boost::smatch matches;
+ unsigned id;
+ while(!getline(f,l).eof()) {
+ if(boost::regex_match(l,matches,idRE)) {
+ std::istringstream i(matches[1]);
+ i>>id;
+ nodeIdMap[id]=nodeCtr++;
+ }
+ if(boost::regex_match(l,matches,fillRE)) {
+ string partition(matches[1]);
+ Partitions::iterator i=partitions.find(partition);
+ partitions[partition].push_back(nodeIdMap[id]);
+ }
+ if(l.find("[")!=string::npos) {
+ indent++;
+ }
+ if(l.find("]")!=string::npos) {
+ indent--;
+ if(indent==0) {
+ return nodeCtr;
+ }
+ }
+ }
+ cerr << "Incomplete node definition!" << endl;
+ return 0;
+}
+
+struct PostIteration : TestConvergence {
+ PostIteration(vector<vpsc::Rectangle*> &rs, vector<list<unsigned> > &ps, vector<double> &bs, const double d,const unsigned i) : TestConvergence(d,i), rs(rs), ps(ps), bs(bs) {}
+ bool operator()(const double new_stress, valarray<double> & X, valarray<double> & Y) {
+ static int iterations=0;
+ unsigned n=X.size();
+ double centreX=0,centreY=0;
+ for(unsigned i=0;i<n;i++) {
+ centreX+=X[i];
+ centreY+=Y[i];
+ }
+ centreX/=(double)n;
+ centreY/=(double)n;
+ //printf("centre=(%f,%f)\n",centreX,centreY);
+ for(unsigned i=0;i<ps.size();i++) {
+ for(list<unsigned>::iterator v=ps[i].begin();v!=ps[i].end();v++) {
+ double dx=X[*v]-centreX, dy=Y[*v]-centreY;
+ double l=sqrt(dx*dx+dy*dy);
+ if(i>0) {
+ double r=bs[i-1]+10;
+ if(l<r) {
+ double dx1=dx*(r/l), dy1=dy*(r/l);
+ X[*v]=centreX+dx1;
+ Y[*v]=centreY+dy1;
+ }
+ }
+ if(i<ps.size()-1) {
+ double r=bs[i]-10;
+ if(l>r) {
+ double dx1=dx*(r/l), dy1=dy*(r/l);
+ X[*v]=centreX+dx1;
+ Y[*v]=centreY+dy1;
+ }
+ }
+ }
+ }
+ for(unsigned i=0;i<rs.size();i++) {
+ rs[i]->moveCentre(X[i],Y[i]);
+ }
+ cout << iterations++ << ":stress="<<new_stress<<endl;
+ return TestConvergence::operator()(new_stress,X,Y);
+ }
+ vector<vpsc::Rectangle*> &rs;
+ vector<list<unsigned> > &ps;
+ vector<double> &bs;
+};
+int main() {
+ //const char *fname="data/test.gml";
+ string fname("data/uetzNetworkGSC-all.gml");
+ ifstream f(fname.c_str());
+ if(!f.is_open()) {
+ cout << "Error opening file: " << fname << endl;
+ exit(1);
+ }
+ unsigned V = 0;
+ double defaultEdgeLength=40;
+ vector<Edge> es;
+ CompoundConstraints cx,cy;
+ NodeIdMap nodeIdMap;
+ Partitions partitions;
+ string l;
+ boost::regex nodeRE(".*node\\s+\\[.*");
+ boost::regex edgeRE(".*edge\\s+\\[.*");
+ while(!getline(f,l).eof()) {
+ if(boost::regex_match(l,nodeRE)) {
+ V=readNode(f,nodeIdMap,partitions);
+ }
+ if(boost::regex_match(l,edgeRE)) {
+ pair<unsigned,unsigned> e=readEdge(f);
+ unsigned start=nodeIdMap[e.first];
+ unsigned end=nodeIdMap[e.second];
+ //printf("edge (%d,%d)\n",start,end);
+ es.push_back(make_pair(start,end));
+ //cy.push_back(
+ //new SeparationConstraint(start,end,defaultEdgeLength/3));
+ }
+ }
+ assert(V==nodeIdMap.size());
+ /*
+ unsigned p1=V++;
+ unsigned p2=V++;
+ // red at the top
+ list<unsigned> &p=partitions[string("FF3333")];
+ //double cgap=defaultEdgeLength/3;
+ double cgap=0;
+ for(list<unsigned>::iterator j=p.begin();j!=p.end();j++) {
+ cy.push_back(
+ new SeparationConstraint(*j,p1,cgap));
+ }
+ // yellow in the middle
+ p=partitions[string("FFFF00")];
+ for(list<unsigned>::iterator j=p.begin();j!=p.end();j++) {
+ cy.push_back(
+ new SeparationConstraint(p1,*j,cgap));
+ cy.push_back(
+ new SeparationConstraint(*j,p2,cgap));
+ }
+ // green at the bottom
+ p=partitions[string("00FF00")];
+ for(list<unsigned>::iterator j=p.begin();j!=p.end();j++) {
+ cy.push_back(
+ new SeparationConstraint(p2,*j,cgap));
+ }
+ */
+ cout << "V="<<V<<endl;
+ double width=1000;
+ double height=1000;
+ vector<vpsc::Rectangle*> rs;
+ cout << "|V|=" << V << endl;
+ //srand(time(nullptr));
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+1,y,y+1));
+ }
+ vector<list<unsigned> > ps;
+ ps.push_back(partitions[string("FF3333")]);
+ ps.push_back(partitions[string("FFFF00")]);
+ ps.push_back(partitions[string("00FF00")]);
+ vector<double> bs;
+ bs.push_back(80);
+ bs.push_back(120);
+ PostIteration test(rs,ps,bs,0.0001,200);
+ ConstrainedMajorizationLayout alg(rs,es,nullptr,defaultEdgeLength,nullptr,test);
+ //ConstrainedFDLayout alg(rs,es,nullptr,defaultEdgeLength,nullptr,test);
+ //alg.setConstrainedLayout(true);
+ //alg.setScaling(true);
+ //alg.setXConstraints(&cx);
+ //alg.setYConstraints(&cy);
+ alg.run();
+ /*
+ vector<ColourRGBA> colours(V);
+ list<unsigned> &p=partitions[string("FF3333")];
+ for(list<unsigned>::iterator i=p.begin();i!=p.end();i++) {
+ //colours[*i]=ColourRGBA(1.,0,0.3,1.);
+ colours[*i]=ColourRGBA(0,0,0,1.);
+ }
+ p=partitions[string("FFFF00")];
+ for(list<unsigned>::iterator i=p.begin();i!=p.end();i++) {
+ //colours[*i]=ColourRGBA((unsigned)255,162,99,255);
+ colours[*i]=ColourRGBA(0,0,0,1.);
+ }
+ p=partitions[string("00FF00")];
+ for(list<unsigned>::iterator i=p.begin();i!=p.end();i++) {
+ //colours[*i]=ColourRGBA((unsigned)24,157,0,255);
+ colours[*i]=ColourRGBA(0,0,0,1.);
+ }
+ */
+ OutputFile of(rs,es,nullptr,"gml_graph-constrained.svg",false,true);
+ //of.colours=&colours;
+ of.generate();
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/graphlayouttest.h b/src/3rdparty/adaptagrams/libcola/tests/graphlayouttest.h
new file mode 100644
index 0000000..2cc51e7
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/graphlayouttest.h
@@ -0,0 +1,275 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <sstream>
+#include <ctime>
+
+#include <libvpsc/rectangle.h>
+#include <libcola/cola.h>
+#include <libtopology/topology_graph.h>
+#include <libcola/output_svg.h>
+
+inline double getRand(double range) {
+ return range*rand()/RAND_MAX;
+}
+
+namespace DFS {
+using namespace std;
+using namespace cola;
+struct Node {
+ unsigned id;
+ bool visited;
+ typedef vector<Node*> PNodes;
+ PNodes neighbours;
+ void visit(vector<unsigned> &order) {
+ visited=true;
+ unsigned mid=neighbours.size()/2;
+ for(unsigned i=0;i<mid;i++) {
+ if(!neighbours[i]->visited) {
+ neighbours[i]->visit(order);
+ }
+ }
+ order.push_back(id);
+ for(unsigned i=mid;i<neighbours.size();i++) {
+ if(!neighbours[i]->visited) {
+ neighbours[i]->visit(order);
+ }
+ }
+ }
+ void visit_leaves(vector<unsigned> &order) {
+ unsigned mid=neighbours.size()/2;
+ Node *v;
+ for(unsigned i=0;i<mid;i++) {
+ v=neighbours[i];
+ if(v->neighbours.size()==0) {
+ order.push_back(v->id);
+ }
+ }
+ order.push_back(id);
+ for(unsigned i=mid;i<neighbours.size();i++) {
+ v=neighbours[i];
+ if(v->neighbours.size()==0) {
+ order.push_back(v->id);
+ }
+ }
+ }
+};
+
+struct Graph {
+ typedef vector<Edge> Edges;
+ typedef vector<Node> Nodes;
+ Nodes nodes;
+ vector<unsigned> order;
+ vector<vector<unsigned> > leaves;
+ Graph(unsigned n,vector<Edge> &edges) {
+ nodes.resize(n);
+ order.resize(0);
+ leaves.resize(n);
+ for(Edges::iterator i=edges.begin();i!=edges.end();i++) {
+ nodes[i->first].neighbours.push_back(&nodes[i->second]);
+ }
+ for(unsigned i=0;i<nodes.size();i++) {
+ nodes[i].id=i;
+ nodes[i].visited=false;
+ }
+ for(Nodes::iterator i=nodes.begin();i!=nodes.end();i++) {
+ if(!i->visited) {
+ i->visit(order);
+ }
+ }
+ for(unsigned i=0;i<nodes.size();i++) {
+ leaves[i].resize(0);
+ nodes[i].visit_leaves(leaves[i]);
+ }
+ assert(order.size()==nodes.size());
+ }
+};
+} // namespace DFS
+using namespace cola;
+using namespace std;
+struct CheckProgress : TestConvergence {
+ CheckProgress(const double d,const unsigned i) : TestConvergence(d,i) {}
+ bool operator()(const double new_stress, valarray<double> & X, valarray<double> & Y) {
+ cout << "stress="<<new_stress<<" iteration="<<iterations<<endl;
+ return TestConvergence::operator()(new_stress,X,Y);
+ }
+};
+
+enum SolverType { CG, UGP, SGP, IP };
+void run_test(
+ vector<pair<double,double> > const &startpos,
+ vector<Edge> const &es,
+ const double defaultEdgeLength,
+ CompoundConstraints &ccs,
+ const SolverType s,
+ const bool constrained,
+ const char *fname,
+ const char *testdesc) {
+ vector<vpsc::Rectangle*> rs;
+ unsigned V=startpos.size();
+ cout << "|V|=" << V << endl;
+ //srand(time(nullptr));
+ for(unsigned i=0;i<V;i++) {
+ double x=startpos[i].first, y=startpos[i].second;
+ rs.push_back(new vpsc::Rectangle(x,x+1,y,y+1));
+ }
+ CheckProgress test(0.001,100);
+ clock_t starttime=clock();
+ ConstrainedMajorizationLayout alg(rs,es,nullptr,defaultEdgeLength,
+ StandardEdgeLengths,&test);
+ switch(s) {
+ cout << "Solver: ";
+ case SGP:
+ cout << "Scaled GP" << endl;
+ alg.setConstrainedLayout(true);
+ alg.setScaling(true);
+ break;
+ case UGP:
+ cout << "Unscaled GP" << endl;
+ alg.setConstrainedLayout(true);
+ alg.setScaling(false);
+ break;
+ case CG:
+ cout << "Conjugate Gradient" << endl;
+ alg.setConstrainedLayout(false);
+ break;
+ case IP:
+ cout << "Interior Point" << endl;
+ alg.setExternalSolver(true);
+ alg.setConstrainedLayout(true);
+ break;
+ }
+ if(!constrained) {
+ cout << "Unconstrained layout" << endl;
+ } else {
+ cout << "Constrained layout" << endl;
+ printf("|CompoundConstraints|=%u\n",(unsigned)ccs.size());
+ alg.setConstraints(&ccs);
+ }
+ alg.run();
+ double t=double(clock()-starttime)/double(CLOCKS_PER_SEC);
+ ostringstream ss;
+ ss << fname << "_" << V << "_" << testdesc << ".svg";
+
+ cout<<ss.str()<<" Time="<<t<<endl;
+ OutputFile of(rs,es,nullptr,ss.str().c_str(),false,true);
+ of.generate();
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+}
+void writeFile(const topology::Nodes& vs, const topology::Edges& es, const string& outputFileName) {
+ const unsigned n=vs.size();
+ vector<cola::Edge> cedges;
+
+ for(unsigned i=0;i<es.size();i++) {
+ cedges.push_back(make_pair(1,2));
+ }
+
+ vector<straightener::Route*> routes;
+ for(topology::Edges::const_iterator e=es.begin();e!=es.end();++e) {
+ routes.push_back((*e)->getRoute());
+ }
+
+ vector<string> labels(n);
+ for(unsigned i=0;i<n;++i) {
+ stringstream ss;
+ ss << i;
+ labels[i]=ss.str();
+ }
+
+ vector<vpsc::Rectangle*> rs;
+ for(topology::Nodes::const_iterator i=vs.begin();i!=vs.end();++i) {
+ rs.push_back((*i)->rect);
+ }
+ OutputFile of(rs,cedges,nullptr,outputFileName,true,false);
+ of.setLabels(labels);
+ of.routes=&routes;
+ of.generate();
+
+ for_each(routes.begin(),routes.end(),delete_object());
+}
+
+void writeDunnartFile(const topology::Nodes& vs, const vector<std::pair<unsigned int, unsigned int> >& es, const string& outputFileName) {
+ FILE *fp = fopen(outputFileName.c_str(), "w");
+ assert (fp != nullptr);
+
+ fprintf(fp, "<svg xmlns:dunnart=\"http://www.csse.monash.edu.au/~mwybrow/dunnart.dtd\">\n");
+ for(unsigned int i = 0; i < vs.size(); ++i) {
+ vpsc::Rectangle *rect = vs[i]->rect;
+
+ int id = i + 1;
+ fprintf(fp, "<rect id=\"%d\" dunnart:label=\"\" dunnart:width=\"20\" "
+ "dunnart:height=\"20\" dunnart:xPos=\"%f\" "
+ "dunnart:yPos=\"%f\" dunnart:type=\"rect\" />\n", id,
+ rect->getCentreX(), rect->getCentreY());
+ }
+
+ for(unsigned int i = 0; i < es.size(); ++i) {
+ const std::pair<unsigned int, unsigned int>& edge = es[i];
+
+ int id = i + 1 + vs.size();
+ fprintf(fp, "<path id=\"%d\" dunnart:srcID=\"%d\" "
+ "dunnart:srcFlags=\"544\" dunnart:dstID=\"%d\" "
+ "dunnart:dstFlags=\"544\" dunnart:directed=\"1\" "
+ "dunnart:type=\"connAvoidPoly\" />\n", id,
+ edge.first + 1, edge.second + 1);
+ }
+
+ fprintf(fp, "</svg>\n");
+
+ fclose(fp);
+
+#if 0
+ for(unsigned i=0;i<es.size();i++) {
+ cedges.push_back(make_pair(1,2));
+ }
+
+ vector<straightener::Route*> routes;
+ for(topology::Edges::const_iterator e=es.begin();e!=es.end();++e) {
+ routes.push_back((*e)->getRoute());
+ }
+
+ vector<string> labels(n);
+ for(unsigned i=0;i<n;++i) {
+ stringstream ss;
+ ss << i;
+ labels[i]=ss.str();
+ }
+
+ vector<vpsc::Rectangle*> rs;
+ for(topology::Nodes::const_iterator i=vs.begin();i!=vs.end();++i) {
+ rs.push_back((*i)->rect);
+ }
+ OutputFile of(rs,cedges,nullptr,outputFileName,true,false);
+ of.setLabels(labels);
+ of.routes=&routes;
+ of.generate();
+
+ for_each(routes.begin(),routes.end(),delete_object());
+#endif
+}
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:
diff --git a/src/3rdparty/adaptagrams/libcola/tests/initialOverlap.cpp b/src/3rdparty/adaptagrams/libcola/tests/initialOverlap.cpp
new file mode 100644
index 0000000..4f0a8bf
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/initialOverlap.cpp
@@ -0,0 +1,168 @@
+// Check that rectangles that start at same position don't get stuck on top of each other
+// during force-directed layout.
+#include <vector>
+#include <utility>
+#include "libcola/cola.h"
+#include "libcola/pseudorandom.h"
+
+using namespace cola;
+
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ EdgeLengths eLengths;
+ double defaultEdgeLength=1;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 20, 0, 20);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 20, 0, 20);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 20, 0, 20);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 20, 0, 20);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 20, 0, 20);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 60, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(0, 100, 0, 60);
+ rs.push_back(rect);
+
+ es.push_back(std::make_pair(0, 3));
+ es.push_back(std::make_pair(1, 3));
+ es.push_back(std::make_pair(2, 3));
+ es.push_back(std::make_pair(2, 8));
+ es.push_back(std::make_pair(2, 11));
+ es.push_back(std::make_pair(3, 4));
+ es.push_back(std::make_pair(3, 5));
+ es.push_back(std::make_pair(6, 8));
+ es.push_back(std::make_pair(7, 8));
+ es.push_back(std::make_pair(8, 22));
+ es.push_back(std::make_pair(8, 23));
+ es.push_back(std::make_pair(9, 11));
+ es.push_back(std::make_pair(10, 11));
+ es.push_back(std::make_pair(11, 12));
+ es.push_back(std::make_pair(11, 23));
+ es.push_back(std::make_pair(12, 13));
+ es.push_back(std::make_pair(12, 14));
+ es.push_back(std::make_pair(13, 17));
+ es.push_back(std::make_pair(13, 18));
+ es.push_back(std::make_pair(13, 19));
+ es.push_back(std::make_pair(13, 20));
+ es.push_back(std::make_pair(14, 15));
+ es.push_back(std::make_pair(14, 16));
+ es.push_back(std::make_pair(14, 20));
+ es.push_back(std::make_pair(14, 21));
+
+ eLengths.resize(25);
+ eLengths[0] = 100;
+ eLengths[1] = 100;
+ eLengths[2] = 100;
+ eLengths[3] = 100;
+ eLengths[4] = 100;
+ eLengths[5] = 100;
+ eLengths[6] = 100;
+ eLengths[7] = 100;
+ eLengths[8] = 100;
+ eLengths[9] = 100;
+ eLengths[10] = 100;
+ eLengths[11] = 100;
+ eLengths[12] = 100;
+ eLengths[13] = 100;
+ eLengths[14] = 100;
+ eLengths[15] = 100;
+ eLengths[16] = 100;
+ eLengths[17] = 100;
+ eLengths[18] = 100;
+ eLengths[19] = 100;
+ eLengths[20] = 100;
+ eLengths[21] = 100;
+ eLengths[22] = 100;
+ eLengths[23] = 100;
+ eLengths[24] = 100;
+
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength, eLengths);
+ alg.run();
+ //alg.outputInstanceToSVG("initialOverlap");
+
+ bool overlaps = false;
+
+ for (size_t i = 0; i < rs.size(); ++i)
+ {
+ for (size_t j = i + 1; j < rs.size(); ++j)
+ {
+ overlaps |= ((rs[i]->overlapD(0, rs[j]) > 0) && (rs[i]->overlapD(1, rs[j]) > 0));
+ if (overlaps)
+ {
+ break;
+ }
+ }
+ if (overlaps)
+ {
+ break;
+ }
+ }
+
+ alg.freeAssociatedObjects();
+
+ return (overlaps) ? 1 : 0;
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/invalid.cpp b/src/3rdparty/adaptagrams/libcola/tests/invalid.cpp
new file mode 100644
index 0000000..175a6b7
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/invalid.cpp
@@ -0,0 +1,80 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+
+/** \file
+ * Interface between Inkscape code (SPItem) and graphlayout functions.
+ *
+ * Authors:
+ * Tim Dwyer <tgdwyer@gmail.com>
+ */
+#include <iostream>
+
+#include <vector>
+#include <algorithm>
+#include <float.h>
+#include <libcola/cola.h>
+//#include <libvspc/exceptions.h>
+#include <libvpsc/constraint.h>
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+int main() {
+
+ const unsigned V = 2;
+ typedef pair < unsigned, unsigned >Edge;
+ Edge edge_array[] = { Edge(0, 1) };
+ unsigned E = sizeof(edge_array) / sizeof(Edge);
+ vector<Edge> es(edge_array,edge_array+E);
+ double width=100;
+ double height=100;
+ vector<vpsc::Rectangle*> rs;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+5,y,y+5));
+ }
+ ConstrainedFDLayout alg(rs, es, width/2);
+ CompoundConstraints ccs;
+ AlignmentConstraint ac(vpsc::YDIM);
+ ccs.push_back(&ac);
+ ac.addShape(0,0);
+ ac.addShape(5,0);
+ alg.setConstraints(ccs);
+ try {
+ alg.run();
+ } catch (cola::InvalidVariableIndexException& e) {
+ cerr << e.what() << endl;
+ return 0;
+ }
+ //assert(fabs(rs[0]->getCentreX()-rs[3]->getCentreX())<0.001);
+ cout<<rs[0]->getCentreX()<<","<<rs[1]->getCentreX()<<endl;
+ //output_svg(rs,es,"unsatisfiable.svg");
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 1;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/large_graph.cpp b/src/3rdparty/adaptagrams/libcola/tests/large_graph.cpp
new file mode 100644
index 0000000..a236991
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/large_graph.cpp
@@ -0,0 +1,144 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+// Loads a graph from a text file, generates constraints for each edge requiring them
+// to point downwards, and proceeds to produce a layout using libcola.
+// The input file format is 2 numeric node labels per line separated by a space,
+// each pair representing a directed edge. Node labels are simply used as array
+// offsets so they should start from 0.
+// The graph should be connected.
+// Default input file is the matrix market 1138_bus graph.
+// Running times:
+// no constraints - steepest descent solver: 149 seconds
+// no constraints - mosek: 49.47 seconds
+// no constraints - conjugate gradient solver: 12.2 seconds
+// dir-edge constraints - mosek: 214.2 seconds
+//
+// V=1138
+#include<iostream>
+#include<iomanip>
+#include<fstream>
+#include<vector>
+#include<valarray>
+#include <libvpsc/linesegment.h>
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+
+int countCrossings(vpsc::Rectangles& rs, vector<cola::Edge>& es) {
+ int crossings=0;
+ for(unsigned i=0;i<es.size()-1;++i) {
+ for(unsigned j=i+1;j<es.size();++j) {
+ Edge e1=es[i], e2=es[j];
+ Rectangle *e1a=rs[e1.first],
+ *e1b=rs[e1.second],
+ *e2a=rs[e2.first],
+ *e2b=rs[e2.second];
+ linesegment::LineSegment s1(
+ linesegment::Vector(e1a->getCentreX(),e1a->getCentreY()),
+ linesegment::Vector(e1b->getCentreX(),e1b->getCentreY()));
+ linesegment::LineSegment s2(
+ linesegment::Vector(e2a->getCentreX(),e2a->getCentreY()),
+ linesegment::Vector(e2b->getCentreX(),e2b->getCentreY()));
+ linesegment::Vector point;
+ if(s1.Intersect(s2,point)==linesegment::LineSegment::INTERSECTING) {
+ ++crossings;
+ }
+ }
+ }
+ return crossings;
+}
+int main() {
+ const char *fname="data/1138_bus.txt"; //"data/dg_850.txt";
+ ifstream f(fname);
+ if(!f.is_open()) {
+ cout << "Error opening file: " << fname << endl;
+ exit(1);
+ }
+ string startlabel, endlabel;
+ unsigned V = 0;
+ double defaultEdgeLength=40;
+ vector<Edge> es;
+ CompoundConstraints cx,cy;
+ while(!getline(f,startlabel,' ').eof()) {
+ getline(f,endlabel);
+ unsigned start = atoi(startlabel.c_str()),
+ end = atoi(endlabel.c_str());
+ es.push_back(make_pair(start,end));
+ cy.push_back(
+ new SeparationConstraint(end,start,defaultEdgeLength/3));
+ V=max(V,max(start,end));
+ }
+ V++;
+ /*
+ DFS::Graph dfs(V,es);
+ for(unsigned i=1;i<dfs.order.size();i++) {
+ cx.push_back(
+ new SeparationConstraint(dfs.order[i-1],dfs.order[i],0));
+ }
+ */
+ cout << "V="<<V<<endl;
+ double width=1000;
+ double height=1000;
+ vector<pair<double,double> > startpos(V);
+ //srand(time(nullptr));
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ startpos[i]=make_pair(x,y);
+ }
+ //const char *testname="large_graph";
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,CG,false,testname,"cg");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,IP,false,testname,"ip");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,false,testname,"ugp");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,false,testname,"sgp");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,IP,true,testname,"cip");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,true,testname,"cugp");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,true,testname,"csgp");
+ vector<vpsc::Rectangle*> rs;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+5,y,y+5));
+ }
+ cout<<"Initial crossings="<<countCrossings(rs,es)<<endl;
+ CheckProgress test(0.0001,200);
+ ConstrainedMajorizationLayout alg(rs,es,nullptr,defaultEdgeLength,nullptr,test);
+ alg.setYConstraints(&cy);
+ alg.run();
+ cout<<"Majorization crossings="<<countCrossings(rs,es)<<endl;
+ OutputFile output1(rs,es,nullptr,"large_graph-majorization.pdf");
+ output1.generate();
+ ConstrainedFDLayout alg2(rs,es,defaultEdgeLength,nullptr,test);
+ alg2.setYConstraints(&cy);
+ alg2.run();
+ cout<<"PStress crossings="<<countCrossings(rs,es)<<endl;
+ OutputFile output(rs,es,nullptr,"large_graph.pdf");
+ output.generate();
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/makefeasible.cpp b/src/3rdparty/adaptagrams/libcola/tests/makefeasible.cpp
new file mode 100644
index 0000000..4bfb082
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/makefeasible.cpp
@@ -0,0 +1,368 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <iostream>
+#include <vector>
+#include <cmath>
+#include <time.h>
+#include <valarray>
+#include <fstream>
+#include <sstream>
+
+#include <libavoid/libavoid.h>
+#include <libavoid/router.h>
+
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+using namespace vpsc;
+
+/*
+// |V|=12, |E|=23
+static const unsigned DAGDEPTH = 3;
+static const unsigned BRANCHFACTOR = 3;
+static const double EXTRAEDGEPROB = 0.5;
+*/
+/*
+// |V|=26, |E|=61
+static const unsigned DAGDEPTH = 3;
+static const unsigned BRANCHFACTOR = 4;
+static const double EXTRAEDGEPROB = 0.1;
+*/
+
+/*
+// |V|=62, |E|=85
+static const unsigned DAGDEPTH = 4;
+static const unsigned BRANCHFACTOR = 4;
+static const double EXTRAEDGEPROB = 0.01;
+*/
+/*
+// |V|=131, |E|=166
+static const unsigned DAGDEPTH = 5;
+static const unsigned BRANCHFACTOR = 4;
+static const double EXTRAEDGEPROB = 0.005;
+*/
+
+static const unsigned DAGDEPTH = 6;
+static const unsigned BRANCHFACTOR = 4;
+static const double EXTRAEDGEPROB = 0.002;
+/*
+// |V|=343, |E|=487
+seed=1208390913;
+static const unsigned DAGDEPTH = 6;
+static const unsigned BRANCHFACTOR = 4;
+static const double EXTRAEDGEPROB = 0.002;
+*/
+
+void makeEdge(unsigned u, unsigned v,
+ vector<Edge> &edges, CompoundConstraints &ccs) {
+ edges.push_back(make_pair(u,v));
+ ccs.push_back(new SeparationConstraint(vpsc::YDIM, u,v,5));
+}
+vector<Edge> random_dag(unsigned depth, unsigned maxbranch, unsigned &V,
+ CompoundConstraints &ccs) {
+ printf("DAG depth=%d\nmaxbranch=%d\nextraedgeprob%f\n",depth,maxbranch,EXTRAEDGEPROB);
+ vector<Edge> edges;
+ unsigned lstart=0, lend=1;
+ V=0;
+ for(unsigned i=0;i<depth;i++) {
+ for(unsigned j=lstart;j<lend;j++) {
+ //makeEdge(j,++V,edges,cy);
+ //makeEdge(j,++V,edges,cy);
+ for(unsigned k=0;k<maxbranch;k++) {
+ double r=(double)rand()/(double)RAND_MAX;
+ if(r < 0.5) {
+ makeEdge(j,++V,edges,ccs);
+ }
+ }
+ }
+ lstart=lend;
+ lend=V+1;
+ }
+ V++;
+ /*
+ DFS::Graph dfs(V,edges);
+ for(unsigned i=1;i<dfs.order.size();i++) {
+ cx.push_back(
+ new SeparationConstraint(dfs.order[i-1],dfs.order[i],0.5));
+ }
+ */
+ for(unsigned i=0;i<V;++i) {
+ for(unsigned j=i+1;j<V;++j) {
+ double r=(double)rand()/(double)RAND_MAX;
+ if(r < EXTRAEDGEPROB) {
+ makeEdge(i,j,edges,ccs);
+ }
+ }
+ }
+ /*
+ for(unsigned i=0;i<dfs.leaves.size();i++) {
+ for(unsigned j=1;j<dfs.leaves[i].size();j++) {
+ cx.push_back( new SeparationConstraint(dfs.leaves[i][j-1],dfs.leaves[i][j],10));
+ }
+ }
+ */
+ return edges;
+}
+void removeoverlaps(vpsc::Rectangles &rs, bool bothaxes) {
+ double xBorder=0, yBorder=0;
+ static const double EXTRA_GAP=1e-5;
+ unsigned n=rs.size();
+ try {
+ // The extra gap avoids numerical imprecision problems
+ Rectangle::setXBorder(xBorder+EXTRA_GAP);
+ Rectangle::setYBorder(yBorder+EXTRA_GAP);
+ vpsc::Variables vs(n);
+ unsigned i=0;
+ for(Variables::iterator v=vs.begin();v!=vs.end();++v,++i) {
+ *v=new Variable(i,0,1);
+ }
+ vpsc::Constraints cs;
+ vpsc::generateXConstraints(rs,vs,cs,bothaxes);
+ vpsc::IncSolver vpsc_x(vs,cs);
+ vpsc_x.solve();
+ vpsc::Rectangles::iterator r=rs.begin();
+ for(Variables::iterator v=vs.begin();v!=vs.end();++v,++r) {
+ assert((*v)->finalPosition==(*v)->finalPosition);
+ (*r)->moveCentreX((*v)->finalPosition);
+ }
+ assert(r==rs.end());
+ for_each(cs.begin(),cs.end(),vpsc::delete_object());
+ cs.clear();
+ if(bothaxes) {
+ // Removing the extra gap here ensures things that were moved to be adjacent to one another above are not considered overlapping
+ Rectangle::setXBorder(Rectangle::xBorder-EXTRA_GAP);
+ vpsc::generateYConstraints(rs,vs,cs);
+ vpsc::IncSolver vpsc_y(vs,cs);
+ vpsc_y.solve();
+ r=rs.begin();
+ for(Variables::iterator v=vs.begin();v!=vs.end();++v,++r) {
+ (*r)->moveCentreY((*v)->finalPosition);
+ }
+ for_each(cs.begin(),cs.end(),vpsc::delete_object());
+ cs.clear();
+ Rectangle::setYBorder(Rectangle::yBorder-EXTRA_GAP);
+ vpsc::generateXConstraints(rs,vs,cs,false);
+ vpsc::IncSolver vpsc_x2(vs,cs);
+ vpsc_x2.solve();
+ r=rs.begin();
+ for(Variables::iterator v=vs.begin();v!=vs.end();++v,++r) {
+ (*r)->moveCentreX((*v)->finalPosition);
+ }
+ for_each(cs.begin(),cs.end(),vpsc::delete_object());
+ }
+ for_each(vs.begin(),vs.end(),vpsc::delete_object());
+ } catch (char *str) {
+ std::cerr<<str<<std::endl;
+ for(vpsc::Rectangles::iterator r=rs.begin();r!=rs.end();++r) {
+ std::cerr << **r <<std::endl;
+ }
+ }
+ Rectangle::setXBorder(xBorder);
+ Rectangle::setYBorder(yBorder);
+}
+/*
+void writeTextFile(vector<cola::Edge>& edges) {
+ ofstream outfile("new.txt",ofstream::binary);
+ for(vector<cola::Edge>::iterator e=edges.begin();e!=edges.end();++e) {
+ outfile<<"node"<<e->first<<",node"<<e->second<<endl;
+ }
+ outfile.close();
+}
+*/
+/*
+ * Make feasible:
+ * - remove overlaps between rectangular boundaries of nodes/clusters
+ * (respecting structural constraints)
+ * - perform routing (preserve previous topology using rubber banding)
+ */
+void makeFeasible(vpsc::Rectangles& rs, vector<cola::Edge>& edges,
+ std::vector<topology::Edge*>& routes,
+ std::vector<topology::Node*>& topologyNodes, double defaultEdgeLength) {
+ printf("Removing overlaps...\n");
+ removeoverlaps(rs,false);
+ printf("done.\n");
+ printf("Running libavoid to compute routes...\n");
+ clock_t libavoidstarttime=clock();
+ // find feasible routes for edges
+ Avoid::Router *router = new Avoid::Router(Avoid::PolyLineRouting);
+ // Use rotational sweep for point visibility
+ router->UseLeesAlgorithm = true;
+ // Don't use invisibility graph.
+ router->InvisibilityGrph = false;
+ double g=0; // make shape that libavoid sees slightly smaller
+ for(unsigned i=0;i<rs.size();++i) {
+ vpsc::Rectangle* r=rs[i];
+ double x=r->getMinX()+g;
+ double X=r->getMaxX()-g;
+ double y=r->getMinY()+g;
+ double Y=r->getMaxY()-g;
+ // Create the ShapeRef:
+ Avoid::Polygon shapePoly(4);
+ // AntiClockwise!
+ shapePoly.ps[0] = Avoid::Point(X,y);
+ shapePoly.ps[1] = Avoid::Point(X,Y);
+ shapePoly.ps[2] = Avoid::Point(x,Y);
+ shapePoly.ps[3] = Avoid::Point(x,y);
+ //if(i==4||i==13||i==9) {
+ //printf("rect[%d]:{%f,%f,%f,%f}\n",i,x,y,X,Y);
+ //}
+ unsigned int shapeID = i + 1;
+ Avoid::ShapeRef *shapeRef = new Avoid::ShapeRef(router, shapePoly,
+ shapeID);
+ // ShapeRef constructor makes a copy of polygon so we can free it:
+ router->addShape(shapeRef);
+ }
+ for(unsigned i=0;i<edges.size();++i) {
+ cola::Edge e=edges[i];
+ Avoid::ConnRef *connRef;
+ unsigned int connID = i + rs.size() + 1;
+ Rectangle* r0=rs[e.first], *r1=rs[e.second];
+ Avoid::Point srcPt(r0->getCentreX(),r0->getCentreY());
+ Avoid::Point dstPt(r1->getCentreX(),r1->getCentreY());
+ connRef = new Avoid::ConnRef(router, srcPt, dstPt, connID);
+ router->processTransaction();
+ const Avoid::Polygon& route = connRef->route();
+ vector<topology::EdgePoint*> eps;
+ eps.push_back( new topology::EdgePoint( topologyNodes[e.first],
+ topology::EdgePoint::CENTRE));
+ for(size_t j=1;j+1<route.size();j++) {
+ const Avoid::Point& p = route.ps[j];
+ const unsigned nodeID=p.id-1;
+ topology::Node* node=topologyNodes[nodeID];
+ topology::EdgePoint::RectIntersect ri;
+ switch(p.vn) {
+ case 0: ri=topology::EdgePoint::BR;
+ break;
+ case 1: ri=topology::EdgePoint::TR;
+ break;
+ case 2: ri=topology::EdgePoint::TL;
+ break;
+ case 3: ri=topology::EdgePoint::BL;
+ break;
+ default: ri=topology::EdgePoint::CENTRE;
+ }
+ eps.push_back(new topology::EdgePoint(node,ri));
+ }
+ eps.push_back(new topology::EdgePoint(topologyNodes[e.second],
+ topology::EdgePoint::CENTRE));
+ topology::Edge* edgeRoute=new topology::Edge(i,defaultEdgeLength, eps);
+ edgeRoute->assertConvexBends();
+ routes.push_back(edgeRoute);
+
+ }
+ writeFile(topologyNodes,routes,"beautify0.svg");
+ assert(topology::assertNoSegmentRectIntersection(topologyNodes,routes));
+ double libavoidtime=double(clock()-libavoidstarttime)/double(CLOCKS_PER_SEC);
+ cout << "done. Libavoid ran in " << libavoidtime << " seconds" << endl;
+ delete router;
+}
+int main() {
+ unsigned V;
+ CompoundConstraints ccs;
+
+ int seed = time(nullptr);
+ //seed=1207906420;
+ //seed=1207920674;
+ //seed=1207982613;
+ //seed=1207984219;
+ seed=1207984299;
+ //seed=1207984743;
+ //seed=1207985027; // very short edge which seems to cause problems
+ //seed=1207986026; // error if we don't check neighbour is actually on scanline when determining visibility when generating straight constraints
+ //seed=1207991731;
+ //seed=1208303930;
+ //seed=1208304508;
+ //seed=1208316284;
+ //seed=1208319019;
+ //seed=1208321702;
+ printf("random seed=%d\n",seed);
+ srand(seed);
+ vector<Edge> es = random_dag(DAGDEPTH,BRANCHFACTOR,V,ccs);
+ double defaultEdgeLength=40;
+
+ cout << "V="<<V<<endl;
+ cout << "E="<<es.size()<<endl;
+ double width=700;
+ double height=700;
+ vector<pair<double,double> > startpos(V);
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ startpos[i]=make_pair(x,y);
+ }
+ vector<vpsc::Rectangle*> rs;
+ vector<topology::Node*> topologyNodes;
+ vector<topology::Edge*> routes;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ vpsc::Rectangle* r =new vpsc::Rectangle(x,x+30,y,y+10);
+ rs.push_back(r);
+ topologyNodes.push_back(new topology::Node(i,r));
+ }
+ CheckProgress test(0.01,100);
+ clock_t unconstrainedstarttime=clock();
+ //writeTextFile(es);
+ es.clear();
+ ConstrainedFDLayout alg2(rs,es,defaultEdgeLength,nullptr,test);
+ //alg2.setConstraints(&ccs);
+
+ alg2.makeFeasible(true);
+ alg2.run();
+
+ alg2.outputInstanceToSVG();
+#if 0
+ double totaltime=0;
+ double unconstrainedtime=double(clock()-unconstrainedstarttime)/double(CLOCKS_PER_SEC);
+ totaltime+=unconstrainedstarttime;
+ cout<<"unconstrained layout ran in "<<unconstrainedtime<<" seconds"<<endl;
+ clock_t makefeasiblestarttime=clock();
+ makeFeasible(rs,es,routes,topologyNodes,defaultEdgeLength);
+ double makefeasibletime=double(clock()-makefeasiblestarttime)/double(CLOCKS_PER_SEC);
+ totaltime+=makefeasibletime;
+ cout<<"makefeasible ran in "<<makefeasibletime<<" seconds"<<endl;
+ clock_t beautifystarttime=clock();
+ test.reset();
+ alg2.setTopology(&topologyNodes, &routes);
+ writeFile(topologyNodes,routes,"beautify1.svg");
+ std::stringstream dunnartfile;
+ dunnartfile << "v" << V << "e" << (int) es.size() << ".svg";
+ writeDunnartFile(topologyNodes,es,dunnartfile.str().c_str());
+
+ alg2.run();
+ double beautifytime=double(clock()-beautifystarttime)/double(CLOCKS_PER_SEC);
+ totaltime+=beautifytime;
+ cout<<"beautify ran in "<<beautifytime<<" seconds"<<endl;
+ cout<<"TOTAL="<<totaltime<<endl;
+ cout <<"---------------------------------------------"<< endl;
+ cout <<V<<" & "<<es.size()<<" & "<<unconstrainedtime<<" & "<<makefeasibletime<<" & "<<beautifytime<<" & "<<totaltime<<" \\\\ % Seed: "<< seed <<endl;
+ writeFile(topologyNodes,routes,"beautify2.svg");
+#endif
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/makefeasible02.cpp b/src/3rdparty/adaptagrams/libcola/tests/makefeasible02.cpp
new file mode 100755
index 0000000..82d55b7
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/makefeasible02.cpp
@@ -0,0 +1,932 @@
+#include <vector>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ double defaultEdgeLength=40;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ rect = new vpsc::Rectangle(252, 272, 930, 950);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(109, 129, 898, 918);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(252, 272, 951, 971);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(99, 139, 931, 971);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(593, 665, 212.5, 459.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(398, 518, 52, 96);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(341, 361, 899, 919);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(450, 470, 930, 950);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(402, 422, 930, 950);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(394, 414, 861, 881);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(394, 414, 840, 860);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(282, 302, 852, 872);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(173, 193, 852, 872);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(521, 541, 851, 871);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(313, 401, 739, 783);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(446, 466, 757, 777);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(446, 466, 688, 708);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(447, 467, 616, 636);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(421, 441, 471, 491);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(196.5, 359.5, 575, 619);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(366, 386, 437, 457);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(446, 466, 391, 411);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(446, 466, 325, 345);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(393, 413, 325, 345);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(515, 535, 182, 202);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(446, 466, 255, 275);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(446, 466, 160, 180);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(366, 386, 289, 309);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(211, 231, 270, 290);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(211, 231, 289, 309);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(320, 340, 256, 276);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(270, 290, 256, 276);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(144, 164, 251, 271);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(211, 231, 214, 234);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(211, 231, 195, 215);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(279, 299, 173, 193);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(306, 326, 141, 161);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(306, 326, 120, 140);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(34.5, 295.5, 39.5, 74.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(225, 245, 895, 915);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(446, 466, 543, 563);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(211, 231, 233, 253);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(211, 231, 308, 328);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(144, 164, 347, 367);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(144, 164, 373, 393);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(254, 274, 346, 366);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(254, 274, 372, 392);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(554, 594, 173, 213);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 121, 161);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 642, 682);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(134, 174, 206, 246);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(134, 174, 279, 319);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(285, 325, 426, 466);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(285, 325, 279, 319);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 208, 248);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 281, 321);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 714, 754);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 570, 610);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 498, 538);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(580, 620, 841, 881);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(267, 307, 884, 924);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(503, 543, 931, 971);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 841, 881);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(331, 371, 841, 881);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(331, 371, 798, 838);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(99, 139, 841, 881);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(331, 371, 931, 971);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(218, 258, 841, 881);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(165, 205, 884, 924);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 351, 391);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(85, 125, 336, 376);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(192, 232, 336, 376);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(192, 232, 362, 402);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(85, 125, 362, 402);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(20.5, 77.5, 716, 880);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(167, 187, 713, 733);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(99, 139, 714, 754);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(402, 422, 951, 971);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(167, 187, 734, 754);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(450, 470, 951, 971);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(532.5, 669.5, 899.5, 934.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(471, 491, 471, 491);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(545, 565, 512, 532);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(518, 538, 531, 551);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(252, 272, 782, 802);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(495, 515, 512, 532);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(351, 391, 534, 574);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(400, 420, 573, 593);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(401, 421, 509, 529);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(436, 476, 426, 466);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(234, 290, 970, 1010);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(29, 85, 888, 928);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(234, 290, 991, 1031);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(261, 317, 889, 929);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(432, 488, 870, 910);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(384, 440, 970, 1010);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(314, 370, 851, 891);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(438, 494, 830, 870);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(202, 258, 842, 882);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(155, 211, 792, 832);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(503, 559, 791, 831);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(490, 546, 747, 787);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(366, 422, 678, 718);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(367, 423, 606, 646);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(341, 397, 461, 501);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(348, 404, 377, 417);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(490, 546, 381, 421);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(490, 546, 315, 355);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(375, 431, 365, 405);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(497, 553, 122, 162);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(490, 546, 245, 285);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(366, 422, 150, 190);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(348, 404, 229, 269);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(193, 249, 210, 250);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(193, 249, 229, 269);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(364, 420, 246, 286);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(190, 246, 246, 286);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(64, 120, 241, 281);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(193, 249, 154, 194);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(193, 249, 135, 175);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(261, 317, 213, 253);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(288, 344, 81, 121);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(288, 344, 160, 200);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(207, 263, 835, 875);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(366, 422, 533, 573);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(193, 249, 173, 213);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(193, 249, 248, 288);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(126, 182, 287, 327);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(126, 182, 413, 453);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(236, 292, 286, 326);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(236, 292, 412, 452);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(149, 205, 653, 693);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(384, 440, 891, 931);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(149, 205, 674, 714);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(432, 488, 991, 1031);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(515, 571, 461, 501);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(527, 583, 452, 492);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(500, 556, 571, 611);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(234, 290, 722, 762);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(539, 595, 502, 542);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(382, 438, 613, 653);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(383, 439, 449, 489);
+ rs.push_back(rect);
+
+#if 1
+ AlignmentConstraint *alignment2424608 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment2424608->addShape(0, 0);
+ alignment2424608->addShape(2, 0);
+ alignment2424608->addShape(45, 0);
+ alignment2424608->addShape(46, 0);
+ alignment2424608->addShape(84, 0);
+ alignment2424608->addShape(90, 0);
+ alignment2424608->addShape(92, 0);
+ alignment2424608->addShape(129, 0);
+ alignment2424608->addShape(130, 0);
+ alignment2424608->addShape(138, 0);
+ ccs.push_back(alignment2424608);
+ AlignmentConstraint *alignment2424744 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment2424744->addShape(1, 0);
+ alignment2424744->addShape(3, 0);
+ alignment2424744->addShape(65, 0);
+ alignment2424744->addShape(76, 0);
+ ccs.push_back(alignment2424744);
+ AlignmentConstraint *alignment1216038856 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216038856->addShape(4, 0);
+ ccs.push_back(alignment1216038856);
+ AlignmentConstraint *alignment1216038920 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216038920->addShape(5, 0);
+ alignment1216038920->addShape(7, 0);
+ alignment1216038920->addShape(15, 0);
+ alignment1216038920->addShape(16, 0);
+ alignment1216038920->addShape(17, 0);
+ alignment1216038920->addShape(21, 0);
+ alignment1216038920->addShape(22, 0);
+ alignment1216038920->addShape(25, 0);
+ alignment1216038920->addShape(26, 0);
+ alignment1216038920->addShape(40, 0);
+ alignment1216038920->addShape(48, 0);
+ alignment1216038920->addShape(49, 0);
+ alignment1216038920->addShape(54, 0);
+ alignment1216038920->addShape(55, 0);
+ alignment1216038920->addShape(56, 0);
+ alignment1216038920->addShape(57, 0);
+ alignment1216038920->addShape(58, 0);
+ alignment1216038920->addShape(62, 0);
+ alignment1216038920->addShape(69, 0);
+ alignment1216038920->addShape(79, 0);
+ alignment1216038920->addShape(89, 0);
+ alignment1216038920->addShape(94, 0);
+ alignment1216038920->addShape(134, 0);
+ ccs.push_back(alignment1216038920);
+ AlignmentConstraint *alignment1216038984 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216038984->addShape(6, 0);
+ alignment1216038984->addShape(63, 0);
+ alignment1216038984->addShape(64, 0);
+ alignment1216038984->addShape(66, 0);
+ ccs.push_back(alignment1216038984);
+ AlignmentConstraint *alignment1216039048 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216039048->addShape(8, 0);
+ alignment1216039048->addShape(77, 0);
+ alignment1216039048->addShape(87, 0);
+ alignment1216039048->addShape(88, 0);
+ alignment1216039048->addShape(95, 0);
+ alignment1216039048->addShape(132, 0);
+ alignment1216039048->addShape(140, 0);
+ alignment1216039048->addShape(141, 0);
+ ccs.push_back(alignment1216039048);
+ AlignmentConstraint *alignment1216039112 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216039112->addShape(9, 0);
+ alignment1216039112->addShape(10, 0);
+ alignment1216039112->addShape(23, 0);
+ alignment1216039112->addShape(108, 0);
+ ccs.push_back(alignment1216039112);
+ AlignmentConstraint *alignment1216039176 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216039176->addShape(11, 0);
+ alignment1216039176->addShape(35, 0);
+ alignment1216039176->addShape(60, 0);
+ alignment1216039176->addShape(93, 0);
+ alignment1216039176->addShape(120, 0);
+ ccs.push_back(alignment1216039176);
+ AlignmentConstraint *alignment1216039240 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216039240->addShape(12, 0);
+ alignment1216039240->addShape(68, 0);
+ alignment1216039240->addShape(99, 0);
+ ccs.push_back(alignment1216039240);
+ AlignmentConstraint *alignment1216039304 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216039304->addShape(13, 0);
+ alignment1216039304->addShape(83, 0);
+ alignment1216039304->addShape(100, 0);
+ alignment1216039304->addShape(137, 0);
+ ccs.push_back(alignment1216039304);
+ AlignmentConstraint *alignment1216040464 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216040464->addShape(14, 0);
+ ccs.push_back(alignment1216040464);
+ AlignmentConstraint *alignment1216040528 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216040528->addShape(18, 0);
+ ccs.push_back(alignment1216040528);
+ AlignmentConstraint *alignment1216040592 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216040592->addShape(19, 0);
+ alignment1216040592->addShape(31, 0);
+ ccs.push_back(alignment1216040592);
+ AlignmentConstraint *alignment1216040656 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216040656->addShape(20, 0);
+ alignment1216040656->addShape(27, 0);
+ alignment1216040656->addShape(86, 0);
+ alignment1216040656->addShape(105, 0);
+ alignment1216040656->addShape(112, 0);
+ ccs.push_back(alignment1216040656);
+ AlignmentConstraint *alignment1216040720 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216040720->addShape(24, 0);
+ alignment1216040720->addShape(61, 0);
+ alignment1216040720->addShape(109, 0);
+ ccs.push_back(alignment1216040720);
+ AlignmentConstraint *alignment1216040784 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216040784->addShape(28, 0);
+ alignment1216040784->addShape(29, 0);
+ alignment1216040784->addShape(33, 0);
+ alignment1216040784->addShape(34, 0);
+ alignment1216040784->addShape(41, 0);
+ alignment1216040784->addShape(42, 0);
+ alignment1216040784->addShape(113, 0);
+ alignment1216040784->addShape(114, 0);
+ alignment1216040784->addShape(116, 0);
+ alignment1216040784->addShape(118, 0);
+ alignment1216040784->addShape(119, 0);
+ alignment1216040784->addShape(125, 0);
+ alignment1216040784->addShape(126, 0);
+ ccs.push_back(alignment1216040784);
+ AlignmentConstraint *alignment1216034032 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216034032->addShape(30, 0);
+ ccs.push_back(alignment1216034032);
+ AlignmentConstraint *alignment1216035736 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216035736->addShape(32, 0);
+ alignment1216035736->addShape(43, 0);
+ alignment1216035736->addShape(44, 0);
+ alignment1216035736->addShape(50, 0);
+ alignment1216035736->addShape(51, 0);
+ alignment1216035736->addShape(127, 0);
+ alignment1216035736->addShape(128, 0);
+ ccs.push_back(alignment1216035736);
+ AlignmentConstraint *alignment1216035800 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216035800->addShape(36, 0);
+ alignment1216035800->addShape(37, 0);
+ alignment1216035800->addShape(121, 0);
+ alignment1216035800->addShape(122, 0);
+ ccs.push_back(alignment1216035800);
+ AlignmentConstraint *alignment1216035864 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216035864->addShape(38, 0);
+ ccs.push_back(alignment1216035864);
+ AlignmentConstraint *alignment1216035928 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216035928->addShape(39, 0);
+ alignment1216035928->addShape(67, 0);
+ alignment1216035928->addShape(98, 0);
+ alignment1216035928->addShape(123, 0);
+ ccs.push_back(alignment1216035928);
+ AlignmentConstraint *alignment1216035992 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216035992->addShape(47, 0);
+ ccs.push_back(alignment1216035992);
+ AlignmentConstraint *alignment1216036056 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036056->addShape(52, 0);
+ alignment1216036056->addShape(53, 0);
+ ccs.push_back(alignment1216036056);
+ AlignmentConstraint *alignment1216036120 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036120->addShape(59, 0);
+ alignment1216036120->addShape(80, 0);
+ ccs.push_back(alignment1216036120);
+ AlignmentConstraint *alignment1216036184 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036184->addShape(70, 0);
+ alignment1216036184->addShape(73, 0);
+ ccs.push_back(alignment1216036184);
+ AlignmentConstraint *alignment1216036248 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036248->addShape(71, 0);
+ alignment1216036248->addShape(72, 0);
+ ccs.push_back(alignment1216036248);
+ AlignmentConstraint *alignment1216036312 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036312->addShape(74, 0);
+ ccs.push_back(alignment1216036312);
+ AlignmentConstraint *alignment1216036376 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036376->addShape(75, 0);
+ alignment1216036376->addShape(78, 0);
+ alignment1216036376->addShape(131, 0);
+ alignment1216036376->addShape(133, 0);
+ ccs.push_back(alignment1216036376);
+ AlignmentConstraint *alignment1216036440 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036440->addShape(81, 0);
+ ccs.push_back(alignment1216036440);
+ AlignmentConstraint *alignment1216036504 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036504->addShape(82, 0);
+ alignment1216036504->addShape(136, 0);
+ ccs.push_back(alignment1216036504);
+ AlignmentConstraint *alignment1216036568 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036568->addShape(85, 0);
+ ccs.push_back(alignment1216036568);
+ AlignmentConstraint *alignment1216036632 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216036632->addShape(91, 0);
+ ccs.push_back(alignment1216036632);
+ AlignmentConstraint *alignment1216034712 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216034712->addShape(96, 0);
+ ccs.push_back(alignment1216034712);
+ AlignmentConstraint *alignment1216034776 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216034776->addShape(97, 0);
+ ccs.push_back(alignment1216034776);
+ AlignmentConstraint *alignment1216034840 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216034840->addShape(101, 0);
+ alignment1216034840->addShape(106, 0);
+ alignment1216034840->addShape(107, 0);
+ alignment1216034840->addShape(110, 0);
+ ccs.push_back(alignment1216034840);
+ AlignmentConstraint *alignment1216034904 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216034904->addShape(102, 0);
+ alignment1216034904->addShape(103, 0);
+ alignment1216034904->addShape(111, 0);
+ alignment1216034904->addShape(115, 0);
+ alignment1216034904->addShape(124, 0);
+ ccs.push_back(alignment1216034904);
+ AlignmentConstraint *alignment1216034968 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216034968->addShape(104, 0);
+ ccs.push_back(alignment1216034968);
+ AlignmentConstraint *alignment1216035032 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216035032->addShape(117, 0);
+ ccs.push_back(alignment1216035032);
+ AlignmentConstraint *alignment1216035096 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216035096->addShape(135, 0);
+ ccs.push_back(alignment1216035096);
+ AlignmentConstraint *alignment1216035160 = new AlignmentConstraint((vpsc::Dim) 0, 0);
+ alignment1216035160->addShape(139, 0);
+ ccs.push_back(alignment1216035160);
+#endif
+
+#if 1
+ AlignmentConstraint *alignment1216035224 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216035224->addShape(0, 0);
+ alignment1216035224->addShape(7, 0);
+ alignment1216035224->addShape(8, 0);
+ ccs.push_back(alignment1216035224);
+ AlignmentConstraint *alignment1216035288 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216035288->addShape(1, 0);
+ alignment1216035288->addShape(6, 0);
+ alignment1216035288->addShape(39, 0);
+ alignment1216035288->addShape(60, 0);
+ alignment1216035288->addShape(68, 0);
+ alignment1216035288->addShape(91, 0);
+ alignment1216035288->addShape(93, 0);
+ alignment1216035288->addShape(132, 0);
+ ccs.push_back(alignment1216035288);
+ AlignmentConstraint *alignment1216035352 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216035352->addShape(2, 0);
+ alignment1216035352->addShape(77, 0);
+ alignment1216035352->addShape(79, 0);
+ ccs.push_back(alignment1216035352);
+ AlignmentConstraint *alignment1216035416 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216035416->addShape(3, 0);
+ alignment1216035416->addShape(61, 0);
+ alignment1216035416->addShape(66, 0);
+ ccs.push_back(alignment1216035416);
+ AlignmentConstraint *alignment1216035480 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216035480->addShape(4, 0);
+ alignment1216035480->addShape(22, 0);
+ alignment1216035480->addShape(23, 0);
+ alignment1216035480->addShape(107, 0);
+ ccs.push_back(alignment1216035480);
+ AlignmentConstraint *alignment1216035544 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216035544->addShape(5, 0);
+ ccs.push_back(alignment1216035544);
+ AlignmentConstraint *alignment1216035608 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216035608->addShape(9, 0);
+ alignment1216035608->addShape(96, 0);
+ ccs.push_back(alignment1216035608);
+ AlignmentConstraint *alignment1216042672 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216042672->addShape(10, 0);
+ alignment1216042672->addShape(97, 0);
+ alignment1216042672->addShape(123, 0);
+ ccs.push_back(alignment1216042672);
+ AlignmentConstraint *alignment1216042736 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216042736->addShape(11, 0);
+ alignment1216042736->addShape(12, 0);
+ alignment1216042736->addShape(13, 0);
+ alignment1216042736->addShape(59, 0);
+ alignment1216042736->addShape(62, 0);
+ alignment1216042736->addShape(63, 0);
+ alignment1216042736->addShape(65, 0);
+ alignment1216042736->addShape(67, 0);
+ alignment1216042736->addShape(98, 0);
+ ccs.push_back(alignment1216042736);
+ AlignmentConstraint *alignment1216042800 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216042800->addShape(14, 0);
+ ccs.push_back(alignment1216042800);
+ AlignmentConstraint *alignment1216042864 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216042864->addShape(15, 0);
+ alignment1216042864->addShape(101, 0);
+ ccs.push_back(alignment1216042864);
+ AlignmentConstraint *alignment1216042928 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216042928->addShape(16, 0);
+ alignment1216042928->addShape(102, 0);
+ alignment1216042928->addShape(133, 0);
+ ccs.push_back(alignment1216042928);
+ AlignmentConstraint *alignment1216042992 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216042992->addShape(17, 0);
+ alignment1216042992->addShape(103, 0);
+ ccs.push_back(alignment1216042992);
+ AlignmentConstraint *alignment1216043056 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043056->addShape(18, 0);
+ alignment1216043056->addShape(81, 0);
+ alignment1216043056->addShape(104, 0);
+ alignment1216043056->addShape(135, 0);
+ ccs.push_back(alignment1216043056);
+ AlignmentConstraint *alignment1216043120 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043120->addShape(19, 0);
+ ccs.push_back(alignment1216043120);
+ AlignmentConstraint *alignment1216043184 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043184->addShape(20, 0);
+ alignment1216043184->addShape(52, 0);
+ alignment1216043184->addShape(89, 0);
+ ccs.push_back(alignment1216043184);
+ AlignmentConstraint *alignment1216043248 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043248->addShape(21, 0);
+ alignment1216043248->addShape(105, 0);
+ alignment1216043248->addShape(106, 0);
+ ccs.push_back(alignment1216043248);
+ AlignmentConstraint *alignment1216043312 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043312->addShape(24, 0);
+ alignment1216043312->addShape(47, 0);
+ alignment1216043312->addShape(125, 0);
+ ccs.push_back(alignment1216043312);
+ AlignmentConstraint *alignment1216043376 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043376->addShape(25, 0);
+ alignment1216043376->addShape(30, 0);
+ alignment1216043376->addShape(31, 0);
+ alignment1216043376->addShape(32, 0);
+ alignment1216043376->addShape(110, 0);
+ alignment1216043376->addShape(115, 0);
+ alignment1216043376->addShape(116, 0);
+ alignment1216043376->addShape(117, 0);
+ alignment1216043376->addShape(126, 0);
+ ccs.push_back(alignment1216043376);
+ AlignmentConstraint *alignment1216043440 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043440->addShape(26, 0);
+ alignment1216043440->addShape(111, 0);
+ alignment1216043440->addShape(118, 0);
+ ccs.push_back(alignment1216043440);
+ AlignmentConstraint *alignment1216043504 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043504->addShape(27, 0);
+ alignment1216043504->addShape(29, 0);
+ alignment1216043504->addShape(51, 0);
+ alignment1216043504->addShape(53, 0);
+ alignment1216043504->addShape(55, 0);
+ ccs.push_back(alignment1216043504);
+ AlignmentConstraint *alignment1216043568 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043568->addShape(28, 0);
+ ccs.push_back(alignment1216043568);
+ AlignmentConstraint *alignment1216043632 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043632->addShape(33, 0);
+ alignment1216043632->addShape(50, 0);
+ alignment1216043632->addShape(54, 0);
+ ccs.push_back(alignment1216043632);
+ AlignmentConstraint *alignment1216043696 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043696->addShape(34, 0);
+ ccs.push_back(alignment1216043696);
+ AlignmentConstraint *alignment1216043760 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043760->addShape(35, 0);
+ alignment1216043760->addShape(122, 0);
+ ccs.push_back(alignment1216043760);
+ AlignmentConstraint *alignment1216043824 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043824->addShape(36, 0);
+ alignment1216043824->addShape(119, 0);
+ ccs.push_back(alignment1216043824);
+ AlignmentConstraint *alignment1216043888 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043888->addShape(37, 0);
+ ccs.push_back(alignment1216043888);
+ AlignmentConstraint *alignment1216043952 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216043952->addShape(38, 0);
+ ccs.push_back(alignment1216043952);
+ AlignmentConstraint *alignment1216044016 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044016->addShape(40, 0);
+ alignment1216044016->addShape(86, 0);
+ alignment1216044016->addShape(124, 0);
+ ccs.push_back(alignment1216044016);
+ AlignmentConstraint *alignment1216044080 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044080->addShape(41, 0);
+ ccs.push_back(alignment1216044080);
+ AlignmentConstraint *alignment1216044144 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044144->addShape(42, 0);
+ ccs.push_back(alignment1216044144);
+ AlignmentConstraint *alignment1216044208 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044208->addShape(43, 0);
+ alignment1216044208->addShape(45, 0);
+ alignment1216044208->addShape(70, 0);
+ alignment1216044208->addShape(71, 0);
+ ccs.push_back(alignment1216044208);
+ AlignmentConstraint *alignment1216044272 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044272->addShape(44, 0);
+ alignment1216044272->addShape(46, 0);
+ alignment1216044272->addShape(72, 0);
+ alignment1216044272->addShape(73, 0);
+ alignment1216044272->addShape(108, 0);
+ ccs.push_back(alignment1216044272);
+ AlignmentConstraint *alignment1216044336 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044336->addShape(48, 0);
+ alignment1216044336->addShape(109, 0);
+ ccs.push_back(alignment1216044336);
+ AlignmentConstraint *alignment1216044400 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044400->addShape(49, 0);
+ ccs.push_back(alignment1216044400);
+ AlignmentConstraint *alignment1216044464 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044464->addShape(56, 0);
+ alignment1216044464->addShape(76, 0);
+ ccs.push_back(alignment1216044464);
+ AlignmentConstraint *alignment1216044528 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044528->addShape(57, 0);
+ alignment1216044528->addShape(137, 0);
+ ccs.push_back(alignment1216044528);
+ AlignmentConstraint *alignment1216044592 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216044592->addShape(58, 0);
+ alignment1216044592->addShape(82, 0);
+ alignment1216044592->addShape(85, 0);
+ alignment1216044592->addShape(88, 0);
+ alignment1216044592->addShape(139, 0);
+ ccs.push_back(alignment1216044592);
+ AlignmentConstraint *alignment1216021552 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216021552->addShape(64, 0);
+ ccs.push_back(alignment1216021552);
+ AlignmentConstraint *alignment1216021616 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216021616->addShape(69, 0);
+ ccs.push_back(alignment1216021616);
+ AlignmentConstraint *alignment1216021680 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216021680->addShape(74, 0);
+ ccs.push_back(alignment1216021680);
+ AlignmentConstraint *alignment1216021744 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216021744->addShape(75, 0);
+ ccs.push_back(alignment1216021744);
+ AlignmentConstraint *alignment1216021808 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216021808->addShape(78, 0);
+ alignment1216021808->addShape(138, 0);
+ ccs.push_back(alignment1216021808);
+ AlignmentConstraint *alignment1216021872 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216021872->addShape(80, 0);
+ ccs.push_back(alignment1216021872);
+ AlignmentConstraint *alignment1216021936 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216021936->addShape(83, 0);
+ ccs.push_back(alignment1216021936);
+ AlignmentConstraint *alignment1216022000 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022000->addShape(84, 0);
+ ccs.push_back(alignment1216022000);
+ AlignmentConstraint *alignment1216022064 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022064->addShape(87, 0);
+ ccs.push_back(alignment1216022064);
+ AlignmentConstraint *alignment1216022128 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022128->addShape(90, 0);
+ alignment1216022128->addShape(95, 0);
+ ccs.push_back(alignment1216022128);
+ AlignmentConstraint *alignment1216022192 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022192->addShape(92, 0);
+ alignment1216022192->addShape(134, 0);
+ ccs.push_back(alignment1216022192);
+ AlignmentConstraint *alignment1216022256 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022256->addShape(94, 0);
+ ccs.push_back(alignment1216022256);
+ AlignmentConstraint *alignment1216022320 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022320->addShape(99, 0);
+ alignment1216022320->addShape(100, 0);
+ ccs.push_back(alignment1216022320);
+ AlignmentConstraint *alignment1216022384 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022384->addShape(112, 0);
+ alignment1216022384->addShape(114, 0);
+ ccs.push_back(alignment1216022384);
+ AlignmentConstraint *alignment1216022448 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022448->addShape(113, 0);
+ alignment1216022448->addShape(120, 0);
+ ccs.push_back(alignment1216022448);
+ AlignmentConstraint *alignment1216022512 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022512->addShape(121, 0);
+ ccs.push_back(alignment1216022512);
+ AlignmentConstraint *alignment1216022576 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022576->addShape(127, 0);
+ alignment1216022576->addShape(129, 0);
+ ccs.push_back(alignment1216022576);
+ AlignmentConstraint *alignment1216022640 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022640->addShape(128, 0);
+ alignment1216022640->addShape(130, 0);
+ ccs.push_back(alignment1216022640);
+ AlignmentConstraint *alignment1216022704 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022704->addShape(131, 0);
+ ccs.push_back(alignment1216022704);
+ AlignmentConstraint *alignment1216022768 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022768->addShape(136, 0);
+ alignment1216022768->addShape(141, 0);
+ ccs.push_back(alignment1216022768);
+ AlignmentConstraint *alignment1216022832 = new AlignmentConstraint((vpsc::Dim) 1, 0);
+ alignment1216022832->addShape(140, 0);
+ ccs.push_back(alignment1216022832);
+#endif
+
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength);
+ alg.setAvoidNodeOverlaps(true);
+ alg.setConstraints(ccs);
+ alg.makeFeasible();
+ alg.outputInstanceToSVG();
+ //alg.run();
+ return 0;
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/makemovie.sh b/src/3rdparty/adaptagrams/libcola/tests/makemovie.sh
new file mode 100644
index 0000000..cd571f9
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/makemovie.sh
@@ -0,0 +1,10 @@
+pattern=containment
+width=200
+height=260
+rm ${pattern}*.pdf
+for file in ${pattern}*.svg
+do
+ echo adding $file...
+ inkscape -w$width -h$height -A ${file%.svg}.pdf $file 2> /dev/null
+done
+convert -page ${width}x${height} -delay 15 ${pattern}*.pdf $pattern.gif
diff --git a/src/3rdparty/adaptagrams/libcola/tests/max_acyclic_subgraph.cpp b/src/3rdparty/adaptagrams/libcola/tests/max_acyclic_subgraph.cpp
new file mode 100644
index 0000000..cb2eb38
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/max_acyclic_subgraph.cpp
@@ -0,0 +1,346 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <iostream>
+#include <vector>
+#include <assert.h>
+#include <libcola/cola.h>
+#include <libcola/max_acyclic_subgraph.h>
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+using vpsc::Rectangle;
+
+int main() {
+ MaxAcyclicSubgraph *mas;
+ Edges case_a, case_b, case_c, case_d, case_e, case_f;
+ Edges *subgraph = nullptr;
+
+ vector<Rectangle *> rs;
+ unsigned V;
+
+ // create case A
+ // case A consists of a basic graph where the start point is a source
+ cout << endl << "ENTERING CASE A" << endl;
+ V = 5;
+ case_a.push_back(Edge(0, 1));
+ case_a.push_back(Edge(1, 2));
+ case_a.push_back(Edge(2, 3));
+ case_a.push_back(Edge(3, 4));
+ case_a.push_back(Edge(4, 1));
+
+ // detect the subgraph
+ mas = new MaxAcyclicSubgraph(V, &case_a);
+ subgraph = mas->find_subgraph();
+
+ if (subgraph != nullptr) {
+ cout << "subgraph->size(): " << subgraph->size() << endl;
+ cout << "Ea: ";
+ for (unsigned i = 0; i < subgraph->size(); i++) {
+ // print out the subgraph
+ cout << "(" << (*subgraph)[i].first << ", " << (*subgraph)[i].second << ") ";
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(10,10+5,10,10+5));
+ rs.push_back(new Rectangle(30,30+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,30,30+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_a, "mas_case_a.svg", false, true, subgraph);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();
+
+ delete subgraph;
+ }
+ else {
+ cout << "No subgraph found" << endl;
+ }
+
+ // create case B
+ // case B is the same graph of case A but with more elements
+ cout << endl << "ENTERING CASE B" << endl;
+ V = 7;
+ case_b.push_back(Edge(0, 1));
+ case_b.push_back(Edge(1, 2));
+ case_b.push_back(Edge(2, 3));
+ case_b.push_back(Edge(3, 4));
+ case_b.push_back(Edge(4, 1));
+ case_b.push_back(Edge(5, 2));
+ case_b.push_back(Edge(6, 5));
+
+ // detect the subgraph
+ mas->mod_graph(V, &case_b);
+ subgraph = mas->find_subgraph();
+
+ if (subgraph != nullptr) {
+ cout << "subgraph->size(): " << subgraph->size() << endl;
+ cout << "Ea: ";
+ for (unsigned i = 0; i < subgraph->size(); i++) {
+ // print out the subgraph
+ cout << "(" << (*subgraph)[i].first << ", " << (*subgraph)[i].second << ") ";
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(10,10+5,10,10+5));
+ rs.push_back(new Rectangle(30,30+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,90,90+5));
+ rs.push_back(new Rectangle(65,65+5,90,90+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_b, "mas_case_b.svg", false, true, subgraph);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();
+
+ delete subgraph;
+ }
+ else {
+ cout << "No subgraph found" << endl;
+ }
+
+ // create case C
+ // case C is a more complicated graph with nested subgraph
+ cout << endl << "ENTERING CASE C" << endl;
+ V = 14;
+ case_c.push_back(Edge(0, 1));
+ case_c.push_back(Edge(0, 5));
+ case_c.push_back(Edge(0, 6));
+ case_c.push_back(Edge(2, 0));
+ case_c.push_back(Edge(3, 5));
+ case_c.push_back(Edge(4, 3));
+ case_c.push_back(Edge(5, 4));
+ case_c.push_back(Edge(5, 13));
+ case_c.push_back(Edge(6, 2));
+ case_c.push_back(Edge(6, 9));
+ case_c.push_back(Edge(7, 6));
+ case_c.push_back(Edge(8, 7));
+ case_c.push_back(Edge(9, 10));
+ case_c.push_back(Edge(9, 11));
+ case_c.push_back(Edge(9, 12));
+ case_c.push_back(Edge(10, 6));
+ case_c.push_back(Edge(12, 10));
+ case_c.push_back(Edge(13, 4));
+
+ // detect the subgraph
+ mas->mod_graph(V, &case_c);
+ subgraph = mas->find_subgraph();
+
+ if (subgraph != nullptr) {
+ cout << "subgraph->size(): " << subgraph->size() << endl;
+ cout << "Ea: ";
+ for (unsigned i = 0; i < subgraph->size(); i++) {
+ // print out the subgraph
+ cout << "(" << (*subgraph)[i].first << ", " << (*subgraph)[i].second << ") ";
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(10,10+5,10,10+5)); // node 0
+ rs.push_back(new Rectangle(20,20+5,40,40+5)); // node 1
+ rs.push_back(new Rectangle(40,40+5,30,30+5)); // node 2
+ rs.push_back(new Rectangle(30,30+5,60,60+5)); // node 3
+ rs.push_back(new Rectangle(60,60+5,60,60+5)); // node 4
+ rs.push_back(new Rectangle(10,10+5,90,90+5)); // node 5
+ rs.push_back(new Rectangle(80,80+5,15,15+5)); // node 6
+ rs.push_back(new Rectangle(110,110+5,15,15+5)); // node 7
+ rs.push_back(new Rectangle(140,140+5,15,15+5)); // node 8
+ rs.push_back(new Rectangle(110,110+5,60,60+5)); // node 9
+ rs.push_back(new Rectangle(100,100+5,85,85+5)); // node 10
+ rs.push_back(new Rectangle(140,140+5,50,50+5)); // node 11
+ rs.push_back(new Rectangle(140,140+5,70,70+5)); // node 12
+ rs.push_back(new Rectangle(45,45+5,90,90+5)); // node 13
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_c, "mas_case_c.svg", false, true, subgraph);
+ for(int i = 0; i < V; i++) { delete rs[i]; }
+ rs.clear();
+ delete subgraph;
+ }
+ else {
+ cout << "No subgraph found" << endl;
+ }
+
+ // create case D
+ // case D consists of the same graph as case A but with a different starting location
+ cout << endl << "ENTERING CASE D" << endl;
+ V = 5;
+ case_d.push_back(Edge(0, 1));
+ case_d.push_back(Edge(1, 2));
+ case_d.push_back(Edge(2, 3));
+ case_d.push_back(Edge(3, 0));
+ case_d.push_back(Edge(4, 1));
+
+ // detect the subgraph
+ mas->mod_graph(V, &case_d);
+ subgraph = mas->find_subgraph();
+
+ if (subgraph != nullptr) {
+ cout << "subgraph->size(): " << subgraph->size() << endl;
+ cout << "Ea: ";
+ for (unsigned i = 0; i < subgraph->size(); i++) {
+ // print out the subgraph
+ cout << "(" << (*subgraph)[i].first << ", " << (*subgraph)[i].second << ") ";
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(65,65+5,60,60+5));
+ rs.push_back(new Rectangle(65,65+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,30,30+5));
+ rs.push_back(new Rectangle(30,30+5,60,60+5));
+ rs.push_back(new Rectangle(10,10+5,10,10+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_d, "mas_case_d.svg", false, true, subgraph);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();
+ delete subgraph;
+ }
+ else {
+ cout << "No subgraph found" << endl;
+ }
+
+ // create case E
+ // case E is a reordering of case C
+ cout << endl << "ENTERING CASE E" << endl;
+ V = 14;
+ case_e.push_back(Edge(0, 6));
+ case_e.push_back(Edge(0, 9));
+ case_e.push_back(Edge(1, 4));
+ case_e.push_back(Edge(3, 10));
+ case_e.push_back(Edge(4, 3));
+ case_e.push_back(Edge(5, 0));
+ case_e.push_back(Edge(6, 7));
+ case_e.push_back(Edge(7, 0));
+ case_e.push_back(Edge(7, 2));
+ case_e.push_back(Edge(7, 10));
+ case_e.push_back(Edge(8, 5));
+ case_e.push_back(Edge(9, 12));
+ case_e.push_back(Edge(9, 11));
+ case_e.push_back(Edge(9, 13));
+ case_e.push_back(Edge(10, 1));
+ case_e.push_back(Edge(10, 4));
+ case_e.push_back(Edge(12, 0));
+ case_e.push_back(Edge(11, 12));
+
+ // detect the subgraph
+ mas->mod_graph(V, &case_e);
+ subgraph = mas->find_subgraph();
+ if (subgraph != nullptr) {
+ cout << "subgraph->size(): " << subgraph->size() << endl;
+ cout << "Ea: ";
+ for (unsigned i = 0; i < subgraph->size(); i++) {
+ // print out the subgraph
+ cout << "(" << (*subgraph)[i].first << ", " << (*subgraph)[i].second << ") ";
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(80,80+5,15,15+5)); // node 6
+ rs.push_back(new Rectangle(45,45+5,90,90+5)); // node 13
+ rs.push_back(new Rectangle(20,20+5,40,40+5)); // node 1
+ rs.push_back(new Rectangle(30,30+5,60,60+5)); // node 3
+ rs.push_back(new Rectangle(60,60+5,60,60+5)); // node 4
+ rs.push_back(new Rectangle(110,110+5,15,15+5)); // node 7
+ rs.push_back(new Rectangle(40,40+5,30,30+5)); // node 2
+ rs.push_back(new Rectangle(10,10+5,10,10+5)); // node 0
+ rs.push_back(new Rectangle(140,140+5,15,15+5)); // node 8
+ rs.push_back(new Rectangle(110,110+5,60,60+5)); // node 9
+ rs.push_back(new Rectangle(10,10+5,90,90+5)); // node 5
+ rs.push_back(new Rectangle(140,140+5,70,70+5)); // node 12
+ rs.push_back(new Rectangle(100,100+5,85,85+5)); // node 10
+ rs.push_back(new Rectangle(140,140+5,50,50+5)); // node 11
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_e, "mas_case_e.svg", false, true, subgraph);
+ for(int i = 0; i < V; i++) { delete rs[i]; }
+ rs.clear();
+ delete subgraph;
+ }
+ else {
+ cout << "No subgraph found" << endl;
+ }
+
+ // create case F
+ // case F consists of the same graph with sinks
+ cout << endl << "ENTERING CASE F" << endl;
+ V = 3;
+ case_f.push_back(Edge(0, 1));
+ case_f.push_back(Edge(0, 2));
+ case_f.push_back(Edge(1, 2));
+
+ // detect the subgraph
+ mas->mod_graph(V, &case_f);
+ subgraph = mas->find_subgraph();
+
+ if (subgraph != nullptr) {
+ cout << "subgraph->size(): " << subgraph->size() << endl;
+ cout << "Ea: ";
+ for (unsigned i = 0; i < subgraph->size(); i++) {
+ // print out the subgraph
+ cout << "(" << (*subgraph)[i].first << ", " << (*subgraph)[i].second << ") ";
+ }
+
+ cout << endl;
+
+ // output a picture
+ rs.push_back(new Rectangle(10,10+5,10,10+5));
+ rs.push_back(new Rectangle(40,40+5,30,30+5));
+ rs.push_back(new Rectangle(15,15+5,60,60+5));
+
+ assert(rs.size() == V);
+
+ output_svg(rs, case_f, "mas_case_f.svg", false, true, subgraph);
+ for (unsigned i = 0; i < rs.size(); i++) { delete rs[i]; }
+ rs.clear();
+ delete subgraph;
+ }
+ else {
+ cout << "No subgraph found" << endl;
+ }
+
+ // END TEST
+ delete mas;
+
+ return 0;
+}
diff --git a/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters01.cpp b/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters01.cpp
new file mode 100644
index 0000000..6031c71
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters01.cpp
@@ -0,0 +1,333 @@
+// Based on debug file from Christoph Daniel Schulze
+// cgraph_3_after_layout.svg
+#include <vector>
+#include <utility>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ EdgeLengths eLengths;
+ double defaultEdgeLength=50;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ rect = new vpsc::Rectangle(245.517, 247.517, 279.574, 281.574);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(222.742, 224.742, 318.708, 320.708);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(460.345, 462.345, 716.936, 718.936);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(607.846, 609.846, 665.496, 667.496);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(640.191, 642.191, 637.391, 639.391);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(743.519, 745.519, 865.48, 867.48);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(807.112, 809.112, 759.798, 761.798);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(807.112, 809.112, 699.132, 701.132);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(121.997, 123.997, 221.049, 223.049);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(224.354, 226.354, 80, 82);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(448.583, 450.583, 517.722, 519.722);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(460.345, 462.345, 639.516, 641.516);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(607.846, 609.846, 583.991, 585.991);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(607.846, 609.846, 684.476, 686.476);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(625.623, 627.623, 602.774, 604.774);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(289.325, 291.325, 455.243, 457.243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(207.785, 209.785, 222.762, 224.762);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(159.658, 161.658, 254.197, 256.197);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(650.816, 652.816, 809.48, 811.48);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(685.012, 687.012, 795.932, 797.932);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(751.112, 753.112, 643.132, 645.132);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(751.112, 753.112, 608.903, 610.903);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(320.184, 322.184, 377.132, 379.132);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(336.233, 338.233, 382.124, 384.124);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(153.571, 155.571, 391.657, 393.657);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(405.396, 407.396, 745.874, 747.874);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(460.345, 462.345, 727.442, 729.442);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(551.846, 553.846, 527.991, 529.991);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(669.714, 671.714, 583.991, 585.991);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(171.168, 221.168, 258.197, 308.197);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(110.328, 160.328, 266.708, 316.708);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(217.18, 267.18, 109.481, 159.481);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(632.075, 682.075, 858.531, 908.531);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(689.012, 739.012, 813.48, 863.48);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(755.112, 805.112, 647.132, 697.132);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(786.403, 836.403, 560.258, 610.258);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(261.651, 311.651, 247.06, 297.06);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(304.164, 354.164, 322.708, 372.708);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(70, 120, 325.132, 375.132);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(353.92, 403.92, 770.169, 820.169);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(464.345, 514.345, 749.874, 799.874);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(555.846, 605.846, 531.991, 581.991);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(696.038, 746.038, 531.991, 581.991);
+ rs.push_back(rect);
+
+ es.push_back(std::make_pair(0, 1));
+ es.push_back(std::make_pair(0, 22));
+ es.push_back(std::make_pair(1, 23));
+ es.push_back(std::make_pair(1, 24));
+ es.push_back(std::make_pair(2, 3));
+ es.push_back(std::make_pair(2, 25));
+ es.push_back(std::make_pair(3, 4));
+ es.push_back(std::make_pair(3, 26));
+ es.push_back(std::make_pair(3, 27));
+ es.push_back(std::make_pair(4, 28));
+ es.push_back(std::make_pair(5, 6));
+ es.push_back(std::make_pair(5, 18));
+ es.push_back(std::make_pair(6, 7));
+ es.push_back(std::make_pair(6, 19));
+ es.push_back(std::make_pair(6, 20));
+ es.push_back(std::make_pair(7, 21));
+ es.push_back(std::make_pair(8, 17));
+ es.push_back(std::make_pair(9, 31));
+ es.push_back(std::make_pair(10, 11));
+ es.push_back(std::make_pair(10, 12));
+ es.push_back(std::make_pair(10, 13));
+ es.push_back(std::make_pair(10, 14));
+ es.push_back(std::make_pair(10, 15));
+ es.push_back(std::make_pair(10, 22));
+ es.push_back(std::make_pair(10, 23));
+ es.push_back(std::make_pair(11, 12));
+ es.push_back(std::make_pair(11, 25));
+ es.push_back(std::make_pair(11, 26));
+ es.push_back(std::make_pair(12, 27));
+ es.push_back(std::make_pair(12, 28));
+ es.push_back(std::make_pair(13, 14));
+ es.push_back(std::make_pair(13, 18));
+ es.push_back(std::make_pair(13, 19));
+ es.push_back(std::make_pair(14, 20));
+ es.push_back(std::make_pair(14, 21));
+ es.push_back(std::make_pair(15, 24));
+ es.push_back(std::make_pair(16, 17));
+ es.push_back(std::make_pair(16, 36));
+ es.push_back(std::make_pair(17, 29));
+ es.push_back(std::make_pair(17, 30));
+ es.push_back(std::make_pair(18, 32));
+ es.push_back(std::make_pair(19, 33));
+ es.push_back(std::make_pair(20, 34));
+ es.push_back(std::make_pair(21, 35));
+ es.push_back(std::make_pair(22, 36));
+ es.push_back(std::make_pair(23, 37));
+ es.push_back(std::make_pair(24, 38));
+ es.push_back(std::make_pair(25, 39));
+ es.push_back(std::make_pair(26, 40));
+ es.push_back(std::make_pair(27, 41));
+ es.push_back(std::make_pair(28, 42));
+ es.push_back(std::make_pair(31, 36));
+ es.push_back(std::make_pair(32, 33));
+ es.push_back(std::make_pair(34, 35));
+ es.push_back(std::make_pair(36, 37));
+ es.push_back(std::make_pair(39, 40));
+ es.push_back(std::make_pair(41, 42));
+
+ double padding = 6;
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength, eLengths);
+ alg.setAvoidNodeOverlaps(true);
+ RootCluster *cluster140389150311456 = new RootCluster();
+ cluster140389150311456->addChildNode(0);
+ cluster140389150311456->addChildNode(1);
+ cluster140389150311456->addChildNode(2);
+ cluster140389150311456->addChildNode(3);
+ cluster140389150311456->addChildNode(4);
+ cluster140389150311456->addChildNode(5);
+ cluster140389150311456->addChildNode(6);
+ cluster140389150311456->addChildNode(7);
+ cluster140389150311456->addChildNode(8);
+ cluster140389150311456->addChildNode(9);
+ cluster140389150311456->addChildNode(10);
+ cluster140389150311456->addChildNode(11);
+ cluster140389150311456->addChildNode(12);
+ cluster140389150311456->addChildNode(13);
+ cluster140389150311456->addChildNode(14);
+ cluster140389150311456->addChildNode(15);
+ cluster140389150311456->addChildNode(16);
+ cluster140389150311456->addChildNode(17);
+ cluster140389150311456->addChildNode(18);
+ cluster140389150311456->addChildNode(19);
+ cluster140389150311456->addChildNode(20);
+ cluster140389150311456->addChildNode(21);
+ cluster140389150311456->addChildNode(22);
+ cluster140389150311456->addChildNode(23);
+ cluster140389150311456->addChildNode(24);
+ cluster140389150311456->addChildNode(25);
+ cluster140389150311456->addChildNode(26);
+ cluster140389150311456->addChildNode(27);
+ cluster140389150311456->addChildNode(28);
+ RectangularCluster *cluster140389152494880 = new RectangularCluster();
+ cluster140389152494880->setPadding(padding);
+ cluster140389152494880->addChildNode(36);
+ cluster140389150311456->addChildCluster(cluster140389152494880);
+ RectangularCluster *cluster140389150048048 = new RectangularCluster();
+ cluster140389150048048->setPadding(padding);
+ cluster140389150048048->addChildNode(38);
+ cluster140389150048048->addChildNode(37);
+ cluster140389150311456->addChildCluster(cluster140389150048048);
+ RectangularCluster *cluster140389150180400 = new RectangularCluster();
+ cluster140389150180400->setPadding(padding);
+ cluster140389150180400->addChildNode(30);
+ cluster140389150180400->addChildNode(29);
+ cluster140389150311456->addChildCluster(cluster140389150180400);
+ RectangularCluster *cluster140389150298288 = new RectangularCluster();
+ cluster140389150298288->setPadding(padding);
+ cluster140389150298288->addChildNode(39);
+ cluster140389150311456->addChildCluster(cluster140389150298288);
+ RectangularCluster *cluster140389150179600 = new RectangularCluster();
+ cluster140389150179600->setPadding(padding);
+ cluster140389150179600->addChildNode(41);
+ cluster140389150179600->addChildNode(40);
+ cluster140389150311456->addChildCluster(cluster140389150179600);
+ RectangularCluster *cluster140389150131760 = new RectangularCluster();
+ cluster140389150131760->setPadding(padding);
+ cluster140389150131760->addChildNode(42);
+ cluster140389150311456->addChildCluster(cluster140389150131760);
+ RectangularCluster *cluster140389150091712 = new RectangularCluster();
+ cluster140389150091712->setPadding(padding);
+ cluster140389150091712->addChildNode(32);
+ cluster140389150311456->addChildCluster(cluster140389150091712);
+ RectangularCluster *cluster140389152581264 = new RectangularCluster();
+ cluster140389152581264->setPadding(padding);
+ cluster140389152581264->addChildNode(34);
+ cluster140389152581264->addChildNode(33);
+ cluster140389150311456->addChildCluster(cluster140389152581264);
+ RectangularCluster *cluster140389144224352 = new RectangularCluster();
+ cluster140389144224352->setPadding(padding);
+ cluster140389144224352->addChildNode(35);
+ cluster140389150311456->addChildCluster(cluster140389144224352);
+ RectangularCluster *cluster140389144198304 = new RectangularCluster();
+ cluster140389144198304->setPadding(padding);
+ cluster140389144198304->addChildNode(30);
+ cluster140389144198304->addChildNode(29);
+ cluster140389150311456->addChildCluster(cluster140389144198304);
+ RectangularCluster *cluster140389144177184 = new RectangularCluster();
+ cluster140389144177184->setPadding(padding);
+ cluster140389144177184->addChildNode(31);
+ cluster140389150311456->addChildCluster(cluster140389144177184);
+ RectangularCluster *cluster140389144168944 = new RectangularCluster();
+ cluster140389144168944->setPadding(padding);
+ cluster140389144168944->addChildNode(36);
+ cluster140389144168944->addChildNode(37);
+ cluster140389150311456->addChildCluster(cluster140389144168944);
+ RectangularCluster *cluster140389144228288 = new RectangularCluster();
+ cluster140389144228288->setPadding(padding);
+ cluster140389144228288->addChildNode(39);
+ cluster140389144228288->addChildNode(40);
+ cluster140389150311456->addChildCluster(cluster140389144228288);
+ RectangularCluster *cluster140389144244064 = new RectangularCluster();
+ cluster140389144228288->setPadding(padding);
+ cluster140389144244064->addChildNode(42);
+ cluster140389144244064->addChildNode(41);
+ cluster140389150311456->addChildCluster(cluster140389144244064);
+ RectangularCluster *cluster140389144206000 = new RectangularCluster();
+ cluster140389144206000->setPadding(padding);
+ cluster140389144206000->addChildNode(32);
+ cluster140389144206000->addChildNode(33);
+ cluster140389150311456->addChildCluster(cluster140389144206000);
+ RectangularCluster *cluster140389144175920 = new RectangularCluster();
+ cluster140389144175920->setPadding(padding);
+ cluster140389144175920->addChildNode(35);
+ cluster140389144175920->addChildNode(34);
+ cluster140389150311456->addChildCluster(cluster140389144175920);
+ RectangularCluster *cluster140389144214752 = new RectangularCluster();
+ cluster140389144214752->setPadding(padding);
+ cluster140389144214752->addChildNode(38);
+ cluster140389150311456->addChildCluster(cluster140389144214752);
+ alg.setClusterHierarchy(cluster140389150311456);
+ alg.setConstraints(ccs);
+
+ UnsatisfiableConstraintInfos unsatisfiableX, unsatisfiableY;
+ alg.setUnsatisfiableConstraintInfo(&unsatisfiableX, &unsatisfiableY);
+
+ //alg.makeFeasible();
+ alg.run();
+ //alg.outputInstanceToSVG("overlappingClusters01");
+
+ for (size_t i = 0; i < unsatisfiableX.size(); ++i)
+ {
+ printf("%s\n", unsatisfiableX[i]->toString().c_str());
+ }
+ for (size_t i = 0; i < unsatisfiableY.size(); ++i)
+ {
+ printf("%s\n", unsatisfiableY[i]->toString().c_str());
+ }
+ alg.freeAssociatedObjects();
+ return (unsatisfiableX.empty() && unsatisfiableY.empty()) ? 0 : 1;
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters02.cpp b/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters02.cpp
new file mode 100644
index 0000000..a6bdaf2
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters02.cpp
@@ -0,0 +1,100 @@
+// Based on Euler Diagram generation example discussed with Aidan Delaney.
+//
+// B
+// +-----------------------------+
+// A | 2 C |
+// +-----------+----------------+ +---+ |
+// | | 1 | | 0 | |
+// | | | +---+ |
+// | 3 +----------------+------------+
+// | |
+// | | 4
+// +----------------------------+
+//
+
+#include <vector>
+#include <utility>
+#include <cstdlib>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ EdgeLengths eLengths;
+ double defaultEdgeLength=10;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ double width = 5;
+ double height = 5;
+ double pos = 0;
+
+ size_t nodes = 5;
+ for (size_t i = 0; i < nodes; ++i)
+ {
+ rect = new vpsc::Rectangle(pos, pos +width, pos, pos +height);
+ rs.push_back(rect);
+
+ // XXX randomness is needed because COLA doesn't currently untangle
+ // the graph properly if all the nodes begin at the same position.
+ pos += (rand() % 10) - 5;
+ }
+
+ // Euler dual graph (optional)
+ es.push_back(std::make_pair(2, 4));
+ es.push_back(std::make_pair(3, 4));
+ es.push_back(std::make_pair(1, 3));
+ es.push_back(std::make_pair(2, 1));
+ es.push_back(std::make_pair(2, 0));
+
+ // Padding around the inside of clusters.
+ double padding = 3;
+
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength, eLengths);
+ alg.setAvoidNodeOverlaps(true);
+ RootCluster *rootCluster = new RootCluster();
+
+ // A contains 1, 3
+ RectangularCluster *clusterA = new RectangularCluster();
+ clusterA->setPadding(padding);
+ clusterA->addChildNode(1);
+ clusterA->addChildNode(3);
+
+ // C contains 0
+ RectangularCluster *clusterC = new RectangularCluster();
+ clusterC->setPadding(padding);
+ clusterC->addChildNode(0);
+
+ // B contains 1, 2, C
+ RectangularCluster *clusterB = new RectangularCluster();
+ clusterB->setPadding(padding);
+ clusterB->addChildNode(1);
+ clusterB->addChildNode(2);
+ clusterB->addChildCluster(clusterC);
+
+ // node 4 is in the empty set.
+
+ rootCluster->addChildCluster(clusterA);
+ rootCluster->addChildCluster(clusterB);
+
+ alg.setConstraints(ccs);
+
+ UnsatisfiableConstraintInfos unsatisfiableX, unsatisfiableY;
+ alg.setUnsatisfiableConstraintInfo(&unsatisfiableX, &unsatisfiableY);
+
+ alg.setClusterHierarchy(rootCluster);
+ //alg.makeFeasible();
+ alg.run();
+ alg.outputInstanceToSVG("overlappingClusters02");
+
+ for (size_t i = 0; i < unsatisfiableX.size(); ++i)
+ {
+ printf("%s\n", unsatisfiableX[i]->toString().c_str());
+ }
+ for (size_t i = 0; i < unsatisfiableY.size(); ++i)
+ {
+ printf("%s\n", unsatisfiableY[i]->toString().c_str());
+ }
+ alg.freeAssociatedObjects();
+ return (unsatisfiableX.empty() && unsatisfiableY.empty()) ? 0 : 1;
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters04.cpp b/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters04.cpp
new file mode 100644
index 0000000..45a06ff
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/overlappingClusters04.cpp
@@ -0,0 +1,61 @@
+// From Aidan Delaney: a_b_ab_abc.json.svg
+// Regression test for SEGFAULT caused by specifing an invalid node index 7
+// in cluster description.
+#include <vector>
+#include <utility>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ EdgeLengths eLengths;
+ double defaultEdgeLength=10;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ rect = new vpsc::Rectangle(0, 5, 0, 5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-2, 3, -2, 3);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-1, 4, -1, 4);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1, 6, 1, 6);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1, 6, 1, 6);
+ rs.push_back(rect);
+
+
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength, eLengths);
+ alg.setAvoidNodeOverlaps(true);
+
+ RootCluster *cluster33771480 = new RootCluster();
+ RectangularCluster *cluster33771952 = new RectangularCluster();
+ cluster33771952->setPadding(Box(2));
+ cluster33771952->addChildNode(1);
+ cluster33771952->addChildNode(3);
+ cluster33771952->addChildNode(7);
+ cluster33771480->addChildCluster(cluster33771952);
+
+ RectangularCluster *cluster33772496 = new RectangularCluster();
+ cluster33772496->setPadding(Box(2));
+ cluster33772496->addChildNode(2);
+ cluster33772496->addChildNode(3);
+ cluster33772496->addChildNode(7);
+ cluster33771480->addChildCluster(cluster33772496);
+
+ RectangularCluster *cluster33773040 = new RectangularCluster();
+ cluster33773040->setPadding(Box(2));
+ cluster33773040->addChildNode(7);
+ cluster33771480->addChildCluster(cluster33773040);
+
+ alg.setClusterHierarchy(cluster33771480);
+
+ alg.setConstraints(ccs);
+ alg.makeFeasible();
+ //alg.outputInstanceToSVG("overlappingCLusters04");
+ alg.freeAssociatedObjects();
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/page_bounds.cpp b/src/3rdparty/adaptagrams/libcola/tests/page_bounds.cpp
new file mode 100644
index 0000000..b753cbf
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/page_bounds.cpp
@@ -0,0 +1,102 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/**
+ * \file page_bounds.cpp
+ *
+ * test/example showing the use of page boundary constraints
+ */
+#include<iostream>
+#include<vector>
+#include <cmath>
+#include <time.h>
+#include <valarray>
+
+#include "graphlayouttest.h"
+
+vector<Edge> random_graph(unsigned n) {
+ vector<Edge> edges;
+ for(unsigned i=1;i<n;i++) {
+ edges.push_back(make_pair(i-1,i));
+ }
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=i+1;j<n;j++) {
+ double r=(double)rand()/(double)RAND_MAX;
+ if(r < 1./(double)n) {
+ edges.push_back(make_pair(i,j));
+ }
+ }
+ }
+
+ return edges;
+}
+int main() {
+ unsigned V=30;
+ CompoundConstraints ccs;
+ vector<Edge> es = random_graph(V);
+ double defaultEdgeLength=40;
+ cola::PageBoundaryConstraints* pbc =
+ new cola::PageBoundaryConstraints(0,200,0,200,100);
+
+ double w=2.0, h=2.0;
+ for(unsigned i=0;i<V;i++) {
+ pbc->addShape(i, w/2, h/2);
+ }
+ ccs.push_back(pbc);
+
+ cout << "V="<<V<<endl;
+ double width=1000;
+ double height=1000;
+ //srand(time(nullptr));
+ vector<pair<double,double> > startpos(V);
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ startpos[i]=make_pair(x,y);
+ }
+
+ /*void run_test(
+ vector<pair<double,double> > const &startpos,
+ vector<Edge> const &es,
+ const double defaultEdgeLength,
+ CompoundConstraints &cx,
+ CompoundConstraints &cy,
+ const SolverType s,
+ const bool constrained,
+ const char *fname,
+ const char *testdesc) {
+ */
+
+/*
+ run_test(startpos,es,defaultEdgeLength,cx,cy,CG,false,"random","cg");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,IP,false,"random", "ip");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,false,"random", "ugp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,false,"random", "sgp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,IP,true,"random", "cip");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,true,"random", "csgp");
+ */
+ run_test(startpos,es,defaultEdgeLength,ccs,UGP,true,"random", "cugp");
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/planar.cpp b/src/3rdparty/adaptagrams/libcola/tests/planar.cpp
new file mode 100644
index 0000000..f5eae9c
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/planar.cpp
@@ -0,0 +1,287 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/** \file topology.cpp
+ *
+ * tests topology preserving layout. graph is a triangle.
+ * We have a fourth disconnected node starting inside the triangle.
+ * We give the disconnected node a desired position outside the triangle
+ * and begin layout. Layout should converge to near zero stress as all
+ * edges should be able to reach their desired lengths, and disconnected
+ * node should still be inside the triangle at the end.
+ */
+/*
+* Authors:
+* Tim Dwyer <tgdwyer@gmail.com>
+*/
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+#include <vector>
+#include <valarray>
+#include <algorithm>
+#include <float.h>
+#include <libcola/cola.h>
+#include <libtopology/topology_graph.h>
+#include "graphlayouttest.h"
+using namespace std;
+using namespace cola;
+
+struct TestCase {
+ topology::Nodes vs;
+ topology::Edges tes;
+ topology::EdgePoints ps;
+ vector<vpsc::Rectangle*> rs;
+ vector<Edge> es;
+ void addNode(double minX, double minY, double w, double h) {
+ vpsc::Rectangle* r = new Rectangle(minX, minX+w, minY, minY+h);
+ rs.push_back(r);
+ topology::Node *v = new topology::Node(vs.size(), r);
+ vs.push_back(v);
+ }
+ void addToPath(unsigned vID, topology::EdgePoint::RectIntersect i) {
+ ps.push_back(new topology::EdgePoint(vs[vID],i));
+ }
+ void addEdge(double l) {
+ tes.push_back(new topology::Edge(l, ps));
+ es.push_back(make_pair(ps[0]->node->id,ps[ps.size()-1]->node->id));
+ ps.clear();
+ }
+ ~TestCase() {
+ for_each(rs.begin(),rs.end(),delete_object());
+ for_each(tes.begin(),tes.end(),delete_object());
+ for_each(vs.begin(),vs.end(),delete_object());
+ }
+};
+void writeFile(const topology::Nodes& vs, const topology::Edges& es, const char *outputFileName) {
+ const unsigned n=vs.size();
+ vector<cola::Edge> cedges;
+
+ for(unsigned i=0;i<es.size();i++) {
+ cedges.push_back(make_pair(1,2));
+ }
+
+ vector<straightener::Route*> routes;
+ for(topology::Edges::const_iterator e=es.begin();e!=es.end();++e) {
+ routes.push_back((*e)->getRoute());
+ }
+
+ vector<string> labels(n);
+ for(unsigned i=0;i<n;++i) {
+ stringstream ss;
+ ss << i;
+ labels[i]=ss.str();
+ }
+
+ vector<vpsc::Rectangle*> rs;
+ for(topology::Nodes::const_iterator i=vs.begin();i!=vs.end();++i) {
+ rs.push_back((*i)->rect);
+ }
+ OutputFile of(rs,cedges,nullptr,outputFileName,true,false);
+ of.setLabels(labels);
+ of.routes=&routes;
+ of.generate();
+
+ for_each(routes.begin(),routes.end(),delete_object());
+}
+struct Test : TestConvergence {
+ Test(const double d,const unsigned i,topology::Nodes& vs, topology::Edges& es) : TestConvergence(d,i), vs(vs), es(es) {}
+ bool operator()(const double new_stress, valarray<double> & X, valarray<double> & Y) {
+ cout << "stress="<<new_stress<<" iteration="<<iterations<<endl;
+ stringstream ss;
+ ss << "planar-" << setfill('0') << setw(3) << ++iterations << ".svg";
+ writeFile(vs,es,ss.str().c_str());
+ if(iterations<100) {
+ return false;
+ }
+ return true;
+ return TestConvergence::operator()(new_stress,X,Y);
+ }
+ double lastStress;
+ topology::Nodes& vs;
+ topology::Edges& es;
+};
+void test() {
+ TestCase t;
+t.addNode(144.000000,511.000000,8.000000,8.000000);
+t.addNode(413.000000,155.000000,8.000000,8.000000);
+t.addNode(437.000000,169.000000,8.000000,8.000000);
+t.addNode(436.000000,122.000000,8.000000,8.000000);
+t.addNode(460.000000,150.000000,8.000000,8.000000);
+t.addNode(466.000000,178.000000,8.000000,8.000000);
+t.addNode(469.000000,198.000000,8.000000,8.000000);
+t.addNode(378.000000,332.000000,8.000000,8.000000);
+t.addNode(368.000000,315.000000,8.000000,8.000000);
+t.addNode(332.000000,341.000000,8.000000,8.000000);
+t.addNode(282.000000,374.000000,8.000000,8.000000);
+t.addNode(329.000000,364.000000,8.000000,8.000000);
+t.addNode(346.000000,390.000000,8.000000,8.000000);
+t.addNode(375.000000,402.000000,8.000000,8.000000);
+t.addNode(357.000000,438.000000,8.000000,8.000000);
+t.addNode(382.000000,422.000000,8.000000,8.000000);
+t.addNode(453.000000,280.000000,8.000000,8.000000);
+t.addNode(452.000000,258.000000,8.000000,8.000000);
+t.addNode(530.000000,449.000000,8.000000,8.000000);
+t.addNode(576.000000,431.000000,8.000000,8.000000);
+t.addNode(577.000000,408.000000,8.000000,8.000000);
+t.addNode(606.000000,438.000000,8.000000,8.000000);
+t.addNode(624.000000,467.000000,8.000000,8.000000);
+t.addNode(620.000000,492.000000,8.000000,8.000000);
+t.addNode(681.000000,492.000000,8.000000,8.000000);
+t.addNode(729.000000,528.000000,8.000000,8.000000);
+t.addNode(765.000000,515.000000,8.000000,8.000000);
+t.addNode(765.000000,492.000000,8.000000,8.000000);
+t.addNode(858.000000,538.000000,8.000000,8.000000);
+t.addNode(2.000000,544.000000,8.000000,8.000000);
+t.addToPath(28,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(27,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(28,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(26,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(25,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(28,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(25,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(29,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(17,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(24,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(16,(topology::EdgePoint::RectIntersect)4);
+//t.addToPath(20,(topology::EdgePoint::RectIntersect)1);
+t.addToPath(24,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(16,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(7,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(24,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(25,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(22,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(24,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(22,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(0,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(22,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(23,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(22,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(18,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(21,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(20,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(20,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(19,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(18,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(20,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(18,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(16,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(14,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(18,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(13,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(14,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(15,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(14,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(12,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(13,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(12,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(10,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(11,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(12,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(10,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(11,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(9,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(13,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(9,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(10,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(6,(topology::EdgePoint::RectIntersect)4);
+//t.addToPath(8,(topology::EdgePoint::RectIntersect)2);
+t.addToPath(9,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(6,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(7,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(8,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(7,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(6,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(25,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(5,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(10,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(5,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(29,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(29,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(1,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(3,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(2,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(5,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(6,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(4,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(5,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(3,(topology::EdgePoint::RectIntersect)4);
+t.addToPath(4,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+t.addToPath(29,(topology::EdgePoint::RectIntersect)4);
+//t.addToPath(1,(topology::EdgePoint::RectIntersect)2);
+t.addToPath(3,(topology::EdgePoint::RectIntersect)4);
+t.addEdge(70.000000);
+ writeFile(t.vs,t.tes,"planar-000.svg");
+ Test test(0.00001,100,t.vs,t.tes);
+ ConstrainedFDLayout alg(t.rs,t.es,70.0,nullptr,test,nullptr);
+ alg.setTopology(&t.vs,&t.tes);
+ alg.run(true,true);
+ double finalStress=alg.computeStress();
+ printf("finalStress=%f\n",finalStress);
+
+ //assert(finalStress<1e-5);
+}
+int main() {
+ test();
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=80 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/random_graph.cpp b/src/3rdparty/adaptagrams/libcola/tests/random_graph.cpp
new file mode 100644
index 0000000..68e2ee1
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/random_graph.cpp
@@ -0,0 +1,113 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include<iostream>
+#include<vector>
+#include <cmath>
+#include <time.h>
+#include <valarray>
+
+#include "graphlayouttest.h"
+
+vector<Edge> random_graph(unsigned n) {
+ vector<Edge> edges;
+ for(unsigned i=1;i<n;i++) {
+ edges.push_back(make_pair(i-1,i));
+ }
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=i+1;j<n;j++) {
+ double r=(double)rand()/(double)RAND_MAX;
+ if(r < 1./(double)n) {
+ edges.push_back(make_pair(i,j));
+ }
+ }
+ }
+
+ return edges;
+}
+int main() {
+ unsigned V=100;
+ CompoundConstraints ccs;
+ vector<Edge> es = random_graph(V);
+ double defaultEdgeLength=40;
+ for(unsigned i=0;i<es.size();i++) {
+ unsigned start=es[i].first, end=es[i].second;
+ ccs.push_back(
+ new SeparationConstraint(vpsc::YDIM, start,end,-10));
+ }
+
+ cout << "V="<<V<<endl;
+ double width=1000;
+ double height=1000;
+ //srand(time(nullptr));
+ vector<pair<double,double> > startpos(V);
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ startpos[i]=make_pair(x,y);
+ }
+
+ /*void run_test(
+ vector<pair<double,double> > const &startpos,
+ vector<Edge> const &es,
+ const double defaultEdgeLength,
+ CompoundConstraints &cx,
+ CompoundConstraints &cy,
+ const SolverType s,
+ const bool constrained,
+ const char *fname,
+ const char *testdesc) {
+ */
+
+/*
+ run_test(startpos,es,defaultEdgeLength,cx,cy,CG,false,"random","cg");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,IP,false,"random", "ip");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,false,"random", "ugp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,false,"random", "sgp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,IP,true,"random", "cip");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,true,"random", "cugp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,true,"random", "csgp");
+ */
+ vector<vpsc::Rectangle*> rs;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+5,y,y+5));
+ }
+ CheckProgress test(0.0001,200);
+ ConstrainedMajorizationLayout alg(rs,es,nullptr,defaultEdgeLength,
+ StandardEdgeLengths,&test);
+ //alg.setYConstraints(&cy);
+ alg.run();
+ ConstrainedFDLayout alg2(rs,es,defaultEdgeLength,
+ StandardEdgeLengths, &test);
+ //alg2.setYConstraints(&cy);
+ alg2.run();
+ OutputFile output(rs,es,nullptr,"random.pdf");
+ output.generate();
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/rectangularClusters01.cpp b/src/3rdparty/adaptagrams/libcola/tests/rectangularClusters01.cpp
new file mode 100644
index 0000000..4269b3b
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/rectangularClusters01.cpp
@@ -0,0 +1,1135 @@
+#include <vector>
+#include <utility>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ EdgeLengths eLengths;
+ double defaultEdgeLength=1;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ rect = new vpsc::Rectangle(56.4457, 117.446, 954.77, 1043.77);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(119.446, 127.446, 992.02, 1000.02);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(119.446, 127.446, 1004.27, 1012.27);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(119.446, 127.446, 1016.52, 1024.52);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(46.4457, 54.4457, 1004.27, 1012.27);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(2165.45, 2239.45, 976.562, 1065.56);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(2155.45, 2163.45, 1026.06, 1034.06);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-106.554, 6.44565, 955.683, 1044.68);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(8.44565, 16.4457, 1005.18, 1013.18);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(331.446, 412.446, 1015.55, 1104.55);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(414.446, 422.446, 1065.05, 1073.05);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(356.112, 364.112, 1106.55, 1114.55);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(339.779, 347.779, 1106.55, 1114.55);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(321.446, 329.446, 1073.22, 1081.22);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(321.446, 329.446, 1056.88, 1064.88);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(477.446, 559.446, 948.569, 1037.57);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(561.446, 569.446, 998.069, 1006.07);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(503.946, 511.946, 1039.57, 1047.57);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(467.446, 475.446, 998.069, 1006.07);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(56.4457, 127.446, 863.77, 952.77);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(129.446, 137.446, 913.27, 921.27);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(46.4457, 54.4457, 913.27, 921.27);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(177.446, 281.446, 922.444, 1011.44);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(283.446, 291.446, 971.944, 979.944);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(167.446, 175.446, 986.644, 994.644);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(167.446, 175.446, 976.844, 984.844);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(167.446, 175.446, 967.044, 975.044);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(167.446, 175.446, 957.244, 965.244);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(331.446, 427.446, 924.551, 1013.55);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(429.446, 437.446, 974.051, 982.051);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(321.446, 329.446, 974.051, 982.051);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(609.446, 730.446, 936.692, 1025.69);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(732.446, 740.446, 971.492, 979.492);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(732.446, 740.446, 981.292, 989.292);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(732.446, 740.446, 991.092, 999.092);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(732.446, 740.446, 1000.89, 1008.89);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(599.446, 607.446, 986.192, 994.192);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(780.446, 846.446, 838.172, 932.172);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(848.446, 856.446, 890.172, 898.172);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(770.446, 778.446, 890.172, 898.172);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(780.446, 846.446, 934.172, 1028.17);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(848.446, 856.446, 986.172, 994.172);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(770.446, 778.446, 986.172, 994.172);
+ rs.push_back(rect);
+
+ // rect-43
+ rect = new vpsc::Rectangle(941.446, 1155.45, 922.958, 1025.96);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1147.45, 1155.45, 979.458, 987.458);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(941.446, 949.446, 998.358, 1006.36);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(941.446, 949.446, 985.757, 993.757);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(941.446, 949.446, 973.158, 981.158);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(941.446, 949.446, 960.558, 968.558);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(780.446, 846.446, 1030.17, 1124.17);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(848.446, 856.446, 1082.17, 1090.17);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(770.446, 778.446, 1082.17, 1090.17);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1195.45, 1263.45, 938.653, 1017.65);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1265.45, 1273.45, 983.153, 991.153);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1185.45, 1193.45, 989.653, 997.653);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1185.45, 1193.45, 976.653, 984.653);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1313.45, 1374.45, 934.988, 1013.99);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1376.45, 1384.45, 979.488, 987.488);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1303.45, 1311.45, 979.488, 987.488);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1586.45, 1660.45, 855.704, 944.704);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1576.45, 1584.45, 905.204, 913.204);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1424.45, 1536.45, 866.456, 945.456);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1538.45, 1546.45, 910.956, 918.956);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1414.45, 1422.45, 910.956, 918.956);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1445.45, 1515.45, 947.456, 1036.46);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1517.45, 1525.45, 996.956, 1004.96);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1471.95, 1479.95, 1038.46, 1046.46);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1435.45, 1443.45, 996.956, 1004.96);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1699.45, 1748.45, 970.163, 1059.16);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1750.45, 1758.45, 1019.66, 1027.66);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1689.45, 1697.45, 1027.83, 1035.83);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1689.45, 1697.45, 1011.5, 1019.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1811.45, 1898.45, 1010.04, 1099.04);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1900.45, 1908.45, 1059.54, 1067.54);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1801.45, 1809.45, 1067.7, 1075.7);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1801.45, 1809.45, 1051.37, 1059.37);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1699.45, 1761.45, 1061.16, 1134.16);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1763.45, 1771.45, 1102.66, 1110.66);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1689.45, 1697.45, 1102.66, 1110.66);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(2053.45, 2115.45, 985.999, 1080);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(2117.45, 2125.45, 1038, 1046);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(2080.11, 2088.11, 1082, 1090);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(2062.78, 2070.78, 1082, 1090);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(2043.45, 2051.45, 1038, 1046);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1948.45, 2003.45, 996.147, 1090.15);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(2005.45, 2013.45, 1048.15, 1056.15);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1975.11, 1983.11, 1092.15, 1100.15);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1957.78, 1965.78, 1092.15, 1100.15);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1938.45, 1946.45, 1048.15, 1056.15);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1565.45, 1649.45, 951.936, 1040.94);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1651.45, 1659.45, 1001.44, 1009.44);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(1555.45, 1563.45, 1001.44, 1009.44);
+ rs.push_back(rect);
+
+ es.push_back(std::make_pair(0, 1));
+ es.push_back(std::make_pair(0, 2));
+ es.push_back(std::make_pair(0, 3));
+ es.push_back(std::make_pair(0, 4));
+ es.push_back(std::make_pair(1, 26));
+ es.push_back(std::make_pair(2, 25));
+ es.push_back(std::make_pair(3, 6));
+ es.push_back(std::make_pair(3, 24));
+ es.push_back(std::make_pair(4, 8));
+ es.push_back(std::make_pair(5, 6));
+ es.push_back(std::make_pair(6, 80));
+ es.push_back(std::make_pair(7, 8));
+ es.push_back(std::make_pair(9, 10));
+ es.push_back(std::make_pair(9, 11));
+ es.push_back(std::make_pair(9, 12));
+ es.push_back(std::make_pair(9, 13));
+ es.push_back(std::make_pair(9, 14));
+ es.push_back(std::make_pair(10, 17));
+ es.push_back(std::make_pair(15, 16));
+ es.push_back(std::make_pair(15, 17));
+ es.push_back(std::make_pair(15, 18));
+ es.push_back(std::make_pair(16, 36));
+ es.push_back(std::make_pair(16, 67));
+ es.push_back(std::make_pair(18, 29));
+ es.push_back(std::make_pair(19, 20));
+ es.push_back(std::make_pair(19, 21));
+ es.push_back(std::make_pair(20, 27));
+ es.push_back(std::make_pair(22, 23));
+ es.push_back(std::make_pair(22, 24));
+ es.push_back(std::make_pair(22, 25));
+ es.push_back(std::make_pair(22, 26));
+ es.push_back(std::make_pair(22, 27));
+ es.push_back(std::make_pair(23, 30));
+ es.push_back(std::make_pair(28, 29));
+ es.push_back(std::make_pair(28, 30));
+ es.push_back(std::make_pair(31, 32));
+ es.push_back(std::make_pair(31, 33));
+ es.push_back(std::make_pair(31, 34));
+ es.push_back(std::make_pair(31, 35));
+ es.push_back(std::make_pair(31, 36));
+ es.push_back(std::make_pair(32, 39));
+ es.push_back(std::make_pair(32, 48));
+ es.push_back(std::make_pair(34, 42));
+ es.push_back(std::make_pair(35, 51));
+ es.push_back(std::make_pair(35, 54));
+ es.push_back(std::make_pair(37, 38));
+ es.push_back(std::make_pair(37, 39));
+ es.push_back(std::make_pair(38, 47));
+ es.push_back(std::make_pair(40, 41));
+ es.push_back(std::make_pair(40, 42));
+ es.push_back(std::make_pair(41, 46));
+ es.push_back(std::make_pair(43, 44));
+ es.push_back(std::make_pair(43, 45));
+ es.push_back(std::make_pair(43, 46));
+ es.push_back(std::make_pair(43, 47));
+ es.push_back(std::make_pair(43, 48));
+ es.push_back(std::make_pair(44, 55));
+ es.push_back(std::make_pair(45, 50));
+ es.push_back(std::make_pair(49, 50));
+ es.push_back(std::make_pair(49, 51));
+ es.push_back(std::make_pair(52, 53));
+ es.push_back(std::make_pair(52, 54));
+ es.push_back(std::make_pair(52, 55));
+ es.push_back(std::make_pair(53, 58));
+ es.push_back(std::make_pair(56, 57));
+ es.push_back(std::make_pair(56, 58));
+ es.push_back(std::make_pair(57, 63));
+ es.push_back(std::make_pair(57, 66));
+ es.push_back(std::make_pair(59, 60));
+ es.push_back(std::make_pair(60, 62));
+ es.push_back(std::make_pair(61, 62));
+ es.push_back(std::make_pair(61, 63));
+ es.push_back(std::make_pair(64, 65));
+ es.push_back(std::make_pair(64, 66));
+ es.push_back(std::make_pair(64, 67));
+ es.push_back(std::make_pair(65, 91));
+ es.push_back(std::make_pair(68, 69));
+ es.push_back(std::make_pair(68, 70));
+ es.push_back(std::make_pair(68, 71));
+ es.push_back(std::make_pair(69, 75));
+ es.push_back(std::make_pair(70, 85));
+ es.push_back(std::make_pair(71, 90));
+ es.push_back(std::make_pair(72, 73));
+ es.push_back(std::make_pair(72, 74));
+ es.push_back(std::make_pair(72, 75));
+ es.push_back(std::make_pair(73, 88));
+ es.push_back(std::make_pair(75, 77));
+ es.push_back(std::make_pair(76, 77));
+ es.push_back(std::make_pair(76, 78));
+ es.push_back(std::make_pair(79, 80));
+ es.push_back(std::make_pair(79, 81));
+ es.push_back(std::make_pair(79, 82));
+ es.push_back(std::make_pair(79, 83));
+ es.push_back(std::make_pair(83, 85));
+ es.push_back(std::make_pair(84, 85));
+ es.push_back(std::make_pair(84, 86));
+ es.push_back(std::make_pair(84, 87));
+ es.push_back(std::make_pair(84, 88));
+ es.push_back(std::make_pair(89, 90));
+ es.push_back(std::make_pair(89, 91));
+
+ eLengths.resize(100);
+ eLengths[0] = 59.6059;
+ eLengths[1] = 59.6059;
+ eLengths[2] = 59.6059;
+ eLengths[3] = 59.6059;
+ eLengths[4] = 63.5296;
+ eLengths[5] = 77.5769;
+ eLengths[6] = 65.8274;
+ eLengths[7] = 65.8274;
+ eLengths[8] = 65.8274;
+ eLengths[9] = 65.8274;
+ eLengths[10] = 65.8274;
+ eLengths[11] = 66.1651;
+ eLengths[12] = 66.1651;
+ eLengths[13] = 66.1651;
+ eLengths[14] = 62.5822;
+ eLengths[15] = 62.5822;
+ eLengths[16] = 74.0984;
+ eLengths[17] = 74.0984;
+ eLengths[18] = 74.0984;
+ eLengths[19] = 74.0984;
+ eLengths[20] = 74.0984;
+ eLengths[21] = 71.111;
+ eLengths[22] = 71.111;
+ eLengths[23] = 80.7601;
+ eLengths[24] = 80.7601;
+ eLengths[25] = 80.7601;
+ eLengths[26] = 80.7601;
+ eLengths[27] = 80.7601;
+ eLengths[28] = 63.0851;
+ eLengths[29] = 63.0851;
+ eLengths[30] = 63.0851;
+ eLengths[31] = 63.0851;
+ eLengths[32] = 115.481;
+ eLengths[33] = 115.481;
+ eLengths[34] = 115.481;
+ eLengths[35] = 115.481;
+ eLengths[36] = 115.481;
+ eLengths[37] = 63.0851;
+ eLengths[38] = 63.0851;
+ eLengths[39] = 57.7745;
+ eLengths[40] = 57.7745;
+ eLengths[41] = 57.7745;
+ eLengths[42] = 55.5618;
+ eLengths[43] = 55.5618;
+ eLengths[44] = 63.5296;
+ eLengths[45] = 74.186;
+ eLengths[46] = 74.186;
+ eLengths[47] = 62.2718;
+ eLengths[48] = 62.2718;
+ eLengths[49] = 62.2718;
+ eLengths[50] = 56.4555;
+ eLengths[51] = 56.4555;
+ eLengths[52] = 56.4555;
+ eLengths[53] = 67.8863;
+ eLengths[54] = 67.8863;
+ eLengths[55] = 67.8863;
+ eLengths[56] = 53.5447;
+ eLengths[57] = 53.5447;
+ eLengths[58] = 61.9596;
+ eLengths[59] = 61.9596;
+ eLengths[60] = 61.9596;
+ eLengths[61] = 61.9596;
+ eLengths[62] = 60.111;
+ eLengths[63] = 60.111;
+ eLengths[64] = 60.111;
+ eLengths[65] = 60.111;
+ eLengths[66] = 66.8471;
+ eLengths[67] = 66.8471;
+ eLengths[68] = 18.3712;
+ eLengths[69] = 18.3712;
+ eLengths[70] = 18.3712;
+ eLengths[71] = 18.3712;
+ eLengths[72] = 10.6066;
+ eLengths[73] = 10.6066;
+ eLengths[74] = 15;
+ eLengths[75] = 15;
+ eLengths[76] = 15;
+ eLengths[77] = 10.6066;
+ eLengths[78] = 10.6066;
+ eLengths[79] = 23.7171;
+ eLengths[80] = 30;
+ eLengths[81] = 23.7171;
+ eLengths[82] = 23.7171;
+ eLengths[83] = 25.9808;
+ eLengths[84] = 21.2132;
+ eLengths[85] = 21.2132;
+ eLengths[86] = 15;
+ eLengths[87] = 21.2132;
+ eLengths[88] = 10.6066;
+ eLengths[89] = 15;
+ eLengths[90] = 15;
+ eLengths[91] = 10.6066;
+ eLengths[92] = 10.6066;
+ eLengths[93] = 15;
+ eLengths[94] = 10.6066;
+ eLengths[95] = 15;
+ eLengths[96] = 15;
+ eLengths[97] = 15;
+ eLengths[98] = 18.3712;
+ eLengths[99] = 15;
+
+ SeparationConstraint *separation479625808 = new SeparationConstraint(vpsc::XDIM, 0, 1, 36.5, true);
+ ccs.push_back(separation479625808);
+
+ SeparationConstraint *separation479626000 = new SeparationConstraint(vpsc::YDIM, 0, 1, -3.25, true);
+ ccs.push_back(separation479626000);
+
+ SeparationConstraint *separation479625936 = new SeparationConstraint(vpsc::XDIM, 0, 2, 36.5, true);
+ ccs.push_back(separation479625936);
+
+ SeparationConstraint *separation479626128 = new SeparationConstraint(vpsc::YDIM, 0, 2, 9, true);
+ ccs.push_back(separation479626128);
+
+ SeparationConstraint *separation479626064 = new SeparationConstraint(vpsc::XDIM, 0, 3, 36.5, true);
+ ccs.push_back(separation479626064);
+
+ SeparationConstraint *separation479626256 = new SeparationConstraint(vpsc::YDIM, 0, 3, 21.25, true);
+ ccs.push_back(separation479626256);
+
+ SeparationConstraint *separation479626192 = new SeparationConstraint(vpsc::XDIM, 0, 4, -36.5, true);
+ ccs.push_back(separation479626192);
+
+ SeparationConstraint *separation479626384 = new SeparationConstraint(vpsc::YDIM, 0, 4, 9, true);
+ ccs.push_back(separation479626384);
+
+ SeparationConstraint *separation479626320 = new SeparationConstraint(vpsc::XDIM, 5, 6, -43, true);
+ ccs.push_back(separation479626320);
+
+ SeparationConstraint *separation479626512 = new SeparationConstraint(vpsc::YDIM, 5, 6, 9, true);
+ ccs.push_back(separation479626512);
+
+ SeparationConstraint *separation479626448 = new SeparationConstraint(vpsc::XDIM, 7, 8, 62.5, true);
+ ccs.push_back(separation479626448);
+
+ SeparationConstraint *separation479626640 = new SeparationConstraint(vpsc::YDIM, 7, 8, 9, true);
+ ccs.push_back(separation479626640);
+
+ SeparationConstraint *separation479626576 = new SeparationConstraint(vpsc::XDIM, 9, 10, 46.5, true);
+ ccs.push_back(separation479626576);
+
+ SeparationConstraint *separation479626768 = new SeparationConstraint(vpsc::YDIM, 9, 10, 9, true);
+ ccs.push_back(separation479626768);
+
+ SeparationConstraint *separation479626704 = new SeparationConstraint(vpsc::XDIM, 9, 11, -11.8333, true);
+ ccs.push_back(separation479626704);
+
+ SeparationConstraint *separation479626896 = new SeparationConstraint(vpsc::YDIM, 9, 11, 50.5, true);
+ ccs.push_back(separation479626896);
+
+ SeparationConstraint *separation479626832 = new SeparationConstraint(vpsc::XDIM, 9, 12, -28.1667, true);
+ ccs.push_back(separation479626832);
+
+ SeparationConstraint *separation479627024 = new SeparationConstraint(vpsc::YDIM, 9, 12, 50.5, true);
+ ccs.push_back(separation479627024);
+
+ SeparationConstraint *separation479626960 = new SeparationConstraint(vpsc::XDIM, 9, 13, -46.5, true);
+ ccs.push_back(separation479626960);
+
+ SeparationConstraint *separation479627152 = new SeparationConstraint(vpsc::YDIM, 9, 13, 17.1667, true);
+ ccs.push_back(separation479627152);
+
+ SeparationConstraint *separation479627088 = new SeparationConstraint(vpsc::XDIM, 9, 14, -46.5, true);
+ ccs.push_back(separation479627088);
+
+ SeparationConstraint *separation479627280 = new SeparationConstraint(vpsc::YDIM, 9, 14, 0.833333, true);
+ ccs.push_back(separation479627280);
+
+ SeparationConstraint *separation479627216 = new SeparationConstraint(vpsc::XDIM, 15, 16, 47, true);
+ ccs.push_back(separation479627216);
+
+ SeparationConstraint *separation479627408 = new SeparationConstraint(vpsc::YDIM, 15, 16, 9, true);
+ ccs.push_back(separation479627408);
+
+ SeparationConstraint *separation479627344 = new SeparationConstraint(vpsc::XDIM, 15, 17, -10.5, true);
+ ccs.push_back(separation479627344);
+
+ SeparationConstraint *separation479627536 = new SeparationConstraint(vpsc::YDIM, 15, 17, 50.5, true);
+ ccs.push_back(separation479627536);
+
+ SeparationConstraint *separation479627472 = new SeparationConstraint(vpsc::XDIM, 15, 18, -47, true);
+ ccs.push_back(separation479627472);
+
+ SeparationConstraint *separation479627664 = new SeparationConstraint(vpsc::YDIM, 15, 18, 9, true);
+ ccs.push_back(separation479627664);
+
+ SeparationConstraint *separation479627600 = new SeparationConstraint(vpsc::XDIM, 19, 20, 41.5, true);
+ ccs.push_back(separation479627600);
+
+ SeparationConstraint *separation479627792 = new SeparationConstraint(vpsc::YDIM, 19, 20, 9, true);
+ ccs.push_back(separation479627792);
+
+ SeparationConstraint *separation479627728 = new SeparationConstraint(vpsc::XDIM, 19, 21, -41.5, true);
+ ccs.push_back(separation479627728);
+
+ SeparationConstraint *separation479627920 = new SeparationConstraint(vpsc::YDIM, 19, 21, 9, true);
+ ccs.push_back(separation479627920);
+
+ SeparationConstraint *separation479627856 = new SeparationConstraint(vpsc::XDIM, 22, 23, 58, true);
+ ccs.push_back(separation479627856);
+
+ SeparationConstraint *separation479628048 = new SeparationConstraint(vpsc::YDIM, 22, 23, 9, true);
+ ccs.push_back(separation479628048);
+
+ SeparationConstraint *separation479627984 = new SeparationConstraint(vpsc::XDIM, 22, 24, -58, true);
+ ccs.push_back(separation479627984);
+
+ SeparationConstraint *separation479628176 = new SeparationConstraint(vpsc::YDIM, 22, 24, 23.7, true);
+ ccs.push_back(separation479628176);
+
+ SeparationConstraint *separation479628112 = new SeparationConstraint(vpsc::XDIM, 22, 25, -58, true);
+ ccs.push_back(separation479628112);
+
+ SeparationConstraint *separation479628304 = new SeparationConstraint(vpsc::YDIM, 22, 25, 13.9, true);
+ ccs.push_back(separation479628304);
+
+ SeparationConstraint *separation479628240 = new SeparationConstraint(vpsc::XDIM, 22, 26, -58, true);
+ ccs.push_back(separation479628240);
+
+ SeparationConstraint *separation479628432 = new SeparationConstraint(vpsc::YDIM, 22, 26, 4.1, true);
+ ccs.push_back(separation479628432);
+
+ SeparationConstraint *separation479628368 = new SeparationConstraint(vpsc::XDIM, 22, 27, -58, true);
+ ccs.push_back(separation479628368);
+
+ SeparationConstraint *separation479628560 = new SeparationConstraint(vpsc::YDIM, 22, 27, -5.7, true);
+ ccs.push_back(separation479628560);
+
+ SeparationConstraint *separation479628496 = new SeparationConstraint(vpsc::XDIM, 28, 29, 54, true);
+ ccs.push_back(separation479628496);
+
+ SeparationConstraint *separation479628688 = new SeparationConstraint(vpsc::YDIM, 28, 29, 9, true);
+ ccs.push_back(separation479628688);
+
+ SeparationConstraint *separation479628624 = new SeparationConstraint(vpsc::XDIM, 28, 30, -54, true);
+ ccs.push_back(separation479628624);
+
+ SeparationConstraint *separation479628816 = new SeparationConstraint(vpsc::YDIM, 28, 30, 9, true);
+ ccs.push_back(separation479628816);
+
+ SeparationConstraint *separation479628752 = new SeparationConstraint(vpsc::XDIM, 31, 32, 66.5, true);
+ ccs.push_back(separation479628752);
+
+ SeparationConstraint *separation479622736 = new SeparationConstraint(vpsc::YDIM, 31, 32, -5.7, true);
+ ccs.push_back(separation479622736);
+
+ SeparationConstraint *separation479622800 = new SeparationConstraint(vpsc::XDIM, 31, 33, 66.5, true);
+ ccs.push_back(separation479622800);
+
+ SeparationConstraint *separation479622864 = new SeparationConstraint(vpsc::YDIM, 31, 33, 4.1, true);
+ ccs.push_back(separation479622864);
+
+ SeparationConstraint *separation479622928 = new SeparationConstraint(vpsc::XDIM, 31, 34, 66.5, true);
+ ccs.push_back(separation479622928);
+
+ SeparationConstraint *separation479622992 = new SeparationConstraint(vpsc::YDIM, 31, 34, 13.9, true);
+ ccs.push_back(separation479622992);
+
+ SeparationConstraint *separation479623056 = new SeparationConstraint(vpsc::XDIM, 31, 35, 66.5, true);
+ ccs.push_back(separation479623056);
+
+ SeparationConstraint *separation479623120 = new SeparationConstraint(vpsc::YDIM, 31, 35, 23.7, true);
+ ccs.push_back(separation479623120);
+
+ SeparationConstraint *separation479623184 = new SeparationConstraint(vpsc::XDIM, 31, 36, -66.5, true);
+ ccs.push_back(separation479623184);
+
+ SeparationConstraint *separation479623248 = new SeparationConstraint(vpsc::YDIM, 31, 36, 9, true);
+ ccs.push_back(separation479623248);
+
+ SeparationConstraint *separation479623312 = new SeparationConstraint(vpsc::XDIM, 37, 38, 39, true);
+ ccs.push_back(separation479623312);
+
+ SeparationConstraint *separation479623440 = new SeparationConstraint(vpsc::YDIM, 37, 38, 9, true);
+ ccs.push_back(separation479623440);
+
+ SeparationConstraint *separation479623504 = new SeparationConstraint(vpsc::XDIM, 37, 39, -39, true);
+ ccs.push_back(separation479623504);
+
+ SeparationConstraint *separation479623568 = new SeparationConstraint(vpsc::YDIM, 37, 39, 9, true);
+ ccs.push_back(separation479623568);
+
+ SeparationConstraint *separation479623632 = new SeparationConstraint(vpsc::XDIM, 40, 41, 39, true);
+ ccs.push_back(separation479623632);
+
+ SeparationConstraint *separation479623696 = new SeparationConstraint(vpsc::YDIM, 40, 41, 9, true);
+ ccs.push_back(separation479623696);
+
+ SeparationConstraint *separation479623760 = new SeparationConstraint(vpsc::XDIM, 40, 42, -39, true);
+ ccs.push_back(separation479623760);
+
+ SeparationConstraint *separation479623888 = new SeparationConstraint(vpsc::YDIM, 40, 42, 9, true);
+ ccs.push_back(separation479623888);
+
+ SeparationConstraint *separation479623952 = new SeparationConstraint(vpsc::XDIM, 43, 44, 103, true);
+ ccs.push_back(separation479623952);
+
+ SeparationConstraint *separation479624016 = new SeparationConstraint(vpsc::YDIM, 43, 44, 9, true);
+ ccs.push_back(separation479624016);
+
+ SeparationConstraint *separation479624080 = new SeparationConstraint(vpsc::XDIM, 43, 45, -103, true);
+ ccs.push_back(separation479624080);
+
+ SeparationConstraint *separation479624144 = new SeparationConstraint(vpsc::YDIM, 43, 45, 27.9, true);
+ ccs.push_back(separation479624144);
+
+ SeparationConstraint *separation479624208 = new SeparationConstraint(vpsc::XDIM, 43, 46, -103, true);
+ ccs.push_back(separation479624208);
+
+ SeparationConstraint *separation479624272 = new SeparationConstraint(vpsc::YDIM, 43, 46, 15.3, true);
+ ccs.push_back(separation479624272);
+
+ SeparationConstraint *separation479624336 = new SeparationConstraint(vpsc::XDIM, 43, 47, -103, true);
+ ccs.push_back(separation479624336);
+
+ SeparationConstraint *separation479624400 = new SeparationConstraint(vpsc::YDIM, 43, 47, 2.7, true);
+ ccs.push_back(separation479624400);
+
+ SeparationConstraint *separation479624528 = new SeparationConstraint(vpsc::XDIM, 43, 48, -103, true);
+ ccs.push_back(separation479624528);
+
+ SeparationConstraint *separation479624592 = new SeparationConstraint(vpsc::YDIM, 43, 48, -9.9, true);
+ ccs.push_back(separation479624592);
+
+ SeparationConstraint *separation479624656 = new SeparationConstraint(vpsc::XDIM, 49, 50, 39, true);
+ ccs.push_back(separation479624656);
+
+ SeparationConstraint *separation479624720 = new SeparationConstraint(vpsc::YDIM, 49, 50, 9, true);
+ ccs.push_back(separation479624720);
+
+ SeparationConstraint *separation479624784 = new SeparationConstraint(vpsc::XDIM, 49, 51, -39, true);
+ ccs.push_back(separation479624784);
+
+ SeparationConstraint *separation479624848 = new SeparationConstraint(vpsc::YDIM, 49, 51, 9, true);
+ ccs.push_back(separation479624848);
+
+ SeparationConstraint *separation479624912 = new SeparationConstraint(vpsc::XDIM, 52, 53, 40, true);
+ ccs.push_back(separation479624912);
+
+ SeparationConstraint *separation479624976 = new SeparationConstraint(vpsc::YDIM, 52, 53, 9, true);
+ ccs.push_back(separation479624976);
+
+ SeparationConstraint *separation479625040 = new SeparationConstraint(vpsc::XDIM, 52, 54, -40, true);
+ ccs.push_back(separation479625040);
+
+ SeparationConstraint *separation479625104 = new SeparationConstraint(vpsc::YDIM, 52, 54, 15.5, true);
+ ccs.push_back(separation479625104);
+
+ SeparationConstraint *separation479625168 = new SeparationConstraint(vpsc::XDIM, 52, 55, -40, true);
+ ccs.push_back(separation479625168);
+
+ SeparationConstraint *separation479625232 = new SeparationConstraint(vpsc::YDIM, 52, 55, 2.5, true);
+ ccs.push_back(separation479625232);
+
+ SeparationConstraint *separation479625296 = new SeparationConstraint(vpsc::XDIM, 56, 57, 36.5, true);
+ ccs.push_back(separation479625296);
+
+ SeparationConstraint *separation479625360 = new SeparationConstraint(vpsc::YDIM, 56, 57, 9, true);
+ ccs.push_back(separation479625360);
+
+ SeparationConstraint *separation479625424 = new SeparationConstraint(vpsc::XDIM, 56, 58, -36.5, true);
+ ccs.push_back(separation479625424);
+
+ SeparationConstraint *separation479625552 = new SeparationConstraint(vpsc::YDIM, 56, 58, 9, true);
+ ccs.push_back(separation479625552);
+
+ SeparationConstraint *separation479625616 = new SeparationConstraint(vpsc::XDIM, 59, 60, -43, true);
+ ccs.push_back(separation479625616);
+
+ SeparationConstraint *separation479625680 = new SeparationConstraint(vpsc::YDIM, 59, 60, 9, true);
+ ccs.push_back(separation479625680);
+
+ SeparationConstraint *separation479625744 = new SeparationConstraint(vpsc::XDIM, 61, 62, 62, true);
+ ccs.push_back(separation479625744);
+
+ SeparationConstraint *separation479625488 = new SeparationConstraint(vpsc::YDIM, 61, 62, 9, true);
+ ccs.push_back(separation479625488);
+
+ SeparationConstraint *separation479624464 = new SeparationConstraint(vpsc::XDIM, 61, 63, -62, true);
+ ccs.push_back(separation479624464);
+
+ SeparationConstraint *separation479623824 = new SeparationConstraint(vpsc::YDIM, 61, 63, 9, true);
+ ccs.push_back(separation479623824);
+
+ SeparationConstraint *separation479623376 = new SeparationConstraint(vpsc::XDIM, 64, 65, 41, true);
+ ccs.push_back(separation479623376);
+
+ SeparationConstraint *separation479628944 = new SeparationConstraint(vpsc::YDIM, 64, 65, 9, true);
+ ccs.push_back(separation479628944);
+
+ SeparationConstraint *separation479628880 = new SeparationConstraint(vpsc::XDIM, 64, 66, -4.5, true);
+ ccs.push_back(separation479628880);
+
+ SeparationConstraint *separation479629008 = new SeparationConstraint(vpsc::YDIM, 64, 66, 50.5, true);
+ ccs.push_back(separation479629008);
+
+ SeparationConstraint *separation479629072 = new SeparationConstraint(vpsc::XDIM, 64, 67, -41, true);
+ ccs.push_back(separation479629072);
+
+ SeparationConstraint *separation479629136 = new SeparationConstraint(vpsc::YDIM, 64, 67, 9, true);
+ ccs.push_back(separation479629136);
+
+ SeparationConstraint *separation479629200 = new SeparationConstraint(vpsc::XDIM, 68, 69, 30.5, true);
+ ccs.push_back(separation479629200);
+
+ SeparationConstraint *separation479629264 = new SeparationConstraint(vpsc::YDIM, 68, 69, 9, true);
+ ccs.push_back(separation479629264);
+
+ SeparationConstraint *separation479629328 = new SeparationConstraint(vpsc::XDIM, 68, 70, -30.5, true);
+ ccs.push_back(separation479629328);
+
+ SeparationConstraint *separation479629392 = new SeparationConstraint(vpsc::YDIM, 68, 70, 17.1667, true);
+ ccs.push_back(separation479629392);
+
+ SeparationConstraint *separation479629456 = new SeparationConstraint(vpsc::XDIM, 68, 71, -30.5, true);
+ ccs.push_back(separation479629456);
+
+ SeparationConstraint *separation479629520 = new SeparationConstraint(vpsc::YDIM, 68, 71, 0.833333, true);
+ ccs.push_back(separation479629520);
+
+ SeparationConstraint *separation479629584 = new SeparationConstraint(vpsc::XDIM, 72, 73, 49.5, true);
+ ccs.push_back(separation479629584);
+
+ SeparationConstraint *separation479629648 = new SeparationConstraint(vpsc::YDIM, 72, 73, 9, true);
+ ccs.push_back(separation479629648);
+
+ SeparationConstraint *separation479629712 = new SeparationConstraint(vpsc::XDIM, 72, 74, -49.5, true);
+ ccs.push_back(separation479629712);
+
+ SeparationConstraint *separation479629776 = new SeparationConstraint(vpsc::YDIM, 72, 74, 17.1667, true);
+ ccs.push_back(separation479629776);
+
+ SeparationConstraint *separation479629840 = new SeparationConstraint(vpsc::XDIM, 72, 75, -49.5, true);
+ ccs.push_back(separation479629840);
+
+ SeparationConstraint *separation479629904 = new SeparationConstraint(vpsc::YDIM, 72, 75, 0.833333, true);
+ ccs.push_back(separation479629904);
+
+ SeparationConstraint *separation479629968 = new SeparationConstraint(vpsc::XDIM, 76, 77, 37, true);
+ ccs.push_back(separation479629968);
+
+ SeparationConstraint *separation479630032 = new SeparationConstraint(vpsc::YDIM, 76, 77, 9, true);
+ ccs.push_back(separation479630032);
+
+ SeparationConstraint *separation479630096 = new SeparationConstraint(vpsc::XDIM, 76, 78, -37, true);
+ ccs.push_back(separation479630096);
+
+ SeparationConstraint *separation479630160 = new SeparationConstraint(vpsc::YDIM, 76, 78, 9, true);
+ ccs.push_back(separation479630160);
+
+ SeparationConstraint *separation479630224 = new SeparationConstraint(vpsc::XDIM, 79, 80, 37, true);
+ ccs.push_back(separation479630224);
+
+ SeparationConstraint *separation479630288 = new SeparationConstraint(vpsc::YDIM, 79, 80, 9, true);
+ ccs.push_back(separation479630288);
+
+ SeparationConstraint *separation479630352 = new SeparationConstraint(vpsc::XDIM, 79, 81, -0.333334, true);
+ ccs.push_back(separation479630352);
+
+ SeparationConstraint *separation479630416 = new SeparationConstraint(vpsc::YDIM, 79, 81, 53, true);
+ ccs.push_back(separation479630416);
+
+ SeparationConstraint *separation477486176 = new SeparationConstraint(vpsc::XDIM, 79, 82, -17.6667, true);
+ ccs.push_back(separation477486176);
+
+ SeparationConstraint *separation477486240 = new SeparationConstraint(vpsc::YDIM, 79, 82, 53, true);
+ ccs.push_back(separation477486240);
+
+ SeparationConstraint *separation477486304 = new SeparationConstraint(vpsc::XDIM, 79, 83, -37, true);
+ ccs.push_back(separation477486304);
+
+ SeparationConstraint *separation477486368 = new SeparationConstraint(vpsc::YDIM, 79, 83, 9, true);
+ ccs.push_back(separation477486368);
+
+ SeparationConstraint *separation477486432 = new SeparationConstraint(vpsc::XDIM, 84, 85, 33.5, true);
+ ccs.push_back(separation477486432);
+
+ SeparationConstraint *separation477486496 = new SeparationConstraint(vpsc::YDIM, 84, 85, 9, true);
+ ccs.push_back(separation477486496);
+
+ SeparationConstraint *separation477486560 = new SeparationConstraint(vpsc::XDIM, 84, 86, 3.16667, true);
+ ccs.push_back(separation477486560);
+
+ SeparationConstraint *separation477486624 = new SeparationConstraint(vpsc::YDIM, 84, 86, 53, true);
+ ccs.push_back(separation477486624);
+
+ SeparationConstraint *separation477486688 = new SeparationConstraint(vpsc::XDIM, 84, 87, -14.1667, true);
+ ccs.push_back(separation477486688);
+
+ SeparationConstraint *separation477486752 = new SeparationConstraint(vpsc::YDIM, 84, 87, 53, true);
+ ccs.push_back(separation477486752);
+
+ SeparationConstraint *separation477486816 = new SeparationConstraint(vpsc::XDIM, 84, 88, -33.5, true);
+ ccs.push_back(separation477486816);
+
+ SeparationConstraint *separation477486880 = new SeparationConstraint(vpsc::YDIM, 84, 88, 9, true);
+ ccs.push_back(separation477486880);
+
+ SeparationConstraint *separation477486944 = new SeparationConstraint(vpsc::XDIM, 89, 90, 48, true);
+ ccs.push_back(separation477486944);
+
+ SeparationConstraint *separation477487008 = new SeparationConstraint(vpsc::YDIM, 89, 90, 9, true);
+ ccs.push_back(separation477487008);
+
+ SeparationConstraint *separation477487072 = new SeparationConstraint(vpsc::XDIM, 89, 91, -48, true);
+ ccs.push_back(separation477487072);
+
+ SeparationConstraint *separation477487136 = new SeparationConstraint(vpsc::YDIM, 89, 91, 9, true);
+ ccs.push_back(separation477487136);
+
+ SeparationConstraint *separation477487200 = new SeparationConstraint(vpsc::XDIM, 7, 0, 137, false);
+ ccs.push_back(separation477487200);
+
+ SeparationConstraint *separation477487264 = new SeparationConstraint(vpsc::XDIM, 0, 5, 118.5, false);
+ ccs.push_back(separation477487264);
+
+ SeparationConstraint *separation477487328 = new SeparationConstraint(vpsc::XDIM, 79, 5, 118, false);
+ ccs.push_back(separation477487328);
+
+ SeparationConstraint *separation477487392 = new SeparationConstraint(vpsc::XDIM, 9, 15, 146.5, false);
+ ccs.push_back(separation477487392);
+
+ SeparationConstraint *separation477487456 = new SeparationConstraint(vpsc::XDIM, 28, 15, 139, false);
+ ccs.push_back(separation477487456);
+
+ SeparationConstraint *separation477487520 = new SeparationConstraint(vpsc::XDIM, 0, 22, 142.5, false);
+ ccs.push_back(separation477487520);
+
+ SeparationConstraint *separation477487584 = new SeparationConstraint(vpsc::XDIM, 0, 22, 142.5, false);
+ ccs.push_back(separation477487584);
+
+ SeparationConstraint *separation477487648 = new SeparationConstraint(vpsc::XDIM, 0, 22, 142.5, false);
+ ccs.push_back(separation477487648);
+
+ SeparationConstraint *separation477487712 = new SeparationConstraint(vpsc::XDIM, 19, 22, 137.5, false);
+ ccs.push_back(separation477487712);
+
+ SeparationConstraint *separation477487776 = new SeparationConstraint(vpsc::XDIM, 22, 28, 150, false);
+ ccs.push_back(separation477487776);
+
+ SeparationConstraint *separation477487840 = new SeparationConstraint(vpsc::XDIM, 15, 31, 151.5, false);
+ ccs.push_back(separation477487840);
+
+ SeparationConstraint *separation477487904 = new SeparationConstraint(vpsc::XDIM, 31, 37, 143.5, false);
+ ccs.push_back(separation477487904);
+
+ SeparationConstraint *separation477487968 = new SeparationConstraint(vpsc::XDIM, 31, 40, 143.5, false);
+ ccs.push_back(separation477487968);
+
+ SeparationConstraint *separation477488032 = new SeparationConstraint(vpsc::XDIM, 31, 43, 207.5, false);
+ ccs.push_back(separation477488032);
+
+ SeparationConstraint *separation477488096 = new SeparationConstraint(vpsc::XDIM, 37, 43, 235, false);
+ ccs.push_back(separation477488096);
+
+ SeparationConstraint *separation477488160 = new SeparationConstraint(vpsc::XDIM, 40, 43, 235, false);
+ ccs.push_back(separation477488160);
+
+ SeparationConstraint *separation477488224 = new SeparationConstraint(vpsc::XDIM, 49, 43, 235, false);
+ ccs.push_back(separation477488224);
+
+ SeparationConstraint *separation477488288 = new SeparationConstraint(vpsc::XDIM, 31, 49, 143.5, false);
+ ccs.push_back(separation477488288);
+
+ SeparationConstraint *separation477488352 = new SeparationConstraint(vpsc::XDIM, 31, 52, 217.5, false);
+ ccs.push_back(separation477488352);
+
+ SeparationConstraint *separation477488416 = new SeparationConstraint(vpsc::XDIM, 43, 52, 181, false);
+ ccs.push_back(separation477488416);
+
+ SeparationConstraint *separation477488480 = new SeparationConstraint(vpsc::XDIM, 52, 56, 114.5, false);
+ ccs.push_back(separation477488480);
+
+ SeparationConstraint *separation477488544 = new SeparationConstraint(vpsc::XDIM, 61, 59, 143, false);
+ ccs.push_back(separation477488544);
+
+ SeparationConstraint *separation477488608 = new SeparationConstraint(vpsc::XDIM, 56, 61, 136.5, false);
+ ccs.push_back(separation477488608);
+
+ SeparationConstraint *separation477488672 = new SeparationConstraint(vpsc::XDIM, 15, 64, 126, false);
+ ccs.push_back(separation477488672);
+
+ SeparationConstraint *separation477488736 = new SeparationConstraint(vpsc::XDIM, 56, 64, 136.5, false);
+ ccs.push_back(separation477488736);
+
+ SeparationConstraint *separation477488800 = new SeparationConstraint(vpsc::XDIM, 89, 68, 116.5, false);
+ ccs.push_back(separation477488800);
+
+ SeparationConstraint *separation477488864 = new SeparationConstraint(vpsc::XDIM, 68, 72, 131, false);
+ ccs.push_back(separation477488864);
+
+ SeparationConstraint *separation477488928 = new SeparationConstraint(vpsc::XDIM, 76, 72, 124.5, false);
+ ccs.push_back(separation477488928);
+
+ SeparationConstraint *separation477488992 = new SeparationConstraint(vpsc::XDIM, 84, 79, 108.5, false);
+ ccs.push_back(separation477488992);
+
+ SeparationConstraint *separation477489056 = new SeparationConstraint(vpsc::XDIM, 72, 84, 121, false);
+ ccs.push_back(separation477489056);
+
+ SeparationConstraint *separation477489120 = new SeparationConstraint(vpsc::XDIM, 64, 89, 127, false);
+ ccs.push_back(separation477489120);
+
+ cola::Box margin = cola::Box(10, 30, 30, 60); //30
+ cola::Box padding = cola::Box(); // cola::Box(10, 30, 30, 60); //10
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength, eLengths);
+ RootCluster *cluster476902600 = new RootCluster();
+ cluster476902600->addChildNode(0);
+ cluster476902600->addChildNode(1);
+ cluster476902600->addChildNode(2);
+ cluster476902600->addChildNode(3);
+ cluster476902600->addChildNode(4);
+ cluster476902600->addChildNode(5);
+ cluster476902600->addChildNode(6);
+ cluster476902600->addChildNode(7);
+ cluster476902600->addChildNode(8);
+ cluster476902600->addChildNode(9);
+ cluster476902600->addChildNode(10);
+ cluster476902600->addChildNode(11);
+ cluster476902600->addChildNode(12);
+ cluster476902600->addChildNode(13);
+ cluster476902600->addChildNode(14);
+ cluster476902600->addChildNode(15);
+ cluster476902600->addChildNode(16);
+ cluster476902600->addChildNode(17);
+ cluster476902600->addChildNode(18);
+ cluster476902600->addChildNode(19);
+ cluster476902600->addChildNode(20);
+ cluster476902600->addChildNode(21);
+ cluster476902600->addChildNode(22);
+ cluster476902600->addChildNode(23);
+ cluster476902600->addChildNode(24);
+ cluster476902600->addChildNode(25);
+ cluster476902600->addChildNode(26);
+ cluster476902600->addChildNode(27);
+ cluster476902600->addChildNode(28);
+ cluster476902600->addChildNode(29);
+ cluster476902600->addChildNode(30);
+ RectangularCluster *cluster417213744 = new RectangularCluster();
+ cluster417213744->setMargin(margin);
+ cluster417213744->setPadding(padding);
+ cluster417213744->addChildNode(59);
+ cluster417213744->addChildNode(60);
+ cluster417213744->addChildNode(61);
+ cluster417213744->addChildNode(62);
+ cluster417213744->addChildNode(63);
+ cluster417213744->addChildNode(64);
+ cluster417213744->addChildNode(65);
+ cluster417213744->addChildNode(66);
+ cluster417213744->addChildNode(67);
+ cluster417213744->addChildNode(89);
+ cluster417213744->addChildNode(90);
+ cluster417213744->addChildNode(91);
+ RectangularCluster *cluster417215984 = new RectangularCluster();
+ cluster417215984->setMargin(margin);
+ cluster417215984->setPadding(padding);
+ cluster417215984->addChildNode(31);
+ cluster417215984->addChildNode(32);
+ cluster417215984->addChildNode(33);
+ cluster417215984->addChildNode(34);
+ cluster417215984->addChildNode(35);
+ cluster417215984->addChildNode(36);
+ cluster417215984->addChildNode(37);
+ cluster417215984->addChildNode(38);
+ cluster417215984->addChildNode(39);
+ cluster417215984->addChildNode(40);
+ cluster417215984->addChildNode(41);
+ cluster417215984->addChildNode(42);
+ cluster417215984->addChildNode(43);
+ cluster417215984->addChildNode(44);
+ cluster417215984->addChildNode(45);
+ cluster417215984->addChildNode(46);
+ cluster417215984->addChildNode(47);
+ cluster417215984->addChildNode(48);
+ cluster417215984->addChildNode(49);
+ cluster417215984->addChildNode(50);
+ cluster417215984->addChildNode(51);
+ cluster417215984->addChildNode(52);
+ cluster417215984->addChildNode(53);
+ cluster417215984->addChildNode(54);
+ cluster417215984->addChildNode(55);
+ cluster417215984->addChildNode(56);
+ cluster417215984->addChildNode(57);
+ cluster417215984->addChildNode(58);
+ cluster417213744->addChildCluster(cluster417215984);
+ RectangularCluster *cluster417215760 = new RectangularCluster();
+ cluster417215760->setMargin(margin);
+ cluster417215760->setPadding(padding);
+ cluster417215760->addChildNode(68);
+ cluster417215760->addChildNode(69);
+ cluster417215760->addChildNode(70);
+ cluster417215760->addChildNode(71);
+ cluster417215760->addChildNode(72);
+ cluster417215760->addChildNode(73);
+ cluster417215760->addChildNode(74);
+ cluster417215760->addChildNode(75);
+ cluster417215760->addChildNode(76);
+ cluster417215760->addChildNode(77);
+ cluster417215760->addChildNode(78);
+ cluster417215760->addChildNode(79);
+ cluster417215760->addChildNode(80);
+ cluster417215760->addChildNode(81);
+ cluster417215760->addChildNode(82);
+ cluster417215760->addChildNode(83);
+ cluster417215760->addChildNode(84);
+ cluster417215760->addChildNode(85);
+ cluster417215760->addChildNode(86);
+ cluster417215760->addChildNode(87);
+ cluster417215760->addChildNode(88);
+ cluster417213744->addChildCluster(cluster417215760);
+ cluster476902600->addChildCluster(cluster417213744);
+ alg.setClusterHierarchy(cluster476902600);
+ alg.setConstraints(ccs);
+
+ UnsatisfiableConstraintInfos unsatisfiableX, unsatisfiableY;
+ alg.setUnsatisfiableConstraintInfo(&unsatisfiableX, &unsatisfiableY);
+
+ // rect-43 and associated port rects.
+ cola::NodeIndexes nonOverlapExemptGroup;
+ nonOverlapExemptGroup.push_back(44);
+ nonOverlapExemptGroup.push_back(45);
+ nonOverlapExemptGroup.push_back(46);
+ nonOverlapExemptGroup.push_back(47);
+ nonOverlapExemptGroup.push_back(48);
+ nonOverlapExemptGroup.push_back(43);
+
+ std::vector<cola::NodeIndexes> nonOverlapExemptGroupList;
+ nonOverlapExemptGroupList.push_back(nonOverlapExemptGroup);
+ alg.setAvoidNodeOverlaps(true, nonOverlapExemptGroupList);
+
+ //alg.makeFeasible();
+ alg.run();
+ alg.outputInstanceToSVG("rectangularClusters01");
+
+ for (size_t i = 0; i < unsatisfiableX.size(); ++i)
+ {
+ printf("%s\n", unsatisfiableX[i]->toString().c_str());
+ }
+ for (size_t i = 0; i < unsatisfiableY.size(); ++i)
+ {
+ printf("%s\n", unsatisfiableY[i]->toString().c_str());
+ }
+ alg.freeAssociatedObjects();
+ return (unsatisfiableX.empty() && unsatisfiableY.empty()) ? 0 : 1;
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/rectclustershapecontainment.cpp b/src/3rdparty/adaptagrams/libcola/tests/rectclustershapecontainment.cpp
new file mode 100644
index 0000000..3c3d704
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/rectclustershapecontainment.cpp
@@ -0,0 +1,2173 @@
+#include <vector>
+#include "libcola/cola.h"
+using namespace cola;
+int main(void) {
+ CompoundConstraints ccs;
+ std::vector<Edge> es;
+ double defaultEdgeLength=40;
+ std::vector<vpsc::Rectangle*> rs;
+ vpsc::Rectangle *rect = nullptr;
+
+ rect = new vpsc::Rectangle(478, 488, 399, 409);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(284, 294, 938, 948);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(141, 151, 906, 916);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(284, 294, 959, 969);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(131, 161, 938, 968);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(550, 762, 155.5, 522.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(430, 540, -6, 158);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(373, 383, 907, 917);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(482, 492, 938, 948);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(434, 444, 938, 948);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(426, 436, 869, 879);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(426, 436, 848, 858);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(314, 324, 860, 870);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(205, 215, 860, 870);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(553, 563, 859, 869);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(345, 423, 746, 780);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(478, 488, 765, 775);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(-34.5, 162.5, 723, 877);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(478, 488, 696, 706);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(478, 488, 624, 634);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(453, 463, 479, 489);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(154.5, 457.5, 574, 624);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(398, 408, 445, 455);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(453, 463, 331, 341);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(403, 413, 331, 341);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(547, 557, 191, 201);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(478, 488, 260, 270);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(478, 488, 168, 178);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(380, 390, 297, 307);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(228, 238, 286, 296);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(228, 238, 307, 317);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(352, 362, 259, 269);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(302, 312, 259, 269);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(176, 186, 259, 269);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(228, 238, 234, 244);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(228, 238, 213, 223);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(311, 321, 181, 191);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(338, 348, 149, 159);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(338, 348, 128, 138);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(40.5, 291.5, 45.5, 70.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(257, 267, 903, 913);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(478, 488, 551, 561);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(276, 286, 213, 223);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(276, 286, 286, 296);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(176, 186, 355, 365);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(176, 186, 381, 391);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(286, 296, 354, 364);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(286, 296, 380, 390);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(586, 616, 180, 210);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 128, 158);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 649, 679);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(166, 196, 213, 243);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(166, 196, 286, 316);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(317, 347, 433, 463);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(317, 347, 286, 316);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 215, 245);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 288, 318);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 721, 751);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 577, 607);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 505, 535);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(612, 642, 848, 878);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(299, 329, 891, 921);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(535, 565, 938, 968);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 848, 878);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(363, 393, 848, 878);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(131, 161, 848, 878);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(363, 393, 938, 968);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(250, 280, 848, 878);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(197, 227, 891, 921);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 358, 388);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(117, 147, 344, 374);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(224, 254, 344, 374);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(224, 254, 370, 400);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(117, 147, 370, 400);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(363, 393, 805, 835);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(181, 227, 711, 741);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(131, 161, 721, 751);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(434, 444, 959, 969);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(199, 209, 742, 752);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(482, 492, 959, 969);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(565.5, 692.5, 842.5, 997.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(503, 513, 479, 489);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(577, 587, 520, 530);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(550, 560, 539, 549);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(284, 294, 790, 800);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(527, 537, 520, 530);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(383, 413, 541, 571);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(432, 442, 581, 591);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(433, 443, 517, 527);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(468, 498, 433, 463);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(91, 101, 906, 916);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(503, 513, 331, 341);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(276, 286, 234, 244);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(276, 286, 307, 317);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(522, 568, 389, 419);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(266, 312, 878, 908);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(185, 231, 896, 926);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(266, 312, 899, 929);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(417, 463, 897, 927);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(464, 510, 878, 908);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(416, 462, 878, 908);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(470, 516, 859, 889);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(470, 516, 838, 868);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(358, 404, 850, 880);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(187, 233, 800, 830);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(535, 581, 799, 829);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(522, 568, 755, 785);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(522, 568, 686, 716);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(522, 568, 614, 644);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(497, 543, 469, 499);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(380, 426, 385, 415);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(497, 543, 321, 351);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(385, 431, 271, 301);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(529, 575, 131, 161);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(522, 568, 250, 280);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(522, 568, 158, 188);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(362, 408, 237, 267);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(210, 256, 226, 256);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(210, 256, 247, 277);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(396, 442, 249, 279);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(346, 392, 249, 279);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(220, 266, 249, 279);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(210, 256, 174, 204);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(210, 256, 153, 183);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(293, 339, 121, 151);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(320, 366, 89, 119);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(320, 366, 68, 98);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(239, 285, 843, 873);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(522, 568, 541, 571);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(258, 304, 153, 183);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(258, 304, 226, 256);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(158, 204, 295, 325);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(158, 204, 321, 351);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(268, 314, 294, 324);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(268, 314, 320, 350);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(416, 462, 899, 929);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(181, 227, 682, 712);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(464, 510, 899, 929);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(547, 593, 469, 499);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(559, 605, 460, 490);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(532, 578, 479, 509);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(266, 312, 730, 760);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(571, 617, 510, 540);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(414, 460, 521, 551);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(415, 461, 457, 487);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(73, 119, 846, 876);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(547, 593, 321, 351);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(258, 304, 174, 204);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(258, 304, 247, 277);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(550.5, 600.5, 304.5, 334.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(550.5, 600.5, 344.5, 374.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(621.5, 651.5, 473, 523);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(661.5, 691.5, 473, 523);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(470.5, 500.5, 108.5, 158.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(113, 163, 765.5, 795.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(113, 163, 805.5, 835.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(408, 458, 584.5, 614.5);
+ rs.push_back(rect);
+
+ rect = new vpsc::Rectangle(614.5, 644.5, 843, 893);
+ rs.push_back(rect);
+
+ AlignmentConstraint *alignment140664475503328 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475503328->addShape(0, 0);
+ alignment140664475503328->addShape(16, 0);
+ alignment140664475503328->addShape(18, 0);
+ alignment140664475503328->addShape(19, 0);
+ alignment140664475503328->addShape(26, 0);
+ alignment140664475503328->addShape(27, 0);
+ alignment140664475503328->addShape(41, 0);
+ alignment140664475503328->addShape(49, 0);
+ alignment140664475503328->addShape(50, 0);
+ alignment140664475503328->addShape(55, 0);
+ alignment140664475503328->addShape(56, 0);
+ alignment140664475503328->addShape(57, 0);
+ alignment140664475503328->addShape(58, 0);
+ alignment140664475503328->addShape(59, 0);
+ alignment140664475503328->addShape(63, 0);
+ alignment140664475503328->addShape(69, 0);
+ alignment140664475503328->addShape(89, 0);
+ ccs.push_back(alignment140664475503328);
+
+ AlignmentConstraint *alignment140664481097440 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664481097440->addShape(1, 0);
+ alignment140664481097440->addShape(3, 0);
+ alignment140664481097440->addShape(46, 0);
+ alignment140664481097440->addShape(47, 0);
+ alignment140664481097440->addShape(84, 0);
+ ccs.push_back(alignment140664481097440);
+
+ AlignmentConstraint *alignment140664483416688 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664483416688->addShape(2, 0);
+ alignment140664483416688->addShape(4, 0);
+ alignment140664483416688->addShape(65, 0);
+ alignment140664483416688->addShape(76, 0);
+ ccs.push_back(alignment140664483416688);
+
+ AlignmentConstraint *alignment140664481096784 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664481096784->addShape(3, 0);
+ alignment140664481096784->addShape(46, 0);
+ alignment140664481096784->addShape(47, 0);
+ alignment140664481096784->addShape(84, 0);
+ ccs.push_back(alignment140664481096784);
+
+ AlignmentConstraint *alignment140664475503952 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475503952->addShape(4, 0);
+ alignment140664475503952->addShape(65, 0);
+ alignment140664475503952->addShape(76, 0);
+ ccs.push_back(alignment140664475503952);
+
+ AlignmentConstraint *alignment140664475504304 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475504304->addShape(7, 0);
+ alignment140664475504304->addShape(64, 0);
+ alignment140664475504304->addShape(66, 0);
+ alignment140664475504304->addShape(74, 0);
+ ccs.push_back(alignment140664475504304);
+
+ AlignmentConstraint *alignment140664475504496 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475504496->addShape(8, 0);
+ alignment140664475504496->addShape(79, 0);
+ ccs.push_back(alignment140664475504496);
+
+ AlignmentConstraint *alignment140664475504720 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475504720->addShape(9, 0);
+ alignment140664475504720->addShape(77, 0);
+ alignment140664475504720->addShape(87, 0);
+ alignment140664475504720->addShape(88, 0);
+ ccs.push_back(alignment140664475504720);
+
+ AlignmentConstraint *alignment140664483418000 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664483418000->addShape(10, 0);
+ alignment140664483418000->addShape(11, 0);
+ ccs.push_back(alignment140664483418000);
+
+ AlignmentConstraint *alignment140664483418368 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664483418368->addShape(11, 0);
+ ccs.push_back(alignment140664483418368);
+
+ AlignmentConstraint *alignment140664483418496 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664483418496->addShape(12, 0);
+ ccs.push_back(alignment140664483418496);
+
+ AlignmentConstraint *alignment140664483418656 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664483418656->addShape(13, 0);
+ alignment140664483418656->addShape(68, 0);
+ ccs.push_back(alignment140664483418656);
+
+ AlignmentConstraint *alignment140664483418880 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664483418880->addShape(14, 0);
+ ccs.push_back(alignment140664483418880);
+
+ AlignmentConstraint *alignment140664483419008 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664483419008->addShape(16, 0);
+ alignment140664483419008->addShape(18, 0);
+ alignment140664483419008->addShape(19, 0);
+ alignment140664483419008->addShape(26, 0);
+ alignment140664483419008->addShape(27, 0);
+ alignment140664483419008->addShape(41, 0);
+ alignment140664483419008->addShape(49, 0);
+ alignment140664483419008->addShape(50, 0);
+ alignment140664483419008->addShape(55, 0);
+ alignment140664483419008->addShape(56, 0);
+ alignment140664483419008->addShape(57, 0);
+ alignment140664483419008->addShape(58, 0);
+ alignment140664483419008->addShape(59, 0);
+ alignment140664483419008->addShape(63, 0);
+ alignment140664483419008->addShape(69, 0);
+ alignment140664483419008->addShape(89, 0);
+ ccs.push_back(alignment140664483419008);
+
+ AlignmentConstraint *alignment140664476991552 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476991552->addShape(18, 0);
+ alignment140664476991552->addShape(19, 0);
+ alignment140664476991552->addShape(26, 0);
+ alignment140664476991552->addShape(27, 0);
+ alignment140664476991552->addShape(41, 0);
+ alignment140664476991552->addShape(49, 0);
+ alignment140664476991552->addShape(50, 0);
+ alignment140664476991552->addShape(55, 0);
+ alignment140664476991552->addShape(56, 0);
+ alignment140664476991552->addShape(57, 0);
+ alignment140664476991552->addShape(58, 0);
+ alignment140664476991552->addShape(59, 0);
+ alignment140664476991552->addShape(63, 0);
+ alignment140664476991552->addShape(69, 0);
+ alignment140664476991552->addShape(89, 0);
+ ccs.push_back(alignment140664476991552);
+
+ AlignmentConstraint *alignment140664476992272 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476992272->addShape(19, 0);
+ alignment140664476992272->addShape(26, 0);
+ alignment140664476992272->addShape(27, 0);
+ alignment140664476992272->addShape(41, 0);
+ alignment140664476992272->addShape(49, 0);
+ alignment140664476992272->addShape(50, 0);
+ alignment140664476992272->addShape(55, 0);
+ alignment140664476992272->addShape(56, 0);
+ alignment140664476992272->addShape(57, 0);
+ alignment140664476992272->addShape(58, 0);
+ alignment140664476992272->addShape(59, 0);
+ alignment140664476992272->addShape(63, 0);
+ alignment140664476992272->addShape(69, 0);
+ alignment140664476992272->addShape(89, 0);
+ ccs.push_back(alignment140664476992272);
+
+ AlignmentConstraint *alignment140664476992960 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476992960->addShape(20, 0);
+ alignment140664476992960->addShape(23, 0);
+ ccs.push_back(alignment140664476992960);
+
+ AlignmentConstraint *alignment140664476993456 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476993456->addShape(22, 0);
+ ccs.push_back(alignment140664476993456);
+
+ AlignmentConstraint *alignment140664476993584 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476993584->addShape(23, 0);
+ ccs.push_back(alignment140664476993584);
+
+ AlignmentConstraint *alignment140664476993744 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476993744->addShape(24, 0);
+ ccs.push_back(alignment140664476993744);
+
+ AlignmentConstraint *alignment140664476993904 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476993904->addShape(25, 0);
+ alignment140664476993904->addShape(62, 0);
+ ccs.push_back(alignment140664476993904);
+
+ AlignmentConstraint *alignment140664476994128 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476994128->addShape(26, 0);
+ alignment140664476994128->addShape(27, 0);
+ alignment140664476994128->addShape(41, 0);
+ alignment140664476994128->addShape(49, 0);
+ alignment140664476994128->addShape(50, 0);
+ alignment140664476994128->addShape(55, 0);
+ alignment140664476994128->addShape(56, 0);
+ alignment140664476994128->addShape(57, 0);
+ alignment140664476994128->addShape(58, 0);
+ alignment140664476994128->addShape(59, 0);
+ alignment140664476994128->addShape(63, 0);
+ alignment140664476994128->addShape(69, 0);
+ alignment140664476994128->addShape(89, 0);
+ ccs.push_back(alignment140664476994128);
+
+ AlignmentConstraint *alignment140664476994608 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476994608->addShape(27, 0);
+ alignment140664476994608->addShape(41, 0);
+ alignment140664476994608->addShape(49, 0);
+ alignment140664476994608->addShape(50, 0);
+ alignment140664476994608->addShape(55, 0);
+ alignment140664476994608->addShape(56, 0);
+ alignment140664476994608->addShape(57, 0);
+ alignment140664476994608->addShape(58, 0);
+ alignment140664476994608->addShape(59, 0);
+ alignment140664476994608->addShape(63, 0);
+ alignment140664476994608->addShape(69, 0);
+ alignment140664476994608->addShape(89, 0);
+ ccs.push_back(alignment140664476994608);
+
+ AlignmentConstraint *alignment140664476995232 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476995232->addShape(28, 0);
+ ccs.push_back(alignment140664476995232);
+
+ AlignmentConstraint *alignment140664476995392 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476995392->addShape(29, 0);
+ alignment140664476995392->addShape(30, 0);
+ alignment140664476995392->addShape(34, 0);
+ alignment140664476995392->addShape(35, 0);
+ ccs.push_back(alignment140664476995392);
+
+ AlignmentConstraint *alignment140664476995616 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476995616->addShape(30, 0);
+ alignment140664476995616->addShape(34, 0);
+ alignment140664476995616->addShape(35, 0);
+ ccs.push_back(alignment140664476995616);
+
+ AlignmentConstraint *alignment140664476995888 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476995888->addShape(31, 0);
+ ccs.push_back(alignment140664476995888);
+
+ AlignmentConstraint *alignment140664476996016 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476996016->addShape(32, 0);
+ ccs.push_back(alignment140664476996016);
+
+ AlignmentConstraint *alignment140664476996176 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476996176->addShape(33, 0);
+ alignment140664476996176->addShape(44, 0);
+ alignment140664476996176->addShape(45, 0);
+ alignment140664476996176->addShape(51, 0);
+ alignment140664476996176->addShape(52, 0);
+ ccs.push_back(alignment140664476996176);
+
+ AlignmentConstraint *alignment140664476996480 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476996480->addShape(34, 0);
+ alignment140664476996480->addShape(35, 0);
+ ccs.push_back(alignment140664476996480);
+
+ AlignmentConstraint *alignment140664476996704 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476996704->addShape(35, 0);
+ ccs.push_back(alignment140664476996704);
+
+ AlignmentConstraint *alignment140664476996832 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476996832->addShape(36, 0);
+ alignment140664476996832->addShape(61, 0);
+ ccs.push_back(alignment140664476996832);
+
+ AlignmentConstraint *alignment140664476997056 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476997056->addShape(37, 0);
+ alignment140664476997056->addShape(38, 0);
+ ccs.push_back(alignment140664476997056);
+
+ AlignmentConstraint *alignment140664476993184 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476993184->addShape(38, 0);
+ ccs.push_back(alignment140664476993184);
+
+ AlignmentConstraint *alignment140664476993312 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476993312->addShape(40, 0);
+ ccs.push_back(alignment140664476993312);
+
+ AlignmentConstraint *alignment140664476997808 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476997808->addShape(41, 0);
+ alignment140664476997808->addShape(49, 0);
+ alignment140664476997808->addShape(50, 0);
+ alignment140664476997808->addShape(55, 0);
+ alignment140664476997808->addShape(56, 0);
+ alignment140664476997808->addShape(57, 0);
+ alignment140664476997808->addShape(58, 0);
+ alignment140664476997808->addShape(59, 0);
+ alignment140664476997808->addShape(63, 0);
+ alignment140664476997808->addShape(69, 0);
+ alignment140664476997808->addShape(89, 0);
+ ccs.push_back(alignment140664476997808);
+
+ AlignmentConstraint *alignment140664476998480 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476998480->addShape(42, 0);
+ alignment140664476998480->addShape(43, 0);
+ alignment140664476998480->addShape(92, 0);
+ alignment140664476998480->addShape(93, 0);
+ ccs.push_back(alignment140664476998480);
+
+ AlignmentConstraint *alignment140664476998704 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476998704->addShape(43, 0);
+ alignment140664476998704->addShape(92, 0);
+ alignment140664476998704->addShape(93, 0);
+ ccs.push_back(alignment140664476998704);
+
+ AlignmentConstraint *alignment140664476998976 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476998976->addShape(44, 0);
+ alignment140664476998976->addShape(45, 0);
+ alignment140664476998976->addShape(51, 0);
+ alignment140664476998976->addShape(52, 0);
+ ccs.push_back(alignment140664476998976);
+
+ AlignmentConstraint *alignment140664476999216 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476999216->addShape(45, 0);
+ alignment140664476999216->addShape(51, 0);
+ alignment140664476999216->addShape(52, 0);
+ ccs.push_back(alignment140664476999216);
+
+ AlignmentConstraint *alignment140664476999488 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476999488->addShape(46, 0);
+ alignment140664476999488->addShape(47, 0);
+ alignment140664476999488->addShape(84, 0);
+ ccs.push_back(alignment140664476999488);
+
+ AlignmentConstraint *alignment140664476999728 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476999728->addShape(47, 0);
+ alignment140664476999728->addShape(84, 0);
+ ccs.push_back(alignment140664476999728);
+
+ AlignmentConstraint *alignment140664476999920 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476999920->addShape(48, 0);
+ ccs.push_back(alignment140664476999920);
+
+ AlignmentConstraint *alignment140664477000048 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477000048->addShape(49, 0);
+ alignment140664477000048->addShape(50, 0);
+ alignment140664477000048->addShape(55, 0);
+ alignment140664477000048->addShape(56, 0);
+ alignment140664477000048->addShape(57, 0);
+ alignment140664477000048->addShape(58, 0);
+ alignment140664477000048->addShape(59, 0);
+ alignment140664477000048->addShape(63, 0);
+ alignment140664477000048->addShape(69, 0);
+ alignment140664477000048->addShape(89, 0);
+ ccs.push_back(alignment140664477000048);
+
+ AlignmentConstraint *alignment140664477000656 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477000656->addShape(50, 0);
+ alignment140664477000656->addShape(55, 0);
+ alignment140664477000656->addShape(56, 0);
+ alignment140664477000656->addShape(57, 0);
+ alignment140664477000656->addShape(58, 0);
+ alignment140664477000656->addShape(59, 0);
+ alignment140664477000656->addShape(63, 0);
+ alignment140664477000656->addShape(69, 0);
+ alignment140664477000656->addShape(89, 0);
+ ccs.push_back(alignment140664477000656);
+
+ AlignmentConstraint *alignment140664477001184 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477001184->addShape(51, 0);
+ alignment140664477001184->addShape(52, 0);
+ ccs.push_back(alignment140664477001184);
+
+ AlignmentConstraint *alignment140664477001408 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477001408->addShape(52, 0);
+ ccs.push_back(alignment140664477001408);
+
+ AlignmentConstraint *alignment140664477001536 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477001536->addShape(53, 0);
+ alignment140664477001536->addShape(54, 0);
+ ccs.push_back(alignment140664477001536);
+
+ AlignmentConstraint *alignment140664477001760 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477001760->addShape(54, 0);
+ ccs.push_back(alignment140664477001760);
+
+ AlignmentConstraint *alignment140664477001888 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477001888->addShape(55, 0);
+ alignment140664477001888->addShape(56, 0);
+ alignment140664477001888->addShape(57, 0);
+ alignment140664477001888->addShape(58, 0);
+ alignment140664477001888->addShape(59, 0);
+ alignment140664477001888->addShape(63, 0);
+ alignment140664477001888->addShape(69, 0);
+ alignment140664477001888->addShape(89, 0);
+ ccs.push_back(alignment140664477001888);
+
+ AlignmentConstraint *alignment140664477002240 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477002240->addShape(56, 0);
+ alignment140664477002240->addShape(57, 0);
+ alignment140664477002240->addShape(58, 0);
+ alignment140664477002240->addShape(59, 0);
+ alignment140664477002240->addShape(63, 0);
+ alignment140664477002240->addShape(69, 0);
+ alignment140664477002240->addShape(89, 0);
+ ccs.push_back(alignment140664477002240);
+
+ AlignmentConstraint *alignment140664477002640 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477002640->addShape(57, 0);
+ alignment140664477002640->addShape(58, 0);
+ alignment140664477002640->addShape(59, 0);
+ alignment140664477002640->addShape(63, 0);
+ alignment140664477002640->addShape(69, 0);
+ alignment140664477002640->addShape(89, 0);
+ ccs.push_back(alignment140664477002640);
+
+ AlignmentConstraint *alignment140664477003008 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477003008->addShape(58, 0);
+ alignment140664477003008->addShape(59, 0);
+ alignment140664477003008->addShape(63, 0);
+ alignment140664477003008->addShape(69, 0);
+ alignment140664477003008->addShape(89, 0);
+ ccs.push_back(alignment140664477003008);
+
+ AlignmentConstraint *alignment140664477003344 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477003344->addShape(59, 0);
+ alignment140664477003344->addShape(63, 0);
+ alignment140664477003344->addShape(69, 0);
+ alignment140664477003344->addShape(89, 0);
+ ccs.push_back(alignment140664477003344);
+
+ AlignmentConstraint *alignment140664477003568 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477003568->addShape(60, 0);
+ ccs.push_back(alignment140664477003568);
+
+ AlignmentConstraint *alignment140664477003728 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477003728->addShape(61, 0);
+ ccs.push_back(alignment140664477003728);
+
+ AlignmentConstraint *alignment140664477003888 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477003888->addShape(62, 0);
+ ccs.push_back(alignment140664477003888);
+
+ AlignmentConstraint *alignment140664477004048 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477004048->addShape(63, 0);
+ alignment140664477004048->addShape(69, 0);
+ alignment140664477004048->addShape(89, 0);
+ ccs.push_back(alignment140664477004048);
+
+ AlignmentConstraint *alignment140664477004320 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477004320->addShape(64, 0);
+ alignment140664477004320->addShape(66, 0);
+ alignment140664477004320->addShape(74, 0);
+ ccs.push_back(alignment140664477004320);
+
+ AlignmentConstraint *alignment140664477004560 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477004560->addShape(65, 0);
+ alignment140664477004560->addShape(76, 0);
+ ccs.push_back(alignment140664477004560);
+
+ AlignmentConstraint *alignment140664477004752 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477004752->addShape(66, 0);
+ alignment140664477004752->addShape(74, 0);
+ ccs.push_back(alignment140664477004752);
+
+ AlignmentConstraint *alignment140664477004944 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477004944->addShape(67, 0);
+ ccs.push_back(alignment140664477004944);
+
+ AlignmentConstraint *alignment140664477005072 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477005072->addShape(68, 0);
+ ccs.push_back(alignment140664477005072);
+
+ AlignmentConstraint *alignment140664477005232 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477005232->addShape(69, 0);
+ alignment140664477005232->addShape(89, 0);
+ ccs.push_back(alignment140664477005232);
+
+ AlignmentConstraint *alignment140664477005456 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477005456->addShape(70, 0);
+ alignment140664477005456->addShape(73, 0);
+ ccs.push_back(alignment140664477005456);
+
+ AlignmentConstraint *alignment140664477005648 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664477005648->addShape(71, 0);
+ alignment140664477005648->addShape(72, 0);
+ ccs.push_back(alignment140664477005648);
+
+ AlignmentConstraint *alignment140664476997248 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476997248->addShape(72, 0);
+ ccs.push_back(alignment140664476997248);
+
+ AlignmentConstraint *alignment140664476997376 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476997376->addShape(73, 0);
+ ccs.push_back(alignment140664476997376);
+
+ AlignmentConstraint *alignment140664476997536 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664476997536->addShape(74, 0);
+ ccs.push_back(alignment140664476997536);
+
+ AlignmentConstraint *alignment140664475640112 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475640112->addShape(76, 0);
+ ccs.push_back(alignment140664475640112);
+
+ AlignmentConstraint *alignment140664475640272 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475640272->addShape(77, 0);
+ alignment140664475640272->addShape(87, 0);
+ alignment140664475640272->addShape(88, 0);
+ ccs.push_back(alignment140664475640272);
+
+ AlignmentConstraint *alignment140664475640544 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475640544->addShape(78, 0);
+ ccs.push_back(alignment140664475640544);
+
+ AlignmentConstraint *alignment140664475640672 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475640672->addShape(79, 0);
+ ccs.push_back(alignment140664475640672);
+
+ AlignmentConstraint *alignment140664475640832 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475640832->addShape(81, 0);
+ alignment140664475640832->addShape(91, 0);
+ ccs.push_back(alignment140664475640832);
+
+ AlignmentConstraint *alignment140664475641056 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475641056->addShape(82, 0);
+ ccs.push_back(alignment140664475641056);
+
+ AlignmentConstraint *alignment140664475641184 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475641184->addShape(83, 0);
+ ccs.push_back(alignment140664475641184);
+
+ AlignmentConstraint *alignment140664475641344 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475641344->addShape(84, 0);
+ ccs.push_back(alignment140664475641344);
+
+ AlignmentConstraint *alignment140664475641504 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475641504->addShape(85, 0);
+ ccs.push_back(alignment140664475641504);
+
+ AlignmentConstraint *alignment140664475641664 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475641664->addShape(86, 0);
+ ccs.push_back(alignment140664475641664);
+
+ AlignmentConstraint *alignment140664475641824 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475641824->addShape(87, 0);
+ alignment140664475641824->addShape(88, 0);
+ ccs.push_back(alignment140664475641824);
+
+ AlignmentConstraint *alignment140664475642048 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475642048->addShape(88, 0);
+ ccs.push_back(alignment140664475642048);
+
+ AlignmentConstraint *alignment140664475642176 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475642176->addShape(89, 0);
+ ccs.push_back(alignment140664475642176);
+
+ AlignmentConstraint *alignment140664475642336 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475642336->addShape(90, 0);
+ ccs.push_back(alignment140664475642336);
+
+ AlignmentConstraint *alignment140664475642496 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475642496->addShape(91, 0);
+ ccs.push_back(alignment140664475642496);
+
+ AlignmentConstraint *alignment140664475642656 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475642656->addShape(92, 0);
+ alignment140664475642656->addShape(93, 0);
+ ccs.push_back(alignment140664475642656);
+
+ AlignmentConstraint *alignment140664475642880 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475642880->addShape(93, 0);
+ ccs.push_back(alignment140664475642880);
+
+ SeparationConstraint *separation140664475644192 = new SeparationConstraint(vpsc::XDIM, alignment140664475642336, alignment140664476997376, 36, false);
+ ccs.push_back(separation140664475644192);
+
+ SeparationConstraint *separation140664481097840 = new SeparationConstraint(vpsc::XDIM, alignment140664476997376, alignment140664475640112, 14, false);
+ ccs.push_back(separation140664481097840);
+
+ SeparationConstraint *separation140664476990640 = new SeparationConstraint(vpsc::XDIM, alignment140664475640112, alignment140664477001408, 35, false);
+ ccs.push_back(separation140664476990640);
+
+ SeparationConstraint *separation140664481098032 = new SeparationConstraint(vpsc::XDIM, alignment140664477001408, alignment140664475640544, 23, false);
+ ccs.push_back(separation140664481098032);
+
+ SeparationConstraint *separation140664481098176 = new SeparationConstraint(vpsc::XDIM, alignment140664475640544, alignment140664483418656, 7, false);
+ ccs.push_back(separation140664481098176);
+
+ SeparationConstraint *separation140664481098320 = new SeparationConstraint(vpsc::XDIM, alignment140664477005072, alignment140664476996704, 21, false);
+ ccs.push_back(separation140664481098320);
+
+ SeparationConstraint *separation140664481098496 = new SeparationConstraint(vpsc::XDIM, alignment140664476996704, alignment140664476997248, 6, false);
+ ccs.push_back(separation140664481098496);
+
+ SeparationConstraint *separation140664481098672 = new SeparationConstraint(vpsc::XDIM, alignment140664476997248, alignment140664476993312, 23, false);
+ ccs.push_back(separation140664481098672);
+
+ SeparationConstraint *separation140664476989584 = new SeparationConstraint(vpsc::XDIM, alignment140664476993312, alignment140664477004944, 3, false);
+ ccs.push_back(separation140664476989584);
+
+ SeparationConstraint *separation140664476989760 = new SeparationConstraint(vpsc::XDIM, alignment140664477004944, alignment140664475642880, 16, false);
+ ccs.push_back(separation140664476989760);
+
+ SeparationConstraint *separation140664476989936 = new SeparationConstraint(vpsc::XDIM, alignment140664475642880, alignment140664475641344, 8, false);
+ ccs.push_back(separation140664476989936);
+
+ SeparationConstraint *separation140664476990112 = new SeparationConstraint(vpsc::XDIM, alignment140664476999488, alignment140664476996016, 16.6667, false);
+ ccs.push_back(separation140664476990112);
+
+ SeparationConstraint *separation140664476990288 = new SeparationConstraint(vpsc::XDIM, alignment140664476996016, alignment140664477003728, 7, false);
+ ccs.push_back(separation140664476990288);
+
+ SeparationConstraint *separation140664476990464 = new SeparationConstraint(vpsc::XDIM, alignment140664476996832, alignment140664483418496, 4, false);
+ ccs.push_back(separation140664476990464);
+
+ SeparationConstraint *separation140664475645632 = new SeparationConstraint(vpsc::XDIM, alignment140664483418496, alignment140664477001760, 13, false);
+ ccs.push_back(separation140664475645632);
+
+ SeparationConstraint *separation140664475645808 = new SeparationConstraint(vpsc::XDIM, alignment140664477001760, alignment140664476993184, 11, false);
+ ccs.push_back(separation140664475645808);
+
+ SeparationConstraint *separation140664475645984 = new SeparationConstraint(vpsc::XDIM, alignment140664476993184, alignment140664476995888, 14, false);
+ ccs.push_back(separation140664475645984);
+
+ SeparationConstraint *separation140664475646160 = new SeparationConstraint(vpsc::XDIM, alignment140664476995888, alignment140664476997536, 21, false);
+ ccs.push_back(separation140664475646160);
+
+ SeparationConstraint *separation140664475646336 = new SeparationConstraint(vpsc::XDIM, alignment140664476997536, alignment140664476995232, 7, false);
+ ccs.push_back(separation140664475646336);
+
+ SeparationConstraint *separation140664475646512 = new SeparationConstraint(vpsc::XDIM, alignment140664476995232, alignment140664475641664, 13, false);
+ ccs.push_back(separation140664475646512);
+
+ SeparationConstraint *separation140664475646688 = new SeparationConstraint(vpsc::XDIM, alignment140664475641664, alignment140664476993456, 5, false);
+ ccs.push_back(separation140664475646688);
+
+ SeparationConstraint *separation140664475646864 = new SeparationConstraint(vpsc::XDIM, alignment140664476993456, alignment140664476993744, 5, false);
+ ccs.push_back(separation140664475646864);
+
+ SeparationConstraint *separation140664475647040 = new SeparationConstraint(vpsc::XDIM, alignment140664476993744, alignment140664483418368, 23, false);
+ ccs.push_back(separation140664475647040);
+
+ SeparationConstraint *separation140664475647216 = new SeparationConstraint(vpsc::XDIM, alignment140664483418368, alignment140664475641824, 6.5, false);
+ ccs.push_back(separation140664475647216);
+
+ SeparationConstraint *separation140664475647392 = new SeparationConstraint(vpsc::XDIM, alignment140664475504720, alignment140664476993584, 19.75, false);
+ ccs.push_back(separation140664475647392);
+
+ SeparationConstraint *separation140664475647568 = new SeparationConstraint(vpsc::XDIM, alignment140664476993584, alignment140664475642176, 25, false);
+ ccs.push_back(separation140664475647568);
+
+ SeparationConstraint *separation140664475647744 = new SeparationConstraint(vpsc::XDIM, alignment140664475642176, alignment140664475640672, 4, false);
+ ccs.push_back(separation140664475647744);
+
+ SeparationConstraint *separation140664475647920 = new SeparationConstraint(vpsc::XDIM, alignment140664475640672, alignment140664475642496, 21, false);
+ ccs.push_back(separation140664475647920);
+
+ SeparationConstraint *separation140664475648096 = new SeparationConstraint(vpsc::XDIM, alignment140664475642496, alignment140664475641504, 24, false);
+ ccs.push_back(separation140664475648096);
+
+ SeparationConstraint *separation140664475648272 = new SeparationConstraint(vpsc::XDIM, alignment140664475641504, alignment140664477003888, 18, false);
+ ccs.push_back(separation140664475648272);
+
+ SeparationConstraint *separation140664475648448 = new SeparationConstraint(vpsc::XDIM, alignment140664476993904, alignment140664475641184, 4, false);
+ ccs.push_back(separation140664475648448);
+
+ SeparationConstraint *separation140664475648624 = new SeparationConstraint(vpsc::XDIM, alignment140664475641184, alignment140664483418880, 3, false);
+ ccs.push_back(separation140664475648624);
+
+ SeparationConstraint *separation140664475648800 = new SeparationConstraint(vpsc::XDIM, alignment140664483418880, alignment140664475641056, 24, false);
+ ccs.push_back(separation140664475648800);
+
+ SeparationConstraint *separation140664475648976 = new SeparationConstraint(vpsc::XDIM, alignment140664475641056, alignment140664476999920, 19, false);
+ ccs.push_back(separation140664475648976);
+
+ SeparationConstraint *separation140664475649152 = new SeparationConstraint(vpsc::XDIM, alignment140664476999920, alignment140664477003568, 26, false);
+ ccs.push_back(separation140664475649152);
+
+ AlignmentConstraint *alignment140664475649328 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475649328->addShape(0, 0);
+ ccs.push_back(alignment140664475649328);
+
+ AlignmentConstraint *alignment140664475649488 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475649488->addShape(1, 0);
+ alignment140664475649488->addShape(8, 0);
+ alignment140664475649488->addShape(9, 0);
+ ccs.push_back(alignment140664475649488);
+
+ AlignmentConstraint *alignment140664475649760 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475649760->addShape(2, 0);
+ alignment140664475649760->addShape(7, 0);
+ alignment140664475649760->addShape(90, 0);
+ ccs.push_back(alignment140664475649760);
+
+ AlignmentConstraint *alignment140664475650000 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475650000->addShape(3, 0);
+ alignment140664475650000->addShape(77, 0);
+ alignment140664475650000->addShape(79, 0);
+ ccs.push_back(alignment140664475650000);
+
+ AlignmentConstraint *alignment140664475650240 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475650240->addShape(4, 0);
+ alignment140664475650240->addShape(62, 0);
+ alignment140664475650240->addShape(66, 0);
+ ccs.push_back(alignment140664475650240);
+
+ AlignmentConstraint *alignment140664475650480 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475650480->addShape(7, 0);
+ alignment140664475650480->addShape(90, 0);
+ ccs.push_back(alignment140664475650480);
+
+ AlignmentConstraint *alignment140664475650672 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475650672->addShape(8, 0);
+ alignment140664475650672->addShape(9, 0);
+ ccs.push_back(alignment140664475650672);
+
+ AlignmentConstraint *alignment140664475650864 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475650864->addShape(9, 0);
+ ccs.push_back(alignment140664475650864);
+
+ AlignmentConstraint *alignment140664475639072 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475639072->addShape(10, 0);
+ ccs.push_back(alignment140664475639072);
+
+ AlignmentConstraint *alignment140664475639232 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475639232->addShape(11, 0);
+ ccs.push_back(alignment140664475639232);
+
+ AlignmentConstraint *alignment140664475639392 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475639392->addShape(12, 0);
+ alignment140664475639392->addShape(13, 0);
+ alignment140664475639392->addShape(14, 0);
+ alignment140664475639392->addShape(60, 0);
+ alignment140664475639392->addShape(63, 0);
+ alignment140664475639392->addShape(64, 0);
+ alignment140664475639392->addShape(65, 0);
+ alignment140664475639392->addShape(67, 0);
+ ccs.push_back(alignment140664475639392);
+
+ AlignmentConstraint *alignment140664475639872 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475639872->addShape(13, 0);
+ alignment140664475639872->addShape(14, 0);
+ alignment140664475639872->addShape(60, 0);
+ alignment140664475639872->addShape(63, 0);
+ alignment140664475639872->addShape(64, 0);
+ alignment140664475639872->addShape(65, 0);
+ alignment140664475639872->addShape(67, 0);
+ ccs.push_back(alignment140664475639872);
+
+ AlignmentConstraint *alignment140664475653264 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475653264->addShape(14, 0);
+ alignment140664475653264->addShape(60, 0);
+ alignment140664475653264->addShape(63, 0);
+ alignment140664475653264->addShape(64, 0);
+ alignment140664475653264->addShape(65, 0);
+ alignment140664475653264->addShape(67, 0);
+ ccs.push_back(alignment140664475653264);
+
+ AlignmentConstraint *alignment140664475653632 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475653632->addShape(16, 0);
+ ccs.push_back(alignment140664475653632);
+
+ AlignmentConstraint *alignment140664475653792 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475653792->addShape(18, 0);
+ ccs.push_back(alignment140664475653792);
+
+ AlignmentConstraint *alignment140664475653952 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475653952->addShape(19, 0);
+ ccs.push_back(alignment140664475653952);
+
+ AlignmentConstraint *alignment140664475654112 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475654112->addShape(20, 0);
+ alignment140664475654112->addShape(81, 0);
+ ccs.push_back(alignment140664475654112);
+
+ AlignmentConstraint *alignment140664475654336 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475654336->addShape(22, 0);
+ alignment140664475654336->addShape(53, 0);
+ alignment140664475654336->addShape(89, 0);
+ ccs.push_back(alignment140664475654336);
+
+ AlignmentConstraint *alignment140664475654528 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475654528->addShape(23, 0);
+ alignment140664475654528->addShape(24, 0);
+ alignment140664475654528->addShape(91, 0);
+ ccs.push_back(alignment140664475654528);
+
+ AlignmentConstraint *alignment140664475654720 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475654720->addShape(24, 0);
+ alignment140664475654720->addShape(91, 0);
+ ccs.push_back(alignment140664475654720);
+
+ AlignmentConstraint *alignment140664475654912 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475654912->addShape(25, 0);
+ alignment140664475654912->addShape(48, 0);
+ ccs.push_back(alignment140664475654912);
+
+ AlignmentConstraint *alignment140664475655104 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475655104->addShape(26, 0);
+ alignment140664475655104->addShape(31, 0);
+ alignment140664475655104->addShape(32, 0);
+ alignment140664475655104->addShape(33, 0);
+ ccs.push_back(alignment140664475655104);
+
+ AlignmentConstraint *alignment140664475655344 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475655344->addShape(27, 0);
+ ccs.push_back(alignment140664475655344);
+
+ AlignmentConstraint *alignment140664475655504 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475655504->addShape(28, 0);
+ alignment140664475655504->addShape(52, 0);
+ alignment140664475655504->addShape(54, 0);
+ alignment140664475655504->addShape(56, 0);
+ ccs.push_back(alignment140664475655504);
+
+ AlignmentConstraint *alignment140664475655776 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475655776->addShape(29, 0);
+ alignment140664475655776->addShape(43, 0);
+ ccs.push_back(alignment140664475655776);
+
+ AlignmentConstraint *alignment140664475656000 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475656000->addShape(30, 0);
+ alignment140664475656000->addShape(93, 0);
+ ccs.push_back(alignment140664475656000);
+
+ AlignmentConstraint *alignment140664475656192 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475656192->addShape(31, 0);
+ alignment140664475656192->addShape(32, 0);
+ alignment140664475656192->addShape(33, 0);
+ ccs.push_back(alignment140664475656192);
+
+ AlignmentConstraint *alignment140664475656432 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475656432->addShape(32, 0);
+ alignment140664475656432->addShape(33, 0);
+ ccs.push_back(alignment140664475656432);
+
+ AlignmentConstraint *alignment140664475656624 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475656624->addShape(33, 0);
+ ccs.push_back(alignment140664475656624);
+
+ AlignmentConstraint *alignment140664475656752 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475656752->addShape(34, 0);
+ alignment140664475656752->addShape(92, 0);
+ ccs.push_back(alignment140664475656752);
+
+ AlignmentConstraint *alignment140664475656976 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475656976->addShape(35, 0);
+ alignment140664475656976->addShape(42, 0);
+ ccs.push_back(alignment140664475656976);
+
+ AlignmentConstraint *alignment140664475657168 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475657168->addShape(36, 0);
+ ccs.push_back(alignment140664475657168);
+
+ AlignmentConstraint *alignment140664475657296 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475657296->addShape(37, 0);
+ ccs.push_back(alignment140664475657296);
+
+ AlignmentConstraint *alignment140664475657456 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475657456->addShape(38, 0);
+ ccs.push_back(alignment140664475657456);
+
+ AlignmentConstraint *alignment140664475657616 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475657616->addShape(40, 0);
+ alignment140664475657616->addShape(61, 0);
+ alignment140664475657616->addShape(68, 0);
+ ccs.push_back(alignment140664475657616);
+
+ AlignmentConstraint *alignment140664475657888 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475657888->addShape(41, 0);
+ alignment140664475657888->addShape(86, 0);
+ ccs.push_back(alignment140664475657888);
+
+ AlignmentConstraint *alignment140664475658080 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475658080->addShape(42, 0);
+ ccs.push_back(alignment140664475658080);
+
+ AlignmentConstraint *alignment140664475658208 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475658208->addShape(43, 0);
+ ccs.push_back(alignment140664475658208);
+
+ AlignmentConstraint *alignment140664475658368 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475658368->addShape(44, 0);
+ alignment140664475658368->addShape(46, 0);
+ alignment140664475658368->addShape(70, 0);
+ alignment140664475658368->addShape(71, 0);
+ ccs.push_back(alignment140664475658368);
+
+ AlignmentConstraint *alignment140664475658640 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475658640->addShape(45, 0);
+ alignment140664475658640->addShape(47, 0);
+ alignment140664475658640->addShape(72, 0);
+ alignment140664475658640->addShape(73, 0);
+ ccs.push_back(alignment140664475658640);
+
+ AlignmentConstraint *alignment140664475658912 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475658912->addShape(46, 0);
+ alignment140664475658912->addShape(70, 0);
+ alignment140664475658912->addShape(71, 0);
+ ccs.push_back(alignment140664475658912);
+
+ AlignmentConstraint *alignment140664475659184 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475659184->addShape(47, 0);
+ alignment140664475659184->addShape(72, 0);
+ alignment140664475659184->addShape(73, 0);
+ ccs.push_back(alignment140664475659184);
+
+ AlignmentConstraint *alignment140664475659424 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475659424->addShape(48, 0);
+ ccs.push_back(alignment140664475659424);
+
+ AlignmentConstraint *alignment140664475659552 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475659552->addShape(49, 0);
+ ccs.push_back(alignment140664475659552);
+
+ AlignmentConstraint *alignment140664475659712 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475659712->addShape(50, 0);
+ ccs.push_back(alignment140664475659712);
+
+ AlignmentConstraint *alignment140664475659872 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475659872->addShape(51, 0);
+ alignment140664475659872->addShape(55, 0);
+ ccs.push_back(alignment140664475659872);
+
+ AlignmentConstraint *alignment140664475660096 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475660096->addShape(52, 0);
+ alignment140664475660096->addShape(54, 0);
+ alignment140664475660096->addShape(56, 0);
+ ccs.push_back(alignment140664475660096);
+
+ AlignmentConstraint *alignment140664475660336 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475660336->addShape(53, 0);
+ alignment140664475660336->addShape(89, 0);
+ ccs.push_back(alignment140664475660336);
+
+ AlignmentConstraint *alignment140664475660528 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475660528->addShape(54, 0);
+ alignment140664475660528->addShape(56, 0);
+ ccs.push_back(alignment140664475660528);
+
+ AlignmentConstraint *alignment140664475660720 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475660720->addShape(55, 0);
+ ccs.push_back(alignment140664475660720);
+
+ AlignmentConstraint *alignment140664475660848 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475660848->addShape(56, 0);
+ ccs.push_back(alignment140664475660848);
+
+ AlignmentConstraint *alignment140664475661008 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475661008->addShape(57, 0);
+ alignment140664475661008->addShape(76, 0);
+ ccs.push_back(alignment140664475661008);
+
+ AlignmentConstraint *alignment140664475661232 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475661232->addShape(58, 0);
+ ccs.push_back(alignment140664475661232);
+
+ AlignmentConstraint *alignment140664475661360 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475661360->addShape(59, 0);
+ alignment140664475661360->addShape(88, 0);
+ ccs.push_back(alignment140664475661360);
+
+ AlignmentConstraint *alignment140664475661584 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475661584->addShape(60, 0);
+ alignment140664475661584->addShape(63, 0);
+ alignment140664475661584->addShape(64, 0);
+ alignment140664475661584->addShape(65, 0);
+ alignment140664475661584->addShape(67, 0);
+ ccs.push_back(alignment140664475661584);
+
+ AlignmentConstraint *alignment140664475661936 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475661936->addShape(61, 0);
+ alignment140664475661936->addShape(68, 0);
+ ccs.push_back(alignment140664475661936);
+
+ AlignmentConstraint *alignment140664475662160 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475662160->addShape(62, 0);
+ alignment140664475662160->addShape(66, 0);
+ ccs.push_back(alignment140664475662160);
+
+ AlignmentConstraint *alignment140664475662352 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475662352->addShape(63, 0);
+ alignment140664475662352->addShape(64, 0);
+ alignment140664475662352->addShape(65, 0);
+ alignment140664475662352->addShape(67, 0);
+ ccs.push_back(alignment140664475662352);
+
+ AlignmentConstraint *alignment140664475662544 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475662544->addShape(64, 0);
+ alignment140664475662544->addShape(65, 0);
+ alignment140664475662544->addShape(67, 0);
+ ccs.push_back(alignment140664475662544);
+
+ AlignmentConstraint *alignment140664475662816 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475662816->addShape(65, 0);
+ alignment140664475662816->addShape(67, 0);
+ ccs.push_back(alignment140664475662816);
+
+ AlignmentConstraint *alignment140664475663008 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475663008->addShape(66, 0);
+ ccs.push_back(alignment140664475663008);
+
+ AlignmentConstraint *alignment140664475663136 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475663136->addShape(67, 0);
+ ccs.push_back(alignment140664475663136);
+
+ AlignmentConstraint *alignment140664475663296 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475663296->addShape(68, 0);
+ ccs.push_back(alignment140664475663296);
+
+ AlignmentConstraint *alignment140664475663456 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475663456->addShape(69, 0);
+ ccs.push_back(alignment140664475663456);
+
+ AlignmentConstraint *alignment140664475663616 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475663616->addShape(70, 0);
+ alignment140664475663616->addShape(71, 0);
+ ccs.push_back(alignment140664475663616);
+
+ AlignmentConstraint *alignment140664475663840 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475663840->addShape(71, 0);
+ ccs.push_back(alignment140664475663840);
+
+ AlignmentConstraint *alignment140664475663968 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475663968->addShape(72, 0);
+ alignment140664475663968->addShape(73, 0);
+ ccs.push_back(alignment140664475663968);
+
+ AlignmentConstraint *alignment140664475664192 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475664192->addShape(73, 0);
+ ccs.push_back(alignment140664475664192);
+
+ AlignmentConstraint *alignment140664475664320 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475664320->addShape(74, 0);
+ ccs.push_back(alignment140664475664320);
+
+ AlignmentConstraint *alignment140664475664480 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475664480->addShape(76, 0);
+ ccs.push_back(alignment140664475664480);
+
+ AlignmentConstraint *alignment140664475664640 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475664640->addShape(77, 0);
+ alignment140664475664640->addShape(79, 0);
+ ccs.push_back(alignment140664475664640);
+
+ AlignmentConstraint *alignment140664475664864 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475664864->addShape(78, 0);
+ ccs.push_back(alignment140664475664864);
+
+ AlignmentConstraint *alignment140664475664992 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475664992->addShape(79, 0);
+ ccs.push_back(alignment140664475664992);
+
+ AlignmentConstraint *alignment140664475665152 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475665152->addShape(81, 0);
+ ccs.push_back(alignment140664475665152);
+
+ AlignmentConstraint *alignment140664475665312 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475665312->addShape(82, 0);
+ alignment140664475665312->addShape(85, 0);
+ ccs.push_back(alignment140664475665312);
+
+ AlignmentConstraint *alignment140664475665536 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475665536->addShape(83, 0);
+ ccs.push_back(alignment140664475665536);
+
+ AlignmentConstraint *alignment140664475665664 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475665664->addShape(84, 0);
+ ccs.push_back(alignment140664475665664);
+
+ AlignmentConstraint *alignment140664475665824 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475665824->addShape(85, 0);
+ ccs.push_back(alignment140664475665824);
+
+ AlignmentConstraint *alignment140664475665984 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475665984->addShape(86, 0);
+ ccs.push_back(alignment140664475665984);
+
+ AlignmentConstraint *alignment140664475666144 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475666144->addShape(87, 0);
+ ccs.push_back(alignment140664475666144);
+
+ AlignmentConstraint *alignment140664475666304 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475666304->addShape(88, 0);
+ ccs.push_back(alignment140664475666304);
+
+ AlignmentConstraint *alignment140664475666464 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475666464->addShape(89, 0);
+ ccs.push_back(alignment140664475666464);
+
+ AlignmentConstraint *alignment140664475666624 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475666624->addShape(90, 0);
+ ccs.push_back(alignment140664475666624);
+
+ AlignmentConstraint *alignment140664475666784 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475666784->addShape(91, 0);
+ ccs.push_back(alignment140664475666784);
+
+ AlignmentConstraint *alignment140664475666944 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475666944->addShape(92, 0);
+ ccs.push_back(alignment140664475666944);
+
+ AlignmentConstraint *alignment140664475667104 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475667104->addShape(93, 0);
+ ccs.push_back(alignment140664475667104);
+
+ SeparationConstraint *separation140664475667264 = new SeparationConstraint(vpsc::YDIM, alignment140664475657456, alignment140664475659552, 10, false);
+ ccs.push_back(separation140664475667264);
+
+ SeparationConstraint *separation140664475667440 = new SeparationConstraint(vpsc::YDIM, alignment140664475659552, alignment140664475657296, 11, false);
+ ccs.push_back(separation140664475667440);
+
+ SeparationConstraint *separation140664475667616 = new SeparationConstraint(vpsc::YDIM, alignment140664475657296, alignment140664475655344, 19, false);
+ ccs.push_back(separation140664475667616);
+
+ SeparationConstraint *separation140664475667792 = new SeparationConstraint(vpsc::YDIM, alignment140664475655344, alignment140664475657168, 13, false);
+ ccs.push_back(separation140664475667792);
+
+ SeparationConstraint *separation140664475667968 = new SeparationConstraint(vpsc::YDIM, alignment140664475657168, alignment140664475659424, 9, false);
+ ccs.push_back(separation140664475667968);
+
+ SeparationConstraint *separation140664475668144 = new SeparationConstraint(vpsc::YDIM, alignment140664475654912, alignment140664475658080, 22.5, false);
+ ccs.push_back(separation140664475668144);
+
+ SeparationConstraint *separation140664475668320 = new SeparationConstraint(vpsc::YDIM, alignment140664475658080, alignment140664475659872, 11, false);
+ ccs.push_back(separation140664475668320);
+
+ SeparationConstraint *separation140664475668496 = new SeparationConstraint(vpsc::YDIM, alignment140664475660720, alignment140664475666944, 9, false);
+ ccs.push_back(separation140664475668496);
+
+ SeparationConstraint *separation140664475668672 = new SeparationConstraint(vpsc::YDIM, alignment140664475666944, alignment140664475656624, 25, false);
+ ccs.push_back(separation140664475668672);
+
+ SeparationConstraint *separation140664475668848 = new SeparationConstraint(vpsc::YDIM, alignment140664475655104, alignment140664475658208, 26.75, false);
+ ccs.push_back(separation140664475668848);
+
+ SeparationConstraint *separation140664475669024 = new SeparationConstraint(vpsc::YDIM, alignment140664475658208, alignment140664475660096, 10.6667, false);
+ ccs.push_back(separation140664475669024);
+
+ SeparationConstraint *separation140664475669200 = new SeparationConstraint(vpsc::YDIM, alignment140664475660848, alignment140664475667104, 9, false);
+ ccs.push_back(separation140664475669200);
+
+ SeparationConstraint *separation140664475669376 = new SeparationConstraint(vpsc::YDIM, alignment140664475667104, alignment140664475666784, 24, false);
+ ccs.push_back(separation140664475669376);
+
+ SeparationConstraint *separation140664475669552 = new SeparationConstraint(vpsc::YDIM, alignment140664475666784, alignment140664475663840, 23, false);
+ ccs.push_back(separation140664475669552);
+
+ SeparationConstraint *separation140664475669728 = new SeparationConstraint(vpsc::YDIM, alignment140664475658368, alignment140664475663456, 13.75, false);
+ ccs.push_back(separation140664475669728);
+
+ SeparationConstraint *separation140664475669904 = new SeparationConstraint(vpsc::YDIM, alignment140664475663456, alignment140664475664192, 12, false);
+ ccs.push_back(separation140664475669904);
+
+ SeparationConstraint *separation140664475670080 = new SeparationConstraint(vpsc::YDIM, alignment140664475658640, alignment140664475649328, 18.75, false);
+ ccs.push_back(separation140664475670080);
+
+ SeparationConstraint *separation140664475670256 = new SeparationConstraint(vpsc::YDIM, alignment140664475649328, alignment140664475666464, 44, false);
+ ccs.push_back(separation140664475670256);
+
+ SeparationConstraint *separation140664475670432 = new SeparationConstraint(vpsc::YDIM, alignment140664475654336, alignment140664475665152, 35.3333, false);
+ ccs.push_back(separation140664475670432);
+
+ SeparationConstraint *separation140664475670608 = new SeparationConstraint(vpsc::YDIM, alignment140664475665152, alignment140664475661360, 37, false);
+ ccs.push_back(separation140664475670608);
+
+ SeparationConstraint *separation140664475670784 = new SeparationConstraint(vpsc::YDIM, alignment140664475666304, alignment140664475665824, 3, false);
+ ccs.push_back(separation140664475670784);
+
+ SeparationConstraint *separation140664475670960 = new SeparationConstraint(vpsc::YDIM, alignment140664475665824, alignment140664475665536, 19, false);
+ ccs.push_back(separation140664475670960);
+
+ SeparationConstraint *separation140664475671136 = new SeparationConstraint(vpsc::YDIM, alignment140664475665536, alignment140664475665984, 12, false);
+ ccs.push_back(separation140664475671136);
+
+ SeparationConstraint *separation140664475671312 = new SeparationConstraint(vpsc::YDIM, alignment140664475665984, alignment140664475666144, 30, false);
+ ccs.push_back(separation140664475671312);
+
+ SeparationConstraint *separation140664475671488 = new SeparationConstraint(vpsc::YDIM, alignment140664475666144, alignment140664475661232, 6, false);
+ ccs.push_back(separation140664475671488);
+
+ SeparationConstraint *separation140664475671664 = new SeparationConstraint(vpsc::YDIM, alignment140664475661232, alignment140664475653952, 37, false);
+ ccs.push_back(separation140664475671664);
+
+ SeparationConstraint *separation140664475508000 = new SeparationConstraint(vpsc::YDIM, alignment140664475653952, alignment140664475659712, 35, false);
+ ccs.push_back(separation140664475508000);
+
+ SeparationConstraint *separation140664475508176 = new SeparationConstraint(vpsc::YDIM, alignment140664475659712, alignment140664475653792, 37, false);
+ ccs.push_back(separation140664475508176);
+
+ SeparationConstraint *separation140664475508352 = new SeparationConstraint(vpsc::YDIM, alignment140664475653792, alignment140664475664480, 35, false);
+ ccs.push_back(separation140664475508352);
+
+ SeparationConstraint *separation140664475508528 = new SeparationConstraint(vpsc::YDIM, alignment140664475664480, alignment140664475664864, 11, false);
+ ccs.push_back(separation140664475508528);
+
+ SeparationConstraint *separation140664475508704 = new SeparationConstraint(vpsc::YDIM, alignment140664475664864, alignment140664475653632, 23, false);
+ ccs.push_back(separation140664475508704);
+
+ SeparationConstraint *separation140664475508880 = new SeparationConstraint(vpsc::YDIM, alignment140664475653632, alignment140664475665664, 25, false);
+ ccs.push_back(separation140664475508880);
+
+ SeparationConstraint *separation140664475509056 = new SeparationConstraint(vpsc::YDIM, alignment140664475665664, alignment140664475664320, 25, false);
+ ccs.push_back(separation140664475509056);
+
+ SeparationConstraint *separation140664475509232 = new SeparationConstraint(vpsc::YDIM, alignment140664475664320, alignment140664475639232, 33, false);
+ ccs.push_back(separation140664475509232);
+
+ SeparationConstraint *separation140664475509408 = new SeparationConstraint(vpsc::YDIM, alignment140664475639232, alignment140664475663136, 10, false);
+ ccs.push_back(separation140664475509408);
+
+ SeparationConstraint *separation140664475509584 = new SeparationConstraint(vpsc::YDIM, alignment140664475639392, alignment140664475639072, 10.375, false);
+ ccs.push_back(separation140664475509584);
+
+ SeparationConstraint *separation140664475509760 = new SeparationConstraint(vpsc::YDIM, alignment140664475639072, alignment140664475663296, 32, false);
+ ccs.push_back(separation140664475509760);
+
+ SeparationConstraint *separation140664475509936 = new SeparationConstraint(vpsc::YDIM, alignment140664475657616, alignment140664475666624, 4.33333, false);
+ ccs.push_back(separation140664475509936);
+
+ SeparationConstraint *separation140664475510112 = new SeparationConstraint(vpsc::YDIM, alignment140664475650480, alignment140664475650864, 31.5, false);
+ ccs.push_back(separation140664475510112);
+
+ SeparationConstraint *separation140664475510288 = new SeparationConstraint(vpsc::YDIM, alignment140664475650864, alignment140664475663008, 10, false);
+ ccs.push_back(separation140664475510288);
+
+ SeparationConstraint *separation140664475510464 = new SeparationConstraint(vpsc::YDIM, alignment140664475663008, alignment140664475664992, 11, false);
+ ccs.push_back(separation140664475510464);
+
+ AlignmentConstraint *alignment140664475511088 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475511088->addShape(75, 0);
+ alignment140664475511088->addShape(75, 0);
+ ccs.push_back(alignment140664475511088);
+
+ SeparationConstraint *separation140664475511312 = new SeparationConstraint(vpsc::YDIM, 75, 75, -50, true);
+ ccs.push_back(separation140664475511312);
+
+ AlignmentConstraint *alignment140664475511456 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475511456->addShape(0, 0);
+ alignment140664475511456->addShape(94, 0);
+ ccs.push_back(alignment140664475511456);
+
+ SeparationConstraint *separation140664475511680 = new SeparationConstraint(vpsc::XDIM, 0, 94, 62, true);
+ ccs.push_back(separation140664475511680);
+
+ AlignmentConstraint *alignment140664475511824 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475511824->addShape(1, 0);
+ alignment140664475511824->addShape(95, 0);
+ ccs.push_back(alignment140664475511824);
+
+ SeparationConstraint *separation140664475512048 = new SeparationConstraint(vpsc::YDIM, 1, 95, -50, true);
+ ccs.push_back(separation140664475512048);
+
+ AlignmentConstraint *alignment140664475512192 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475512192->addShape(2, 0);
+ alignment140664475512192->addShape(96, 0);
+ ccs.push_back(alignment140664475512192);
+
+ SeparationConstraint *separation140664475512416 = new SeparationConstraint(vpsc::XDIM, 2, 96, 62, true);
+ ccs.push_back(separation140664475512416);
+
+ AlignmentConstraint *alignment140664475512560 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475512560->addShape(3, 0);
+ alignment140664475512560->addShape(97, 0);
+ ccs.push_back(alignment140664475512560);
+
+ SeparationConstraint *separation140664475512784 = new SeparationConstraint(vpsc::YDIM, 3, 97, -50, true);
+ ccs.push_back(separation140664475512784);
+
+ AlignmentConstraint *alignment140664475650992 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475650992->addShape(7, 0);
+ alignment140664475650992->addShape(98, 0);
+ ccs.push_back(alignment140664475650992);
+
+ SeparationConstraint *separation140664475651216 = new SeparationConstraint(vpsc::XDIM, 7, 98, 62, true);
+ ccs.push_back(separation140664475651216);
+
+ AlignmentConstraint *alignment140664475651360 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475651360->addShape(8, 0);
+ alignment140664475651360->addShape(99, 0);
+ ccs.push_back(alignment140664475651360);
+
+ SeparationConstraint *separation140664475651584 = new SeparationConstraint(vpsc::YDIM, 8, 99, -50, true);
+ ccs.push_back(separation140664475651584);
+
+ AlignmentConstraint *alignment140664475651728 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475651728->addShape(9, 0);
+ alignment140664475651728->addShape(100, 0);
+ ccs.push_back(alignment140664475651728);
+
+ SeparationConstraint *separation140664475651952 = new SeparationConstraint(vpsc::YDIM, 9, 100, -50, true);
+ ccs.push_back(separation140664475651952);
+
+ AlignmentConstraint *alignment140664475652096 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475652096->addShape(10, 0);
+ alignment140664475652096->addShape(101, 0);
+ ccs.push_back(alignment140664475652096);
+
+ SeparationConstraint *separation140664475652320 = new SeparationConstraint(vpsc::XDIM, 10, 101, 62, true);
+ ccs.push_back(separation140664475652320);
+
+ AlignmentConstraint *alignment140664475652464 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475652464->addShape(11, 0);
+ alignment140664475652464->addShape(102, 0);
+ ccs.push_back(alignment140664475652464);
+
+ SeparationConstraint *separation140664475652688 = new SeparationConstraint(vpsc::XDIM, 11, 102, 62, true);
+ ccs.push_back(separation140664475652688);
+
+ AlignmentConstraint *alignment140664475652832 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475652832->addShape(12, 0);
+ alignment140664475652832->addShape(103, 0);
+ ccs.push_back(alignment140664475652832);
+
+ SeparationConstraint *separation140664475517040 = new SeparationConstraint(vpsc::XDIM, 12, 103, 62, true);
+ ccs.push_back(separation140664475517040);
+
+ AlignmentConstraint *alignment140664475517184 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475517184->addShape(13, 0);
+ alignment140664475517184->addShape(104, 0);
+ ccs.push_back(alignment140664475517184);
+
+ SeparationConstraint *separation140664475517408 = new SeparationConstraint(vpsc::YDIM, 13, 104, -50, true);
+ ccs.push_back(separation140664475517408);
+
+ AlignmentConstraint *alignment140664475517552 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475517552->addShape(14, 0);
+ alignment140664475517552->addShape(105, 0);
+ ccs.push_back(alignment140664475517552);
+
+ SeparationConstraint *separation140664475517776 = new SeparationConstraint(vpsc::YDIM, 14, 105, -50, true);
+ ccs.push_back(separation140664475517776);
+
+ AlignmentConstraint *alignment140664475517920 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475517920->addShape(16, 0);
+ alignment140664475517920->addShape(106, 0);
+ ccs.push_back(alignment140664475517920);
+
+ SeparationConstraint *separation140664475518144 = new SeparationConstraint(vpsc::XDIM, 16, 106, 62, true);
+ ccs.push_back(separation140664475518144);
+
+ AlignmentConstraint *alignment140664475518288 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475518288->addShape(18, 0);
+ alignment140664475518288->addShape(107, 0);
+ ccs.push_back(alignment140664475518288);
+
+ SeparationConstraint *separation140664475518512 = new SeparationConstraint(vpsc::XDIM, 18, 107, 62, true);
+ ccs.push_back(separation140664475518512);
+
+ AlignmentConstraint *alignment140664475518656 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475518656->addShape(19, 0);
+ alignment140664475518656->addShape(108, 0);
+ ccs.push_back(alignment140664475518656);
+
+ SeparationConstraint *separation140664475518880 = new SeparationConstraint(vpsc::XDIM, 19, 108, 62, true);
+ ccs.push_back(separation140664475518880);
+
+ AlignmentConstraint *alignment140664475519024 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475519024->addShape(20, 0);
+ alignment140664475519024->addShape(109, 0);
+ ccs.push_back(alignment140664475519024);
+
+ SeparationConstraint *separation140664475519248 = new SeparationConstraint(vpsc::XDIM, 20, 109, 62, true);
+ ccs.push_back(separation140664475519248);
+
+ AlignmentConstraint *alignment140664475519392 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475519392->addShape(22, 0);
+ alignment140664475519392->addShape(110, 0);
+ ccs.push_back(alignment140664475519392);
+
+ SeparationConstraint *separation140664475519616 = new SeparationConstraint(vpsc::YDIM, 22, 110, -50, true);
+ ccs.push_back(separation140664475519616);
+
+ AlignmentConstraint *alignment140664475519760 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475519760->addShape(23, 0);
+ alignment140664475519760->addShape(111, 0);
+ ccs.push_back(alignment140664475519760);
+
+ SeparationConstraint *separation140664475519984 = new SeparationConstraint(vpsc::XDIM, 23, 111, 62, true);
+ ccs.push_back(separation140664475519984);
+
+ AlignmentConstraint *alignment140664475520128 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475520128->addShape(24, 0);
+ alignment140664475520128->addShape(112, 0);
+ ccs.push_back(alignment140664475520128);
+
+ SeparationConstraint *separation140664475520352 = new SeparationConstraint(vpsc::YDIM, 24, 112, -50, true);
+ ccs.push_back(separation140664475520352);
+
+ AlignmentConstraint *alignment140664475520496 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475520496->addShape(25, 0);
+ alignment140664475520496->addShape(113, 0);
+ ccs.push_back(alignment140664475520496);
+
+ SeparationConstraint *separation140664475520720 = new SeparationConstraint(vpsc::YDIM, 25, 113, -50, true);
+ ccs.push_back(separation140664475520720);
+
+ AlignmentConstraint *alignment140664475520864 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475520864->addShape(26, 0);
+ alignment140664475520864->addShape(114, 0);
+ ccs.push_back(alignment140664475520864);
+
+ SeparationConstraint *separation140664475521088 = new SeparationConstraint(vpsc::XDIM, 26, 114, 62, true);
+ ccs.push_back(separation140664475521088);
+
+ AlignmentConstraint *alignment140664475521232 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475521232->addShape(27, 0);
+ alignment140664475521232->addShape(115, 0);
+ ccs.push_back(alignment140664475521232);
+
+ SeparationConstraint *separation140664475521456 = new SeparationConstraint(vpsc::XDIM, 27, 115, 62, true);
+ ccs.push_back(separation140664475521456);
+
+ AlignmentConstraint *alignment140664475521600 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475521600->addShape(28, 0);
+ alignment140664475521600->addShape(116, 0);
+ ccs.push_back(alignment140664475521600);
+
+ SeparationConstraint *separation140664475521824 = new SeparationConstraint(vpsc::YDIM, 28, 116, -50, true);
+ ccs.push_back(separation140664475521824);
+
+ AlignmentConstraint *alignment140664475521968 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475521968->addShape(29, 0);
+ alignment140664475521968->addShape(117, 0);
+ ccs.push_back(alignment140664475521968);
+
+ SeparationConstraint *separation140664475522192 = new SeparationConstraint(vpsc::YDIM, 29, 117, -50, true);
+ ccs.push_back(separation140664475522192);
+
+ AlignmentConstraint *alignment140664475522336 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475522336->addShape(30, 0);
+ alignment140664475522336->addShape(118, 0);
+ ccs.push_back(alignment140664475522336);
+
+ SeparationConstraint *separation140664475522560 = new SeparationConstraint(vpsc::YDIM, 30, 118, -50, true);
+ ccs.push_back(separation140664475522560);
+
+ AlignmentConstraint *alignment140664475522704 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475522704->addShape(31, 0);
+ alignment140664475522704->addShape(119, 0);
+ ccs.push_back(alignment140664475522704);
+
+ SeparationConstraint *separation140664475522928 = new SeparationConstraint(vpsc::XDIM, 31, 119, 62, true);
+ ccs.push_back(separation140664475522928);
+
+ AlignmentConstraint *alignment140664475523072 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475523072->addShape(32, 0);
+ alignment140664475523072->addShape(120, 0);
+ ccs.push_back(alignment140664475523072);
+
+ SeparationConstraint *separation140664475523296 = new SeparationConstraint(vpsc::XDIM, 32, 120, 62, true);
+ ccs.push_back(separation140664475523296);
+
+ AlignmentConstraint *alignment140664475523440 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475523440->addShape(33, 0);
+ alignment140664475523440->addShape(121, 0);
+ ccs.push_back(alignment140664475523440);
+
+ SeparationConstraint *separation140664475523664 = new SeparationConstraint(vpsc::XDIM, 33, 121, 62, true);
+ ccs.push_back(separation140664475523664);
+
+ AlignmentConstraint *alignment140664475523808 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475523808->addShape(34, 0);
+ alignment140664475523808->addShape(122, 0);
+ ccs.push_back(alignment140664475523808);
+
+ SeparationConstraint *separation140664475524032 = new SeparationConstraint(vpsc::YDIM, 34, 122, -50, true);
+ ccs.push_back(separation140664475524032);
+
+ AlignmentConstraint *alignment140664475524176 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475524176->addShape(35, 0);
+ alignment140664475524176->addShape(123, 0);
+ ccs.push_back(alignment140664475524176);
+
+ SeparationConstraint *separation140664475524400 = new SeparationConstraint(vpsc::YDIM, 35, 123, -50, true);
+ ccs.push_back(separation140664475524400);
+
+ AlignmentConstraint *alignment140664475524544 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475524544->addShape(36, 0);
+ alignment140664475524544->addShape(124, 0);
+ ccs.push_back(alignment140664475524544);
+
+ SeparationConstraint *separation140664475524768 = new SeparationConstraint(vpsc::YDIM, 36, 124, -50, true);
+ ccs.push_back(separation140664475524768);
+
+ AlignmentConstraint *alignment140664475524912 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475524912->addShape(37, 0);
+ alignment140664475524912->addShape(125, 0);
+ ccs.push_back(alignment140664475524912);
+
+ SeparationConstraint *separation140664475525136 = new SeparationConstraint(vpsc::YDIM, 37, 125, -50, true);
+ ccs.push_back(separation140664475525136);
+
+ AlignmentConstraint *alignment140664475525280 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475525280->addShape(38, 0);
+ alignment140664475525280->addShape(126, 0);
+ ccs.push_back(alignment140664475525280);
+
+ SeparationConstraint *separation140664475525504 = new SeparationConstraint(vpsc::YDIM, 38, 126, -50, true);
+ ccs.push_back(separation140664475525504);
+
+ AlignmentConstraint *alignment140664475525648 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475525648->addShape(40, 0);
+ alignment140664475525648->addShape(127, 0);
+ ccs.push_back(alignment140664475525648);
+
+ SeparationConstraint *separation140664475525872 = new SeparationConstraint(vpsc::YDIM, 40, 127, -50, true);
+ ccs.push_back(separation140664475525872);
+
+ AlignmentConstraint *alignment140664475526016 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475526016->addShape(41, 0);
+ alignment140664475526016->addShape(128, 0);
+ ccs.push_back(alignment140664475526016);
+
+ SeparationConstraint *separation140664475526240 = new SeparationConstraint(vpsc::XDIM, 41, 128, 62, true);
+ ccs.push_back(separation140664475526240);
+
+ AlignmentConstraint *alignment140664475526384 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475526384->addShape(42, 0);
+ alignment140664475526384->addShape(129, 0);
+ ccs.push_back(alignment140664475526384);
+
+ SeparationConstraint *separation140664475526608 = new SeparationConstraint(vpsc::YDIM, 42, 129, -50, true);
+ ccs.push_back(separation140664475526608);
+
+ AlignmentConstraint *alignment140664475526752 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475526752->addShape(43, 0);
+ alignment140664475526752->addShape(130, 0);
+ ccs.push_back(alignment140664475526752);
+
+ SeparationConstraint *separation140664475526976 = new SeparationConstraint(vpsc::YDIM, 43, 130, -50, true);
+ ccs.push_back(separation140664475526976);
+
+ AlignmentConstraint *alignment140664475527120 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475527120->addShape(44, 0);
+ alignment140664475527120->addShape(131, 0);
+ ccs.push_back(alignment140664475527120);
+
+ SeparationConstraint *separation140664475527344 = new SeparationConstraint(vpsc::YDIM, 44, 131, -50, true);
+ ccs.push_back(separation140664475527344);
+
+ AlignmentConstraint *alignment140664475527488 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475527488->addShape(45, 0);
+ alignment140664475527488->addShape(132, 0);
+ ccs.push_back(alignment140664475527488);
+
+ SeparationConstraint *separation140664475527712 = new SeparationConstraint(vpsc::YDIM, 45, 132, -50, true);
+ ccs.push_back(separation140664475527712);
+
+ AlignmentConstraint *alignment140664475527856 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475527856->addShape(46, 0);
+ alignment140664475527856->addShape(133, 0);
+ ccs.push_back(alignment140664475527856);
+
+ SeparationConstraint *separation140664475528080 = new SeparationConstraint(vpsc::YDIM, 46, 133, -50, true);
+ ccs.push_back(separation140664475528080);
+
+ AlignmentConstraint *alignment140664475528224 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475528224->addShape(47, 0);
+ alignment140664475528224->addShape(134, 0);
+ ccs.push_back(alignment140664475528224);
+
+ SeparationConstraint *separation140664475528448 = new SeparationConstraint(vpsc::YDIM, 47, 134, -50, true);
+ ccs.push_back(separation140664475528448);
+
+ AlignmentConstraint *alignment140664475528592 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475528592->addShape(77, 0);
+ alignment140664475528592->addShape(135, 0);
+ ccs.push_back(alignment140664475528592);
+
+ SeparationConstraint *separation140664475528816 = new SeparationConstraint(vpsc::YDIM, 77, 135, -50, true);
+ ccs.push_back(separation140664475528816);
+
+ AlignmentConstraint *alignment140664475528960 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475528960->addShape(78, 0);
+ alignment140664475528960->addShape(136, 0);
+ ccs.push_back(alignment140664475528960);
+
+ SeparationConstraint *separation140664475529184 = new SeparationConstraint(vpsc::YDIM, 78, 136, -50, true);
+ ccs.push_back(separation140664475529184);
+
+ AlignmentConstraint *alignment140664475529328 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475529328->addShape(79, 0);
+ alignment140664475529328->addShape(137, 0);
+ ccs.push_back(alignment140664475529328);
+
+ SeparationConstraint *separation140664475529552 = new SeparationConstraint(vpsc::YDIM, 79, 137, -50, true);
+ ccs.push_back(separation140664475529552);
+
+ AlignmentConstraint *alignment140664475529696 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475529696->addShape(81, 0);
+ alignment140664475529696->addShape(138, 0);
+ ccs.push_back(alignment140664475529696);
+
+ SeparationConstraint *separation140664475529920 = new SeparationConstraint(vpsc::XDIM, 81, 138, 62, true);
+ ccs.push_back(separation140664475529920);
+
+ AlignmentConstraint *alignment140664475530064 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475530064->addShape(82, 0);
+ alignment140664475530064->addShape(139, 0);
+ ccs.push_back(alignment140664475530064);
+
+ SeparationConstraint *separation140664475530288 = new SeparationConstraint(vpsc::YDIM, 82, 139, -50, true);
+ ccs.push_back(separation140664475530288);
+
+ AlignmentConstraint *alignment140664475530432 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475530432->addShape(83, 0);
+ alignment140664475530432->addShape(140, 0);
+ ccs.push_back(alignment140664475530432);
+
+ SeparationConstraint *separation140664475530656 = new SeparationConstraint(vpsc::YDIM, 83, 140, -50, true);
+ ccs.push_back(separation140664475530656);
+
+ AlignmentConstraint *alignment140664475530800 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475530800->addShape(84, 0);
+ alignment140664475530800->addShape(141, 0);
+ ccs.push_back(alignment140664475530800);
+
+ SeparationConstraint *separation140664475531024 = new SeparationConstraint(vpsc::YDIM, 84, 141, -50, true);
+ ccs.push_back(separation140664475531024);
+
+ AlignmentConstraint *alignment140664475531168 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475531168->addShape(85, 0);
+ alignment140664475531168->addShape(142, 0);
+ ccs.push_back(alignment140664475531168);
+
+ SeparationConstraint *separation140664475531392 = new SeparationConstraint(vpsc::XDIM, 85, 142, 62, true);
+ ccs.push_back(separation140664475531392);
+
+ AlignmentConstraint *alignment140664475531536 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475531536->addShape(87, 0);
+ alignment140664475531536->addShape(143, 0);
+ ccs.push_back(alignment140664475531536);
+
+ SeparationConstraint *separation140664475531760 = new SeparationConstraint(vpsc::YDIM, 87, 143, -50, true);
+ ccs.push_back(separation140664475531760);
+
+ AlignmentConstraint *alignment140664475531904 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475531904->addShape(88, 0);
+ alignment140664475531904->addShape(144, 0);
+ ccs.push_back(alignment140664475531904);
+
+ SeparationConstraint *separation140664475532128 = new SeparationConstraint(vpsc::YDIM, 88, 144, -50, true);
+ ccs.push_back(separation140664475532128);
+
+ AlignmentConstraint *alignment140664475532272 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475532272->addShape(90, 0);
+ alignment140664475532272->addShape(145, 0);
+ ccs.push_back(alignment140664475532272);
+
+ SeparationConstraint *separation140664475532496 = new SeparationConstraint(vpsc::YDIM, 90, 145, -50, true);
+ ccs.push_back(separation140664475532496);
+
+ AlignmentConstraint *alignment140664475532640 = new AlignmentConstraint(vpsc::YDIM, 0);
+ alignment140664475532640->addShape(91, 0);
+ alignment140664475532640->addShape(146, 0);
+ ccs.push_back(alignment140664475532640);
+
+ SeparationConstraint *separation140664475532864 = new SeparationConstraint(vpsc::XDIM, 91, 146, 62, true);
+ ccs.push_back(separation140664475532864);
+
+ AlignmentConstraint *alignment140664475533008 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475533008->addShape(92, 0);
+ alignment140664475533008->addShape(147, 0);
+ ccs.push_back(alignment140664475533008);
+
+ SeparationConstraint *separation140664475533232 = new SeparationConstraint(vpsc::YDIM, 92, 147, -50, true);
+ ccs.push_back(separation140664475533232);
+
+ AlignmentConstraint *alignment140664475533376 = new AlignmentConstraint(vpsc::XDIM, 0);
+ alignment140664475533376->addShape(93, 0);
+ alignment140664475533376->addShape(148, 0);
+ ccs.push_back(alignment140664475533376);
+
+ SeparationConstraint *separation140664475533600 = new SeparationConstraint(vpsc::YDIM, 93, 148, -50, true);
+ ccs.push_back(separation140664475533600);
+
+ RootCluster *cluster140664475533920 = new RootCluster();
+
+ RectangularCluster *cluster140664475534416 = new RectangularCluster(5);
+ cluster140664475534416->addChildNode(149);
+ cluster140664475534416->addChildNode(150);
+ cluster140664475534416->addChildNode(151);
+ cluster140664475534416->addChildNode(152);
+ cluster140664475533920->addChildCluster(cluster140664475534416);
+
+ RectangularCluster *cluster140664475535040 = new RectangularCluster(6);
+ cluster140664475535040->addChildNode(153);
+ cluster140664475533920->addChildCluster(cluster140664475535040);
+
+ RectangularCluster *cluster140664475535648 = new RectangularCluster(15);
+ cluster140664475533920->addChildCluster(cluster140664475535648);
+
+ RectangularCluster *cluster140664475535952 = new RectangularCluster(17);
+ cluster140664475535952->addChildNode(154);
+ cluster140664475535952->addChildNode(155);
+ cluster140664475533920->addChildCluster(cluster140664475535952);
+
+ RectangularCluster *cluster140664475536320 = new RectangularCluster(21);
+ cluster140664475536320->addChildNode(156);
+ cluster140664475533920->addChildCluster(cluster140664475536320);
+
+ RectangularCluster *cluster140664475536720 = new RectangularCluster(39);
+ cluster140664475533920->addChildCluster(cluster140664475536720);
+
+ RectangularCluster *cluster140664475537056 = new RectangularCluster(80);
+ cluster140664475537056->addChildNode(157);
+ cluster140664475533920->addChildCluster(cluster140664475537056);
+
+ ConstrainedFDLayout alg(rs, es, defaultEdgeLength);
+ alg.setAvoidNodeOverlaps(true);
+ alg.setClusterHierarchy(cluster140664475533920);
+ alg.setConstraints(ccs);
+ alg.makeFeasible();
+
+ alg.outputInstanceToSVG("test-rectclustershapecontainment");
+ //alg.run();
+ alg.freeAssociatedObjects();
+
+ return 0;
+};
diff --git a/src/3rdparty/adaptagrams/libcola/tests/resize.cpp b/src/3rdparty/adaptagrams/libcola/tests/resize.cpp
new file mode 100644
index 0000000..97c2e9d
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/resize.cpp
@@ -0,0 +1,132 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/** \file nodedragging.cpp
+ *
+ * tests interaction with layout and solver. We have a number of disconnected
+ * shapes. One shape is "dragged" through the others. Overlaps should be
+ * avoided.
+ */
+/*
+* Authors:
+* Tim Dwyer <tgdwyer@gmail.com>
+*/
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+#include <vector>
+#include <valarray>
+#include <algorithm>
+#include <float.h>
+#include <libcola/cola.h>
+#include <libtopology/topology_graph.h>
+#include <libproject/project.h>
+#include "graphlayouttest.h"
+using namespace std;
+using namespace cola;
+
+string outFName="resize";
+
+topology::Node* addNode(
+ topology::Nodes& vs, vpsc::Rectangle* r) {
+ topology::Node *v = new topology::Node(vs.size(), r);
+ vs.push_back(v);
+ return v;
+}
+void addToPath(topology::EdgePoints& ps, topology::Node *v, topology::EdgePoint::RectIntersect i) {
+ ps.push_back(new topology::EdgePoint(v,i));
+}
+struct Test : TestConvergence {
+ Test(const double d,const unsigned i,topology::Nodes& vs, topology::Edges& es) : TestConvergence(d,i), vs(vs), es(es), iter(1) {}
+ bool operator()(const double new_stress, valarray<double> & X, valarray<double> & Y) {
+ bool converged = TestConvergence::operator()(new_stress,X,Y);
+ if(converged) {
+ cout << "stress="<<new_stress<<" iteration="<<iter<<endl;
+ stringstream ss;
+ ss<<outFName<<"-"<< setfill('0') << setw(3) << iter++ << ".svg";
+ writeFile(vs,es,ss.str());
+ }
+ return converged;
+ }
+ double lastStress;
+ topology::Nodes& vs;
+ topology::Edges& es;
+ int iter;
+};
+
+void resize() {
+//printf(
+//"tests resizing of a shape. We have a number of disconnected"
+//"shapes. One shape is 'enlarged'. Overlaps should be"
+//"avoided."
+//"\n");
+ const unsigned V = 9;
+ Edge edge_array[] = { Edge(0, 1), Edge(1, 2), Edge(2, 0) };
+ const std::size_t E = sizeof(edge_array) / sizeof(Edge);
+ vector<Edge> es(edge_array,edge_array+E);
+ vector<vpsc::Rectangle*> rs;
+ const double w=54, h=34;
+ const double
+ x[]={406, 444, 474, 406, 441, 375, 408, 373, 339},
+ y[]={279, 224, 179, 92, 135, 135, 179, 226, 179};
+ const unsigned resizeID=6;
+ for(unsigned i=0;i<V;++i) {
+ rs.push_back(new vpsc::Rectangle(x[i],x[i]+w,y[i],y[i]+h));
+ }
+ double idealLength=60;
+ // set up topology graph
+ topology::Nodes vs;
+ for(vector<Rectangle*>::iterator i = rs.begin(); i!=rs.end();++i) {
+ addNode(vs,*i);
+ }
+ topology::Edges tes;
+ writeFile(vs,tes,outFName+"-000.svg");
+
+ Resizes resize;
+ vpsc::Rectangle* r=rs[resizeID];
+ resize.push_back(Resize(resizeID,r->getCentreX()-30, r->getCentreY()-30,
+ r->width()+60,r->height()+60));
+ PreIteration preIteration(resize);
+ Test test(0.00001,100,vs,tes);
+ ConstrainedFDLayout alg(rs,es,idealLength,nullptr,test,&preIteration);
+ alg.setTopology(&vs,&tes);
+
+ alg.run(true,true);
+
+ double finalStress=alg.computeStress();
+ printf("finalStress=%f\n",finalStress);
+
+ //assert(finalStress<1e-5);
+ for_each(rs.begin(),rs.end(),delete_object());
+ for_each(tes.begin(),tes.end(),delete_object());
+ for_each(vs.begin(),vs.end(),delete_object());
+}
+int main() {
+ resize();
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=80 :
+
diff --git a/src/3rdparty/adaptagrams/libcola/tests/runtest.sh b/src/3rdparty/adaptagrams/libcola/tests/runtest.sh
new file mode 100755
index 0000000..2ee1526
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/runtest.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+r=0
+while [ $r == 0 ]
+do
+ ./beautify
+ r=$?
+ echo result=$r
+done
diff --git a/src/3rdparty/adaptagrams/libcola/tests/scale_free.cpp b/src/3rdparty/adaptagrams/libcola/tests/scale_free.cpp
new file mode 100644
index 0000000..d9c2934
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/scale_free.cpp
@@ -0,0 +1,135 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+// generates a random graph with a power-law distribution of node degrees
+// the algorithm is pretty much the Barabasi-Albert model but with an extra step
+// so that I can guarantee the number of nodes in the graph.
+// We begin with an initial chain of m nodes.
+// Then, we add new nodes, connecting them to existing nodes v with probability
+// degree(v)/(sum all degrees)
+// We perform an extra step, looking for disconnected nodes, connecting them
+// to other nodes again with probability dependent on degree
+#include<iostream>
+#include<vector>
+#include <cmath>
+#include <time.h>
+#include <valarray>
+
+#include "graphlayouttest.h"
+
+void scale_free(const unsigned n = 50) {
+ const unsigned m = 3; // begin with a chain of m nodes
+ const double g=0.08; // edge density, every time we add a node we add 1+g*rand(0-1) edges
+ // connecting them to existing nodes with probability based on degree
+ unsigned d[n];
+ double defaultEdgeLength=100;
+ vector<Edge> es;
+ CompoundConstraints cx,cy;
+ for(unsigned i=0;i<n;i++) {
+ d[i]=0;
+ }
+ unsigned sumdegree=0;
+ for(unsigned i=1;i<m;i++) {
+ es.push_back(make_pair(i-1,i));
+ d[i]++;d[i-1]++;
+ sumdegree+=2;
+ }
+ srand(3);
+ for(unsigned i=2;i<n;i++) {
+ for(unsigned j=0;j<i;j++) {
+ double p=(double)d[j]/(double)sumdegree;
+ double r=(double)rand()/(double)RAND_MAX;
+ if(r*p>g) {
+ es.push_back(make_pair(j,i));
+ d[j]++;d[i]++;
+ sumdegree+=2;
+ }
+ }
+ }
+ for(unsigned i=0;i<n;i++) {
+ if(d[i]==0) {
+ double maxP=0;
+ unsigned end=0;
+ for(unsigned j=0;j<n;j++) {
+ if(j==i) continue;
+ double p=(double)d[j]/(double)sumdegree;
+ double r=(double)rand()/(double)RAND_MAX;
+ if(r*p>maxP) {
+ maxP=r*p;
+ end=j;
+ }
+ }
+ if(end>i) {
+ es.push_back(make_pair(i,end));
+ } else {
+ es.push_back(make_pair(end,i));
+ }
+ d[end]++;d[i]++;
+ sumdegree+=2;
+ }
+ }
+ valarray<double> eweights(es.size());
+ sort(d,d+n);
+ unsigned degree=0,ctr=0;
+ printf("degree distribution:\n");
+ for(unsigned i=0;i<n;i++) {
+ if(degree!=d[i]) {
+ if(degree!=0) printf("%d,%d\n",degree,ctr);
+ degree=d[i];
+ ctr=0;
+ }
+ ctr++;
+ }
+ printf("%d,%d\n",degree,ctr);
+ for(unsigned i=0;i<es.size();i++) {
+ unsigned a=es[i].first, b=es[i].second;
+ eweights[i]=1;
+ cy.push_back(new SeparationConstraint(a,b,defaultEdgeLength/3));
+ }
+
+ cout << "|V|="<<n<<endl;
+ double width=1000;
+ double height=1000;
+ vector<pair<double,double> > startpos(n);
+ for(unsigned i=0;i<n;i++) {
+ double x=getRand(width), y=getRand(height);
+ startpos[i]=make_pair(x,y);
+ }
+ const char *f="scalefree";
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,CG,false,f,"cg");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,IP,false,f,"ip");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,false,f,"ugp");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,false,f,"sgp");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,IP,true,f,"cip");
+ //run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,true,f,"cugp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,true,f,"csgp");
+}
+int main() {
+ for(unsigned i=1;i<2;i++) {
+ scale_free(i*50);
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/shortest_paths.cpp b/src/3rdparty/adaptagrams/libcola/tests/shortest_paths.cpp
new file mode 100644
index 0000000..617f136
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/shortest_paths.cpp
@@ -0,0 +1,140 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <fstream>
+#include <iostream>
+#include <iomanip>
+//#define TEST_AGAINST_BOOST
+#ifdef TEST_AGAINST_BOOST
+#include <boost/config.hpp>
+#include <boost/property_map.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/graphviz.hpp>
+#include <boost/graph/johnson_all_pairs_shortest.hpp>
+using namespace boost;
+#endif // TEST_AGAINST_BOOST
+#include <libcola/shortest_paths.h>
+#include <cmath>
+#include <time.h>
+#include <assert.h>
+
+using namespace std;
+// creates a (not necessarily connected random graph) with n nodes.
+vector<shortest_paths::Edge> random_graph(unsigned n) {
+ vector<shortest_paths::Edge> edges;
+ for(unsigned i=0;i<n;i++) {
+ for(unsigned j=i+1;j<n;j++) {
+ double r=(double)rand()/(double)RAND_MAX;
+ if(r < 0.1) {
+ edges.push_back(make_pair(i,j));
+ }
+ }
+ }
+
+ return edges;
+}
+clock_t lastTime;
+static void resetClock() {
+ lastTime=clock();
+}
+static double getRunTime() {
+ clock_t time = clock()-lastTime;
+ return (double)time/(double)CLOCKS_PER_SEC;
+}
+
+int
+main(void)
+{
+ bool dump=false;
+ srand(time(0));
+#ifdef TEST_AGAINST_BOOST
+ typedef adjacency_list<vecS, vecS, undirectedS, no_property,
+ property< edge_weight_t, double, property< edge_weight2_t, double > > > Graph;
+ Graph g;
+#endif
+ unsigned V = 100;
+ vector<shortest_paths::Edge> es = random_graph(V);
+ unsigned E=es.size();
+ cout << " Test graph |V|="<<V<<",|E|="<<E<<endl;
+ valarray<double> weights(E);
+ for(unsigned i=0;i<E;i++) {
+ weights[i]=round((static_cast<double>(rand())/static_cast<double>(RAND_MAX))*10);
+#ifdef TEST_AGAINST_BOOST
+ add_edge(es[i].first,es[i].second,weights[i],g);
+#endif
+ }
+
+#ifdef TEST_AGAINST_BOOST
+ vector < double >d(V, (numeric_limits < double >::max)());
+ typedef vector<double> weight_vec;
+ vector<weight_vec> D(V,weight_vec(V));
+ cout<<"Running boost::johnson_all_pairs_shortest_paths..."<<endl;
+ resetClock();
+ johnson_all_pairs_shortest_paths(g, D, distance_map(&d[0]));
+ cout<<" ...done, time="<<getRunTime()<<endl;
+#endif
+ double** D1=new double*[V];
+ for(unsigned i=0;i<V;i++) {
+ D1[i]=new double[V];
+ }
+ cout<<"Running shortest_paths::johnsons..."<<endl;
+ resetClock();
+ shortest_paths::johnsons(V,D1,es,weights);
+ cout<<" ...done, time="<<getRunTime()<<endl;
+ double** D2=new double*[V];
+ for(unsigned i=0;i<V;i++) {
+ D2[i]=new double[V];
+ }
+ cout<<"Running shortest_paths::floyd_warshall..."<<endl;
+ resetClock();
+ shortest_paths::floyd_warshall(V,D2,es,weights);
+ cout<<" ...done, time="<<getRunTime()<<endl;
+
+ for (unsigned int i = 0; i < V; ++i) {
+ if(dump) cout << i << " -> ";
+ for (unsigned int j = 0; j < V; ++j) {
+ if(dump) cout << setw(5) << D1[i][j];
+ assert(D1[i][j]==D2[i][j]);
+#ifdef TEST_AGAINST_BOOST
+ assert(D[i][j]==D2[i][j]);
+#endif
+ }
+ if(dump) cout << endl;
+ }
+#ifdef TEST_AGAINST_BOOST
+ if(dump) {
+ ofstream fout("figs/johnson-eg.dot");
+ fout << "graph A {\n" << "node[shape=\"circle\"]\n";
+
+ graph_traits < Graph >::edge_iterator ei, ei_end;
+ for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei)
+ fout << source(*ei, g) << " -- " << target(*ei, g)
+ << "[label=" << get(edge_weight, g)[*ei] << "]\n";
+
+ fout << "}\n";
+ }
+#endif
+ return 0;
+}
diff --git a/src/3rdparty/adaptagrams/libcola/tests/small_graph.cpp b/src/3rdparty/adaptagrams/libcola/tests/small_graph.cpp
new file mode 100644
index 0000000..53103c9
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/small_graph.cpp
@@ -0,0 +1,111 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+// Loads a graph from a text file, generates constraints for each edge requiring them
+// to point downwards, and proceeds to produce a layout using libcola.
+// The input file format is 2 numeric node labels per line separated by a space,
+// each pair representing a directed edge. Node labels are simply used as array
+// offsets so they should start from 0.
+// The graph should be connected.
+// Default input file is the matrix market 1138_bus graph.
+// Running times:
+// no constraints - steepest descent solver: 149 seconds
+// no constraints - conjugate gradient solver: 21.7 seconds
+// dir-edge constraints - conj grad. solver: 155.69 seconds
+#include<iostream>
+#include<iomanip>
+#include<fstream>
+#include<vector>
+#include<valarray>
+#include<libcola/output_svg.h>
+#include<graphlayouttest.h>
+
+using namespace std;
+using namespace cola;
+
+struct CheckProgress : TestConvergence {
+ CheckProgress(const double d,const unsigned i) : TestConvergence(d,i) {}
+ bool operator()(const double new_stress, valarray<double> & X, valarray<double> & Y) {
+ cout << "stress="<<new_stress<<endl;
+ return TestConvergence::operator()(new_stress,X,Y);
+ }
+};
+int main() {
+ const char *fname="data/wheel.txt"; //"data/dg_850.txt";
+ ifstream f(fname);
+ if(!f.is_open()) {
+ cout << "Error opening file: " << fname << endl;
+ exit(1);
+ }
+ string startlabel, endlabel;
+ unsigned V = 0;
+ double defaultEdgeLength=40;
+ vector<Edge> es;
+ CompoundConstraints cy;
+ //CompoundConstraints cx;
+ while(!getline(f,startlabel,' ').eof()) {
+ getline(f,endlabel);
+ unsigned start = atoi(startlabel.c_str()),
+ end = atoi(endlabel.c_str());
+ es.push_back(make_pair(start,end));
+ //cx.push_back(
+ //new SeparationConstraint(start,end,defaultEdgeLength/3));
+ cy.push_back(
+ new SeparationConstraint(start,end,defaultEdgeLength/3));
+ V=max(V,max(start,end));
+ }
+ V++;
+ cout << "V="<<V<<endl;
+ double width=1000;
+ double height=1000;
+ vector<vpsc::Rectangle*> rs;
+ //srand(time(nullptr));
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+1,y,y+1));
+ }
+ CheckProgress test(0.001,100);
+ clock_t starttime=clock();
+ ConstrainedMajorizationLayout alg(rs,es,nullptr,defaultEdgeLength,nullptr,test);
+ bool constrained=false;
+ if(!constrained) {
+ cout << "Unconstrained layout" << endl;
+ alg.setConstrainedLayout(true);
+ alg.run();
+ } else {
+ cout << "Constrained layout" << endl;
+ //alg.setXConstraints(&cx);
+ alg.setYConstraints(&cy);
+ alg.run();
+ }
+ double t=double(clock()-starttime)/double(CLOCKS_PER_SEC);
+ cout<<"Time="<<t<<endl;
+ output_svg(rs,es,nullptr,"small_graph.svg",true);
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/sparse_matrix.cpp b/src/3rdparty/adaptagrams/libcola/tests/sparse_matrix.cpp
new file mode 100644
index 0000000..099fcf3
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/sparse_matrix.cpp
@@ -0,0 +1,88 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <map>
+#include <valarray>
+#include <libcola/sparse_matrix.h>
+#include <boost/numeric/ublas/matrix_sparse.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/io.hpp>
+#include <time.h>
+#include <cmath>
+
+using namespace boost::numeric::ublas;
+int sparse_test(const unsigned n, cola::SparseMatrix::SparseMap& cm, mapped_matrix<double>& bm) {
+ printf("Sparse test...");
+ srand(time(0));
+ for (unsigned i = 0; i < n; ++ i) {
+ for (unsigned j = 0; j < n; ++ j) {
+ double r=(double)rand()/(double)RAND_MAX;
+ double s=(double)rand()/(double)RAND_MAX;
+ if(r < 0.2) {
+ cm[std::make_pair(i,j)] = s;
+ bm (i, j) = s;
+ }
+ }
+ }
+}
+int dense_test(const unsigned n, cola::SparseMatrix::SparseMap& cm, mapped_matrix<double>& bm) {
+ printf("Dense test...");
+ for (unsigned i = 0; i < n; ++ i) {
+ for (unsigned j = 0; j < n; ++ j) {
+ bm (i, j) = n * i + j;
+ cm[std::make_pair(i,j)]=bm(i,j);
+ }
+ }
+}
+
+void test(int (*generate)(const unsigned, cola::SparseMatrix::SparseMap&, mapped_matrix<double>&)) {
+ using std::valarray;
+ const unsigned n = 20;
+ mapped_matrix<double> bm (n, n, n * n);
+ cola::SparseMatrix::SparseMap cm;
+ generate(n,cm,bm);
+ vector<double> bv (n);
+ valarray<double> cv(n);
+ for (unsigned i = 0; i < n; ++ i) {
+ bv(i) = i;
+ cv[i] = i;
+ }
+ vector<double> br(n);
+ valarray<double> cr(n);
+ cola::SparseMatrix a(cm,n);
+ br=prod(bm,bv);
+ a.rightMultiply(cv,cr);
+ for (unsigned i = 0; i < n; ++ i) {
+ assert(fabs(cr[i]-br(i))<0.000001);
+ }
+ printf(" passed!\n");
+}
+int main() {
+ test(&dense_test);
+ test(&sparse_test);
+ return 0;
+}
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/test_cg.cpp b/src/3rdparty/adaptagrams/libcola/tests/test_cg.cpp
new file mode 100644
index 0000000..13e7d02
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/test_cg.cpp
@@ -0,0 +1,164 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include <stdio.h>
+#include <cassert>
+#include <libcola/conjugate_gradient.h>
+#include <gsl/gsl_linalg.h>
+
+using std::valarray;
+
+static valarray<double>
+outer_prod(valarray<double> x, valarray<double> y) {
+ valarray<double> result(x.size()*y.size());
+ for(int j = 0; j < x.size(); j++) {
+ for(int i = 0; i < y.size(); i++) {
+ result[j*y.size() + i] = x[j]*y[i];
+ }
+ }
+ return result;
+}
+
+static double
+uniform() {
+ return double(rand())/ RAND_MAX;
+}
+
+static void
+matrix_times_vector(valarray<double> const &matrix, /* m * n */
+ valarray<double> const &vec, /* n */
+ valarray<double> &result) /* m */
+{
+ unsigned n = vec.size();
+ unsigned m = result.size();
+ assert(m*n == matrix.size());
+ const double* mp = &matrix[0];
+ for (unsigned i = 0; i < m; i++) {
+ double res = 0;
+ for (unsigned j = 0; j < n; j++)
+ res += *mp++ * vec[j];
+ result[i] = res;
+ }
+}
+
+static double
+Linfty(valarray<double> const &vec) {
+ return std::max(vec.max(), -vec.min());
+}
+
+int
+main (void)
+{
+ double tolerance = 1e-6;
+ for(int iters = 0; iters < 100; iters++) {
+ const unsigned N = unsigned(uniform()*40) + 1;
+ double A_data[N*N];
+ printf("%ux%u matrix\n", N,N);
+ for(int r = 0; r < N; r++) {
+ for(int c = 0; c <= r; c++) {
+ A_data[r*N + c] = A_data[c*N + r] = fabs(uniform());
+ }
+ }
+
+ double * A_c[N];
+ for(int i = 0; i < N; i++)
+ A_c[i] = &A_data[N*i];
+
+ double b_data[N];
+ for(int i = 0; i < N; i++)
+ b_data[i] = uniform()*3;
+ std::valarray<double> b(b_data, N), xx(0.0, N);
+ std::valarray<double> A(A_data, N*N);
+
+ conjugate_gradient(A, xx, b, N, tolerance, 2*N);
+
+ gsl_matrix_view m
+ = gsl_matrix_view_array (A_data, N, N);
+ gsl_vector_view bgsl
+ = gsl_vector_view_array (b_data, N);
+
+ gsl_vector *xgsl = gsl_vector_alloc (N);
+
+ int s;
+
+ gsl_permutation * p = gsl_permutation_alloc (N);
+
+ gsl_linalg_LU_decomp (&m.matrix, p, &s);
+
+ gsl_linalg_LU_solve (&m.matrix, p, &bgsl.vector, xgsl);
+
+ std::valarray<double> gsl_xx(0.0, N);
+ for(unsigned i = 0; i < xx.size(); i++) {
+ gsl_xx[i] = gsl_vector_get(xgsl, i);
+ }
+
+ double err = Linfty(xx - gsl_xx);
+ printf ("|xx-nxgsl|_infty = %g\n", err);
+ if(err > tolerance) {
+#if 0 //dubious value
+ for(int r = 0; r < N; r++) {
+ for(int c = 0; c < N; c++) {
+ printf("%g ", A_data[r*N + c]);
+ }
+ printf("\n");
+ }
+#endif
+ printf("\nx njh-cg = \n");
+ for(unsigned i = 0; i < xx.size(); i++)
+ printf("%g ", xx[i]);
+ printf("\nxgsl = ");
+ for(unsigned i = 0; i < xx.size(); i++)
+ printf("%g ", gsl_xx[i]);
+ printf("\n");
+ valarray<double> result(0.0,N);
+ matrix_times_vector(A, xx, result);
+ result -= b;
+ printf("\nA xx -b = ");
+ for(unsigned i = 0; i < xx.size(); i++)
+ printf("%g ", result[i]);
+ printf("\n");
+ matrix_times_vector(A, gsl_xx, result);
+ result -= b;
+ printf("\nA gsl_xx -b = ");
+ for(unsigned i = 0; i < xx.size(); i++)
+ printf("%g ", result[i]);
+ printf("\n");
+
+ printf("FAILED!!!!!!!!!!!!!!!!!!!!!!!!\n");
+ exit(1);
+ }
+ }
+ return 0;
+}
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
diff --git a/src/3rdparty/adaptagrams/libcola/tests/topology.cpp b/src/3rdparty/adaptagrams/libcola/tests/topology.cpp
new file mode 100644
index 0000000..4c94ef7
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/topology.cpp
@@ -0,0 +1,177 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/** \file topology.cpp
+ *
+ * tests topology preserving layout. graph is a triangle.
+ * We have a fourth disconnected node starting inside the triangle.
+ * We give the disconnected node a desired position outside the triangle
+ * and begin layout. Layout should converge to near zero stress as all
+ * edges should be able to reach their desired lengths, and disconnected
+ * node should still be inside the triangle at the end.
+ *
+ *
+ * Authors:
+ * Tim Dwyer <tgdwyer@gmail.com>
+ */
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+#include <vector>
+#include <valarray>
+#include <algorithm>
+#include <float.h>
+#include <libcola/cola.h>
+#include <libtopology/topology_graph.h>
+#include "graphlayouttest.h"
+using namespace std;
+using namespace cola;
+
+topology::Node* addNode(
+ topology::Nodes& vs, vpsc::Rectangle* r) {
+ topology::Node *v = new topology::Node(vs.size(), r);
+ vs.push_back(v);
+ return v;
+}
+void addToPath(topology::EdgePoints& ps, topology::Node *v, topology::EdgePoint::RectIntersect i) {
+ ps.push_back(new topology::EdgePoint(v,i));
+}
+struct SetDesiredPos : public PreIteration {
+ SetDesiredPos(Locks& locks) : PreIteration(locks) {}
+ bool operator()() {
+ return true;
+ }
+};
+void writeFile(const topology::Nodes& vs, const topology::Edges& es, const char *outputFileName) {
+ const unsigned n=vs.size();
+ vector<cola::Edge> cedges;
+
+ for(unsigned i=0;i<es.size();i++) {
+ cedges.push_back(make_pair(1,2));
+ }
+
+ vector<straightener::Route*> routes;
+ for(topology::Edges::const_iterator e=es.begin();e!=es.end();++e) {
+ routes.push_back((*e)->getRoute());
+ }
+
+ vector<string> labels(n);
+ for(unsigned i=0;i<n;++i) {
+ stringstream ss;
+ ss << i;
+ labels[i]=ss.str();
+ }
+
+ vector<vpsc::Rectangle*> rs;
+ for(topology::Nodes::const_iterator i=vs.begin();i!=vs.end();++i) {
+ rs.push_back((*i)->rect);
+ }
+ OutputFile of(rs,cedges,nullptr,outputFileName,true,false);
+ of.setLabels(labels);
+ of.routes=&routes;
+ of.generate();
+
+ for_each(routes.begin(),routes.end(),delete_object());
+}
+struct Test : TestConvergence {
+ Test(const double d,const unsigned i,topology::Nodes& vs, topology::Edges& es) : TestConvergence(d,i), vs(vs), es(es) {}
+ bool operator()(const double new_stress, valarray<double> & X, valarray<double> & Y) {
+ cout << "stress="<<new_stress<<" iteration="<<iterations<<endl;
+ stringstream ss;
+ ss << "topology-" << setfill('0') << setw(3) << ++iterations << ".svg";
+ writeFile(vs,es,ss.str().c_str());
+ if(iterations<100) {
+ return false;
+ }
+ return true;
+ return TestConvergence::operator()(new_stress,X,Y);
+ }
+ double lastStress;
+ topology::Nodes& vs;
+ topology::Edges& es;
+};
+void randomMove(int i) {
+ printf("We have a triangle of three connected nodes and a fourth disconnected node. We set the fourth node's desired position at a point some random direction outside the triangle.\n");
+ printf("Using srand=%d\n",i);
+ srand(i);
+ const unsigned V = 4;
+ Edge edge_array[] = { Edge(0, 1), Edge(1, 2), Edge(2, 0) };
+ const std::size_t E = sizeof(edge_array) / sizeof(Edge);
+ vector<Edge> es(edge_array,edge_array+E);
+ vector<vpsc::Rectangle*> rs;
+ double x[]={200,250,300,250},y[]={200,250,200,225},size=10;
+ for(unsigned i=0;i<V;++i) {
+ rs.push_back(new vpsc::Rectangle(x[i],x[i]+size,y[i],y[i]+size));
+ }
+ double idealLength=60;
+ // set up topology graph
+ topology::Nodes vs;
+ for(vector<Rectangle*>::iterator i = rs.begin(); i!=rs.end();++i) {
+ addNode(vs,*i);
+ }
+ topology::Edges tes;
+ unsigned eID=0;
+ for(vector<Edge>::iterator e=es.begin();e!=es.end();++e, ++eID) {
+ topology::EdgePoints ps;
+ addToPath(ps,vs[e->first],topology::EdgePoint::CENTRE);
+ addToPath(ps,vs[e->second],topology::EdgePoint::CENTRE);
+ tes.push_back(new topology::Edge(eID, idealLength, ps));
+ }
+ writeFile(vs,tes,"topology-000.svg");
+ Locks locks;
+ // we move the 4th node somewhere outside the triangle. The triangle should be
+ // dragged along!
+ const double PI = 2.0*acos(0.0);
+ double angle = getRand(2.0*PI);
+ double dx=150*cos(angle), dy=150*sin(angle);
+
+ double lx=rs[3]->getCentreX()+dx,
+ ly=rs[3]->getCentreY()+dy;
+ //double lx=353.886210, ly=342.789705;
+ locks.push_back(Lock(3,lx,ly));
+ printf(" Lock: %f,%f\n",lx,ly);
+ SetDesiredPos preIteration(locks);
+ Test test(0.00001,100,vs,tes);
+ ConstrainedFDLayout alg(rs,es,idealLength,nullptr,test,&preIteration);
+
+ alg.setTopology(&vs,&tes);
+ alg.run(true,true);
+ double finalStress=alg.computeStress();
+ printf("finalStress=%f\n",finalStress);
+
+ //assert(finalStress<1e-5);
+ for_each(rs.begin(),rs.end(),delete_object());
+ for_each(tes.begin(),tes.end(),delete_object());
+ for_each(vs.begin(),vs.end(),delete_object());
+}
+int main() {
+ unsigned i=0;
+ for(;i<1;i++) {
+ randomMove(i);
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=80 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/trees.cpp b/src/3rdparty/adaptagrams/libcola/tests/trees.cpp
new file mode 100644
index 0000000..72fb296
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/trees.cpp
@@ -0,0 +1,103 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#include<iostream>
+#include<vector>
+#include <cmath>
+#include <time.h>
+#include <valarray>
+
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+
+void makeEdge(unsigned u, unsigned v,
+ vector<Edge> &edges, CompoundConstraints &cy) {
+ edges.push_back(make_pair(u,v));
+ cy.push_back(new SeparationConstraint(u,v,20));
+}
+vector<Edge> random_tree(unsigned depth, unsigned maxbranch, unsigned &V,
+ CompoundConstraints &cx, CompoundConstraints &cy) {
+ vector<Edge> edges;
+ unsigned lstart=0, lend=1;
+ V=0;
+ for(unsigned i=0;i<depth;i++) {
+ for(unsigned j=lstart;j<lend;j++) {
+ //makeEdge(j,++V,edges,cy);
+ //makeEdge(j,++V,edges,cy);
+ for(unsigned k=0;k<maxbranch;k++) {
+ double r=(double)rand()/(double)RAND_MAX;
+ if(r < 0.5) {
+ makeEdge(j,++V,edges,cy);
+ }
+ }
+ }
+ lstart=lend;
+ lend=V+1;
+ }
+ V++;
+ DFS::Graph dfs(V,edges);
+ for(unsigned i=1;i<dfs.order.size();i++) {
+ cx.push_back(
+ new SeparationConstraint(dfs.order[i-1],dfs.order[i],0.5));
+ }
+ /*
+ for(unsigned i=0;i<dfs.leaves.size();i++) {
+ for(unsigned j=1;j<dfs.leaves[i].size();j++) {
+ cx.push_back(
+ new SeparationConstraint(dfs.leaves[i][j-1],dfs.leaves[i][j],10));
+ }
+ }
+ */
+ return edges;
+}
+int main() {
+ unsigned V;
+ CompoundConstraints cx,cy;
+ //srand(time(nullptr));
+ srand(3);
+ vector<Edge> es = random_tree(7,4,V,cx,cy);
+ double defaultEdgeLength=40;
+
+ cout << "V="<<V<<endl;
+ double width=1000;
+ double height=1000;
+ vector<pair<double,double> > startpos(V);
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ startpos[i]=make_pair(x,y);
+ }
+ const char *testname="trees";
+ run_test(startpos,es,defaultEdgeLength,cx,cy,CG,false,testname,"cg");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,IP,false,testname,"ip");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,false,testname,"sgp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,false,testname,"ugp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,IP,true,testname,"cip");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,SGP,true,testname,"csgp");
+ run_test(startpos,es,defaultEdgeLength,cx,cy,UGP,true,testname,"cugp");
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/unconstrained.cpp b/src/3rdparty/adaptagrams/libcola/tests/unconstrained.cpp
new file mode 100644
index 0000000..f6f112b
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/unconstrained.cpp
@@ -0,0 +1,71 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/** \file unconstrained.cpp
+ *
+ * Unconstrained graph layout test. Simple graph with 4 nodes and 4 edges,
+ * a triangle with a dangle. Final stress checked.
+ *
+ *
+ * Authors:
+ * Tim Dwyer <tgdwyer@gmail.com>
+ */
+#include <iostream>
+#include <fstream>
+
+#include <vector>
+#include <valarray>
+#include <algorithm>
+#include <float.h>
+#include "graphlayouttest.h"
+using namespace std;
+
+using namespace cola;
+int main() {
+
+ const unsigned V = 4;
+ Edge edge_array[] = { Edge(0, 1), Edge(1, 2), Edge(2, 3), Edge(1, 3) };
+ const std::size_t E = sizeof(edge_array) / sizeof(Edge);
+ vector<Edge> es(E);
+ copy(edge_array,edge_array+E,es.begin());
+ double width=100;
+ double height=100;
+ vector<vpsc::Rectangle*> rs;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+5,y,y+5));
+ }
+ CheckProgress test(1e-9,100);
+ ConstrainedFDLayout alg(rs,es,width/2,nullptr,&test);
+ alg.run();
+ double stress = alg.computeStress();
+ assert(stress < 0.0013);
+ OutputFile output(rs,es,nullptr,"unconstrained.svg");
+ output.generate();
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
diff --git a/src/3rdparty/adaptagrams/libcola/tests/unsatisfiable.cpp b/src/3rdparty/adaptagrams/libcola/tests/unsatisfiable.cpp
new file mode 100644
index 0000000..4e768f7
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/unsatisfiable.cpp
@@ -0,0 +1,85 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library in the file LICENSE; if not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+
+/** \file
+ * Interface between Inkscape code (SPItem) and graphlayout functions.
+ *
+ * Authors:
+ * Tim Dwyer <tgdwyer@gmail.com>
+ */
+#include <iostream>
+
+#include <vector>
+#include <algorithm>
+#include <float.h>
+#include <libcola/cola.h>
+#include <libvpsc/exceptions.h>
+#include <libvpsc/constraint.h>
+#include "graphlayouttest.h"
+
+using namespace std;
+using namespace cola;
+int main() {
+
+ const unsigned V = 2;
+ typedef pair < unsigned, unsigned >Edge;
+ Edge edge_array[] = { Edge(0, 1) };
+ unsigned E = sizeof(edge_array) / sizeof(Edge);
+ vector<Edge> es(edge_array,edge_array+E);
+ double width=100;
+ double height=100;
+ vector<vpsc::Rectangle*> rs;
+ for(unsigned i=0;i<V;i++) {
+ double x=getRand(width), y=getRand(height);
+ rs.push_back(new vpsc::Rectangle(x,x+5,y,y+5));
+ }
+ ConstrainedFDLayout alg(rs,es,width/2);
+ CompoundConstraints ccs;
+ AlignmentConstraint ac(vpsc::YDIM, 1);
+ ccs.push_back(&ac);
+ ac.addShape(0,0);
+ ac.addShape(1,0);
+ ccs.push_back(new SeparationConstraint(vpsc::YDIM, 0,1,10));
+ alg.setConstraints(ccs);
+ try {
+ alg.run();
+ } catch (vpsc::UnsatisfiableException& e) {
+ cerr << "Unsatisfiable" << endl;
+ for(vector<vpsc::Constraint*>::iterator i=e.path.begin();
+ i!=e.path.end();i++) {
+ cout << **i << endl;
+ }
+ exit(1);
+ }
+ //assert(fabs(rs[0]->getCentreX()-rs[3]->getCentreX())<0.001);
+ cout<<rs[0]->getCentreX()<<","<<rs[1]->getCentreX()<<endl;
+ //output_svg(rs,es,"unsatisfiable.svg");
+ for(unsigned i=0;i<V;i++) {
+ delete rs[i];
+ }
+ return 0;
+}
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4:textwidth=99 :
diff --git a/src/3rdparty/adaptagrams/libcola/tests/view_cd_output.sh b/src/3rdparty/adaptagrams/libcola/tests/view_cd_output.sh
new file mode 100755
index 0000000..cb74ae8
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/view_cd_output.sh
@@ -0,0 +1,43 @@
+#! /bin/bash
+
+if [ $# -lt 1 ] ; then
+ echo "Need case letter (eg: A) or ALL for all cases (CLEAN to delete)"
+ exit
+else
+ CASE=$1
+ shift
+fi
+
+cd /home/kierans/libcola3/libcola/tests
+
+if [ $CASE == 'a' -o $CASE == 'A' ] ; then
+ inkview cycle_detector_case_a.svg
+fi
+
+if [ $CASE == 'b' -o $CASE == 'B' ] ; then
+ inkview cycle_detector_case_b.svg
+fi
+
+if [ $CASE == 'c' -o $CASE == 'C' ] ; then
+ inkview cycle_detector_case_c.svg
+fi
+
+if [ $CASE == 'd' -o $CASE == 'D' ] ; then
+ inkview cycle_detector_case_d.svg
+fi
+
+if [ $CASE == 'e' -o $CASE == 'E' ] ; then
+ inkview cycle_detector_case_e.svg
+fi
+
+if [ $CASE == 'f' -o $CASE == 'F' ] ; then
+ inkview cycle_detector_case_f.svg
+fi
+
+if [ $CASE == 'all' -o $CASE == 'ALL' ] ; then
+ inkview cycle_detector_case_a.svg cycle_detector_case_b.svg cycle_detector_case_c.svg cycle_detector_case_d.svg cycle_detector_case_e.svg cycle_detector_case_f.svg
+fi
+
+if [ $CASE == 'clean' ] ; then
+ rm cycle_detector_case* -fv
+fi
diff --git a/src/3rdparty/adaptagrams/libcola/tests/view_mas_output.sh b/src/3rdparty/adaptagrams/libcola/tests/view_mas_output.sh
new file mode 100755
index 0000000..11f5a8a
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/tests/view_mas_output.sh
@@ -0,0 +1,43 @@
+#! /bin/bash
+
+if [ $# -lt 1 ] ; then
+ echo "Need case letter (eg: A) or ALL for all cases (CLEAN to delete)"
+ exit
+else
+ CASE=$1
+ shift
+fi
+
+cd /home/kierans/libcola3/libcola/tests
+
+if [ $CASE == 'a' -o $CASE == 'A' ] ; then
+ inkview mas_case_a.svg
+fi
+
+if [ $CASE == 'b' -o $CASE == 'B' ] ; then
+ inkview mas_case_b.svg
+fi
+
+if [ $CASE == 'c' -o $CASE == 'C' ] ; then
+ inkview mas_case_c.svg
+fi
+
+if [ $CASE == 'd' -o $CASE == 'D' ] ; then
+ inkview mas_case_d.svg
+fi
+
+if [ $CASE == 'e' -o $CASE == 'E' ] ; then
+ inkview mas_case_e.svg
+fi
+
+if [ $CASE == 'f' -o $CASE == 'F' ] ; then
+ inkview mas_case_f.svg
+fi
+
+if [ $CASE == 'all' -o $CASE == 'ALL' ] ; then
+ inkview mas_case_a.svg mas_case_b.svg mas_case_c.svg mas_case_d.svg mas_case_e.svg mas_case_f.svg
+fi
+
+if [ $CASE == 'clean' ] ; then
+ rm mas_case* -fv
+fi
diff --git a/src/3rdparty/adaptagrams/libcola/unused.h b/src/3rdparty/adaptagrams/libcola/unused.h
new file mode 100644
index 0000000..1e519fe
--- /dev/null
+++ b/src/3rdparty/adaptagrams/libcola/unused.h
@@ -0,0 +1,26 @@
+/*
+ * vim: ts=4 sw=4 et tw=0 wm=0
+ *
+ * libcola - A library providing force-directed network layout using the
+ * stress-majorization method subject to separation constraints.
+ *
+ * Copyright (C) 2006-2008 Monash University
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * See the file LICENSE.LGPL distributed with the library.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+*/
+
+#ifndef _UNUSED_H
+#define _UNUSED_H
+
+#define COLA_UNUSED(expr) do { (void)(expr); } while (0)
+
+#endif