Skip to content

Instantly share code, notes, and snippets.

@rpgove
Last active April 21, 2019 23:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rpgove/2c523eb97f594de8ae0d04e305495c72 to your computer and use it in GitHub Desktop.
Save rpgove/2c523eb97f594de8ae0d04e305495c72 to your computer and use it in GitHub Desktop.
Composing multiple forces and constraints with Random Vertex Sampling
license: bsd-3-clause
height: 250

This example shows how to compose d3.forceManyBodySampled() with other forces and position constraints using the Les Miserables character interaction graph. Vertices repel each other using the Random Vertex Sampling algorithm; edges attract vertices, but the force is stronger for vertices within the same group; constraints confine vertices to rectangular regions based on the book volume that introduced each character; and each rectangular region has a gravitational force that draws the vertices of that region toward its center.

// Copyright 2019 Two Six Labs, LLC. v1.0.0 d3-force-sampled https://github.com/twosixlabs/d3-force-sampled/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.d3 = global.d3 || {})));
}(this, (function (exports) { 'use strict';
function constant(x) {
return function() {
return x;
};
}
function manyBodySampled() {
var nodes,
alpha,
strength = constant(-30),
strengths,
indicesRepulse,
prevIndex = 0,
distanceMin2 = 1,
distanceMax2 = Infinity,
neighborSize = function () {
return 15;
},
updateSize = function (nodes) { return Math.pow(nodes.length, 0.75); },
sampleSize = function (nodes) { return Math.pow(nodes.length, 0.25); },
numNeighbors,
numUpdate,
numSamples,
chargeMultiplier = function (nodes) {
return nodes.length < 100 ? 1 : nodes.length < 200 ? 3 : Math.sqrt(nodes.length);
},
cMult,
rand = Math.random;
function addRandomNode(node) {
var randIdx = Math.floor(rand() * nodes.length),
randNode = nodes[randIdx],
randDist = (node.x - randNode.x) * (node.x - randNode.x) + (node.y - randNode.y) * (node.y - randNode.y),
currIdx,
currNode,
currDist,
maxI,
maxDist = -Infinity,
i = -1;
// Is this already in the list?
if (node.nearest.indexOf(randIdx) >= 0) return;
// If there is room for another, add it.
if (node.nearest.length < numNeighbors) {
node.nearest.push(randIdx);
return;
}
// Replace the farthest away "neighbor" with the new node.
while (++i < node.nearest.length) {
currIdx = node.nearest[i];
currNode = nodes[currIdx];
currDist = Math.hypot(node.x - currNode.x, node.y - currNode.y);
if (currDist > maxDist) {
maxI = i;
maxDist = currDist;
}
}
if (randDist < maxDist) {
node.nearest[maxI] = randIdx;
}
}
function getRandIndices(indices, num) {
num = Math.floor(num);
var i,
n = nodes.length,
cnt = n - num,
randIdx,
temp;
// Choose random indices.
for (i = n-1; i >= cnt; --i) {
randIdx = Math.floor(rand() * i);
temp = indices[randIdx];
indices[randIdx] = indices[i];
indices[i] = temp;
}
return indices.slice(cnt);
}
function approxRepulse(node) {
var i,
randIndices,
currNode,
w,
x,
y,
l;
// Choose random nodes to update.
randIndices = getRandIndices(indicesRepulse, numSamples);
for (i = randIndices.length - 1; i >= 0; --i) {
currNode = nodes[randIndices[i]];
if (currNode === node) continue;
x = currNode.x - node.x;
y = currNode.y - node.y;
l = x * x + y * y;
if (l >= distanceMax2) continue;
// Limit forces for very close nodes; randomize direction if coincident.
if (x === 0) x = (rand() - 0.5) * 1e-6, l += x * x;
if (y === 0) y = (rand() - 0.5) * 1e-6, l += y * y;
if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
w = strengths[node.index] * alpha * cMult / l;
node.vx += x * w;
node.vy += y * w;
}
}
function constantRepulse(node) {
var i,
nearest,
currNode,
w,
x,
y,
l;
// Update the list of nearest nodes.
if (numNeighbors) addRandomNode(node);
nearest = node.nearest;
if (numNeighbors) for (i = nearest.length - 1; i >= 0; --i) {
currNode = nodes[nearest[i]];
if (currNode === node) continue;
x = currNode.x - node.x;
y = currNode.y - node.y;
l = x * x + y * y;
if (l >= distanceMax2) continue;
// Limit forces for very close nodes; randomize direction if coincident.
if (x === 0) x = (rand() - 0.5) * 1e-6, l += x * x;
if (y === 0) y = (rand() - 0.5) * 1e-6, l += y * y;
if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
w = strengths[node.index] * alpha * cMult / l;
node.vx += x * w;
node.vy += y * w;
}
}
function force(_) {
var i = 0, j = prevIndex, n = nodes.length, upperIndex = prevIndex + numUpdate;
for (alpha = _; i < n || j < upperIndex; ++i, ++j) {
if (j < upperIndex) approxRepulse(nodes[j%n]);
if (numNeighbors && i < n) constantRepulse(nodes[i]);
}
prevIndex = upperIndex % n;
}
function initialize() {
if (!nodes) return;
var i, n = nodes.length, node;
indicesRepulse = new Array(n);
for (i = 0; i < n; ++i) indicesRepulse[i] = i;
strengths = new Array(n);
// Cannot be negative.
numNeighbors = Math.min(Math.ceil(neighborSize(nodes)), n);
numNeighbors = numNeighbors < 0 ? 0 : Math.min(numNeighbors, nodes.length);
numUpdate = Math.ceil(updateSize(nodes));
numUpdate = numUpdate < 0 ? 0 : Math.min(numUpdate, n);
numSamples = Math.ceil(sampleSize(nodes));
numSamples = numSamples < 0 ? 0 : Math.min(numSamples, n);
cMult = chargeMultiplier(nodes);
alpha = 1;
for (i = 0; i < n; ++i) {
node = nodes[i];
strengths[node.index] = +strength(node, i, nodes);
node.nearest = [];
while (node.nearest.length < numNeighbors) addRandomNode(node);
}
}
force.initialize = function(_) {
nodes = _;
initialize();
};
force.strength = function(_) {
return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initialize(), force) : strength;
};
force.distanceMin = function(_) {
return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
};
force.distanceMax = function(_) {
return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
};
force.neighborSize = function(_) {
return arguments.length ? (neighborSize = typeof _ === "function" ? _ : constant(+_), initialize(), force) : neighborSize;
};
force.updateSize = function(_) {
return arguments.length ? (updateSize = typeof _ === "function" ? _ : constant(+_), initialize(), force) : updateSize;
};
force.sampleSize = function(_) {
return arguments.length ? (sampleSize = typeof _ === "function" ? _ : constant(+_), initialize(), force) : sampleSize;
};
force.chargeMultiplier = function(_) {
return arguments.length ? (chargeMultiplier = typeof _ === "function" ? _ : constant(+_), initialize(), force) : chargeMultiplier;
};
force.source = function(_) {
return arguments.length ? (rand = _, force) : rand;
};
return force;
}
exports.forceManyBodySampled = manyBodySampled;
Object.defineProperty(exports, '__esModule', { value: true });
})));
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
background: white;
}
.bars line {
stroke: #333;
stroke-width: 1.5px;
stroke-dasharray: 4px 10px;
}
.labels text {
font: 12px sans-serif;
text-anchor: middle;
}
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
fill: #d62333;
stroke: #fff;
stroke-width: 2px;
}
</style>
<svg></svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="d3-force-sampled.js"></script>
<script>
var width = 960;
var height = 250;
var nodeRadius = d3.scaleSqrt().range([4, 10]);
var linkWidth = d3.scaleLinear().range([1, 2 * nodeRadius.range()[0]])
var padding = nodeRadius.range()[1] + 2;
var radius = Math.min(width - padding, height - padding)/2;
var xGravity = d3.scaleOrdinal();
var xMin = d3.scaleOrdinal();
var xMax = d3.scaleOrdinal();
var drag = d3.drag()
.on('start', dragStart)
.on('drag', dragging)
.on('end', dragEnd);
var svg = d3.select('svg')
.attr('width', width)
.attr('height', height);
var linkForce = d3.forceLink()
.id(function(d) { return d.id; })
.strength(function (d) {
if (d.source.firstVolume === d.target.firstVolume)
return 0.2;
else return Math.pow(0.05, Math.abs(+d.source.firstVolume - +d.target.firstVolume));
});
var forceSim = d3.forceSimulation()
.velocityDecay(0.2)
.force('link', linkForce)
.force('charge', d3.forceManyBodySampled())
.force('forceX', d3.forceX().strength(0.01).x(function (d) { return xGravity(d.firstVolume); }))
.force('forceY', d3.forceY().strength(0.01).y(function (d) { return height / 2; }));
d3.json('jean.json').then(function (graph) {
var volumes = d3.set(graph.nodes.map(function (d) {
d.firstVolume = d.chapters.map(function (c) { return c[0]; }).sort()[0];
return d.firstVolume;
})).values().sort();
// Make sure small nodes are drawn on top of larger nodes
graph.nodes.sort(function (a, b) { return b.chapters.length - a.chapters.length; });
nodeRadius.domain([graph.nodes[graph.nodes.length-1].chapters.length, graph.nodes[0].chapters.length]);
linkWidth.domain(d3.extent(graph.links, function (d) { return d.chapters.length; }));
xGravity.domain(volumes).range(d3.range(0,volumes.length).map(function (d) { return width / (2 * volumes.length) + d * width / volumes.length; }));
xMin.domain(volumes).range(d3.range(0,volumes.length).map(function (d) { return d * width / volumes.length; }));
xMax.domain(volumes).range(d3.range(0,volumes.length).map(function (d) { return (d + 1) * width / volumes.length; }));
graph.nodes.forEach(function (d) { d.x = xGravity(d.firstVolume) + width * (Math.random() - 0.5); d.y = height * (Math.random() - 0.5); });
var bars = svg.append('g')
.attr('class', 'bars')
.selectAll('line')
.data(volumes.slice(0, volumes.length - 1))
.enter().append('line')
.attr('x1', function (d) { return xMax(d); })
.attr('y1', 0)
.attr('x2', function (d) { return xMax(d); })
.attr('y2', height);
var labels = svg.append('g')
.attr('class', 'labels')
.selectAll('text')
.data(volumes)
.enter().append('text')
.attr('x', function (d) { return xGravity(d); })
.attr('y', height - 10)
.attr('dy', '0.35em')
.text(function (d) { return 'Vol. ' + d; });
var link = svg.append('g')
.attr('class', 'links')
.selectAll('line')
.data(graph.links)
.enter().append('line')
.attr('stroke-width', function (d) { return linkWidth(d.chapters.length); });
var node = svg.append('g')
.attr('class', 'nodes')
.selectAll('circle')
.data(graph.nodes)
.enter().append('circle')
.attr('r', function (d) { return nodeRadius(d.chapters.length); })
.call(drag);
node.append('title').text(function (d) { return d.name; });
forceSim.nodes(graph.nodes)
.on('tick', tick);
forceSim.force('link').links(graph.links);
function tick () {
graph.nodes.forEach(function (d) {
// Viewport constraint.
if (d.y < 0 + nodeRadius(d.chapters.length)) d.y = nodeRadius(d.chapters.length);
else if (d.y > height - nodeRadius(d.chapters.length)) d.y = height - nodeRadius(d.chapters.length);
// Chapter boundary constraints.
if (d.x < xMin(d.firstVolume) + nodeRadius(d.chapters.length) + 2) d.x = xMin(d.firstVolume) + nodeRadius(d.chapters.length) + 2;
else if (d.x > xMax(d.firstVolume) - nodeRadius(d.chapters.length) - 2) d.x = xMax(d.firstVolume) - nodeRadius(d.chapters.length) - 2;
});
link
.attr('x1', function (d) { return d.source.x; })
.attr('x2', function (d) { return d.target.x; })
.attr('y1', function (d) { return d.source.y; })
.attr('y2', function (d) { return d.target.y; });
node
.attr('cx', function (d) { return d.x; })
.attr('cy', function (d) { return d.y; });
}
});
function dragStart (d) {
if (!d3.event.active) forceSim.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragging (d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragEnd (d) {
if (!d3.event.active) forceSim.alphaTarget(0);
d.fx = null;
d.fy = null;
}
function distance (d) {
if (d.source.firstVolume === d.target.firstVolume)
return 30;
else return 0.95 * Math.abs(xGravity(d.source.firstVolume) - xGravity(d.target.firstVolume));
}
</script>
{"nodes": [{"id": "TH", "chapters": ["1.4.1", "3.8.9", "5.9.4", "2.2.2", "5.3.3", "3.8.18", "3.8.19", "2.5.10", "3.8.12", "3.8.16", "3.8.17", "2.3.8", "2.3.9", "1.4.3", "2.3.2", "2.3.10", "3.8.8", "5.3.8", "3.8.6", "3.8.7", "3.8.4", "4.6.3", "4.8.4", "2.1.19", "5.6.1", "3.8.21", "3.8.20"], "name": "Th\\'enardier"}, {"id": "MN", "chapters": ["3.2.6", "4.6.1"], "name": "Magnon"}, {"id": "FT", "chapters": ["1.3.3", "1.3.2", "1.3.7", "3.6.6", "1.3.4", "1.3.8"], "name": "F\\'elix Tholomy\\`es"}, {"id": "BA", "chapters": ["4.12.6", "4.12.4", "4.12.3", "3.4.4", "4.14.1", "4.14.3", "3.4.1", "4.11.4", "4.11.5"], "name": "Bahorel"}, {"id": "BB", "chapters": ["3.8.21", "4.6.3", "3.8.20", "3.7.3", "4.8.4"], "name": "Babet"}, {"id": "BL", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.6", "1.3.4"], "name": "Blacheville"}, {"id": "BM", "chapters": ["1.7.10", "1.7.9", "1.5.12"], "name": "Monsieur Bamatabois"}, {"id": "JV", "chapters": ["5.1.24", "5.5.5", "5.5.4", "5.5.7", "5.5.8", "1.5.13", "3.8.18", "3.8.19", "1.6.1", "2.5.10", "3.8.14", "1.8.4", "2.3.10", "5.8.1", "2.8.8", "5.8.2", "4.5.2", "5.8.3", "5.3.11", "2.8.9", "5.3.10", "2.8.7", "2.8.6", "2.8.4", "2.8.1", "1.8.1", "4.3.7", "4.3.4", "4.3.5", "5.6.2", "1.8.2", "4.3.1", "4.3.8", "2.3.8", "1.2.11", "5.6.3", "1.7.11", "5.9.2", "4.3.2", "4.15.1", "4.15.2", "4.15.3", "5.8.4", "3.6.1", "3.6.2", "2.5.8", "3.8.9", "2.5.6", "2.2.1", "2.5.7", "2.5.4", "1.6.2", "5.3.4", "2.5.9", "5.3.2", "1.2.9", "5.3.9", "1.5.6", "1.5.1", "1.5.3", "1.5.2", "2.4.3", "2.4.2", "2.4.1", "4.9.1", "2.4.5", "2.4.4", "1.7.9", "1.7.8", "1.7.7", "1.8.5", "1.7.5", "1.7.4", "1.7.3", "1.7.2", "1.7.1", "1.8.3", "1.2.10", "2.3.9", "1.2.12", "1.2.13", "5.1.19", "5.1.18", "5.9.3", "1.7.10", "5.1.11", "2.3.6", "2.3.7", "1.2.6", "1.2.7", "1.2.4", "1.2.5", "1.2.3", "3.8.8", "5.3.8", "5.3.7", "5.3.6", "5.3.5", "2.5.5", "2.5.2", "2.5.3", "5.3.1", "2.5.1", "1.2.1", "5.1.9", "5.1.4", "5.1.6", "4.4.1", "4.4.2", "5.7.1", "5.9.5", "3.8.21", "3.8.20"], "name": "Jean Valjean"}, {"id": "BO", "chapters": ["3.4.2", "4.12.6", "3.4.1", "4.12.3", "4.12.2", "3.4.4", "5.1.14", "5.1.7", "5.1.11", "5.1.2", "4.14.1", "4.14.3", "4.14.5", "5.1.21", "3.8.15", "5.1.18"], "name": "Bossuet (Lesgle)"}, {"id": "JP", "chapters": ["4.12.6", "4.14.3", "3.4.1", "4.12.3", "4.12.8"], "name": "Jean Prouvaire"}, {"id": "BJ", "chapters": ["4.6.3", "4.8.4"], "name": "Brujon"}, {"id": "DA", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.6", "1.3.4"], "name": "Dahlia"}, {"id": "BT", "chapters": ["3.3.1", "3.3.3"], "name": "Baroness of T--"}, {"id": "BU", "chapters": ["3.1.8", "3.8.22"], "name": "Madame Burgon"}, {"id": "EN", "chapters": ["4.12.7", "4.12.6", "4.12.5", "4.12.4", "4.12.3", "5.1.21", "5.1.22", "5.1.23", "4.12.8", "4.1.6", "4.14.1", "4.14.3", "4.14.5", "5.1.19", "5.1.18", "5.1.14", "5.1.17", "5.1.11", "5.1.13", "5.1.12", "3.4.3", "3.4.1", "5.1.9", "5.1.8", "3.4.5", "5.1.5", "5.1.4", "5.1.7", "5.1.6", "5.1.3", "5.1.2"], "name": "Enjolras"}, {"id": "SP", "chapters": ["1.8.5", "1.7.1"], "name": "Sister Perp\\'etue"}, {"id": "FE", "chapters": ["4.12.6", "3.4.1", "4.12.3", "5.1.18", "5.1.21", "5.1.2", "4.14.1"], "name": "Feuilly"}, {"id": "BR", "chapters": ["1.7.11", "1.7.10"], "name": "Brevet"}, {"id": "BS", "chapters": ["5.2.3", "5.2.4"], "name": "Bruneseau"}, {"id": "JD", "chapters": ["3.1.8"], "name": "Jondrette"}, {"id": "ZE", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.4"], "name": "Zephine"}, {"id": "LI", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.4"], "name": "Listolier"}, {"id": "JA", "chapters": ["4.12.7", "5.4.1", "1.5.13", "1.5.12", "1.6.2", "4.14.3", "4.14.5", "2.5.10", "1.8.5", "4.15.1", "1.8.3", "5.1.19", "5.1.18", "1.5.5", "1.5.6", "1.8.4", "5.3.9", "5.3.3", "2.4.5", "5.3.11", "5.3.10", "5.1.6", "3.8.21", "3.8.20"], "name": "Javert"}, {"id": "BZ", "chapters": ["5.5.1", "2.2.2"], "name": "Boulatruelle"}, {"id": "GR", "chapters": ["2.8.7", "2.8.5"], "name": "Gribier"}, {"id": "FV", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.6", "1.3.4"], "name": "Favourite"}, {"id": "TM", "chapters": ["2.3.8", "1.4.1", "1.4.3", "2.3.9", "2.3.2", "2.3.3", "2.3.4", "3.8.18", "3.8.19", "4.6.1", "3.8.7", "3.8.12", "3.8.21", "3.8.20", "3.8.16", "3.8.17"], "name": "Madame Th\\'enardier"}, {"id": "LL", "chapters": ["2.4.3", "2.5.10", "2.4.5", "2.4.4"], "name": "Old woman 2"}, {"id": "GP", "chapters": ["3.3.2", "2.1.19", "3.3.4"], "name": "George Pontmercy"}, {"id": "TS", "chapters": ["4.5.3", "4.15.1"], "name": "Toussaint"}, {"id": "EP", "chapters": ["2.3.8", "4.14.6", "4.2.3", "3.8.7", "4.9.2", "4.11.6", "4.2.4", "3.8.11", "4.8.3", "4.8.4", "3.8.16"], "name": "Eponine"}, {"id": "XB", "chapters": ["5.1.16", "4.6.2"], "name": "Child 2"}, {"id": "MV", "chapters": ["3.2.8"], "name": "Madamoiselle Vaubois"}, {"id": "FN", "chapters": ["1.4.1", "1.5.9", "1.5.8", "1.5.10", "1.5.13", "1.5.12", "1.3.3", "1.8.5", "1.6.1", "1.7.1", "1.3.4", "1.8.4", "1.7.6", "1.3.9", "1.3.8", "1.8.1", "1.8.2", "1.8.3"], "name": "Fantine"}, {"id": "LP", "chapters": ["4.1.4", "4.1.3"], "name": "Louis Philippe"}, {"id": "JU", "chapters": ["1.7.11", "1.7.9", "1.7.10"], "name": "Judge of Douai"}, {"id": "NP", "chapters": ["1.1.1", "2.1.10", "2.1.8", "2.1.9", "2.1.7", "2.1.4"], "name": "Napoleon"}, {"id": "TG", "chapters": ["3.5.6", "3.2.8", "3.3.7", "4.5.1"], "name": "Lieutenant Theodule Gillenormand"}, {"id": "PO", "chapters": ["1.8.5", "1.7.4"], "name": "Old woman 1"}, {"id": "PL", "chapters": ["4.9.3", "3.5.4", "4.4.2"], "name": "Mother Plutarch"}, {"id": "PG", "chapters": ["1.2.13"], "name": "Petit Gervais"}, {"id": "SS", "chapters": ["1.7.6", "1.8.1", "1.7.1", "1.8.5"], "name": "Sister Simplice"}, {"id": "GU", "chapters": ["3.8.21", "4.6.3", "3.8.20", "3.7.3", "4.8.4"], "name": "Gueulemer"}, {"id": "CH", "chapters": ["1.7.11", "1.7.9", "1.7.10"], "name": "Champmathieu"}, {"id": "CO", "chapters": ["5.9.5", "2.5.6", "2.4.2", "4.8.3", "2.5.5", "5.5.4", "5.5.6", "4.3.4", "5.7.1", "4.3.5", "5.6.2", "5.8.1", "5.8.2", "5.8.3", "4.15.1", "2.3.8", "5.9.4", "1.4.3", "5.9.1", "2.3.1", "2.3.3", "2.3.4", "2.3.5", "2.3.6", "2.3.7", "2.4.4", "3.8.8", "2.4.3", "2.5.7", "2.5.4", "4.8.2", "2.5.2", "2.5.3", "2.4.5", "2.5.1", "4.5.1", "4.5.2", "4.5.3", "4.5.5", "4.5.6", "2.4.1", "2.8.4", "4.4.1", "4.3.6", "4.3.7", "3.6.2", "3.6.3", "4.8.6", "3.6.6", "5.6.1", "3.6.8", "5.1.10", "3.6.1", "4.8.1", "4.3.8"], "name": "Cosette"}, {"id": "CN", "chapters": ["1.7.11", "1.7.10"], "name": "Chenildieu"}, {"id": "CM", "chapters": ["4.12.6", "4.1.6", "3.4.1", "5.1.8", "3.4.5", "5.1.4", "5.1.7", "4.12.8", "4.14.1", "4.14.3", "4.11.4", "4.11.5", "5.1.21", "4.14.5", "5.1.2", "5.1.17", "5.1.18"], "name": "Combeferre"}, {"id": "CL", "chapters": ["1.1.4"], "name": "Countess de L\\^o"}, {"id": "CC", "chapters": ["1.7.11", "1.7.10"], "name": "Cochepaille"}, {"id": "VI", "chapters": ["1.5.9", "1.5.8"], "name": "Madame Victurnien"}, {"id": "IS", "chapters": ["1.2.6"], "name": "Isabeau"}, {"id": "XA", "chapters": ["5.1.16", "4.6.2"], "name": "Child 1"}, {"id": "MG", "chapters": ["5.5.4", "3.5.6", "3.3.1", "5.6.2", "3.3.2", "3.3.5", "3.3.7", "3.3.8", "3.2.8", "4.8.7"], "name": "Madamoiselle Gillenormand"}, {"id": "HL", "chapters": ["4.12.4", "4.12.2", "4.12.1"], "name": "Madame Hucheloup"}, {"id": "GG", "chapters": ["1.1.10"], "name": "G--"}, {"id": "GE", "chapters": ["1.1.4"], "name": "G\\'eborand"}, {"id": "GA", "chapters": ["4.12.7", "4.12.4", "4.12.3", "5.1.8", "5.1.15", "5.1.7", "3.1.8", "5.1.11", "4.14.3", "4.14.1", "4.11.1", "4.11.2", "4.11.3", "4.11.4", "4.14.7", "4.15.4", "4.14.5", "4.6.3", "4.6.2", "4.15.2", "3.8.22"], "name": "Gavroche"}, {"id": "CR", "chapters": ["4.12.6", "4.12.5", "4.12.4", "4.12.3", "5.1.21", "4.1.6", "4.14.1", "4.14.3", "4.14.5", "3.8.15", "5.1.18", "5.1.15", "5.1.14", "5.1.17", "5.1.13", "4.11.4", "4.11.5", "4.11.6", "4.8.3", "4.9.2", "3.4.2", "3.4.3", "3.4.1", "3.4.6", "3.4.5", "5.1.7", "5.1.2"], "name": "Courfeyrac"}, {"id": "QU", "chapters": ["4.12.8", "3.8.21", "3.8.20", "3.7.3", "4.8.4"], "name": "Claquesous"}, {"id": "AZ", "chapters": ["2.3.8", "3.8.16", "5.6.1"], "name": "Anzelma"}, {"id": "CV", "chapters": ["1.1.7"], "name": "Cravatte"}, {"id": "GI", "chapters": ["3.2.4", "5.5.3", "5.3.12", "5.5.6", "3.5.6", "3.2.3", "5.6.2", "3.3.1", "3.2.5", "3.2.6", "3.2.7", "3.3.5", "3.3.4", "3.2.2", "5.6.1", "3.3.8", "3.2.1", "3.2.8", "4.8.7", "5.5.4"], "name": "Monsieur Luke Esprit Gillenormand"}, {"id": "ME", "chapters": ["1.2.12", "1.1.2", "1.1.5", "1.1.4", "1.1.7", "1.1.6", "1.2.4", "1.2.5", "1.2.2", "1.2.3"], "name": "Madame Magloire"}, {"id": "JL", "chapters": ["1.2.1"], "name": "Jacquin Labarre"}, {"id": "FF", "chapters": ["1.5.6", "2.8.9", "2.8.8", "2.8.7", "1.5.7", "2.8.4", "2.8.3", "2.8.2", "2.8.1", "2.5.8", "2.5.9", "2.8.5"], "name": "Fauchelevent"}, {"id": "GT", "chapters": ["4.1.6", "3.4.1", "4.12.3", "4.12.2", "3.4.4", "5.1.23"], "name": "Grantaire"}, {"id": "MA", "chapters": ["4.13.3", "4.13.1", "5.1.21", "5.1.8", "5.1.24", "3.8.4", "5.3.7", "5.9.1", "5.6.2", "5.3.5", "5.6.1", "3.6.2", "4.3.6", "5.5.3", "5.5.2", "5.5.4", "5.5.7", "5.5.6", "5.5.8", "3.6.9", "5.7.1", "3.8.5", "5.3.2", "4.14.3", "3.3.2", "4.14.5", "4.14.4", "4.14.7", "4.14.6", "3.8.10", "3.3.5", "3.8.13", "3.8.14", "3.3.4", "5.9.5", "5.9.4", "5.1.19", "3.3.7", "5.3.1", "4.2.4", "4.8.6", "4.9.2", "3.4.6", "4.8.2", "3.8.11", "4.8.1", "5.3.6", "4.8.3", "5.3.4", "3.8.2", "3.8.3", "4.8.7", "3.8.1", "3.4.2", "3.4.3", "4.5.4", "5.3.12", "4.5.6", "3.4.5", "5.1.4", "3.5.3", "3.5.2", "3.5.1", "3.6.7", "3.3.1", "5.7.2", "4.2.1", "3.6.3", "3.6.4", "3.6.5", "3.6.6", "3.3.6", "3.6.8", "3.3.8", "3.6.1", "3.2.8", "3.3.3"], "name": "Marius"}, {"id": "MC", "chapters": ["1.1.4"], "name": "Marquis de Champtercier"}, {"id": "FA", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.4"], "name": "Fameuil"}, {"id": "MM", "chapters": ["4.2.3", "3.5.5", "3.5.4", "4.4.2", "4.14.1", "4.14.2", "3.3.5", "4.11.5", "4.9.3"], "name": "Monsieur Mabeuf"}, {"id": "MO", "chapters": ["4.8.4", "3.8.21", "4.6.2", "3.7.3", "4.4.2"], "name": "Montparnasse"}, {"id": "MB", "chapters": ["1.1.1", "1.1.2", "1.1.5", "1.1.4", "1.1.7", "1.1.9", "1.2.4", "1.2.2", "1.2.3"], "name": "Mademoiselle Baptistine"}, {"id": "MI", "chapters": ["2.8.3", "2.8.2", "2.6.7", "2.8.8"], "name": "Mother Innocent"}, {"id": "SN", "chapters": ["1.1.8", "1.1.14"], "name": "Count ***"}, {"id": "MT", "chapters": ["1.5.9", "1.5.10", "1.2.1"], "name": "Marguerite"}, {"id": "JO", "chapters": ["4.12.6", "3.4.1", "4.12.3", "4.12.2", "3.4.4", "5.1.21", "5.1.2", "4.14.1", "4.14.3"], "name": "Joly"}, {"id": "MP", "chapters": ["3.3.2", "3.2.8"], "name": "Madame Pontmercy"}, {"id": "MR", "chapters": ["1.2.1"], "name": "Madame de R--"}, {"id": "SC", "chapters": ["1.7.2"], "name": "Monsieur Scaufflaire"}, {"id": "MY", "chapters": ["1.1.1", "1.1.3", "1.1.2", "1.1.5", "1.1.4", "1.1.7", "1.1.6", "1.1.8", "1.2.12", "1.2.4", "1.2.5", "1.2.2", "1.2.3", "1.5.4", "1.1.11", "1.1.10", "1.1.13", "1.1.12", "1.1.14"], "name": "Monsieur Charles Fran\\c{c}ois Bienvenu Myriel"}], "links": [{"source": "EN", "target": "GT", "chapters": ["4.1.6", "5.1.23", "4.12.3"]}, {"source": "BJ", "target": "GU", "chapters": ["4.6.3", "4.8.4"]}, {"source": "MA", "target": "TH", "chapters": ["5.9.4", "3.8.4"]}, {"source": "BB", "target": "QU", "chapters": ["3.8.21", "3.8.20", "4.8.4"]}, {"source": "EN", "target": "QU", "chapters": ["4.12.8"]}, {"source": "BL", "target": "ZE", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "JA", "target": "PO", "chapters": ["1.8.5"]}, {"source": "BA", "target": "EN", "chapters": ["4.14.1", "4.12.6", "4.12.4", "4.12.3"]}, {"source": "JO", "target": "MM", "chapters": ["4.14.1"]}, {"source": "GT", "target": "HL", "chapters": ["4.12.2"]}, {"source": "BJ", "target": "GA", "chapters": ["4.6.3"]}, {"source": "FE", "target": "MA", "chapters": ["5.1.21"]}, {"source": "BM", "target": "JV", "chapters": ["1.7.9", "1.7.10"]}, {"source": "EN", "target": "JA", "chapters": ["4.12.7", "4.14.3", "5.1.6", "4.14.5"]}, {"source": "MO", "target": "TH", "chapters": ["4.8.4"]}, {"source": "EN", "target": "FE", "chapters": ["4.12.6", "4.12.3", "5.1.18", "5.1.21", "5.1.2", "4.14.1"]}, {"source": "JO", "target": "JP", "chapters": ["4.12.6", "4.12.3"]}, {"source": "JV", "target": "PO", "chapters": ["1.8.5", "1.7.4"]}, {"source": "MG", "target": "MP", "chapters": ["3.2.8"]}, {"source": "MG", "target": "MV", "chapters": ["3.2.8"]}, {"source": "GA", "target": "MO", "chapters": ["4.6.2"]}, {"source": "JV", "target": "PG", "chapters": ["1.2.13"]}, {"source": "MY", "target": "NP", "chapters": ["1.1.1"]}, {"source": "BU", "target": "GA", "chapters": ["3.1.8", "3.8.22"]}, {"source": "BO", "target": "HL", "chapters": ["4.12.2"]}, {"source": "GA", "target": "MM", "chapters": ["4.14.1"]}, {"source": "EP", "target": "TH", "chapters": ["3.8.7", "4.8.4", "3.8.16"]}, {"source": "FE", "target": "JP", "chapters": ["4.12.6", "4.12.3"]}, {"source": "EP", "target": "TM", "chapters": ["2.3.8", "3.8.16"]}, {"source": "EP", "target": "GU", "chapters": ["4.8.4"]}, {"source": "CO", "target": "JA", "chapters": ["4.15.1"]}, {"source": "CR", "target": "GA", "chapters": ["4.12.4", "4.12.3", "5.1.15", "5.1.7", "4.14.1", "4.11.4", "4.14.5"]}, {"source": "CV", "target": "MY", "chapters": ["1.1.7"]}, {"source": "BT", "target": "GI", "chapters": ["3.3.1"]}, {"source": "MA", "target": "MM", "chapters": ["3.3.5"]}, {"source": "FN", "target": "ZE", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.4"]}, {"source": "QU", "target": "TH", "chapters": ["3.8.20", "4.8.4"]}, {"source": "ME", "target": "MY", "chapters": ["1.2.12", "1.1.2", "1.1.5", "1.1.4", "1.1.7", "1.1.6", "1.2.4", "1.2.5", "1.2.2", "1.2.3"]}, {"source": "FE", "target": "JO", "chapters": ["4.14.1", "4.12.6", "4.12.3", "5.1.21", "5.1.2"]}, {"source": "CO", "target": "FT", "chapters": ["3.6.6"]}, {"source": "GA", "target": "JO", "chapters": ["4.14.1", "4.14.3", "4.12.3"]}, {"source": "GU", "target": "JA", "chapters": ["3.8.21"]}, {"source": "BA", "target": "MM", "chapters": ["4.14.1", "4.11.5"]}, {"source": "BB", "target": "EP", "chapters": ["4.8.4"]}, {"source": "CO", "target": "MG", "chapters": ["5.6.2", "5.5.4"]}, {"source": "CM", "target": "JP", "chapters": ["4.12.6", "4.12.8"]}, {"source": "GA", "target": "JA", "chapters": ["4.12.7"]}, {"source": "AZ", "target": "EP", "chapters": ["2.3.8", "3.8.16"]}, {"source": "CM", "target": "JO", "chapters": ["4.14.1", "4.12.6", "4.14.3", "5.1.21", "5.1.2"]}, {"source": "EN", "target": "JV", "chapters": ["5.1.4", "5.1.6", "5.1.9", "5.1.18"]}, {"source": "BO", "target": "CR", "chapters": ["3.4.2", "4.12.6", "4.12.3", "5.1.18", "5.1.14", "5.1.7", "5.1.2", "4.14.1", "4.14.5", "5.1.21", "3.8.15"]}, {"source": "FF", "target": "MI", "chapters": ["2.8.3", "2.8.2", "2.8.8"]}, {"source": "GA", "target": "JV", "chapters": ["4.15.2"]}, {"source": "GU", "target": "MO", "chapters": ["3.8.21", "4.8.4"]}, {"source": "JV", "target": "QU", "chapters": ["3.8.20"]}, {"source": "BU", "target": "JD", "chapters": ["3.1.8"]}, {"source": "CR", "target": "HL", "chapters": ["4.12.4"]}, {"source": "GA", "target": "JP", "chapters": ["4.12.3"]}, {"source": "DA", "target": "FN", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.4"]}, {"source": "GP", "target": "MA", "chapters": ["3.3.4"]}, {"source": "GG", "target": "MY", "chapters": ["1.1.10"]}, {"source": "BA", "target": "GA", "chapters": ["4.14.1", "4.11.4", "4.14.3", "4.12.4", "4.12.3"]}, {"source": "DA", "target": "FA", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "GA", "target": "GT", "chapters": ["4.12.3"]}, {"source": "BJ", "target": "EP", "chapters": ["4.8.4"]}, {"source": "CH", "target": "JU", "chapters": ["1.7.11", "1.7.9", "1.7.10"]}, {"source": "CH", "target": "JV", "chapters": ["1.7.11", "1.7.9", "1.7.10"]}, {"source": "GP", "target": "MP", "chapters": ["3.3.2"]}, {"source": "FE", "target": "MM", "chapters": ["4.14.1"]}, {"source": "DA", "target": "FT", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "DA", "target": "FV", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.6", "1.3.4"]}, {"source": "BA", "target": "GT", "chapters": ["4.12.3"]}, {"source": "GA", "target": "XA", "chapters": ["4.6.2"]}, {"source": "BJ", "target": "TH", "chapters": ["4.6.3", "4.8.4"]}, {"source": "GI", "target": "TG", "chapters": ["3.5.6"]}, {"source": "EP", "target": "MO", "chapters": ["4.8.4"]}, {"source": "BM", "target": "BR", "chapters": ["1.7.10"]}, {"source": "BJ", "target": "QU", "chapters": ["4.8.4"]}, {"source": "BA", "target": "HL", "chapters": ["4.12.4"]}, {"source": "BO", "target": "FE", "chapters": ["4.12.6", "4.12.3", "5.1.18", "5.1.21", "5.1.2", "4.14.1"]}, {"source": "JV", "target": "MA", "chapters": ["5.9.5", "5.5.4", "5.5.7", "5.1.4", "5.1.24", "3.6.2", "3.6.1", "5.7.1", "5.6.2", "5.5.8", "5.3.7", "5.3.6", "5.3.5", "5.3.4", "3.8.14", "5.3.2", "5.3.1"]}, {"source": "FF", "target": "JA", "chapters": ["1.5.6"]}, {"source": "MA", "target": "MG", "chapters": ["5.5.4", "3.3.1", "3.3.2", "3.3.5", "5.6.2", "3.2.8"]}, {"source": "BL", "target": "LI", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.4"]}, {"source": "BA", "target": "JO", "chapters": ["4.14.1", "4.12.6", "4.14.3", "4.12.3", "3.4.4"]}, {"source": "FF", "target": "JV", "chapters": ["2.8.4", "2.8.9", "2.8.8", "2.8.7", "1.5.6", "2.8.1", "2.5.8", "2.5.9"]}, {"source": "GU", "target": "JV", "chapters": ["3.8.20"]}, {"source": "CM", "target": "GT", "chapters": ["4.1.6"]}, {"source": "FV", "target": "LI", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "JV", "target": "ME", "chapters": ["1.2.4", "1.2.5", "1.2.3"]}, {"source": "GA", "target": "XB", "chapters": ["4.6.2"]}, {"source": "HL", "target": "JO", "chapters": ["4.12.2"]}, {"source": "BL", "target": "FT", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.4"]}, {"source": "MN", "target": "TM", "chapters": ["4.6.1"]}, {"source": "GI", "target": "JV", "chapters": ["5.6.2", "5.5.4"]}, {"source": "BA", "target": "JP", "chapters": ["4.12.6", "4.12.3"]}, {"source": "GU", "target": "QU", "chapters": ["3.8.21", "3.8.20", "4.8.4"]}, {"source": "EP", "target": "MA", "chapters": ["3.8.11", "4.8.3", "4.14.6", "4.9.2", "4.2.4"]}, {"source": "CM", "target": "MA", "chapters": ["5.1.4", "4.14.3", "4.14.5", "5.1.21", "3.4.5"]}, {"source": "GP", "target": "TH", "chapters": ["2.1.19"]}, {"source": "FA", "target": "LI", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.4"]}, {"source": "JV", "target": "MI", "chapters": ["2.8.8"]}, {"source": "GI", "target": "MG", "chapters": ["5.5.4", "3.5.6", "3.3.1", "5.6.2", "3.3.5", "3.3.8", "3.2.8", "4.8.7"]}, {"source": "EN", "target": "GA", "chapters": ["4.12.4", "4.12.3", "5.1.7", "5.1.11", "4.14.1", "4.14.5"]}, {"source": "SP", "target": "SS", "chapters": ["1.8.5", "1.7.1"]}, {"source": "BB", "target": "GA", "chapters": ["4.6.3"]}, {"source": "LI", "target": "ZE", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "CR", "target": "JP", "chapters": ["4.12.6", "4.14.3", "4.12.3"]}, {"source": "BZ", "target": "TH", "chapters": ["2.2.2"]}, {"source": "JA", "target": "QU", "chapters": ["3.8.21"]}, {"source": "FT", "target": "ZE", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "CN", "target": "JU", "chapters": ["1.7.11", "1.7.10"]}, {"source": "GA", "target": "HL", "chapters": ["4.12.4"]}, {"source": "BB", "target": "GU", "chapters": ["4.6.3", "3.8.21", "3.8.20", "4.8.4"]}, {"source": "BB", "target": "MO", "chapters": ["3.8.21", "4.8.4"]}, {"source": "JA", "target": "TH", "chapters": ["2.5.10", "5.3.3", "3.8.21", "3.8.20"]}, {"source": "JL", "target": "JV", "chapters": ["1.2.1"]}, {"source": "JA", "target": "TM", "chapters": ["3.8.21"]}, {"source": "BL", "target": "FN", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "CR", "target": "EP", "chapters": ["4.11.6"]}, {"source": "CR", "target": "FE", "chapters": ["4.12.6", "4.12.3", "5.1.18", "5.1.21", "5.1.2", "4.14.1"]}, {"source": "BA", "target": "FE", "chapters": ["4.14.1", "4.12.6", "4.12.3"]}, {"source": "MY", "target": "SN", "chapters": ["1.1.8", "1.1.14"]}, {"source": "EN", "target": "JO", "chapters": ["4.14.1", "4.12.6", "4.12.3", "5.1.21", "5.1.2"]}, {"source": "GE", "target": "MY", "chapters": ["1.1.4"]}, {"source": "EP", "target": "QU", "chapters": ["4.8.4"]}, {"source": "CO", "target": "MA", "chapters": ["5.9.5", "5.9.4", "5.9.1", "5.5.4", "4.5.6", "5.5.6", "3.6.2", "4.3.6", "3.6.1", "5.7.1", "3.6.3", "5.6.2", "3.6.6", "5.6.1", "3.6.8", "4.8.3", "4.8.2", "4.8.1", "4.8.6"]}, {"source": "EN", "target": "JP", "chapters": ["4.12.6", "4.14.3", "4.12.3", "4.12.8"]}, {"source": "CR", "target": "EN", "chapters": ["3.4.3", "4.1.6", "4.12.4", "4.12.3", "5.1.18", "3.4.5", "5.1.21", "5.1.7", "4.12.5", "5.1.13", "5.1.2", "4.14.1", "4.14.3", "4.14.5", "4.12.6", "5.1.17"]}, {"source": "JA", "target": "TS", "chapters": ["4.15.1"]}, {"source": "CR", "target": "MA", "chapters": ["3.4.2", "3.4.3", "3.4.6", "3.4.5", "5.1.21", "4.14.5", "4.8.3", "4.9.2"]}, {"source": "TH", "target": "TM", "chapters": ["2.3.8", "1.4.1", "2.3.2", "3.8.18", "3.8.19", "3.8.7", "3.8.12", "3.8.21", "3.8.20", "3.8.16", "3.8.17"]}, {"source": "FT", "target": "LI", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.4"]}, {"source": "MB", "target": "ME", "chapters": ["1.1.2", "1.1.5", "1.1.7", "1.2.4", "1.2.2", "1.2.3"]}, {"source": "CR", "target": "MM", "chapters": ["4.14.1", "4.11.5"]}, {"source": "BA", "target": "BO", "chapters": ["4.14.1", "4.12.6", "4.14.3", "4.12.3"]}, {"source": "JV", "target": "TM", "chapters": ["2.3.8", "2.3.9", "3.8.18", "3.8.20", "3.8.19"]}, {"source": "JV", "target": "TH", "chapters": ["2.3.8", "2.3.9", "5.3.8", "3.8.18", "3.8.19", "2.3.10", "3.8.8", "3.8.9", "3.8.20"]}, {"source": "CO", "target": "TS", "chapters": ["4.5.3", "4.15.1"]}, {"source": "MA", "target": "TG", "chapters": ["3.3.7"]}, {"source": "JA", "target": "LL", "chapters": ["2.5.10"]}, {"source": "JV", "target": "LL", "chapters": ["2.4.3", "2.4.5", "2.4.4"]}, {"source": "BJ", "target": "MO", "chapters": ["4.8.4"]}, {"source": "BO", "target": "CM", "chapters": ["4.12.6", "5.1.18", "5.1.21", "5.1.7", "5.1.2", "4.14.1", "4.14.3", "4.14.5"]}, {"source": "CO", "target": "TM", "chapters": ["2.3.8", "2.3.3", "2.3.4"]}, {"source": "BA", "target": "CM", "chapters": ["4.14.1", "4.12.6", "4.14.3", "4.11.4", "4.11.5"]}, {"source": "GI", "target": "MA", "chapters": ["5.5.3", "5.3.12", "5.5.6", "3.3.1", "5.6.2", "3.3.5", "3.3.4", "5.6.1", "3.3.8", "3.2.8", "4.8.7", "5.5.4"]}, {"source": "BO", "target": "MA", "chapters": ["3.4.2", "5.1.21", "4.14.3", "4.14.5"]}, {"source": "GA", "target": "TH", "chapters": ["4.6.3"]}, {"source": "FN", "target": "LI", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "EP", "target": "MM", "chapters": ["4.2.3"]}, {"source": "MB", "target": "MY", "chapters": ["1.1.1", "1.1.5", "1.1.4", "1.1.7", "1.2.4", "1.2.2", "1.2.3"]}, {"source": "GA", "target": "MA", "chapters": ["4.14.3", "4.14.5", "5.1.8", "4.14.7"]}, {"source": "BA", "target": "MA", "chapters": ["4.14.3"]}, {"source": "CO", "target": "TH", "chapters": ["3.8.8"]}, {"source": "GA", "target": "GU", "chapters": ["4.6.3"]}, {"source": "JV", "target": "TS", "chapters": ["4.15.1"]}, {"source": "CM", "target": "EN", "chapters": ["4.12.6", "4.1.6", "5.1.8", "3.4.5", "5.1.4", "5.1.7", "4.12.8", "4.14.1", "4.14.5", "5.1.21", "5.1.2", "5.1.17", "5.1.18"]}, {"source": "BM", "target": "JA", "chapters": ["1.5.12"]}, {"source": "CH", "target": "CN", "chapters": ["1.7.11", "1.7.10"]}, {"source": "EN", "target": "MA", "chapters": ["3.4.3", "5.1.19", "3.4.5", "5.1.21", "4.14.5", "5.1.4"]}, {"source": "BL", "target": "DA", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "FN", "target": "FV", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.4"]}, {"source": "BO", "target": "GT", "chapters": ["4.12.3", "4.12.2", "3.4.4"]}, {"source": "FN", "target": "FT", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "GI", "target": "MN", "chapters": ["3.2.6"]}, {"source": "JU", "target": "JV", "chapters": ["1.7.11", "1.7.9", "1.7.10"]}, {"source": "BM", "target": "JU", "chapters": ["1.7.9", "1.7.10"]}, {"source": "JA", "target": "JV", "chapters": ["5.1.6", "5.1.19", "5.1.18", "5.3.11", "5.3.10", "1.5.6", "1.5.13", "1.6.2", "1.8.4", "5.3.9", "2.5.10", "3.8.21", "2.4.5", "1.8.3"]}, {"source": "JA", "target": "SS", "chapters": ["1.8.5"]}, {"source": "JV", "target": "MR", "chapters": ["1.2.1"]}, {"source": "FN", "target": "MT", "chapters": ["1.5.9", "1.5.10"]}, {"source": "FA", "target": "FN", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "JV", "target": "MT", "chapters": ["1.2.1"]}, {"source": "BB", "target": "JA", "chapters": ["3.8.21"]}, {"source": "JV", "target": "MY", "chapters": ["1.2.12", "1.2.4", "1.2.5", "1.2.3"]}, {"source": "FV", "target": "ZE", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.4"]}, {"source": "CM", "target": "FE", "chapters": ["4.14.1", "4.12.6", "5.1.21", "5.1.18", "5.1.2"]}, {"source": "JV", "target": "MB", "chapters": ["1.2.4", "1.2.3"]}, {"source": "MM", "target": "PL", "chapters": ["4.9.3", "3.5.4", "4.4.2"]}, {"source": "BM", "target": "CC", "chapters": ["1.7.10"]}, {"source": "JV", "target": "MG", "chapters": ["5.6.2", "5.5.4"]}, {"source": "MC", "target": "MY", "chapters": ["1.1.4"]}, {"source": "BM", "target": "CH", "chapters": ["1.7.9", "1.7.10"]}, {"source": "DA", "target": "LI", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "CM", "target": "GA", "chapters": ["4.14.1", "4.11.4", "4.14.3", "4.14.5", "5.1.7"]}, {"source": "JV", "target": "MO", "chapters": ["4.4.2"]}, {"source": "FA", "target": "FV", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "BM", "target": "CN", "chapters": ["1.7.10"]}, {"source": "FA", "target": "FT", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.4"]}, {"source": "MO", "target": "QU", "chapters": ["3.8.21", "4.8.4"]}, {"source": "BO", "target": "MM", "chapters": ["4.14.1"]}, {"source": "FE", "target": "GA", "chapters": ["4.14.1", "4.12.3"]}, {"source": "CR", "target": "GT", "chapters": ["4.1.6", "4.12.3"]}, {"source": "IS", "target": "JV", "chapters": ["1.2.6"]}, {"source": "GT", "target": "JO", "chapters": ["4.12.3", "4.12.2"]}, {"source": "EN", "target": "HL", "chapters": ["4.12.4"]}, {"source": "GT", "target": "JP", "chapters": ["4.12.3"]}, {"source": "BA", "target": "CR", "chapters": ["4.12.6", "4.12.4", "4.12.3", "4.14.1", "4.11.4", "4.11.5"]}, {"source": "CL", "target": "MY", "chapters": ["1.1.4"]}, {"source": "BO", "target": "JO", "chapters": ["4.12.6", "4.12.3", "4.12.2", "5.1.21", "5.1.2", "4.14.1", "4.14.3"]}, {"source": "CR", "target": "JO", "chapters": ["4.14.1", "4.12.6", "4.12.3", "5.1.21", "5.1.2"]}, {"source": "FT", "target": "FV", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "MG", "target": "TG", "chapters": ["3.2.8", "3.3.7"]}, {"source": "EN", "target": "MM", "chapters": ["4.14.1"]}, {"source": "FN", "target": "JA", "chapters": ["1.8.4", "1.5.12", "1.5.13", "1.8.3"]}, {"source": "BB", "target": "JV", "chapters": ["3.8.20"]}, {"source": "CO", "target": "TG", "chapters": ["4.5.1"]}, {"source": "BO", "target": "JV", "chapters": ["5.1.11"]}, {"source": "BB", "target": "BJ", "chapters": ["4.6.3", "4.8.4"]}, {"source": "BM", "target": "FN", "chapters": ["1.5.12"]}, {"source": "JA", "target": "MO", "chapters": ["3.8.21"]}, {"source": "FN", "target": "JV", "chapters": ["1.5.13", "1.6.1", "1.8.2", "1.8.4", "1.8.1", "1.7.1", "1.8.3"]}, {"source": "FA", "target": "ZE", "chapters": ["1.3.3", "1.3.8", "1.3.4"]}, {"source": "CM", "target": "CR", "chapters": ["4.12.6", "4.1.6", "5.1.18", "3.4.5", "5.1.21", "5.1.7", "5.1.2", "4.14.1", "4.11.4", "4.11.5", "4.14.5", "5.1.17"]}, {"source": "BR", "target": "JV", "chapters": ["1.7.11", "1.7.10"]}, {"source": "BR", "target": "JU", "chapters": ["1.7.11", "1.7.10"]}, {"source": "FN", "target": "SP", "chapters": ["1.8.5"]}, {"source": "FN", "target": "SS", "chapters": ["1.7.6", "1.8.5"]}, {"source": "CN", "target": "JV", "chapters": ["1.7.11", "1.7.10"]}, {"source": "CM", "target": "MM", "chapters": ["4.14.1", "4.11.5"]}, {"source": "CC", "target": "CH", "chapters": ["1.7.11", "1.7.10"]}, {"source": "JO", "target": "MA", "chapters": ["5.1.21", "4.14.3"]}, {"source": "CC", "target": "CN", "chapters": ["1.7.11", "1.7.10"]}, {"source": "FE", "target": "GT", "chapters": ["4.12.3"]}, {"source": "FF", "target": "GR", "chapters": ["2.8.7", "2.8.5"]}, {"source": "DA", "target": "ZE", "chapters": ["1.3.3", "1.3.9", "1.3.8", "1.3.4"]}, {"source": "CO", "target": "GI", "chapters": ["5.6.2", "5.5.4", "5.5.6"]}, {"source": "BL", "target": "FV", "chapters": ["1.3.3", "1.3.8", "1.3.6", "1.3.4"]}, {"source": "BT", "target": "MA", "chapters": ["3.3.3"]}, {"source": "CO", "target": "JV", "chapters": ["2.5.6", "2.4.2", "2.4.1", "5.5.4", "4.3.7", "4.3.4", "5.7.1", "5.8.1", "5.8.2", "2.4.4", "5.9.5", "2.3.6", "2.3.7", "3.8.8", "2.4.3", "2.5.7", "2.5.4", "2.5.5", "2.5.2", "2.5.3", "2.4.5", "2.5.1", "4.5.2", "5.8.3", "2.8.4", "4.4.1", "3.6.1", "3.6.2", "4.3.5", "5.6.2", "4.3.8"]}, {"source": "BR", "target": "CC", "chapters": ["1.7.11", "1.7.10"]}, {"source": "BL", "target": "FA", "chapters": ["1.3.3", "1.3.2", "1.3.8", "1.3.4"]}, {"source": "CO", "target": "LL", "chapters": ["2.4.4"]}, {"source": "BR", "target": "CN", "chapters": ["1.7.11", "1.7.10"]}, {"source": "BO", "target": "GA", "chapters": ["4.14.1", "4.12.3", "4.14.3", "4.14.5", "5.1.7"]}, {"source": "BR", "target": "CH", "chapters": ["1.7.11", "1.7.10"]}, {"source": "BO", "target": "JP", "chapters": ["4.12.6", "4.12.3"]}, {"source": "JV", "target": "SC", "chapters": ["1.7.2"]}, {"source": "BB", "target": "TH", "chapters": ["4.6.3", "3.8.21", "3.8.20", "4.8.4"]}, {"source": "CC", "target": "JU", "chapters": ["1.7.11", "1.7.10"]}, {"source": "CC", "target": "JV", "chapters": ["1.7.11", "1.7.10"]}, {"source": "BB", "target": "TM", "chapters": ["3.8.20"]}, {"source": "FN", "target": "TH", "chapters": ["1.4.1"]}, {"source": "GU", "target": "TM", "chapters": ["3.8.20"]}, {"source": "JV", "target": "SS", "chapters": ["1.8.5", "1.8.1", "1.7.1"]}, {"source": "QU", "target": "TM", "chapters": ["3.8.20"]}, {"source": "GU", "target": "TH", "chapters": ["4.6.3", "3.8.20", "4.8.4"]}, {"source": "FN", "target": "TM", "chapters": ["1.4.1"]}, {"source": "XA", "target": "XB", "chapters": ["5.1.16", "4.6.2"]}, {"source": "FT", "target": "MA", "chapters": ["3.6.6"]}, {"source": "AZ", "target": "TM", "chapters": ["3.8.16"]}, {"source": "BO", "target": "EN", "chapters": ["4.12.6", "4.12.3", "5.1.18", "5.1.14", "5.1.7", "5.1.2", "4.14.1", "4.14.5", "5.1.21"]}, {"source": "AZ", "target": "TH", "chapters": ["3.8.16", "5.6.1"]}]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment