block by nitaku 8289840

Fractal treemap of Kyupapa (321 leaves)

Full Screen

Another unambiguous fractal treemap, this time a very small one.

index.js

(function() {
  var concat;

  concat = function(a) {
    return a.reduce((function(a, o) {
      return a.concat(o);
    }), []);
  };

  window.main = function() {
    /* "globals"
    */
    var categories, colorify, container, dx, dy, height, legend, path_generator, radius, scale, svg, vis, whiten, whiteness, width, _i, _ref, _ref2, _results;
    vis = null;
    width = 960;
    height = 500;
    svg = d3.select('body').append('svg').attr('width', width).attr('height', height);
    /* ZOOM and PAN
    */
    /* create container elements
    */
    container = svg.append('g').attr('transform', 'translate(470, 136)');
    container.call(d3.behavior.zoom().scaleExtent([1, 49]).on('zoom', (function() {
      return vis.attr('transform', "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    })));
    vis = container.append('g');
    /* create a rectangular overlay to catch events
    */
    /* WARNING rect size is huge but not infinite. this is a dirty hack
    */
    vis.append('rect').attr('class', 'overlay').attr('x', -500000).attr('y', -500000).attr('width', 1000000).attr('height', 1000000);
    /* END ZOOM and PAN
    */
    /* custom projection to make hexagons appear regular (y axis is also flipped)
    */
    radius = 6;
    dx = radius * 2 * Math.sin(Math.PI / 3);
    dy = radius * 1.5;
    path_generator = d3.geo.path().projection(d3.geo.transform({
      point: function(x, y) {
        return this.stream.point(x * dx / 2, -(y - (2 - (y & 1)) / 3) * dy / 2);
      }
    }));
    /* depth scale
    */
    whiteness = 0.6;
    whiten = function(color) {
      return d3.interpolateHcl(color, d3.hcl(void 0, 0, 100))(whiteness);
    };
    colorify = d3.scale.quantize().domain([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).range(['#396353', '#0DB14B', '#6DC067', '#ABD69B', '#DAEAC1', '#DFCCE4', '#C7B2D6', '#9474B4', '#754098', '#504971'].map(whiten));
    /* legend
    */
    legend = svg.append('g').attr('id', 'legend').attr('transform', 'translate(30,20)');
    scale = (function() {
      _results = [];
      for (var _i = _ref = colorify.domain()[0], _ref2 = colorify.domain()[1]; _ref <= _ref2 ? _i <= _ref2 : _i >= _ref2; _ref <= _ref2 ? _i++ : _i--){ _results.push(_i); }
      return _results;
    }).apply(this);
    categories = legend.selectAll('.category').data(scale).enter().append('g').attr('class', 'category').attr('transform', function(d, i) {
      return "translate(0," + (i * 22) + ")";
    });
    categories.append('rect').attr('x', 0).attr('y', 0).attr('width', 22).attr('height', 22).attr('fill', function(d) {
      return colorify(d);
    });
    categories.append('text').attr('y', 11).attr('dx', -4).attr('dy', '0.35em').text(function(d) {
      return d;
    });
    /* load topoJSON data
    */
    return d3.json('regions_depth.topo.json', function(error, data) {
      /* write the name of the land
      */
      var defs, depth, title;
      title = svg.append('text').attr('class', 'title').text(topojson.feature(data, data.objects['0']).features[0].properties.label).attr('transform', 'translate(80,40)');
      /* define the level zero region (the land)
      */
      defs = svg.append('defs');
      defs.append('path').datum(topojson.feature(data, data.objects['0']).features[0]).attr('id', 'land').attr('d', path_generator);
      /* faux land glow (using filters takes too much resources)
      */
      vis.append('use').attr('class', 'land-glow-outer').attr('xlink:href', '#land');
      vis.append('use').attr('class', 'land-glow-inner').attr('xlink:href', '#land');
      /* draw the depth levels
      */
      vis.selectAll('.contour').data(topojson.feature(data, data.objects.depth).features).enter().append('path').attr('class', 'contour').attr('d', path_generator).attr('fill', function(d) {
        return colorify(d.properties.depth);
      });
      /* draw the land border
      */
      vis.append('use').attr('class', 'land-fill').attr('xlink:href', '#land');
      /* draw the political boundaries
      */
      for (depth = 1; depth <= 2; depth++) {
        vis.append('path').datum(topojson.mesh(data, data.objects[depth], (function(a, b) {
          return a !== b;
        }))).attr('d', path_generator).attr('class', 'boundary').style('stroke-width', "" + (1.8 / depth) + "px");
      }
      /* draw the other labels
      */
      return vis.selectAll('.label').data(concat((function() {
        var _results2;
        _results2 = [];
        for (depth = 2; depth >= 1; depth--) {
          _results2.push(topojson.feature(data, data.objects[depth]).features.map(function(d) {
            return {
              feature: d,
              depth: depth
            };
          }));
        }
        return _results2;
      })())).enter().append('text').attr('class', 'label').attr('dy', '0.35em').attr('transform', (function(d) {
        var area, centroid;
        centroid = path_generator.centroid(d.feature);
        area = path_generator.area(d.feature);
        return "translate(" + centroid[0] + "," + centroid[1] + ") scale(" + (10 / d.depth) + ")";
      })).text(function(d) {
        return d.feature.properties.label;
      });
    });
  };

}).call(this);

index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Fractal treemap - Kyupapa (321)</title>
        <link type="text/css" href="index.css" rel="stylesheet"/>
        <script src="//d3js.org/d3.v3.min.js"></script>
        <script src="//d3js.org/topojson.v1.min.js"></script>
        <script src="index.js"></script>
    </head>
    <body onload="main()">
    </body>
</html>

gosper_regions_depth.py

from __future__ import print_function
from itertools import izip
import csv
import json
from shapely.geometry.polygon import Polygon
import shapely.wkt
from fiona import collection
from shapely.geometry import mapping
import re
import os

# yield the leaves of the tree, also computing each leaf path
def leafify(node, path=()):
    if 'c' not in node:
        node['path'] = path + (node,)
        yield node
    else:
        for c in node['c']:
            for l in leafify(c, path + (node,)):
                yield l 
                
def gosperify(tree_path, hexes_path, output_regions_dir_path, depth_filename):
    leaves_done = 0
    layers = {}
    depth_levels = {}
    
    print('Reading the tree...')
    
    with open(tree_path, 'rb') as tree_file:
        tree = json.loads(tree_file.read())
        
    print('Reading hexes...')
    
    # iterate over the hexes taken from the file
    with open(hexes_path, 'rb') as hexes_file:
        hexes_reader = csv.reader(hexes_file, delimiter=';', quotechar='#')
        
        for leaf, hexes_row in izip(leafify(tree), hexes_reader):
            path = leaf['path']
            hex = shapely.wkt.loads(hexes_row[0])
            
            for depth in xrange(len(path)):
                # add the hex to its political regions
                ancestor_or_self = path[depth]
                
                if depth not in layers:
                    layers[depth] = {}
                    
                if id(ancestor_or_self) not in layers[depth]:
                    layers[depth][id(ancestor_or_self)] = {
                        'geometry': hex,
                        'node': ancestor_or_self
                    }
                else:
                    layers[depth][id(ancestor_or_self)]['geometry'] = layers[depth][id(ancestor_or_self)]['geometry'].union(hex)
                    
                # add the hex to all the depth levels with d <= depth
                if depth not in depth_levels:
                    depth_levels[depth] = hex
                else:
                    depth_levels[depth] = depth_levels[depth].union(hex)
                    
            # logging
            leaves_done += 1
            print('%d leaves done' % leaves_done, end='\r')
    
    print('Writing political regions...')
    
    schema = {'geometry': 'Polygon', 'properties': {'label': 'str'}}
    
    if not os.path.exists(output_regions_dir_path):
        os.makedirs(output_regions_dir_path)
        
    for depth, regions in layers.items():
        with collection(output_regions_dir_path+'/'+str(depth)+'.json', 'w', 'GeoJSON', schema) as output:
            for _, region_obj in regions.items():
                output.write({
                    'properties': {
                        'label': region_obj['node']['l']
                    },
                    'geometry': mapping(region_obj['geometry'])
                })
            
    print('Writing depth_levels...')
    
    schema = {'geometry': 'Polygon', 'properties': {'depth': 'int'}}
    
    with collection(depth_filename, 'w', 'GeoJSON', schema) as output:
        for depth, region in depth_levels.items():
            output.write({
                'properties': {
                    'depth': depth
                },
                'geometry': mapping(region)
            })
            

index.coffee

concat = (a) -> a.reduce ((a,o) -> a.concat(o)), []

window.main = () ->
    ### "globals" ###
    vis = null
    
    width = 960
    height = 500
    
    svg = d3.select('body').append('svg')
        .attr('width', width)
        .attr('height', height)
        
    ### ZOOM and PAN ###
    ### create container elements ###
    container = svg.append('g')
        .attr('transform','translate(470, 136)')
        
    container.call(d3.behavior.zoom().scaleExtent([1, 49]).on('zoom', (() -> vis.attr('transform', "translate(#{d3.event.translate})scale(#{d3.event.scale})"))))
    
    vis = container.append('g')
    
    ### create a rectangular overlay to catch events ###
    ### WARNING rect size is huge but not infinite. this is a dirty hack ###
    vis.append('rect')
        .attr('class', 'overlay')
        .attr('x', -500000)
        .attr('y', -500000)
        .attr('width', 1000000)
        .attr('height', 1000000)
        
    ### END ZOOM and PAN ###
    
    ### custom projection to make hexagons appear regular (y axis is also flipped) ###
    radius = 6
    dx = radius * 2 * Math.sin(Math.PI / 3)
    dy = radius * 1.5
    
    path_generator = d3.geo.path()
        .projection d3.geo.transform({
            point: (x,y) ->
                this.stream.point(x * dx / 2, -(y - (2 - (y & 1)) / 3) * dy / 2)
        })
        
    ### depth scale ###
    whiteness = 0.6
    whiten = (color) -> d3.interpolateHcl(color, d3.hcl(undefined,0,100))(whiteness)
    colorify = d3.scale.quantize()
        .domain([0..9])
        .range(['#396353','#0DB14B','#6DC067','#ABD69B','#DAEAC1','#DFCCE4','#C7B2D6','#9474B4','#754098','#504971'].map(whiten))
        # .range(['#59A80F','#9ED54C','#C4ED68','#E2FF9E','#F0F2DD','#F8CA8C','#E9A189','#D47384','#AC437B','#8C286E'])
        # .range(['#FFFCF6','#FFF7DB','#FFF4C2','#FEECAE','#F8CA8C','#F0A848','#C07860','#A86060','#784860','#604860'])
        
    ### legend ###
    legend = svg.append('g')
        .attr('id','legend')
        .attr('transform', 'translate(30,20)')
        
    scale = [colorify.domain()[0]..colorify.domain()[1]]
    categories = legend.selectAll('.category')
        .data(scale)
      .enter().append('g')
        .attr('class', 'category')
        .attr('transform', (d,i) -> "translate(0,#{i*22})")
        
    categories.append('rect')
        .attr('x', 0).attr('y', 0)
        .attr('width', 22).attr('height', 22)
        .attr('fill', (d) -> colorify(d))
        
    categories.append('text')
        .attr('y', 11)
        .attr('dx', -4)
        .attr('dy', '0.35em')
        .text((d) -> d)
        
    ### load topoJSON data ###
    d3.json 'regions_depth.topo.json', (error, data) ->
        ### write the name of the land ###
        title = svg.append('text')
            .attr('class', 'title')
            .text(topojson.feature(data, data.objects['0']).features[0].properties.label)
            .attr('transform', 'translate(80,40)')
            
        ### define the level zero region (the land) ###
        defs = svg.append('defs')
        
        defs.append('path')
            .datum(topojson.feature(data, data.objects['0']).features[0])
            .attr('id', 'land')
            .attr('d', path_generator)
            
        ### faux land glow (using filters takes too much resources) ###
        vis.append('use')
            .attr('class', 'land-glow-outer')
            .attr('xlink:href', '#land')
            
        vis.append('use')
            .attr('class', 'land-glow-inner')
            .attr('xlink:href', '#land')
            
        ### draw the depth levels ###
        vis.selectAll('.contour')
            .data(topojson.feature(data, data.objects.depth).features)
          .enter().append('path')
            .attr('class', 'contour')
            .attr('d', path_generator)
            .attr('fill', (d) -> colorify(d.properties.depth))
            
        ### draw the land border ###
        vis.append('use')
            .attr('class', 'land-fill')
            .attr('xlink:href', '#land')
            
        ### draw the political boundaries ###
        for depth in [1..2]
            vis.append('path')
                .datum(topojson.mesh(data, data.objects[depth], ((a,b) -> a isnt b)))
                .attr('d', path_generator)
                .attr('class', 'boundary')
                .style('stroke-width', "#{1.8/depth}px")
                
        ### draw the other labels ###
        vis.selectAll('.label')
            .data(concat((topojson.feature(data, data.objects[depth]).features.map((d) -> {feature: d, depth: depth}) for depth in [2..1])))
          .enter().append('text')
            .attr('class', 'label')
            .attr('dy','0.35em')
            .attr('transform', ((d) ->
                centroid = path_generator.centroid(d.feature)
                area = path_generator.area(d.feature)
                return "translate(#{centroid[0]},#{centroid[1]}) scale(#{10/d.depth})"
            ))
            .text((d) -> d.feature.properties.label)
            

index.css

#land {
  fill: none;
}

.land-glow-outer {
  stroke: #eeeeee;
  stroke-width: 16px;
}

.land-glow-inner {
  stroke: #dddddd;
  stroke-width: 8px;
}

.land-fill {
  stroke: #444444;
  stroke-width: 2px;
}

.contour {
  stroke: none;
}

.category text {
  text-anchor: end;
  fill: #444444;
  font-family: sans-serif;
  font-weight: bold;
  font-size: 14px;
  pointer-events: none;
  text-shadow: -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white;
}

.boundary {
  stroke: #444444;
  fill: none;
  pointer-events: none;
}

@font-face {
  font-family: "Lacuna";
  src: url("lacuna.ttf");
}

.label {
  text-transform: capitalize;
  text-anchor: middle;
  font-size: 2.5px;
  fill: #444444;
  pointer-events: none;
  font-family: "Lacuna";
  text-shadow: -2px 0 white, 0 2px white, 2px 0 white, 0 -2px white, -1px -1px white, 1px -1px white, 1px 1px white, -1px 1px white;
}

.title {
  text-transform: capitalize;
  text-anchor: start;
  font-size: 24pt;
  fill: #444444;
  pointer-events: none;
  font-family: "Lacuna";
  text-shadow: -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white;
}

.overlay {
  fill: transparent;
}

index.sass

@mixin halo($color)
    text-shadow: -1px 0 $color, 0 1px $color, 1px 0 $color, 0 -1px $color
    
@mixin halo_double($color)
    text-shadow: -2px 0 $color, 0 2px $color, 2px 0 $color, 0 -2px $color, -1px -1px $color, 1px -1px $color, 1px 1px $color, -1px 1px $color
    
#land
    fill: none
    
.land-glow-outer
    stroke: #EEE
    stroke-width: 16px
    
.land-glow-inner
    stroke: #DDD
    stroke-width: 8px
    
.land-fill
    stroke: #444
    stroke-width: 2px
    
.contour
    stroke: none
    
.category text
    text-anchor: end
    fill: #444
    font-family: sans-serif
    font-weight: bold
    font-size: 14px
    pointer-events: none
    @include halo(white)
    
.boundary
    stroke: #444
    fill: none
    
    // avoid blinking when hovering regions
    pointer-events: none
    
@font-face
    font-family: 'Lacuna'
    src: url('lacuna.ttf')
    
.label
    text-transform: capitalize
    text-anchor: middle
    font-size: 2.5px
    fill: #444
    pointer-events: none
    font-family: 'Lacuna'
    @include halo_double(white)
    
.title
    text-transform: capitalize
    text-anchor: start
    font-size: 24pt
    fill: #444
    pointer-events: none
    font-family: 'Lacuna'
    @include halo(white)
    
// zoom and pan
.overlay
    fill: transparent

kyupapa_321.json

{"c": [{"c": [{"c": [{"c": [{"c": [{"l": "fokata"}, {"c": [{"l": "pasizoma"}, {"l": "arfusiopa"}], "l": "pafle"}, {"c": [{"l": "piibotri"}, {"l": "anflebugolu"}, {"l": "kyana"}, {"l": "koflenopi"}, {"c": [{"l": "aressibi"}], "l": "kyasu"}, {"l": "busifoko"}], "l": "sipa"}, {"l": "esse"}, {"l": "kanapakyu"}], "l": "kasuleno"}, {"c": [{"l": "sefle"}, {"l": "oo"}], "l": "boes"}, {"l": "mabu"}, {"l": "subuisu"}], "l": "sebu"}, {"l": "noketrike"}], "l": "gokafu"}, {"l": "zoosulu"}], "l": "gofunelu"}, {"c": [{"l": "luflenonopa"}, {"c": [{"c": [{"l": "fugonoango"}], "l": "esflesulupe"}, {"l": "lufo"}], "l": "pakasubono"}, {"c": [{"l": "kabutazo"}, {"l": "iboilui"}, {"l": "kyasufo"}, {"l": "futafufo"}, {"c": [{"l": "fletrikonape"}, {"c": [{"c": [{"l": "nokyanapa"}, {"c": [{"l": "komasuanne"}, {"l": "learbimano"}, {"l": "keflo"}, {"l": "flekekezo"}], "l": "tabu"}, {"l": "annoluarfo"}, {"l": "arseluflo"}, {"l": "taisi"}, {"l": "pifuanpa"}, {"c": [{"l": "tapi"}, {"l": "luopa"}], "l": "flepearnai"}], "l": "trisebibobi"}, {"c": [{"l": "estri"}, {"l": "fubifle"}, {"l": "nafubu"}, {"l": "nopale"}, {"c": [{"l": "napi"}, {"l": "zoflenafo"}], "l": "okyukyu"}, {"l": "kyukebole"}, {"l": "tase"}], "l": "pamasesi"}, {"l": "koespi"}, {"l": "tanepaflean"}, {"l": "notritai"}, {"l": "osi"}], "l": "artrikepa"}, {"l": "nakefotale"}, {"l": "kyapa"}], "l": "bumalu"}, {"l": "buanmago"}], "l": "koboarma"}, {"c": [{"l": "sigofumatri"}, {"c": [{"l": "lusike"}, {"l": "fogo"}, {"c": [{"c": [{"l": "flepiespibu"}, {"l": "okaarzosi"}, {"l": "floanta"}, {"c": [{"l": "kataan"}, {"l": "zonoluta"}, {"l": "anbu"}, {"l": "nosina"}], "l": "sekyubupe"}, {"l": "omabu"}, {"l": "esma"}, {"l": "nofumaflo"}], "l": "nobu"}], "l": "kyaflofupina"}], "l": "nesibo"}, {"c": [{"c": [{"c": [{"l": "flomaflepi"}, {"l": "butaflean"}, {"l": "trisibimafo"}, {"l": "lekakafu"}], "l": "arsegotako"}, {"l": "mabubotrise"}, {"c": [{"l": "seno"}, {"l": "fuan"}, {"c": [{"l": "anlebies"}, {"l": "fobule"}, {"l": "arbifoneno"}, {"l": "pekyatribule"}], "l": "manakaluflo"}, {"l": "peflolebiko"}, {"l": "kyuan"}], "l": "sikale"}, {"c": [{"c": [{"l": "pesuzofu"}, {"l": "goigo"}, {"l": "segoikeno"}, {"l": "peibigo"}, {"l": "keesgoeses"}, {"l": "nole"}], "l": "suifose"}, {"c": [{"l": "fokoesar"}, {"l": "nakyu"}, {"l": "buo"}, {"l": "sigotrise"}, {"l": "kana"}, {"l": "boanflefo"}], "l": "trinose"}], "l": "senesupe"}], "l": "tritaesfle"}, {"c": [{"c": [{"c": [{"l": "flolu"}, {"l": "flelunearne"}, {"l": "kokaise"}, {"l": "lupaflo"}, {"l": "bufufono"}], "l": "trikyusefle"}, {"l": "koflo"}, {"l": "masesepepi"}, {"l": "kose"}], "l": "sumapifo"}], "l": "paluar"}], "l": "esfukezobi"}, {"c": [{"l": "ibi"}, {"l": "zobi"}, {"c": [{"l": "anpebufloi"}, {"c": [{"c": [{"l": "nenope"}, {"l": "subuneno"}, {"l": "nabuzo"}, {"l": "arisitripe"}, {"l": "flear"}, {"l": "neke"}, {"l": "lese"}], "l": "piesanle"}, {"c": [{"l": "konake"}], "l": "buko"}, {"c": [{"l": "kyupebina"}, {"l": "selene"}], "l": "kyutatrio"}, {"l": "fosi"}, {"l": "keo"}], "l": "ifleanse"}, {"l": "anma"}, {"l": "estri"}], "l": "itrika"}, {"c": [{"l": "kyupikoesse"}, {"c": [{"l": "talukyaka"}], "l": "sepabule"}], "l": "peimakaes"}, {"c": [{"c": [{"l": "takakyuflo"}, {"c": [{"l": "pakyu"}, {"l": "kago"}, {"l": "floflokyanezo"}, {"l": "arpaigo"}, {"l": "nefle"}], "l": "arsu"}, {"c": [{"l": "near"}], "l": "osesu"}, {"l": "bieskyaka"}, {"l": "flokapitano"}, {"l": "fupaflofletri"}], "l": "nasi"}, {"l": "zosubuke"}, {"l": "kesipian"}, {"l": "fuzo"}, {"c": [{"l": "sufoopibi"}], "l": "biipa"}], "l": "zoes"}], "l": "suseo"}], "l": "fuzotrisilu"}, {"c": [{"l": "keseotries"}, {"l": "petafopasi"}, {"c": [{"c": [{"c": [{"l": "piose"}, {"l": "luko"}, {"l": "imaes"}, {"l": "anpego"}], "l": "esna"}, {"c": [{"l": "futri"}, {"l": "keoarkya"}, {"l": "bobimape"}, {"l": "paanfoitri"}], "l": "pekotrisu"}, {"l": "nalugonesi"}, {"l": "pao"}, {"l": "bisugogo"}, {"c": [{"l": "ipaar"}, {"c": [{"l": "fleke"}, {"l": "siflo"}], "l": "makya"}, {"l": "mamakaoma"}, {"l": "obu"}, {"l": "noopalena"}], "l": "suoneflole"}], "l": "okya"}, {"c": [{"l": "bunakolui"}, {"l": "lukeole"}, {"l": "fosinaflo"}], "l": "pikobi"}, {"l": "sule"}, {"l": "zopitrii"}, {"l": "okeke"}, {"l": "bubi"}, {"c": [{"l": "noarkyuna"}, {"l": "kako"}, {"c": [{"c": [{"l": "bisukyubopi"}, {"l": "sukya"}, {"l": "naesar"}, {"l": "kyuo"}, {"l": "otrika"}, {"l": "flepa"}], "l": "kyafoflekya"}, {"l": "kyunozo"}, {"c": [{"l": "tanekata"}, {"l": "trinoarar"}, {"l": "koluo"}, {"l": "ianle"}, {"l": "kyusu"}, {"l": "nenama"}], "l": "ifuar"}, {"c": [{"l": "legonomasi"}, {"l": "kyubosu"}, {"l": "leanifle"}], "l": "anpakyaneflo"}, {"c": [{"l": "zofosetri"}, {"l": "nokesusi"}, {"l": "kyuzo"}, {"l": "lenoanne"}, {"l": "senafle"}, {"l": "noeszopi"}], "l": "tamabi"}], "l": "gokyasugona"}, {"c": [{"l": "bigosi"}, {"c": [{"l": "sunotabuo"}, {"l": "peika"}], "l": "osemakyu"}], "l": "kyakear"}, {"c": [{"l": "bunao"}, {"c": [{"l": "koseko"}, {"l": "sunefusu"}, {"l": "nearoan"}], "l": "kyasi"}], "l": "fleflofle"}, {"l": "gokyuse"}], "l": "lubuflezo"}], "l": "lekyubose"}, {"c": [{"l": "triflo"}, {"c": [{"c": [{"c": [{"l": "eskafle"}, {"l": "sufopa"}, {"l": "sekeansisi"}, {"l": "zolunono"}, {"l": "tafu"}, {"l": "nokyakyu"}], "l": "lelepees"}, {"l": "seko"}], "l": "zotrikyaanle"}, {"l": "mago"}, {"c": [{"l": "luesbinosi"}, {"c": [{"l": "mabinosuar"}], "l": "kosu"}], "l": "nafloluzo"}], "l": "takya"}, {"l": "kyafleibibo"}, {"c": [{"c": [{"c": [{"l": "lekoflolulu"}, {"l": "pafo"}, {"l": "lupama"}], "l": "papi"}, {"l": "makyu"}, {"l": "butripesi"}, {"l": "lulugoma"}, {"c": [{"l": "boeskyanaflo"}, {"l": "sitabofuar"}, {"l": "bofleartase"}, {"l": "zobupafle"}], "l": "zokokesebi"}, {"l": "nozo"}], "l": "nabuseikya"}, {"l": "sisebu"}, {"c": [{"l": "penezo"}, {"l": "eskya"}], "l": "flozofletri"}, {"l": "funafleo"}], "l": "ketri"}, {"l": "arsubugo"}], "l": "fokasuflo"}, {"c": [{"c": [{"l": "sinabikesi"}, {"l": "nasufle"}, {"c": [{"l": "kyaflobo"}], "l": "kyunakasian"}], "l": "kyakaluflene"}, {"c": [{"l": "arse"}, {"c": [{"l": "tailees"}, {"l": "kotrifle"}], "l": "ikonezo"}, {"c": [{"l": "lesupifo"}], "l": "kamakakao"}], "l": "tako"}], "l": "supiflenoke"}, {"l": "koeslubuar"}, {"c": [{"c": [{"c": [{"l": "arfle"}], "l": "suta"}, {"l": "konesumalu"}, {"c": [{"l": "nean"}, {"c": [{"l": "nebi"}, {"l": "luogo"}, {"l": "foka"}, {"l": "nesubikyu"}, {"l": "kebo"}], "l": "neke"}, {"l": "flopabiflole"}, {"c": [{"l": "kona"}], "l": "kane"}], "l": "kope"}, {"l": "bipakyubu"}], "l": "tafotrinana"}, {"l": "lefofo"}], "l": "estribubian"}], "l": "mana"}], "l": "esfle"}, {"c": [{"c": [{"l": "zokearse"}, {"l": "bupipifle"}, {"c": [{"l": "kobiarflo"}, {"c": [{"l": "leta"}, {"l": "floikekyubo"}, {"l": "fofulu"}, {"l": "bolusunao"}, {"l": "fleluno"}, {"l": "kyafosusefo"}], "l": "pekasi"}, {"c": [{"l": "nafugo"}, {"c": [{"l": "sesi"}, {"l": "tribo"}, {"l": "sukyuse"}, {"l": "zotrina"}, {"l": "pefoka"}, {"l": "naar"}, {"c": [{"l": "gokya"}, {"l": "flesetri"}, {"l": "kyutri"}, {"l": "luflosikyu"}, {"l": "taar"}], "l": "esboko"}], "l": "piotalu"}, {"l": "supabitrisu"}, {"c": [{"l": "kosu"}], "l": "sekobi"}, {"l": "kyunebi"}, {"c": [{"l": "kyuflosipeke"}, {"c": [{"l": "kyasunano"}, {"l": "artano"}, {"l": "arnele"}, {"l": "oankya"}, {"l": "lenekyaizo"}], "l": "omale"}, {"l": "tako"}], "l": "zoka"}, {"l": "nofloanpi"}], "l": "sususunoar"}, {"l": "kyutatriko"}], "l": "flokyaflefokyu"}], "l": "fubigobo"}, {"c": [{"c": [{"c": [{"c": [{"l": "flenatafleke"}, {"l": "butritrikese"}, {"l": "bibugofo"}, {"l": "trike"}], "l": "siluanfu"}, {"c": [{"l": "floke"}, {"l": "neflesu"}, {"l": "taibu"}, {"l": "kyaesarfofu"}, {"l": "kefo"}, {"l": "tai"}], "l": "flees"}, {"l": "ipapalena"}, {"c": [{"l": "buonafle"}, {"c": [{"l": "kyukobokyu"}, {"l": "bokyu"}, {"l": "fleflofo"}, {"l": "bulene"}, {"l": "naan"}], "l": "peflotritri"}, {"l": "fletana"}, {"l": "nosenopa"}, {"l": "tritane"}, {"c": [{"l": "taflo"}, {"l": "nalubuna"}, {"l": "kona"}, {"l": "trizoobi"}, {"l": "pabo"}, {"l": "arkokefu"}, {"l": "anna"}], "l": "kosi"}, {"l": "zosina"}], "l": "zogo"}, {"l": "tribi"}, {"l": "sibobiesar"}], "l": "palukekyuka"}, {"c": [{"l": "fogotataes"}, {"l": "seseflelu"}, {"l": "nozooo"}, {"l": "ilema"}], "l": "leesflo"}, {"l": "koflofuflofu"}, {"l": "zopezoko"}], "l": "luosu"}, {"c": [{"l": "goflolukyu"}], "l": "lufoansipe"}, {"l": "makyanabu"}, {"l": "setri"}, {"l": "mapepeko"}], "l": "fomanoseo"}, {"c": [{"c": [{"l": "tasikyu"}, {"l": "flekaflozosu"}, {"c": [{"l": "sukyukyu"}], "l": "naleno"}, {"c": [{"l": "fupaleka"}, {"c": [{"l": "nefobi"}], "l": "arbi"}, {"c": [{"l": "zoflelefuna"}, {"l": "flezopebio"}, {"c": [{"l": "lekoikyu"}, {"l": "gobuta"}, {"l": "sugole"}, {"l": "neopago"}, {"l": "zobukekyu"}], "l": "koanflekabu"}], "l": "kyuzoflokyako"}], "l": "flokekalupe"}], "l": "kasekaselu"}], "l": "masinanoma"}], "l": "pemapeo"}], "l": "kyupapa"}