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.
Last active
April 21, 2019 23:31
-
-
Save rpgove/2c523eb97f594de8ae0d04e305495c72 to your computer and use it in GitHub Desktop.
Composing multiple forces and constraints with Random Vertex Sampling
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: bsd-3-clause | |
height: 250 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 }); | |
}))); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"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