summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMicha White <botahamec@outlook.com>2024-08-15 20:16:32 -0400
committerMicha White <botahamec@outlook.com>2024-08-15 20:16:32 -0400
commitdb9aa9f1bf49e8bede384b9ceb1e1fb82b522799 (patch)
tree0d60727acf481f59b42ef0f74ed07c16ec562bcf
parentf8a80039c74332e2101a177ef3fde31ef2077224 (diff)
Delete stuff
-rw-r--r--Cargo.toml3
-rw-r--r--packer/Cargo.toml13
-rw-r--r--packer/packed.pngbin1268654 -> 0 bytes
-rw-r--r--packer/src/bin/benchmark.rs28
-rw-r--r--packer/src/bin/res/bunny.ffbin8208 -> 0 bytes
-rw-r--r--packer/src/bin/res/bunny.pngbin438 -> 0 bytes
-rw-r--r--packer/src/bin/res/gator.bmpbin750054 -> 0 bytes
-rw-r--r--packer/src/bin/res/gator.ffbin2000016 -> 0 bytes
-rw-r--r--packer/src/bin/res/ghost.icobin67646 -> 0 bytes
-rw-r--r--packer/src/lib.rs175
-rw-r--r--render/Cargo.toml34
-rw-r--r--render/dhat-heap.json15424
-rw-r--r--render/examples/black.rs28
-rw-r--r--render/examples/bmp.rs93
-rw-r--r--render/examples/bunnymark.rs165
-rw-r--r--render/examples/res/bunny.ffbin8208 -> 0 bytes
-rw-r--r--render/examples/res/bunny.pngbin438 -> 0 bytes
-rw-r--r--render/examples/res/gator.bmpbin750054 -> 0 bytes
-rw-r--r--render/examples/res/gator.ffbin2000016 -> 0 bytes
-rw-r--r--render/examples/res/ghost.icobin67646 -> 0 bytes
-rw-r--r--render/shaders/sprite.wgsl50
-rw-r--r--render/src/camera.rs187
-rw-r--r--render/src/config.rs198
-rw-r--r--render/src/instance.rs150
-rw-r--r--render/src/lib.rs20
-rw-r--r--render/src/renderer.rs438
-rw-r--r--render/src/texture.rs127
-rw-r--r--render/src/vertex.rs39
-rw-r--r--src/main.rs15
-rw-r--r--textures/Cargo.toml13
-rw-r--r--textures/src/lib.rs96
-rw-r--r--tvg/Cargo.toml13
-rw-r--r--tvg/src/colors.rs517
-rw-r--r--tvg/src/commands.rs756
-rw-r--r--tvg/src/header.rs157
-rw-r--r--tvg/src/lib.rs167
-rw-r--r--tvg/src/path.rs320
-rw-r--r--tvg/src/render.rs506
-rw-r--r--tvg/tests/examples/tvg/everything-32.tvgbin2637 -> 0 bytes
-rw-r--r--tvg/tests/examples/tvg/everything.tvgbin1447 -> 0 bytes
-rw-r--r--tvg/tests/examples/tvg/shield-16.tvgbin203 -> 0 bytes
-rw-r--r--tvg/tests/examples/tvg/shield-32.tvgbin371 -> 0 bytes
-rw-r--r--tvg/tests/examples/tvg/shield-8.tvgbin119 -> 0 bytes
-rw-r--r--tvg/tests/parse.rs19
44 files changed, 1 insertions, 19750 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 8138b5c..9a0015a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,5 @@
[workspace]
-members = ["packer", "textures", "tvg", "scripts", "sprites", "sys", "console"]
+members = ["scripts", "sprites", "sys", "console"]
resolver = "2"
[package]
@@ -13,7 +13,6 @@ publish = false
alligator_scripts = { path = "scripts" }
alligator_sprites = { path = "sprites" }
alligator_sys = { path = "sys" }
-alligator_textures = { path = "textures" }
clap = "4"
serde = "1"
diff --git a/packer/Cargo.toml b/packer/Cargo.toml
deleted file mode 100644
index 0b1beb8..0000000
--- a/packer/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "packer"
-version = "0.1.0"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-image = "0.24"
-exun = "0.2"
-
-[[bin]]
-name = "benchmark"
diff --git a/packer/packed.png b/packer/packed.png
deleted file mode 100644
index 9602cdb..0000000
--- a/packer/packed.png
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/benchmark.rs b/packer/src/bin/benchmark.rs
deleted file mode 100644
index 4d898d5..0000000
--- a/packer/src/bin/benchmark.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-use std::{fs::File, sync::Arc, time::Instant};
-
-use image::{io::Reader as ImageReader, ImageOutputFormat};
-use packer::RectanglePacker;
-
-fn main() -> Result<(), exun::RawUnexpected> {
- let img1 = ImageReader::open("src/bin/res/gator.bmp")?.decode()?;
- let img2 = ImageReader::open("src/bin/res/bunny.ff")?.decode()?;
- let img3 = ImageReader::open("src/bin/res/ghost.ico")?.decode()?;
-
- let start = Instant::now();
- let mut packer = RectanglePacker::new();
- packer.add_texture("gator".into(), Arc::new(img1.to_rgba8()));
- packer.add_texture("bunny".into(), Arc::new(img2.to_rgba8()));
- packer.add_texture("ghost".into(), Arc::new(img3.to_rgba8()));
- println!("{} milliseconds", start.elapsed().as_secs_f32() * 1000.0);
-
- let start = Instant::now();
- let packed = packer.output(1, 1);
- println!("{} milliseconds", start.elapsed().as_secs_f32() * 1000.0);
-
- let mut file = File::create("packed.png")?;
- packed?
- .get_full_atlas()
- .write_to(&mut file, ImageOutputFormat::Bmp)?;
-
- Ok(())
-}
diff --git a/packer/src/bin/res/bunny.ff b/packer/src/bin/res/bunny.ff
deleted file mode 100644
index 64c5a69..0000000
--- a/packer/src/bin/res/bunny.ff
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/res/bunny.png b/packer/src/bin/res/bunny.png
deleted file mode 100644
index 87ba72d..0000000
--- a/packer/src/bin/res/bunny.png
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/res/gator.bmp b/packer/src/bin/res/gator.bmp
deleted file mode 100644
index e752b56..0000000
--- a/packer/src/bin/res/gator.bmp
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/res/gator.ff b/packer/src/bin/res/gator.ff
deleted file mode 100644
index aac1bcb..0000000
--- a/packer/src/bin/res/gator.ff
+++ /dev/null
Binary files differ
diff --git a/packer/src/bin/res/ghost.ico b/packer/src/bin/res/ghost.ico
deleted file mode 100644
index 102de00..0000000
--- a/packer/src/bin/res/ghost.ico
+++ /dev/null
Binary files differ
diff --git a/packer/src/lib.rs b/packer/src/lib.rs
deleted file mode 100644
index 6715a9e..0000000
--- a/packer/src/lib.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use std::collections::HashMap;
-use std::ops::Deref;
-use std::sync::Arc;
-
-use exun::RawUnexpected;
-use image::{GenericImage, RgbaImage};
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct Rectangle {
- pub x: u32,
- pub y: u32,
- pub width: u32,
- pub height: u32,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-struct Texture {
- id: Arc<str>,
- x: u32,
- y: u32,
- texture: Arc<RgbaImage>,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-struct ImageRect(Arc<RgbaImage>, Arc<str>);
-
-#[derive(Debug, Default, Clone)]
-pub struct RectanglePacker {
- min_width: u32,
- textures: Vec<ImageRect>,
-}
-
-#[derive(Debug, Clone)]
-pub struct TextureAtlas {
- atlas: RgbaImage,
- ids: HashMap<Arc<str>, Rectangle>,
-}
-
-impl PartialOrd for ImageRect {
- fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl Ord for ImageRect {
- fn cmp(&self, other: &Self) -> std::cmp::Ordering {
- self.0.height().cmp(&other.0.height())
- }
-}
-
-impl RectanglePacker {
- pub fn new() -> Self {
- Self {
- min_width: 1,
- textures: Vec::new(),
- }
- }
-
- pub fn with_capacity(capacity: usize) -> Self {
- Self {
- min_width: 1,
- textures: Vec::with_capacity(capacity),
- }
- }
-
- pub fn capacity(&self) -> usize {
- self.textures.capacity()
- }
-
- pub fn len(&self) -> usize {
- self.textures.len()
- }
-
- pub fn is_empty(&self) -> bool {
- self.textures.is_empty()
- }
-
- pub fn reserve(&mut self, additional: usize) {
- self.textures.reserve(additional)
- }
-
- pub fn shrink_to_fit(&mut self) {
- self.textures.shrink_to_fit()
- }
-
- pub fn add_texture(&mut self, name: Arc<str>, texture: Arc<RgbaImage>) {
- if texture.width() > self.min_width {
- self.min_width = texture.width() + 1;
- }
- self.textures.push(ImageRect(texture, name));
- }
-
- fn pack(&mut self, min_width: u32) -> (Vec<Texture>, u32, u32) {
- let image_width = self.min_width.max(min_width);
-
- // to make sure padding is rounded up and not down, 64 is added
- // to make sure some padding is always present, minimum is 1 pixel
- let horizontal_padding = ((image_width + 64) / 128).max(1);
-
- let mut x_position = 0;
- let mut y_position = 0;
- let mut largest_row_height = 0;
- let mut rectangles = Vec::with_capacity(self.textures.len());
-
- self.textures.sort();
- self.textures.reverse();
- for texture in &self.textures {
- // loop to the next row if we've gone off the edge
- if (x_position + texture.0.width()) > image_width {
- let vertical_padding = ((largest_row_height + 64) / 128).max(1);
-
- y_position += largest_row_height + vertical_padding;
- x_position = 0;
- largest_row_height = 0;
- }
-
- // set the rectangle position
- let x = x_position;
- let y = y_position;
-
- x_position += texture.0.width() + horizontal_padding;
-
- if texture.0.height() > largest_row_height {
- largest_row_height = texture.0.height();
- }
-
- rectangles.push(Texture {
- id: texture.1.clone(),
- x,
- y,
- texture: texture.0.clone(),
- });
- }
-
- let vertical_padding = ((largest_row_height + 64) / 128).max(1);
- let total_height = y_position + largest_row_height + vertical_padding;
-
- (rectangles, image_width, total_height)
- }
-
- pub fn output(
- &mut self,
- min_width: u32,
- min_height: u32,
- ) -> Result<TextureAtlas, RawUnexpected> {
- let (rectangles, image_width, image_height) = self.pack(min_width);
- let image_height = image_height.max(min_height);
- let mut atlas = RgbaImage::new(image_width, image_height);
- let mut ids = HashMap::with_capacity(rectangles.len());
- for rectangle in rectangles {
- atlas.copy_from(rectangle.texture.deref(), rectangle.x, rectangle.y)?;
- ids.insert(
- rectangle.id,
- Rectangle {
- x: rectangle.x,
- y: rectangle.y,
- width: rectangle.texture.width(),
- height: rectangle.texture.height(),
- },
- );
- }
-
- Ok(TextureAtlas { atlas, ids })
- }
-}
-
-impl TextureAtlas {
- pub fn get_full_atlas(&self) -> &RgbaImage {
- &self.atlas
- }
-
- pub fn get_texture_rect(&self, id: &str) -> Option<Rectangle> {
- self.ids.get(id).cloned()
- }
-}
diff --git a/render/Cargo.toml b/render/Cargo.toml
deleted file mode 100644
index 1cb523c..0000000
--- a/render/Cargo.toml
+++ /dev/null
@@ -1,34 +0,0 @@
-[package]
-name = "alligator_render"
-version = "0.1.0"
-edition = "2021"
-rust-version = "1.65"
-publish = false
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-bytemuck = { version = "1", features = ["derive"] }
-thiserror = "1"
-profiling = "1"
-wgpu = "0.18"
-winit = "0.28"
-image = "0.24"
-cgmath = "0.18"
-pollster = "0.2"
-log = "0.4"
-
-[dev-dependencies]
-tracy-client = "0.15"
-
-[lib]
-crate-type = ["cdylib", "lib"]
-
-[[example]]
-name = "black"
-
-[[example]]
-name = "bmp"
-
-[[example]]
-name = "bunnymark"
diff --git a/render/dhat-heap.json b/render/dhat-heap.json
deleted file mode 100644
index 2b694d3..0000000
--- a/render/dhat-heap.json
+++ /dev/null
@@ -1,15424 +0,0 @@
-{
-"dhatFileVersion": 2,
-"mode": "rust-heap",
-"verb": "Allocated",
-"bklt": true,
-"bkacc": false,
-"tu": "µs",
-"Mtu": "s",
-"tuth": 10,
-"cmd": "C:\\Users\\epice\\Projects\\alligator\\target\\release\\examples\\black.exe",
-"pid": 7632,
-"tg": 397502,
-"te": 405798,
-"pps": [
-{
-"tb": 30,
-"tbk": 1,
-"tl": 6,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 33,
-"tbk": 1,
-"tl": 8,
-"mb": 33,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 30739,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 18,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 5,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 3,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 2893,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 131,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 1352,
-"mb": 32,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 7,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 65,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 9,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 30352,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 6,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 29391,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 128,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 18,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 7,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2327,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 84,
-"tbk": 2,
-"tl": 68,
-"mb": 56,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 8,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 344,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6879,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 3168,
-"tbk": 1,
-"tl": 30799,
-"mb": 3168,
-"mbk": 1,
-"gb": 3168,
-"gbk": 1,
-"eb": 3168,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 14,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 2,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 84,
-"tbk": 3,
-"tl": 400412,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 48,
-"ebk": 1,
-"fs": [
-1,
-2
-]
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 9,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 3,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 101153,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 128,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1023,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 75,
-"tbk": 1,
-"tl": 0,
-"mb": 75,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 11,
-"tbk": 1,
-"tl": 2,
-"mb": 11,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 10,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1084,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": [
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-8
-]
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 37387,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 30618,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 35722,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 128,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 80,
-"tbk": 5,
-"tl": 26753,
-"mb": 80,
-"mbk": 5,
-"gb": 80,
-"gbk": 5,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 54,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 6,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 5,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 2,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 1,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 17915,
-"mb": 52,
-"mbk": 1,
-"gb": 52,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6618,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 4,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 19,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 4,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 6,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 1,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 5,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 320,
-"tbk": 2,
-"tl": 10855,
-"mb": 320,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 7,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 4,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 3,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 10,
-"tbk": 1,
-"tl": 2,
-"mb": 10,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 320,
-"tbk": 4,
-"tl": 1382,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 6,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1564,
-"tbk": 4,
-"tl": 79158,
-"mb": 1232,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 10,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 7,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 3,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 1016,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 19,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 8,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 3,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 157,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 9,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 2,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 8,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 31340,
-"mb": 52,
-"mbk": 1,
-"gb": 52,
-"gbk": 1,
-"eb": 52,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 259,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 7,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 43,
-"tbk": 1,
-"tl": 10,
-"mb": 43,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 620,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 18074,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 5,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 10,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 6,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 16754,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 3,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 2,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 1,
-"tl": 9404,
-"mb": 96,
-"mbk": 1,
-"gb": 96,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 7,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 6,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 3,
-"tl": 696,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 79,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4321,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 3,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 34510,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 6,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 4,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 15,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 4,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 5,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 97968,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 5,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 775,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 992,
-"tbk": 5,
-"tl": 5570,
-"mb": 512,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 9,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 33,
-"tbk": 1,
-"tl": 7,
-"mb": 33,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 101391,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 48,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 36502,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2025,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 8,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 1,
-"tl": 99087,
-"mb": 96,
-"mbk": 1,
-"gb": 96,
-"gbk": 1,
-"eb": 96,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 56,
-"tbk": 3,
-"tl": 1,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1024,
-"tbk": 1,
-"tl": 195,
-"mb": 1024,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 1024,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 9,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 10,
-"tbk": 1,
-"tl": 3,
-"mb": 10,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 10,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 88,
-"tbk": 1,
-"tl": 581,
-"mb": 88,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 9,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 896,
-"tbk": 3,
-"tl": 6164,
-"mb": 512,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 5,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 4,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 7,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 13,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 30064,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 40,
-"tbk": 1,
-"tl": 1863,
-"mb": 40,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 2,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 11,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 8,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 11,
-"tbk": 1,
-"tl": 5,
-"mb": 11,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 1,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 12,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 31,
-"tbk": 1,
-"tl": 10,
-"mb": 31,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 23,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3409,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 11,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 397524,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": [
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-8
-]
-},
-{
-"tb": 9,
-"tbk": 1,
-"tl": 2,
-"mb": 9,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 3,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 88,
-"tbk": 1,
-"tl": 2600,
-"mb": 88,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2859,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 512,
-"tbk": 1,
-"tl": 402132,
-"mb": 512,
-"mbk": 1,
-"gb": 512,
-"gbk": 1,
-"eb": 512,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 5950,
-"mb": 52,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 9,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 2,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 18964,
-"mb": 52,
-"mbk": 1,
-"gb": 52,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 8,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 9,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 4,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 64,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 70,
-"tbk": 3,
-"tl": 826,
-"mb": 40,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 50,
-"tbk": 1,
-"tl": 3271,
-"mb": 50,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 11,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 1,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 8,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 4,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 7,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 11,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 100876,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 3,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 6,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 5,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 3,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 68,
-"tbk": 1,
-"tl": 108,
-"mb": 68,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 305,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 6,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 7,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 5,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 7,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 36,
-"tbk": 2,
-"tl": 87,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 33,
-"tbk": 1,
-"tl": 7,
-"mb": 33,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 37444,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 30410,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 112,
-"tbk": 7,
-"tl": 32233,
-"mb": 112,
-"mbk": 7,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 513,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 4042,
-"mb": 52,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 5,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 5,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 28641,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 22824,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 28,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 11,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 80,
-"tbk": 5,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 9,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 3389,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 3077,
-"mb": 32,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 15,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 59996,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 36447,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 530,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 26043,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 6,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 40,
-"tbk": 1,
-"tl": 105,
-"mb": 40,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 60,
-"tbk": 2,
-"tl": 97053,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 48,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 2055,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 9,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6682,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 373,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 80,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 624,
-"tbk": 3,
-"tl": 1086,
-"mb": 336,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 2,
-"tl": 43976,
-"mb": 14,
-"mbk": 2,
-"gb": 14,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 31,
-"tbk": 1,
-"tl": 5,
-"mb": 31,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 18240,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 2,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 7,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 180,
-"tbk": 1,
-"tl": 3925,
-"mb": 180,
-"mbk": 1,
-"gb": 180,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 3,
-"tl": 21624,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 4,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 5,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 532,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 3456,
-"tbk": 6,
-"tl": 1066,
-"mb": 1536,
-"mbk": 1,
-"gb": 1536,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 3380,
-"tbk": 1,
-"tl": 1883,
-"mb": 3380,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 3,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 6,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 36775,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 112,
-"tbk": 3,
-"tl": 405518,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 5,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 1,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 5,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 2,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 2,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 15,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 7,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 19,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 2,
-"tl": 29631,
-"mb": 32,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 4,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 2,
-"tl": 68,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 17,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 10,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 31216,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 30162,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 44310,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1564,
-"tbk": 4,
-"tl": 1776,
-"mb": 1232,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 10,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 5,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 6,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 18019,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 3,
-"tl": 55546,
-"mb": 24,
-"mbk": 3,
-"gb": 24,
-"gbk": 3,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 10,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6816,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 11,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 5,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 7,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 11,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 8,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 5,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 4,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 84,
-"tbk": 1,
-"tl": 17114,
-"mb": 84,
-"mbk": 1,
-"gb": 84,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 2,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 1,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 11,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 7,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 214223,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 8,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 10,
-"tbk": 1,
-"tl": 4,
-"mb": 10,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 115103,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6749,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 7,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 5,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 69,
-"tbk": 2,
-"tl": 37242,
-"mb": 38,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 12,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 6,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 9,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 9,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 1,
-"tl": 24610,
-"mb": 224,
-"mbk": 1,
-"gb": 224,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 127,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 73,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 26,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 416,
-"tbk": 1,
-"tl": 20854,
-"mb": 416,
-"mbk": 1,
-"gb": 416,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 3,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1280,
-"tbk": 1,
-"tl": 101034,
-"mb": 1280,
-"mbk": 1,
-"gb": 1280,
-"gbk": 1,
-"eb": 1280,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 8,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 5,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 0,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 62,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 5,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 6864,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 3387,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 620,
-"tbk": 2,
-"tl": 3774,
-"mb": 620,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 7,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 576,
-"tbk": 3,
-"tl": 19663,
-"mb": 576,
-"mbk": 3,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 6340,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 397469,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 48,
-"ebk": 1,
-"fs": [
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-8
-]
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 2,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 2,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 77299,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 21,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 644,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 433,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 1,
-"tl": 101445,
-"mb": 96,
-"mbk": 1,
-"gb": 96,
-"gbk": 1,
-"eb": 96,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 50,
-"tbk": 1,
-"tl": 12512,
-"mb": 50,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 17,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 8,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 71615,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 2,
-"tl": 23824,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 54,
-"tbk": 1,
-"tl": 6,
-"mb": 54,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 20,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 11,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 5,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 160,
-"tbk": 10,
-"tl": 13879,
-"mb": 144,
-"mbk": 9,
-"gb": 144,
-"gbk": 9,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 1,
-"tl": 5822,
-"mb": 96,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 574,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 4,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 31120,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 8,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 320,
-"tbk": 1,
-"tl": 195,
-"mb": 320,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 98,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 92,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 34,
-"tbk": 1,
-"tl": 7,
-"mb": 34,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 34,
-"tbk": 1,
-"tl": 5,
-"mb": 34,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 10,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 4,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 4,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 10,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 30311,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 1274,
-"tbk": 1,
-"tl": 1844,
-"mb": 1274,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 9338,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 62,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 6,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 402337,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 4,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 7512,
-"tbk": 1,
-"tl": 214497,
-"mb": 7512,
-"mbk": 1,
-"gb": 7512,
-"gbk": 1,
-"eb": 7512,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 30208,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 23047,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1008,
-"tbk": 6,
-"tl": 3449,
-"mb": 512,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 5,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 11,
-"tbk": 1,
-"tl": 8,
-"mb": 11,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 960,
-"tbk": 4,
-"tl": 5569,
-"mb": 512,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 9,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 646,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 216,
-"tbk": 1,
-"tl": 3030,
-"mb": 216,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 136,
-"tbk": 1,
-"tl": 145,
-"mb": 136,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 5,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 7,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 6,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 672,
-"tbk": 3,
-"tl": 296686,
-"mb": 672,
-"mbk": 3,
-"gb": 672,
-"gbk": 3,
-"eb": 672,
-"ebk": 3,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 241,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 8,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 2,
-"tl": 4451,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2461,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 536,
-"tbk": 23,
-"tl": 1806645,
-"mb": 536,
-"mbk": 23,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1228800,
-"tbk": 1,
-"tl": 28871,
-"mb": 1228800,
-"mbk": 1,
-"gb": 1228800,
-"gbk": 1,
-"eb": 1228800,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 1,
-"tl": 20344,
-"mb": 224,
-"mbk": 1,
-"gb": 224,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 483,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 3,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 80,
-"tbk": 5,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 36555,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 5,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 6,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 3,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 6,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 1,
-"tl": 35837,
-"mb": 96,
-"mbk": 1,
-"gb": 96,
-"gbk": 1,
-"eb": 96,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 6267,
-"mb": 32,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1076,
-"tbk": 1,
-"tl": 1205,
-"mb": 1076,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 1076,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 11,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 6,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 95,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 34221,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 65,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 7,
-"tbk": 1,
-"tl": 1,
-"mb": 7,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2923,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 11,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 136,
-"tbk": 1,
-"tl": 3380,
-"mb": 136,
-"mbk": 1,
-"gb": 136,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 1,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2080,
-"tbk": 1,
-"tl": 587,
-"mb": 2080,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 2080,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 9,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 6,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 22885,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 7,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 7,
-"tbk": 1,
-"tl": 6114,
-"mb": 7,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 6,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 11,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 14,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 8,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 3,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 3,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 36154,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 5,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 136,
-"tbk": 2,
-"tl": 1500,
-"mb": 68,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 12,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 4,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 100810,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 8,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 11,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2407,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 5,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 4,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 4,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 536,
-"tbk": 2,
-"tl": 1236,
-"mb": 536,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 34326,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 3,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 18,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 39,
-"tbk": 1,
-"tl": 7,
-"mb": 39,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 9,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 4,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 2,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 3,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 4,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 2,
-"tl": 97589,
-"mb": 12,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 992,
-"tbk": 1,
-"tl": 36025,
-"mb": 992,
-"mbk": 1,
-"gb": 992,
-"gbk": 1,
-"eb": 992,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 33,
-"tbk": 1,
-"tl": 12,
-"mb": 33,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 15,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 0,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 6,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 8,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 3050,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 46,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 402614,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 48,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 56,
-"tbk": 3,
-"tl": 588,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 3,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 0,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 280,
-"tbk": 3,
-"tl": 72430,
-"mb": 280,
-"mbk": 3,
-"gb": 280,
-"gbk": 3,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 13,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 160,
-"tbk": 1,
-"tl": 31615,
-"mb": 160,
-"mbk": 1,
-"gb": 160,
-"gbk": 1,
-"eb": 160,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 11,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 8,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 5,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 15,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 6,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 7,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 35,
-"tbk": 2,
-"tl": 402676,
-"mb": 18,
-"mbk": 1,
-"gb": 18,
-"gbk": 1,
-"eb": 18,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 10,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 44,
-"tbk": 5,
-"tl": 110998,
-"mb": 44,
-"mbk": 5,
-"gb": 44,
-"gbk": 5,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 98307,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 1344,
-"tbk": 3,
-"tl": 2923,
-"mb": 768,
-"mbk": 1,
-"gb": 768,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2152,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 4,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 3,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 7,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 3,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 212,
-"tbk": 1,
-"tl": 29768,
-"mb": 212,
-"mbk": 1,
-"gb": 212,
-"gbk": 1,
-"eb": 212,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 6,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 12,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 20,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 7,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 13,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 70,
-"tbk": 3,
-"tl": 12198,
-"mb": 40,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 4,
-"tl": 203,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 5090,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 17,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 5,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 112,
-"tbk": 3,
-"tl": 62,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 33,
-"tbk": 1,
-"tl": 4,
-"mb": 33,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 7,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 35,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 20,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 1,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 10,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 7,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 8,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 2,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 104,
-"tbk": 2,
-"tl": 1307,
-"mb": 52,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 38,
-"tbk": 1,
-"tl": 5,
-"mb": 38,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 9,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 2,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2880,
-"tbk": 4,
-"tl": 5092,
-"mb": 1536,
-"mbk": 1,
-"gb": 1536,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 10,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 134611,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 1,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 80,
-"tbk": 1,
-"tl": 682,
-"mb": 80,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 4,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 44,
-"tbk": 1,
-"tl": 2,
-"mb": 44,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 5200,
-"tbk": 1,
-"tl": 27649,
-"mb": 5200,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 7,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 712,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 232,
-"tbk": 2,
-"tl": 580,
-"mb": 116,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 11,
-"tbk": 1,
-"tl": 4,
-"mb": 11,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 3,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 100928,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 98604,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 128,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 8,
-"tl": 10794,
-"mb": 128,
-"mbk": 8,
-"gb": 128,
-"gbk": 8,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 10,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 621,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 2,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 26,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1088,
-"tbk": 7,
-"tl": 42730,
-"mb": 576,
-"mbk": 2,
-"gb": 576,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 38,
-"tbk": 1,
-"tl": 6,
-"mb": 38,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 3,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 8,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 3,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 11,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 4,
-"tbk": 1,
-"tl": 1,
-"mb": 4,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 416,
-"tbk": 1,
-"tl": 205,
-"mb": 416,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 378478,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 4,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 8,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 10,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 6267,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 5,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 2,
-"tl": 1291,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 6,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 10,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 59725,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 5440,
-"tbk": 7,
-"tl": 42730,
-"mb": 2880,
-"mbk": 2,
-"gb": 2880,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 14,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 5,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 5,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 17,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 5,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 8,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 3,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 11,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 5,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 3012,
-"tbk": 7,
-"tl": 92,
-"mb": 1608,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 11,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 8,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 6,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 3,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 2,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 2,
-"tl": 182,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 30,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 10,
-"tbk": 1,
-"tl": 2,
-"mb": 10,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 3,
-"tbk": 1,
-"tl": 22946,
-"mb": 3,
-"mbk": 1,
-"gb": 3,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 11,
-"tbk": 1,
-"tl": 2,
-"mb": 11,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 31250,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 8,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 3,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 192,
-"tbk": 3,
-"tl": 36379,
-"mb": 144,
-"mbk": 2,
-"gb": 144,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 4,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 2,
-"tl": 5479,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1344,
-"tbk": 3,
-"tl": 3261,
-"mb": 768,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1243,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 84,
-"tbk": 1,
-"tl": 1522,
-"mb": 84,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 5,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 78,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 26,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 11,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 4,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 20,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 5,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 13,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 7,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 347380,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 13,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 184,
-"tbk": 1,
-"tl": 402161,
-"mb": 184,
-"mbk": 1,
-"gb": 184,
-"gbk": 1,
-"eb": 184,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 14087,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 59835,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 83,
-"tbk": 7,
-"tl": 167785,
-"mb": 83,
-"mbk": 7,
-"gb": 83,
-"gbk": 7,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 2,
-"tl": 0,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 8,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 576,
-"tbk": 2,
-"tl": 643,
-"mb": 384,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 4,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 304,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 7,
-"tbk": 2,
-"tl": 44624,
-"mb": 7,
-"mbk": 2,
-"gb": 7,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 18118,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 7,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 144,
-"tbk": 2,
-"tl": 101,
-"mb": 72,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 212819,
-"mb": 21,
-"mbk": 1,
-"gb": 21,
-"gbk": 1,
-"eb": 21,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 7,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 20388,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 7,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 3,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 15,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 207,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 34175,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 29908,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 5,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 8,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 2,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 14,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 12,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 4,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 22,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 2,
-"tl": 59569,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 7,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 62,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2545,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 4,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 3,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 5,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 320,
-"tbk": 1,
-"tl": 156,
-"mb": 320,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 73,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 4,
-"tbk": 1,
-"tl": 389670,
-"mb": 4,
-"mbk": 1,
-"gb": 4,
-"gbk": 1,
-"eb": 4,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 10,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 1,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 10,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 5,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 3,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 4,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 9,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 5,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 292,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2496,
-"tbk": 2,
-"tl": 5480,
-"mb": 1664,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 3,
-"tl": 67711,
-"mb": 24,
-"mbk": 3,
-"gb": 24,
-"gbk": 3,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 9474,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 37591,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1280,
-"tbk": 1,
-"tl": 100983,
-"mb": 1280,
-"mbk": 1,
-"gb": 1280,
-"gbk": 1,
-"eb": 1280,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 320,
-"tbk": 2,
-"tl": 42430,
-"mb": 320,
-"mbk": 2,
-"gb": 320,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 144,
-"tbk": 1,
-"tl": 10,
-"mb": 144,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 688,
-"tbk": 1,
-"tl": 7540,
-"mb": 688,
-"mbk": 1,
-"gb": 688,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 12,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 4,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 2,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 5656,
-"tbk": 1,
-"tl": 218257,
-"mb": 5656,
-"mbk": 1,
-"gb": 5656,
-"gbk": 1,
-"eb": 5656,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 8,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 18560,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 9,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 724,
-"tbk": 1,
-"tl": 18366,
-"mb": 724,
-"mbk": 1,
-"gb": 724,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 4,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 212,
-"tbk": 1,
-"tl": 36223,
-"mb": 212,
-"mbk": 1,
-"gb": 212,
-"gbk": 1,
-"eb": 212,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 4,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 9,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 80,
-"tbk": 5,
-"tl": 23436,
-"mb": 80,
-"mbk": 5,
-"gb": 80,
-"gbk": 5,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 0,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 10,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 7,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 1,
-"tl": 98404,
-"mb": 224,
-"mbk": 1,
-"gb": 224,
-"gbk": 1,
-"eb": 224,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 4510,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 1,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 5,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 97401,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 11,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 2,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 4,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 3,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1280,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 10,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 137,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 10,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 10,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 192,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 144,
-"tbk": 1,
-"tl": 101087,
-"mb": 144,
-"mbk": 1,
-"gb": 144,
-"gbk": 1,
-"eb": 144,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 30679,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 212,
-"tbk": 2,
-"tl": 22362,
-"mb": 160,
-"mbk": 1,
-"gb": 160,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 4,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 4,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 7,
-"tbk": 1,
-"tl": 0,
-"mb": 7,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 3,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 30112,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 7051,
-"tbk": 291,
-"tl": 66269446,
-"mb": 7051,
-"mbk": 291,
-"gb": 7051,
-"gbk": 291,
-"eb": 7051,
-"ebk": 291,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 9,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 6,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 16,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 28684,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 24,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 257,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 62,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 134547,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 20,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 536,
-"tbk": 23,
-"tl": 21101,
-"mb": 536,
-"mbk": 23,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 10,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 5,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 28910,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 2,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 2,
-"tl": 0,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 31530,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 7,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 1,
-"tl": 594,
-"mb": 96,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 9,
-"tbk": 1,
-"tl": 2,
-"mb": 9,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 3,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 7,
-"tl": 1715,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 402642,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 48,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 2,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 7,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 3,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 288,
-"tbk": 1,
-"tl": 390299,
-"mb": 288,
-"mbk": 1,
-"gb": 288,
-"gbk": 1,
-"eb": 288,
-"ebk": 1,
-"fs": [
-1,
-9,
-10
-]
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 5,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 9,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 12269,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 18,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 31683,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 6941,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 276,
-"tbk": 1,
-"tl": 2391,
-"mb": 276,
-"mbk": 1,
-"gb": 276,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 0,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 3,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 98019,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 256,
-"tbk": 1,
-"tl": 373,
-"mb": 256,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 4216,
-"tbk": 7,
-"tl": 89,
-"mb": 2328,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 4,
-"tbk": 1,
-"tl": 2805,
-"mb": 4,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 800,
-"tbk": 1,
-"tl": 3242,
-"mb": 800,
-"mbk": 1,
-"gb": 800,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 37484,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 31,
-"tbk": 1,
-"tl": 9,
-"mb": 31,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 181,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 84,
-"tbk": 3,
-"tl": 12234,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 7,
-"tbk": 2,
-"tl": 44264,
-"mb": 7,
-"mbk": 2,
-"gb": 7,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2976,
-"tbk": 1,
-"tl": 18173,
-"mb": 2976,
-"mbk": 1,
-"gb": 2976,
-"gbk": 1,
-"eb": 2976,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4835,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 2,
-"tl": 5563,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 10,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 34,
-"tbk": 1,
-"tl": 8,
-"mb": 34,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 4,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 130,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 320,
-"tbk": 2,
-"tl": 44174,
-"mb": 320,
-"mbk": 2,
-"gb": 320,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 31,
-"tbk": 1,
-"tl": 6,
-"mb": 31,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 98,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 13,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2400,
-"tbk": 1,
-"tl": 214276,
-"mb": 2400,
-"mbk": 1,
-"gb": 2400,
-"gbk": 1,
-"eb": 2400,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 1920,
-"tbk": 4,
-"tl": 441,
-"mb": 1024,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 20,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2032,
-"tbk": 7,
-"tl": 586,
-"mb": 1024,
-"mbk": 1,
-"gb": 1024,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 9,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 674,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 2,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 17388,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 0,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 36414,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 11,
-"tbk": 1,
-"tl": 5,
-"mb": 11,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 7,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 6,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 2,
-"tl": 97343,
-"mb": 16,
-"mbk": 1,
-"gb": 4,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 8,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 0,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 4,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 9,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 7609,
-"mb": 52,
-"mbk": 1,
-"gb": 52,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4125,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 36614,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 36,
-"tbk": 2,
-"tl": 64,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 5,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 9,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 2,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 5,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 9,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12048,
-"tbk": 1,
-"tl": 98216,
-"mb": 12048,
-"mbk": 1,
-"gb": 12048,
-"gbk": 1,
-"eb": 12048,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 6,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 14,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 1,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 29508,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 2,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 3,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 8,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 7,
-"tbk": 1,
-"tl": 0,
-"mb": 7,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 30462,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 36,
-"tbk": 1,
-"tl": 63,
-"mb": 36,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 10,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 20,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 5,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 3,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 5,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 5,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 5,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 2,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2048,
-"tbk": 4,
-"tl": 10181,
-"mb": 1280,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 24557,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 4,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 6,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 10,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 24964,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 240,
-"tbk": 4,
-"tl": 1210,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 3,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 3,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 7,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 68,
-"tbk": 2,
-"tl": 383,
-"mb": 52,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 3,
-"tl": 10748,
-"mb": 96,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 32,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 36274,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 4,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 3,
-"tl": 22003,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 0,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 65,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 2,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 6,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 33,
-"tbk": 1,
-"tl": 8,
-"mb": 33,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 2,
-"tl": 9115,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 688,
-"tbk": 1,
-"tl": 3970,
-"mb": 688,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 14,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 31,
-"tbk": 1,
-"tl": 5,
-"mb": 31,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 36,
-"tbk": 1,
-"tl": 1,
-"mb": 36,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 2,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 8,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 7,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 5,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 5,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 1,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 8,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 27,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 7,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 41,
-"tbk": 1,
-"tl": 212665,
-"mb": 41,
-"mbk": 1,
-"gb": 41,
-"gbk": 1,
-"eb": 41,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 90,
-"tbk": 6,
-"tl": 551,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 88,
-"tbk": 1,
-"tl": 4767,
-"mb": 88,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 4,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25628,
-"tbk": 8,
-"tl": 234396,
-"mb": 19232,
-"mbk": 2,
-"gb": 12816,
-"gbk": 1,
-"eb": 12816,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 7,
-"tbk": 1,
-"tl": 9708,
-"mb": 7,
-"mbk": 1,
-"gb": 7,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 5,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 1,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 3,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 7,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 8,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 620,
-"tbk": 2,
-"tl": 4100,
-"mb": 620,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 5,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 2,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 9,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 736,
-"tbk": 1,
-"tl": 28405,
-"mb": 736,
-"mbk": 1,
-"gb": 736,
-"gbk": 1,
-"eb": 736,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 11217,
-"mb": 32,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 10,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 2,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 9,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 8,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 2,
-"tl": 3234,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 130,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 28351,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 425,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 6,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 257,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 0,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 5,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 34371,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 11,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 12,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 40,
-"tbk": 1,
-"tl": 9,
-"mb": 40,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2912,
-"tbk": 3,
-"tl": 22004,
-"mb": 1664,
-"mbk": 1,
-"gb": 1664,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 34,
-"tbk": 1,
-"tl": 6,
-"mb": 34,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 15,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 640,
-"tbk": 4,
-"tl": 10402,
-"mb": 448,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 57,
-"tbk": 1,
-"tl": 100759,
-"mb": 57,
-"mbk": 1,
-"gb": 57,
-"gbk": 1,
-"eb": 57,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 98155,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 586,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 5,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 24,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 36666,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 4,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 392590,
-"mb": 52,
-"mbk": 1,
-"gb": 52,
-"gbk": 1,
-"eb": 52,
-"ebk": 1,
-"fs": [
-1,
-2,
-3,
-4,
-5,
-6
-]
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 4,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 3,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 29300,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 29089,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 100,
-"tbk": 1,
-"tl": 277,
-"mb": 100,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 11,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 9,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 2,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 2,
-"tl": 0,
-"mb": 4,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 40,
-"tbk": 2,
-"tl": 36076,
-"mb": 32,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 31494,
-"mb": 64,
-"mbk": 1,
-"gb": 64,
-"gbk": 1,
-"eb": 64,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 6944,
-"tbk": 5,
-"tl": 5570,
-"mb": 3584,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 140,
-"tbk": 2,
-"tl": 42518,
-"mb": 140,
-"mbk": 2,
-"gb": 140,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 3,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 6,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 8,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 212742,
-"mb": 22,
-"mbk": 1,
-"gb": 22,
-"gbk": 1,
-"eb": 22,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 4,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 8,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 532,
-"tbk": 2,
-"tl": 877,
-"mb": 416,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3206,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 496,
-"tbk": 1,
-"tl": 349047,
-"mb": 496,
-"mbk": 1,
-"gb": 496,
-"gbk": 1,
-"eb": 496,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 13,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 5,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 4,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 21,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 928,
-"tbk": 1,
-"tl": 31393,
-"mb": 928,
-"mbk": 1,
-"gb": 928,
-"gbk": 1,
-"eb": 928,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 7,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 11,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 80,
-"tbk": 5,
-"tl": 3,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 13,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 99158,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 5,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 8,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 7,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 268,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 9,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 23,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 10,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4576,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 536,
-"tbk": 2,
-"tl": 1247,
-"mb": 536,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 25584,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 6,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 34074,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 6,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 25,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 0,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 986,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 4,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1216,
-"tbk": 1,
-"tl": 21632,
-"mb": 1216,
-"mbk": 1,
-"gb": 1216,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 40,
-"tbk": 2,
-"tl": 3,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 14,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 84,
-"tbk": 1,
-"tl": 1456,
-"mb": 84,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 1,
-"tl": 1351,
-"mb": 96,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 5,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 2,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 6,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 6,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 59779,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 1566,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 160,
-"tbk": 1,
-"tl": 29452,
-"mb": 160,
-"mbk": 1,
-"gb": 160,
-"gbk": 1,
-"eb": 160,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 4,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 10,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 632,
-"tbk": 2,
-"tl": 232,
-"mb": 632,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 6,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 8,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 30903,
-"mb": 12,
-"mbk": 1,
-"gb": 12,
-"gbk": 1,
-"eb": 12,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 9,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 270,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 7,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 3,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 5,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 449,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 192,
-"tbk": 2,
-"tl": 16687,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 120,
-"tbk": 1,
-"tl": 5,
-"mb": 120,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 23101,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 638,
-"mb": 52,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 94,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 40,
-"tbk": 1,
-"tl": 392531,
-"mb": 40,
-"mbk": 1,
-"gb": 40,
-"gbk": 1,
-"eb": 40,
-"ebk": 1,
-"fs": [
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-8
-]
-},
-{
-"tb": 248,
-"tbk": 1,
-"tl": 398749,
-"mb": 248,
-"mbk": 1,
-"gb": 248,
-"gbk": 1,
-"eb": 248,
-"ebk": 1,
-"fs": [
-1,
-2,
-3,
-4,
-5,
-6,
-7,
-8
-]
-},
-{
-"tb": 210,
-"tbk": 14,
-"tl": 129,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 13,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 5,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 11,
-"tbk": 1,
-"tl": 3,
-"mb": 11,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 9,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1008,
-"tbk": 6,
-"tl": 68,
-"mb": 512,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 5882,
-"mb": 48,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1248,
-"tbk": 1,
-"tl": 36719,
-"mb": 1248,
-"mbk": 1,
-"gb": 1248,
-"gbk": 1,
-"eb": 1248,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 5,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 496,
-"tbk": 5,
-"tl": 67,
-"mb": 256,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 1356,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 10,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 3,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 51,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2016,
-"tbk": 9,
-"tl": 333634,
-"mb": 2016,
-"mbk": 9,
-"gb": 2016,
-"gbk": 9,
-"eb": 2016,
-"ebk": 9,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 2,
-"tl": 386,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 9,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 17501,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 4,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 5,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 40,
-"tbk": 1,
-"tl": 402585,
-"mb": 40,
-"mbk": 1,
-"gb": 40,
-"gbk": 1,
-"eb": 40,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 7,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 7,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 6,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 6,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 214345,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 44,
-"tbk": 1,
-"tl": 234509,
-"mb": 44,
-"mbk": 1,
-"gb": 44,
-"gbk": 1,
-"eb": 44,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 35931,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 2,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 68,
-"tbk": 1,
-"tl": 16952,
-"mb": 68,
-"mbk": 1,
-"gb": 68,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 6,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2032,
-"tbk": 7,
-"tl": 3857,
-"mb": 1024,
-"mbk": 1,
-"gb": 1024,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 6392,
-"mb": 32,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 9,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 36,
-"tbk": 1,
-"tl": 7,
-"mb": 36,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 8,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 2,
-"tl": 36012,
-"mb": 14,
-"mbk": 2,
-"gb": 14,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 427,
-"mb": 52,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 388753,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 10,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 62,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 53,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 14,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 4,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 112,
-"tbk": 7,
-"tl": 57138,
-"mb": 112,
-"mbk": 7,
-"gb": 112,
-"gbk": 7,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 10,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 4,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 5,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 10,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 3,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 1,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 5,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 4,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 12,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 37539,
-"mb": 12,
-"mbk": 1,
-"gb": 12,
-"gbk": 1,
-"eb": 12,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 2,
-"tl": 15,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 29863,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 3,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 14,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 168,
-"tbk": 3,
-"tl": 117,
-"mb": 96,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 412,
-"tbk": 3,
-"tl": 276,
-"mb": 344,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 27,
-"tbk": 1,
-"tl": 8,
-"mb": 27,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1504,
-"tbk": 1,
-"tl": 30033,
-"mb": 1504,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 6,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 9,
-"tbk": 1,
-"tl": 4,
-"mb": 9,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 5,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 42640,
-"tbk": 1,
-"tl": 213048,
-"mb": 42640,
-"mbk": 1,
-"gb": 42640,
-"gbk": 1,
-"eb": 42640,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 1,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 4,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 23,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 26,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1310,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 5,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 4,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 31,
-"tbk": 1,
-"tl": 11,
-"mb": 31,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 40,
-"tbk": 1,
-"tl": 47,
-"mb": 40,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 2,
-"tl": 1490,
-"mb": 32,
-"mbk": 2,
-"gb": 32,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 3,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 5,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 6,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 7,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 1,
-"tl": 18613,
-"mb": 224,
-"mbk": 1,
-"gb": 224,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 402557,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 7,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 30856,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 1536,
-"tbk": 3,
-"tl": 21512,
-"mb": 896,
-"mbk": 1,
-"gb": 896,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 3,
-"tl": 697,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 0,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 60,
-"tbk": 4,
-"tl": 65,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 20793,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 496,
-"tbk": 5,
-"tl": 711,
-"mb": 256,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 7,
-"tbk": 1,
-"tl": 0,
-"mb": 7,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 8,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 5,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 3,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 6,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 6,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 3,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 12,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 10,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 344,
-"tbk": 2,
-"tl": 944,
-"mb": 344,
-"mbk": 2,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 46,
-"tbk": 1,
-"tl": 7,
-"mb": 46,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 104,
-"tbk": 2,
-"tl": 768,
-"mb": 52,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 416,
-"tbk": 1,
-"tl": 20298,
-"mb": 416,
-"mbk": 1,
-"gb": 416,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 246,
-"mb": 32,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 1,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 8,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 5,
-"tbk": 1,
-"tl": 38631,
-"mb": 5,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 3,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 97560,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 11,
-"tbk": 1,
-"tl": 1,
-"mb": 11,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 5,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 88,
-"tbk": 1,
-"tl": 5878,
-"mb": 88,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 1,
-"tl": 99021,
-"mb": 224,
-"mbk": 1,
-"gb": 224,
-"gbk": 1,
-"eb": 224,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 10,
-"tbk": 1,
-"tl": 1,
-"mb": 10,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 60,
-"tbk": 2,
-"tl": 31015,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 48,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 9,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 18,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 4,
-"tbk": 1,
-"tl": 0,
-"mb": 4,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 4,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 9,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 31,
-"tbk": 1,
-"tl": 6,
-"mb": 31,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 5,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 3,
-"tl": 6164,
-"mb": 128,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 6,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 8,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 96,
-"tbk": 2,
-"tl": 1721,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 520,
-"tbk": 1,
-"tl": 100676,
-"mb": 520,
-"mbk": 1,
-"gb": 520,
-"gbk": 1,
-"eb": 520,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 128,
-"tbk": 1,
-"tl": 2264,
-"mb": 128,
-"mbk": 1,
-"gb": 128,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 30560,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 12,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 160,
-"tbk": 1,
-"tl": 90,
-"mb": 160,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 36,
-"tbk": 1,
-"tl": 7,
-"mb": 36,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 14162,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 864,
-"tbk": 1,
-"tl": 30258,
-"mb": 864,
-"mbk": 1,
-"gb": 864,
-"gbk": 1,
-"eb": 864,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 111,
-"mb": 8,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 1763,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 8,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 25,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 28595,
-"mb": 16,
-"mbk": 1,
-"gb": 16,
-"gbk": 1,
-"eb": 16,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 17,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 8,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 29,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 2,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 4,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 52,
-"tbk": 1,
-"tl": 9548,
-"mb": 52,
-"mbk": 1,
-"gb": 52,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 6,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 10,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 36,
-"tbk": 3,
-"tl": 71825,
-"mb": 36,
-"mbk": 3,
-"gb": 36,
-"gbk": 3,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 5,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 724,
-"tbk": 1,
-"tl": 35618,
-"mb": 724,
-"mbk": 1,
-"gb": 724,
-"gbk": 1,
-"eb": 724,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 31,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 13,
-"tbk": 1,
-"tl": 4,
-"mb": 13,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 8,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 5,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 52,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 9,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 21,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 23,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 5,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 28455,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 2,
-"tl": 42335,
-"mb": 14,
-"mbk": 2,
-"gb": 14,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 3,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 9,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 8,
-"tbk": 1,
-"tl": 30011,
-"mb": 8,
-"mbk": 1,
-"gb": 8,
-"gbk": 1,
-"eb": 8,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 48,
-"tbk": 1,
-"tl": 3929,
-"mb": 48,
-"mbk": 1,
-"gb": 48,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 7,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 29,
-"tbk": 1,
-"tl": 4,
-"mb": 29,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 29814,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 7,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16000,
-"tbk": 1,
-"tl": 31309,
-"mb": 16000,
-"mbk": 1,
-"gb": 16000,
-"gbk": 1,
-"eb": 16000,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 15,
-"tbk": 1,
-"tl": 9,
-"mb": 15,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 352,
-"tbk": 1,
-"tl": 1787,
-"mb": 352,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1864,
-"tbk": 1,
-"tl": 78022,
-"mb": 1864,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 5,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 1,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 11,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 4,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 36,
-"tbk": 1,
-"tl": 59,
-"mb": 36,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 19,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 5,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 2184,
-"tbk": 2,
-"tl": 39166,
-"mb": 2184,
-"mbk": 2,
-"gb": 2184,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 7,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 18,
-"tbk": 1,
-"tl": 5,
-"mb": 18,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 4,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 6,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 8,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1888,
-"tbk": 1,
-"tl": 134477,
-"mb": 1888,
-"mbk": 1,
-"gb": 1888,
-"gbk": 1,
-"eb": 1888,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 4,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 4,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 25,
-"tbk": 1,
-"tl": 7,
-"mb": 25,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 9,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 0,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 11,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 6,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 21,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1736,
-"tbk": 1,
-"tl": 101339,
-"mb": 1736,
-"mbk": 1,
-"gb": 1736,
-"gbk": 1,
-"eb": 1736,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 4,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1280,
-"tbk": 1,
-"tl": 34272,
-"mb": 1280,
-"mbk": 1,
-"gb": 1280,
-"gbk": 1,
-"eb": 1280,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 4,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 100,
-"tbk": 1,
-"tl": 270,
-"mb": 100,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 26,
-"tbk": 1,
-"tl": 8,
-"mb": 26,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 33,
-"tbk": 1,
-"tl": 6,
-"mb": 33,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 28,
-"tbk": 1,
-"tl": 6,
-"mb": 28,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 2,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 10,
-"mb": 24,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 60,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 3,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 12,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 23,
-"tbk": 1,
-"tl": 8,
-"mb": 23,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 5,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 24,
-"tbk": 1,
-"tl": 402101,
-"mb": 24,
-"mbk": 1,
-"gb": 24,
-"gbk": 1,
-"eb": 24,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 19,
-"tbk": 1,
-"tl": 5,
-"mb": 19,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 224,
-"tbk": 1,
-"tl": 29956,
-"mb": 224,
-"mbk": 1,
-"gb": 224,
-"gbk": 1,
-"eb": 224,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 180,
-"tbk": 1,
-"tl": 1628,
-"mb": 180,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 6,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 30,
-"tbk": 1,
-"tl": 12,
-"mb": 30,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 16,
-"tbk": 1,
-"tl": 4,
-"mb": 16,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 6,
-"tbk": 2,
-"tl": 39270,
-"mb": 6,
-"mbk": 2,
-"gb": 6,
-"gbk": 2,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 17,
-"tbk": 1,
-"tl": 5,
-"mb": 17,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 22,
-"tbk": 1,
-"tl": 4,
-"mb": 22,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 20,
-"tbk": 1,
-"tl": 1291,
-"mb": 20,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 64,
-"tbk": 1,
-"tl": 436,
-"mb": 64,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 14,
-"tbk": 1,
-"tl": 7,
-"mb": 14,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 34124,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 32,
-"tbk": 1,
-"tl": 30499,
-"mb": 32,
-"mbk": 1,
-"gb": 32,
-"gbk": 1,
-"eb": 32,
-"ebk": 1,
-"fs": []
-},
-{
-"tb": 160,
-"tbk": 1,
-"tl": 98,
-"mb": 160,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 1120,
-"tbk": 3,
-"tl": 21624,
-"mb": 640,
-"mbk": 1,
-"gb": 640,
-"gbk": 1,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 21,
-"tbk": 1,
-"tl": 3759,
-"mb": 21,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-},
-{
-"tb": 12,
-"tbk": 1,
-"tl": 1,
-"mb": 12,
-"mbk": 1,
-"gb": 0,
-"gbk": 0,
-"eb": 0,
-"ebk": 0,
-"fs": []
-}
-],
-"ftbl": [
-"[root]",
-"0x7ffe9a1ae858: CallWindowProcW (???:0:0)",
-"0x7ffe9a1ae3dc: DispatchMessageW (???:0:0)",
-"0x7ffe9a1c2cc7: InitDManipHook (???:0:0)",
-"0x7ffe9bd10e64: KiUserCallbackDispatcher (???:0:0)",
-"0x7ffe99581ec4: NtUserCreateWindowEx (???:0:0)",
-"0x7ffe9a1a7d8b: CreateWindowExW (???:0:0)",
-"0x7ffe9a1a7958: CreateWindowExW (???:0:0)",
-"0x7ffe9a1a77a2: CreateWindowExW (???:0:0)",
-"0x7ffe9a1ade1b: SendMessageW (???:0:0)",
-"0x7ffe9a1acbc3: GetWindowTextW (???:0:0)"
-]
-} \ No newline at end of file
diff --git a/render/examples/black.rs b/render/examples/black.rs
deleted file mode 100644
index c1cc538..0000000
--- a/render/examples/black.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-//#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
-
-//#[global_allocator]
-//static ALLOC: dhat::Alloc = dhat::Alloc;
-
-use alligator_render::{RenderWindowConfig, Renderer};
-
-fn update(_renderer: &mut Renderer) {}
-
-fn main() {
- //let _profiler = dhat::Profiler::new_heap();
- let start = std::time::Instant::now();
-
- // configure the render window
- let render_config = RenderWindowConfig {
- vsync: false,
- //mode: alligator_render::config::WindowMode::BorderlessFullscreen,
- title: "Black Screen.exe",
- ..Default::default()
- };
-
- let renderer = Renderer::new(&render_config).unwrap();
- println!("Startup time: {:?}", start.elapsed());
-
- //drop(_profiler);
-
- renderer.run(update);
-}
diff --git a/render/examples/bmp.rs b/render/examples/bmp.rs
deleted file mode 100644
index 373a68c..0000000
--- a/render/examples/bmp.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
-
-use std::{num::NonZeroU32, sync::Arc};
-
-use alligator_render::{Instance, RenderWindowConfig, Renderer};
-
-#[profiling::function]
-fn update(renderer: &mut Renderer) {
- let camera = renderer.camera_mut();
- camera.set_rotation(camera.rotation() + 0.01);
-}
-
-fn main() {
- // configure the render window
- let render_config = RenderWindowConfig {
- title: "Bumper Stickers",
- instance_capacity: 2,
- default_width: NonZeroU32::new(1280).unwrap(),
- default_height: NonZeroU32::new(720).unwrap(),
- //mode: alligator_render::config::WindowMode::BorderlessFullscreen,
- //vsync: false,
- ..Default::default()
- };
-
- let texture_config = TextureManagerConfig {
- initial_capacity: 3,
- max_size: 3_000_000,
- };
-
- let texture_manager = Arc::new(TextureManager::new(&texture_config));
- let mut renderer = Renderer::new(&render_config).unwrap();
-
- // render the alligator
- let gator = include_bytes!("res/gator.ff");
- let gator_id = texture_manager
- .load_from_memory(gator, ImageFormat::Farbfeld)
- .unwrap();
- renderer.textures_mut().load_texture(gator_id).unwrap();
- let gator_width = renderer.textures_mut().texture_width(gator_id).unwrap();
- let gator_height = renderer.textures_mut().texture_height(gator_id).unwrap();
- let gator_x = renderer.textures_mut().texture_x(gator_id).unwrap();
- let gator_y = renderer.textures_mut().texture_y(gator_id).unwrap();
-
- renderer.instances_mut().push_instance(Instance {
- position: [-0.5, 0.5],
- size: [1.5; 2],
- z_index: 1.0,
- texture_size: [gator_width, gator_height],
- texture_coordinates: [gator_x, gator_y],
- ..Default::default()
- });
-
- // render the ghost
- let icon = include_bytes!("res/ghost.ico");
- let icon_id = texture_manager
- .load_from_memory(icon, ImageFormat::Ico)
- .unwrap();
- renderer.textures_mut().load_texture(icon_id).unwrap();
- let icon_width = renderer.textures_mut().texture_width(icon_id).unwrap();
- let icon_height = renderer.textures_mut().texture_height(icon_id).unwrap();
- let icon_x = renderer.textures_mut().texture_x(icon_id).unwrap();
- let icon_y = renderer.textures_mut().texture_y(icon_id).unwrap();
-
- renderer.instances_mut().push_instance(Instance {
- position: [0.5, 0.5],
- size: [0.75; 2],
- rotation: 0.5,
- z_index: 1.0,
- texture_size: [icon_width, icon_height],
- texture_coordinates: [icon_x, icon_y],
- ..Default::default()
- });
-
- // render the bitmap alligator
- let gator = include_bytes!("res/gator.bmp");
- let gator_id = texture_manager
- .load_from_memory(gator, ImageFormat::Bmp)
- .unwrap();
- let gator_width = renderer.textures_mut().texture_width(gator_id).unwrap();
- let gator_height = renderer.textures_mut().texture_height(gator_id).unwrap();
- let gator_x = renderer.textures_mut().texture_x(gator_id).unwrap();
- let gator_y = renderer.textures_mut().texture_y(gator_id).unwrap();
-
- renderer.instances_mut().push_instance(Instance {
- position: [0.0, -0.5],
- size: [1.5; 2],
- texture_size: [gator_width, gator_height],
- texture_coordinates: [gator_x, gator_y],
- ..Default::default()
- });
-
- renderer.run(update);
-}
diff --git a/render/examples/bunnymark.rs b/render/examples/bunnymark.rs
deleted file mode 100644
index 1e171c1..0000000
--- a/render/examples/bunnymark.rs
+++ /dev/null
@@ -1,165 +0,0 @@
-#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
-
-use std::{num::NonZeroU32, sync::Arc, time::Instant};
-
-use alligator_render::{Instance, InstanceId, RenderWindowConfig, Renderer};
-use alligator_resources::texture::{ImageFormat, TextureId, TextureManager, TextureManagerConfig};
-
-fn xorshift_plus(seed: &mut [u64; 2]) -> u64 {
- let mut t = seed[0];
- let s = seed[1];
-
- t ^= t << 23;
- t ^= t >> 18;
- t ^= s ^ (s >> 5);
-
- seed[0] = s;
- seed[1] = t;
-
- t.wrapping_add(s)
-}
-
-#[derive(Debug)]
-struct State {
- texture_id: TextureId,
- bunnies: Vec<Bunny>,
- previous_timestamp: Option<Instant>,
- bad_frames: u8,
- seed: [u64; 2],
- stopped: bool,
-}
-
-impl State {
- fn new(texture_id: TextureId) -> Self {
- Self {
- texture_id,
- bunnies: Vec::with_capacity(10_000_000),
- previous_timestamp: None,
- seed: [0x0D15EA5E8BADF00D, 0xDECAFBADDEADBEAF],
- bad_frames: 0,
- stopped: false,
- }
- }
-
- #[profiling::function]
- fn update(&mut self, renderer: &mut Renderer) {
- let Some(instant) = self.previous_timestamp else {
- self.previous_timestamp = Some(Instant::now());
- return;
- };
-
- let frame_time = instant.elapsed();
- let fps = 1.0 / frame_time.as_secs_f32();
-
- renderer.set_title(&format!(
- "BunnyMark - {} bunnies - {} FPS",
- self.bunnies.len(),
- fps.round()
- ));
-
- if fps < 15.0 {
- self.bad_frames += 1;
- if self.bad_frames == 3 {
- self.stopped = true;
- }
- } else {
- self.bad_frames = 0;
- }
-
- self.previous_timestamp = Some(Instant::now());
-
- if self.stopped {
- return;
- }
-
- for bunny in self.bunnies.iter_mut() {
- let instance = renderer
- .instances_mut()
- .get_instance_mut(bunny.instance_id)
- .unwrap();
-
- instance.position[0] += bunny.velocity_x;
- instance.position[1] += bunny.velocity_y;
-
- if !(-1.5..1.5).contains(&instance.position[0]) {
- instance.position[0] = instance.position[0].clamp(-1.0, 1.0);
- bunny.velocity_x = -bunny.velocity_x;
- }
-
- if !(-0.75..0.75).contains(&instance.position[1]) {
- instance.position[1] = instance.position[1].clamp(-0.5, 0.5);
- bunny.velocity_y *= -0.90;
- }
-
- bunny.velocity_y -= 0.005;
- }
-
- for _ in 0..=(fps as u64 * 50) {
- let texture_x = renderer.textures_mut().texture_x(self.texture_id).unwrap();
- let texture_y = renderer.textures_mut().texture_y(self.texture_id).unwrap();
- let texture_height = renderer
- .textures_mut()
- .texture_height(self.texture_id)
- .unwrap();
- let texture_width = renderer
- .textures_mut()
- .texture_width(self.texture_id)
- .unwrap();
- let instance_id = renderer.instances_mut().push_instance(Instance {
- texture_coordinates: [texture_x, texture_y],
- texture_size: [texture_width, texture_height],
- size: [0.08, 0.08],
- position: [-1.5, 0.70],
- ..Default::default()
- });
-
- let velocity_x = (xorshift_plus(&mut self.seed) % 1_000_000) as f32 / 25_000_000.0;
- let velocity_y = (xorshift_plus(&mut self.seed) % 1_000_000) as f32 / 25_000_000.0;
- self.bunnies.push(Bunny {
- instance_id,
- velocity_x,
- velocity_y,
- });
- }
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-struct Bunny {
- instance_id: InstanceId,
- velocity_x: f32,
- velocity_y: f32,
-}
-
-fn main() {
- #[cfg(feature = "profile-with-tracy")]
- profiling::tracy_client::Client::start();
- profiling::register_thread!("main");
-
- // configure the render window
- let render_config = RenderWindowConfig {
- title: "BunnyMark",
- instance_capacity: 150_000,
- default_width: NonZeroU32::new(1280).unwrap(),
- default_height: NonZeroU32::new(720).unwrap(),
- vsync: false,
- low_power: false,
- ..Default::default()
- };
-
- let texture_config = TextureManagerConfig {
- initial_capacity: 1,
- max_size: 10_000,
- };
-
- let bunny = include_bytes!("res/bunny.ff");
- let texture_manager = Arc::new(TextureManager::new(&texture_config));
- let mut renderer = Renderer::new(&render_config, texture_manager.clone()).unwrap();
- let texture_id = texture_manager
- .load_from_memory(bunny, ImageFormat::Farbfeld)
- .unwrap();
- renderer.textures_mut().load_texture(texture_id).unwrap();
-
- let state = Box::leak(Box::new(State::new(texture_id)));
- renderer.run(|r| state.update(r));
-}
diff --git a/render/examples/res/bunny.ff b/render/examples/res/bunny.ff
deleted file mode 100644
index 64c5a69..0000000
--- a/render/examples/res/bunny.ff
+++ /dev/null
Binary files differ
diff --git a/render/examples/res/bunny.png b/render/examples/res/bunny.png
deleted file mode 100644
index 87ba72d..0000000
--- a/render/examples/res/bunny.png
+++ /dev/null
Binary files differ
diff --git a/render/examples/res/gator.bmp b/render/examples/res/gator.bmp
deleted file mode 100644
index e752b56..0000000
--- a/render/examples/res/gator.bmp
+++ /dev/null
Binary files differ
diff --git a/render/examples/res/gator.ff b/render/examples/res/gator.ff
deleted file mode 100644
index aac1bcb..0000000
--- a/render/examples/res/gator.ff
+++ /dev/null
Binary files differ
diff --git a/render/examples/res/ghost.ico b/render/examples/res/ghost.ico
deleted file mode 100644
index 102de00..0000000
--- a/render/examples/res/ghost.ico
+++ /dev/null
Binary files differ
diff --git a/render/shaders/sprite.wgsl b/render/shaders/sprite.wgsl
deleted file mode 100644
index 1e7f1a2..0000000
--- a/render/shaders/sprite.wgsl
+++ /dev/null
@@ -1,50 +0,0 @@
-
-@group(0) @binding(0)
-var<uniform> camera: mat4x4<f32>;
-
-struct VertexInput {
- @location(0) position: vec2<f32>
-}
-
-struct InstanceInput {
- @location(1) position: vec2<f32>,
- @location(2) size: vec2<f32>,
- @location(3) texture_coordinates: vec2<f32>,
- @location(4) texture_size: vec2<f32>,
-}
-
-struct VertexOutput {
- @builtin(position) clip_position: vec4<f32>,
- @location(0) texture_coordinates: vec2<f32>,
-}
-
-@vertex
-fn vs_main(model: VertexInput, instance: InstanceInput) -> VertexOutput {
- var out: VertexOutput;
-
- // scale the sprite
- let scaled = model.position * instance.size;
-
- // move the sprite
- let position2d = scaled + instance.position;
-
- // camera stuff
- let position4d = vec4<f32>(position2d, 0.0, 1.0);
- let position = camera * position4d;
-
- let tex_coords = vec2<f32>(model.position[0] + 0.5, 1.0 - (model.position[1] + 0.5));
-
- out.clip_position = position;
- out.texture_coordinates = tex_coords * instance.texture_size + instance.texture_coordinates;
- return out;
-}
-
-@group(1) @binding(0)
-var t_diffuse: texture_2d<f32>;
-@group(1) @binding(1)
-var s_diffuse: sampler;
-
-@fragment
-fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
- return textureSample(t_diffuse, s_diffuse, in.texture_coordinates);
-} \ No newline at end of file
diff --git a/render/src/camera.rs b/render/src/camera.rs
deleted file mode 100644
index ecece90..0000000
--- a/render/src/camera.rs
+++ /dev/null
@@ -1,187 +0,0 @@
-use std::mem::size_of;
-
-use cgmath::{Matrix4, Vector2};
-
-#[derive(Debug)]
-pub struct Camera {
- position: (f32, f32),
- zoom: f32,
- rotation: f32,
- inverse_aspect_ratio: f32,
- buffer: wgpu::Buffer,
- bind_group: wgpu::BindGroup,
-}
-
-type CameraUniform = [[f32; 4]; 4];
-
-#[allow(clippy::cast_precision_loss)]
-fn inverse_aspect_ratio(width: u32, height: u32) -> f32 {
- (height as f32) / (width as f32)
-}
-
-impl Camera {
- /// Create a new camera, with a position of (0, 0), and a zoom of 1.0
- pub(crate) fn new(
- device: &wgpu::Device,
- width: u32,
- height: u32,
- ) -> (Self, wgpu::BindGroupLayout) {
- let buffer = device.create_buffer(&wgpu::BufferDescriptor {
- label: Some("Camera Uniform"),
- size: size_of::<CameraUniform>() as wgpu::BufferAddress,
- usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
- mapped_at_creation: false,
- });
-
- let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
- label: Some("Camera Bind Group Layout"),
- entries: &[wgpu::BindGroupLayoutEntry {
- binding: 0,
- visibility: wgpu::ShaderStages::VERTEX,
- ty: wgpu::BindingType::Buffer {
- ty: wgpu::BufferBindingType::Uniform,
- has_dynamic_offset: false,
- min_binding_size: None,
- },
- count: None,
- }],
- });
-
- let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
- label: Some("Camera Bind Group"),
- layout: &bind_group_layout,
- entries: &[wgpu::BindGroupEntry {
- binding: 0,
- resource: buffer.as_entire_binding(),
- }],
- });
-
- (
- Self {
- position: (0.0, 0.0),
- zoom: 1.0,
- rotation: 0.0,
- inverse_aspect_ratio: inverse_aspect_ratio(width, height),
- buffer,
- bind_group,
- },
- bind_group_layout,
- )
- }
-
- /// Get the camera's current x position
- #[must_use]
- pub const fn x(&self) -> f32 {
- self.position.0
- }
-
- /// Get the camera's current y position
- #[must_use]
- pub const fn y(&self) -> f32 {
- self.position.1
- }
-
- /// Get the camera's current zoom
- #[must_use]
- pub const fn zoom(&self) -> f32 {
- self.zoom
- }
-
- /// Get the camera's current rotation, in radians
- #[must_use]
- pub const fn rotation(&self) -> f32 {
- self.rotation
- }
-
- /// Set the position of the camera
- pub fn set_position(&mut self, x: f32, y: f32) {
- #[cfg(debug_assertions)]
- if !(-1000.0..1000.0).contains(&x) || !(-1000.0..1000.0).contains(&y) {
- log::warn!(
- "The position of the camera is (x: {}, y: {}). \
- Please keep both the x and y positions above -1000 and below 1000 units. \
- Otherwise, everything will look crazy. \
- For an explanation, see https://www.youtube.com/watch?v=Q2OGwnRik24",
- x,
- y
- );
- }
-
- self.position = (x, y);
- }
-
- /// Set the zoom of the camera
- pub fn set_zoom(&mut self, zoom: f32) {
- #[cfg(debug_assertions)]
- if !(-1000.0..1000.0).contains(&zoom) {
- log::warn!(
- "The zoom of the camera is {}. \
- Please keep above -1000, and below 1000, or else smooth zoom may be difficult. \
- For an explanation, see https://www.youtube.com/watch?v=Q2OGwnRik24",
- zoom
- );
- }
-
- self.zoom = zoom;
- }
-
- /// Set the camera rotation, in radians
- pub fn set_rotation(&mut self, rotation: f32) {
- self.rotation = rotation % std::f32::consts::TAU;
- }
-
- /// Set the aspect ratio of the camera
- pub(crate) fn set_size(&mut self, width: u32, height: u32) {
- self.inverse_aspect_ratio = inverse_aspect_ratio(width, height);
- }
-
- /// Create a matrix that can be multiplied by any vector to transform it
- /// according to the current camera
- #[allow(clippy::wrong_self_convention)]
- fn to_matrix(&self) -> CameraUniform {
- let cos = self.rotation.cos();
- let sin = self.rotation.sin();
-
- let x_axis = Vector2::new(cos, -sin);
- let y_axis = Vector2::new(sin, cos);
-
- let eye = Vector2::new(self.position.0, self.position.1);
- let x_dot = -cgmath::dot(x_axis, eye);
- let y_dot = -cgmath::dot(y_axis, eye);
-
- #[rustfmt::skip]
- let view_matrix = Matrix4::new(
- x_axis.x, y_axis.x, 0.0, 0.0,
- x_axis.y, y_axis.y, 0.0, 0.0,
- 0.0, 0.0, 1.0, 0.0,
- x_dot, y_dot, 0.0, 1.0
- );
-
- #[rustfmt::skip]
- // TODO implement more scaling coordinate systems
- let projection_matrix = Matrix4::new(
- self.inverse_aspect_ratio * self.zoom, 0.0, 0.0, 0.0,
- 0.0, self.zoom, 0.0, 0.0,
- 0.0, 0.0, 1.0 / 256.0, 0.0,
- 0.0, 0.0, 0.0, 1.0
- );
-
- let transform = projection_matrix * view_matrix;
- transform.into()
- }
-
- /// Get the bind group for the camera
- pub(crate) const fn bind_group(&self) -> &wgpu::BindGroup {
- &self.bind_group
- }
-
- /// Refresh the camera buffer for the next frame
- #[profiling::function]
- pub(crate) fn refresh(&self, queue: &wgpu::Queue) {
- queue.write_buffer(
- &self.buffer,
- 0 as wgpu::BufferAddress,
- bytemuck::cast_slice(&self.to_matrix()),
- );
- }
-}
diff --git a/render/src/config.rs b/render/src/config.rs
deleted file mode 100644
index c3cc6b6..0000000
--- a/render/src/config.rs
+++ /dev/null
@@ -1,198 +0,0 @@
-use std::num::NonZeroU32;
-
-use winit::dpi::{LogicalPosition, LogicalSize};
-use winit::window::{Fullscreen, WindowBuilder};
-
-/// Describes how a window may be resized
-#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
-pub struct Resizable {
- /// The minimum width of the window, or None if unconstrained
- pub min_width: Option<NonZeroU32>,
- /// The minimum height of the window, or None if unconstrained
- pub min_height: Option<NonZeroU32>,
- /// The maximum width of the window, or None if unconstrained
- pub max_width: Option<NonZeroU32>,
- /// The maximum height of the window, or None if unconstrained
- pub max_height: Option<NonZeroU32>,
-}
-
-/// Information about a window, that is not fullscreened
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub struct WindowInfo {
- pub default_x: i32,
- pub default_y: i32,
- pub resizable: Option<Resizable>,
- pub default_maximized: bool,
-}
-
-impl Default for WindowInfo {
- fn default() -> Self {
- Self {
- default_x: 100,
- default_y: 100,
- resizable: Some(Resizable::default()),
- default_maximized: false,
- }
- }
-}
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub enum WindowMode {
- Windowed(WindowInfo),
- // TODO support choosing a monitor
- BorderlessFullscreen, // TODO exclusive fullscreen
-}
-
-impl Default for WindowMode {
- fn default() -> Self {
- Self::Windowed(WindowInfo::default())
- }
-}
-
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
-// TODO window icon
-pub struct RenderWindowConfig<'a> {
- /// The width of the window, once initialized
- pub default_width: NonZeroU32,
- /// The height of the window, once initialized
- pub default_height: NonZeroU32,
- /// The window may be fullscreen
- pub mode: WindowMode,
- /// The title for the window
- pub title: &'a str,
- /// If true, a low-power device will be selected as the GPU, if possible
- pub low_power: bool,
- /// If true, Fifo mode is used to present frames. If false, then Mailbox or
- /// Immediate will be used if available. Otherwise, Fifo will be used.
- pub vsync: bool,
- /// The initial capacity of the instance buffer. The size will increase if
- /// it's not large enough. Increasing this value may improve performance
- /// towards the beginning, if a lot of instances are being created. For
- /// compatibility with older devices, it's recommended to keep this number
- /// below 150 thousand.
- pub instance_capacity: usize,
-}
-
-impl<'a> Default for RenderWindowConfig<'a> {
- fn default() -> Self {
- Self {
- default_width: NonZeroU32::new(640).unwrap(),
- default_height: NonZeroU32::new(480).unwrap(),
- mode: WindowMode::default(),
- title: "Alligator Game",
- low_power: true,
- vsync: true,
- instance_capacity: 500,
- }
- }
-}
-
-impl<'a> RenderWindowConfig<'a> {
- /// Based on the vsync settings, choose a presentation mode
- pub(crate) fn present_mode(
- vsync: bool,
- supported_modes: &[wgpu::PresentMode],
- ) -> wgpu::PresentMode {
- if vsync {
- wgpu::PresentMode::Fifo
- } else if supported_modes.contains(&wgpu::PresentMode::Mailbox) {
- wgpu::PresentMode::Mailbox
- } else if supported_modes.contains(&wgpu::PresentMode::Immediate) {
- wgpu::PresentMode::Immediate
- } else {
- wgpu::PresentMode::Fifo
- }
- }
-
- /// Pick an alpha mode
- fn alpha_mode(supported_modes: &[wgpu::CompositeAlphaMode]) -> wgpu::CompositeAlphaMode {
- if supported_modes.contains(&wgpu::CompositeAlphaMode::PostMultiplied) {
- wgpu::CompositeAlphaMode::PostMultiplied
- } else {
- wgpu::CompositeAlphaMode::Auto
- }
- }
-
- /// Create a `WindowBuilder` from the configuration given. This window is
- /// initially invisible and must later be made visible.
- pub(crate) fn to_window(&self) -> WindowBuilder {
- // start building the window
- let mut builder = WindowBuilder::new()
- .with_title(self.title)
- .with_visible(false)
- .with_inner_size(LogicalSize::new(
- self.default_width.get(),
- self.default_height.get(),
- ));
-
- match self.mode {
- WindowMode::Windowed(window_info) => {
- builder = builder.with_maximized(window_info.default_maximized);
-
- if let Some(resizing_options) = window_info.resizable {
- if resizing_options.max_height.is_some() || resizing_options.max_width.is_some()
- {
- builder = builder.with_max_inner_size(LogicalSize::new(
- resizing_options.max_width.unwrap_or(NonZeroU32::MAX).get(),
- resizing_options.max_height.unwrap_or(NonZeroU32::MAX).get(),
- ));
- }
-
- if resizing_options.min_height.is_some() || resizing_options.min_width.is_some()
- {
- builder = builder.with_min_inner_size(LogicalSize::new(
- resizing_options.min_width.unwrap_or(NonZeroU32::MAX).get(),
- resizing_options.min_height.unwrap_or(NonZeroU32::MAX).get(),
- ));
- }
- } else {
- builder = builder.with_resizable(false);
- }
-
- // TODO clamp the position to the monitor's size
- builder = builder.with_position(LogicalPosition::new(
- window_info.default_x,
- window_info.default_y,
- ));
- }
- WindowMode::BorderlessFullscreen => {
- builder = builder.with_fullscreen(Some(Fullscreen::Borderless(None)));
- }
- }
-
- builder
- }
-
- /// Gets a surface configuration out of the config.
- pub(crate) fn to_surface_configuration(
- &self,
- supported_present_modes: &[wgpu::PresentMode],
- supported_alpha_modes: &[wgpu::CompositeAlphaMode],
- ) -> wgpu::SurfaceConfiguration {
- let present_mode = Self::present_mode(self.vsync, supported_present_modes);
- let alpha_mode = Self::alpha_mode(supported_alpha_modes);
-
- // configuration for the surface
- wgpu::SurfaceConfiguration {
- usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
- format: wgpu::TextureFormat::Bgra8Unorm,
- width: self.default_width.get(),
- height: self.default_height.get(),
- alpha_mode,
- present_mode,
- view_formats: vec![
- wgpu::TextureFormat::Bgra8Unorm,
- wgpu::TextureFormat::Bgra8UnormSrgb,
- ],
- }
- }
-
- /// Get the power preference
- pub(crate) const fn power_preference(&self) -> wgpu::PowerPreference {
- if self.low_power {
- wgpu::PowerPreference::LowPower
- } else {
- wgpu::PowerPreference::HighPerformance
- }
- }
-}
diff --git a/render/src/instance.rs b/render/src/instance.rs
deleted file mode 100644
index 15317c7..0000000
--- a/render/src/instance.rs
+++ /dev/null
@@ -1,150 +0,0 @@
-use std::mem::size_of;
-
-use bytemuck::{Pod, Zeroable};
-
-/// The ID for an instance
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
-pub struct InstanceId(usize);
-
-/// A sprite, that can be used by the alligator shader
-#[repr(C)]
-#[derive(Copy, Clone, Debug, PartialEq, Pod, Zeroable)]
-pub struct Instance {
- /// Position on the screen
- pub position: [f32; 2],
- /// Relative size
- pub size: [f32; 2],
- /// The location of the texture in the texture atlas
- pub texture_coordinates: [f32; 2],
- /// The size of the sprite's texture
- pub texture_size: [f32; 2],
-}
-
-impl Default for Instance {
- fn default() -> Self {
- Self {
- position: [0.0; 2],
- size: [1.0; 2],
- texture_coordinates: [0.0; 2],
- texture_size: [1.0; 2],
- }
- }
-}
-
-impl Instance {
- // whenever this is updated, please also update `sprite.wgsl`
- const ATTRIBUTES: [wgpu::VertexAttribute; 7] = wgpu::vertex_attr_array![
- 1 => Float32x2, 2 => Float32x2, 3 => Float32x2, 4 => Float32x2,
- 5 => Uint32, 6 => Float32, 7 => Float32
- ];
-
- pub(crate) fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
- // make sure these two don't conflict
- debug_assert_eq!(
- Self::ATTRIBUTES[0].shader_location as usize,
- crate::Vertex::ATTRIBUTES.len()
- );
- wgpu::VertexBufferLayout {
- array_stride: size_of::<Self>() as wgpu::BufferAddress,
- step_mode: wgpu::VertexStepMode::Instance,
- attributes: &Self::ATTRIBUTES,
- }
- }
-}
-
-/// A buffer of sprites, for both CPU and GPU memory
-pub struct InstanceBuffer {
- instances: Vec<Instance>,
- instance_buffer: wgpu::Buffer,
- instance_buffer_size: usize,
-}
-
-fn create_buffer(device: &wgpu::Device, instances: &Vec<Instance>) -> wgpu::Buffer {
- device.create_buffer(&wgpu::BufferDescriptor {
- label: Some("Sprite Instance Buffer"),
- size: (instances.capacity() * size_of::<Instance>()) as wgpu::BufferAddress,
- usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
- mapped_at_creation: false,
- })
-}
-
-impl InstanceBuffer {
- /// Create a new buffer with the given capacity
- pub(crate) fn new(device: &wgpu::Device, capacity: usize) -> Self {
- let instances = Vec::with_capacity(capacity);
- let instance_buffer_size = instances.capacity();
- let instance_buffer = create_buffer(device, &instances);
-
- Self {
- instances,
- instance_buffer,
- instance_buffer_size,
- }
- }
-
- /// The number of sprites
- pub fn len(&self) -> u32 {
- self.instances
- .len()
- .try_into()
- .expect("expected less than 3 billion instances")
- }
-
- /// Returns `true` if there are no sprites
- pub fn is_empty(&self) -> bool {
- self.instances.is_empty()
- }
-
- /// The capacity of the buffer
- pub const fn buffer_size(&self) -> usize {
- self.instance_buffer_size
- }
-
- /// Get a slice containing the entire buffer
- pub(crate) fn buffer_slice(&self) -> wgpu::BufferSlice {
- self.instance_buffer.slice(..)
- }
-
- /// Add a new sprite. The new sprite's `InstanceId` is returned. This ID
- /// becomes invalid if the buffer is cleared.
- pub fn push_instance(&mut self, instance: Instance) -> InstanceId {
- let index = self.instances.len();
- self.instances.push(instance);
- InstanceId(index)
- }
-
- /// Get a specific instance
- pub fn get_instance(&self, id: InstanceId) -> Option<&Instance> {
- self.instances.get(id.0)
- }
-
- /// Get a mutable reference to a specific sprite
- pub fn get_instance_mut(&mut self, id: InstanceId) -> Option<&mut Instance> {
- self.instances.get_mut(id.0)
- }
-
- /// Clear the instance buffer. This invalidates all `InstanceId`'s
- pub fn clear(&mut self) {
- self.instances.clear();
- }
-
- /// Increase the capacity of the buffer
- fn expand_buffer(&mut self, device: &wgpu::Device) {
- self.instance_buffer_size = self.instances.capacity();
- self.instance_buffer = create_buffer(device, &self.instances);
- }
-
- /// Fill the GPU buffer with the sprites in the CPU buffer.
- #[profiling::function]
- pub(crate) fn fill_buffer(&mut self, device: &wgpu::Device, queue: &wgpu::Queue) {
- if self.instances.len() > self.instance_buffer_size {
- self.expand_buffer(device);
- }
-
- queue.write_buffer(
- &self.instance_buffer,
- 0 as wgpu::BufferAddress,
- bytemuck::cast_slice(&self.instances),
- );
- }
-}
diff --git a/render/src/lib.rs b/render/src/lib.rs
deleted file mode 100644
index 6f96fc2..0000000
--- a/render/src/lib.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-#![feature(type_alias_impl_trait)]
-#![warn(clippy::pedantic)]
-#![warn(clippy::nursery)]
-#![allow(clippy::module_name_repetitions)]
-
-mod camera;
-pub mod config;
-pub mod instance;
-pub mod renderer;
-mod texture;
-mod vertex;
-
-pub(crate) use camera::Camera;
-pub use config::*;
-pub use instance::Instance;
-pub(crate) use instance::InstanceBuffer;
-pub use instance::InstanceId;
-pub use renderer::Renderer;
-pub(crate) use texture::TextureAtlas;
-pub(crate) use vertex::Vertex;
diff --git a/render/src/renderer.rs b/render/src/renderer.rs
deleted file mode 100644
index 4b4f60d..0000000
--- a/render/src/renderer.rs
+++ /dev/null
@@ -1,438 +0,0 @@
-use std::num::NonZeroU32;
-use std::{convert::TryInto, sync::Arc};
-
-use crate::{
- vertex::SQUARE, Camera, Instance, InstanceBuffer, RenderWindowConfig, TextureAtlas, Vertex,
-};
-use pollster::FutureExt;
-use thiserror::Error;
-use wgpu::{include_wgsl, util::DeviceExt};
-use winit::{
- dpi::PhysicalSize,
- error::OsError,
- event::{Event, WindowEvent},
- event_loop::{ControlFlow, EventLoop},
- window::Window,
-};
-
-/// No device could be found which supports the given surface
-#[derive(Clone, Copy, Debug, Error)]
-#[error("No GPU could be found on this machine")]
-pub struct NoGpuError {
- /// Prevents this type from being constructed
- _priv: (),
-}
-
-impl NoGpuError {
- /// Create a new error
- const fn new() -> Self {
- Self { _priv: () }
- }
-}
-
-/// No device could be found which supports the given surface
-#[derive(Clone, Copy, Debug, Error)]
-#[error("A WebGPU or WebGL context could not be obtained")]
-pub struct NoWebContextError {
- /// Prevents this type from being constructed
- _priv: (),
-}
-
-impl NoWebContextError {
- /// Create a new error
- const fn new() -> Self {
- Self { _priv: () }
- }
-}
-
-#[derive(Debug, Error)]
-pub enum NewRendererError {
- #[error(transparent)]
- NoGpu(#[from] NoGpuError),
- #[error(transparent)]
- NoWebContext(#[from] NoWebContextError),
- #[error(transparent)]
- // TODO better error
- WindowInitError(#[from] OsError),
-}
-
-// TODO make this Debug
-pub struct Renderer {
- // TODO move some of this data elsewhere
- surface: wgpu::Surface,
- surface_config: wgpu::SurfaceConfiguration,
- supported_present_modes: Box<[wgpu::PresentMode]>,
- device: wgpu::Device,
- queue: wgpu::Queue,
- render_pipeline: wgpu::RenderPipeline,
- square_vertex_buffer: wgpu::Buffer,
- square_vertices: u32,
- instances: InstanceBuffer,
- camera: Camera,
- textures: TextureAtlas,
- event_loop: Option<EventLoop<()>>,
- window: Window,
-}
-
-fn get_adapter(
- instance: &wgpu::Instance,
- surface: &wgpu::Surface,
- power_preference: wgpu::PowerPreference,
-) -> Result<wgpu::Adapter, NoGpuError> {
- let adapter = instance
- .request_adapter(&wgpu::RequestAdapterOptions {
- power_preference,
- compatible_surface: Some(surface),
- force_fallback_adapter: false,
- })
- .block_on(); // TODO this takes too long
-
- let adapter = adapter.or_else(|| {
- instance
- .enumerate_adapters(wgpu::Backends::VULKAN)
- .find(|adapter| !surface.get_capabilities(adapter).formats.is_empty())
- });
-
- adapter.ok_or(NoGpuError::new())
-}
-
-fn sprite_render_pipeline(
- device: &wgpu::Device,
- texture_format: wgpu::TextureFormat,
- render_pipeline_layout: &wgpu::PipelineLayout,
-) -> wgpu::RenderPipeline {
- let shader = device.create_shader_module(include_wgsl!("../shaders/sprite.wgsl"));
-
- device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
- label: Some("Sprite Render Pipeline"),
- layout: Some(render_pipeline_layout),
- // information about the vertex shader
- vertex: wgpu::VertexState {
- module: &shader,
- entry_point: "vs_main",
- buffers: &[Vertex::desc(), Instance::desc()],
- },
- // information about the fragment shader
- fragment: Some(wgpu::FragmentState {
- module: &shader,
- entry_point: "fs_main",
- targets: &[Some(wgpu::ColorTargetState {
- format: texture_format,
- blend: Some(wgpu::BlendState::ALPHA_BLENDING),
- write_mask: wgpu::ColorWrites::ALL,
- })],
- }),
- primitive: wgpu::PrimitiveState {
- // don't render the back of a sprite
- cull_mode: Some(wgpu::Face::Back),
- ..Default::default()
- },
- depth_stencil: None,
- multisample: wgpu::MultisampleState::default(),
- multiview: None,
- })
-}
-
-impl Renderer {
- /// Initializes the renderer
- ///
- /// # Errors
- ///
- /// Returns a [`NoGpu`] error if no device could be detected that can
- /// display to the window
- ///
- /// # Panics
- ///
- /// This function **must** be called on the main thread, or else it may
- /// panic on some platforms.
- // TODO make it possible to use without a window (ie, use a bitmap in memory as a surface)
- // TODO this function needs to be smaller
- pub fn new(config: &RenderWindowConfig) -> Result<Self, NewRendererError> {
- // build the window
- let event_loop = EventLoop::new();
- let window = config.to_window().build(&event_loop)?;
- let event_loop = Some(event_loop);
-
- // the instance's main purpose is to create an adapter and a surface
- let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::default());
-
- // the surface is the part of the screen we'll draw to
- let surface =
- unsafe { instance.create_surface(&window) }.map_err(|_| NoWebContextError::new())?;
-
- let power_preference = config.power_preference();
-
- // the adapter is the handle to the GPU
- let adapter = get_adapter(&instance, &surface, power_preference)?;
-
- // gets a connection to the device, as well as a handle to its command queue
- // the options chosen here ensure that this is guaranteed to not panic
- let (device, queue) = adapter
- .request_device(
- &wgpu::DeviceDescriptor {
- features: wgpu::Features::empty(),
- limits: wgpu::Limits {
- max_buffer_size: adapter.limits().max_buffer_size,
- max_texture_dimension_2d: adapter.limits().max_texture_dimension_2d,
- ..Default::default()
- },
- ..Default::default()
- },
- None,
- )
- .block_on()
- .expect("there was no device with the selected features");
-
- // configuration for the surface
- let capabilities = surface.get_capabilities(&adapter);
- let supported_present_modes = capabilities.present_modes.into_boxed_slice();
- let supported_alpha_modes = capabilities.alpha_modes.into_boxed_slice();
- let surface_config =
- config.to_surface_configuration(&supported_present_modes, &supported_alpha_modes);
- surface.configure(&device, &surface_config);
-
- // create the camera
- let width = window.inner_size().width;
- let height = window.inner_size().height;
- let (camera, camera_bind_group_layout) = Camera::new(&device, width, height);
-
- // the vertex buffer used for rendering squares
- let square_vertices = SQUARE
- .len()
- .try_into()
- .expect("expected fewer than 3 billion vertices in a square");
- let square_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
- label: Some("Square Vertex Buffer"),
- contents: bytemuck::cast_slice(&SQUARE),
- usage: wgpu::BufferUsages::VERTEX,
- });
-
- // create the instance buffer
- let instances = InstanceBuffer::new(&device, config.instance_capacity);
-
- // TODO make this configurable
- let (textures, texture_layout) = TextureAtlas::new(
- &device,
- window.inner_size().width,
- window.inner_size().height,
- );
-
- let render_pipeline_layout =
- device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
- label: Some("Sprite Render Pipeline Layout"),
- bind_group_layouts: &[&camera_bind_group_layout, &texture_layout],
- push_constant_ranges: &[],
- });
-
- // set up a pipeline for sprite rendering
- let render_pipeline =
- sprite_render_pipeline(&device, surface_config.format, &render_pipeline_layout);
-
- Ok(Self {
- surface,
- surface_config,
- supported_present_modes,
- device,
- queue,
- render_pipeline,
- square_vertex_buffer,
- square_vertices,
- instances,
- camera,
- textures,
- event_loop,
- window,
- })
- }
-
- /// Reconfigure the surface
- fn reconfigure(&mut self) {
- self.surface.configure(&self.device, &self.surface_config);
- }
-
- /// Resize just the renderer. The window will remain unchanged
- fn resize_renderer(&mut self, size: PhysicalSize<u32>) {
- if size.width == 0 || size.height == 0 {
- log::error!("The window was somehow set to a size of zero");
- return;
- }
-
- self.surface_config.height = size.height;
- self.surface_config.width = size.width;
- self.camera.set_size(size.width, size.height);
- self.reconfigure();
- }
-
- /// Set the physical window and renderer size
- pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) {
- let size = PhysicalSize::new(width.get(), height.get());
- self.window.set_inner_size(size);
- self.resize_renderer(size);
- }
-
- /// Set vsync on or off. See `[RenderWindowConfig::present_mode]` for more details.
- pub fn set_vsync(&mut self, vsync: bool) {
- self.surface_config.present_mode =
- RenderWindowConfig::present_mode(vsync, &self.supported_present_modes);
- self.reconfigure();
- }
-
- /// Set the window's title
- pub fn set_title(&mut self, title: &str) {
- self.window.set_title(title);
- }
-
- /// The reference buffer
- pub const fn instances(&self) -> &InstanceBuffer {
- &self.instances
- }
-
- /// The reference buffer
- pub fn instances_mut(&mut self) -> &mut InstanceBuffer {
- &mut self.instances
- }
-
- /// Get the camera information
- pub const fn camera(&self) -> &Camera {
- &self.camera
- }
-
- /// Get a mutable reference to the camera
- pub fn camera_mut(&mut self) -> &mut Camera {
- &mut self.camera
- }
-
- /// Get a reference to the texture atlas
- pub const fn texture_atlas(&self) -> &TextureAtlas {
- &self.textures
- }
-
- /// Get a mutable reference to the texture atlas
- pub fn textures_mut(&mut self) -> &mut TextureAtlas {
- &mut self.textures
- }
-
- /// Renders a new frame to the window
- ///
- /// # Errors
- ///
- /// A number of problems could occur here. A timeout could occur while
- /// trying to acquire the next frame. There may also be no more memory left
- /// that can be used for the new frame.
- // TODO this needs to be smaller
- // TODO don't return wgpu errors
- #[profiling::function]
- fn render(&mut self) -> Result<(), wgpu::SurfaceError> {
- // this will allow us to send commands to the gpu
- let mut encoder = self
- .device
- .create_command_encoder(&wgpu::CommandEncoderDescriptor {
- label: Some("Render Encoder"),
- });
-
- let num_instances = self.instances.len();
- self.instances.fill_buffer(&self.device, &self.queue);
- self.camera.refresh(&self.queue);
- self.textures.fill_textures(&self.queue);
-
- // the new texture we can render to
- let output = self.surface.get_current_texture()?;
- let view = output
- .texture
- .create_view(&wgpu::TextureViewDescriptor::default());
-
- {
- profiling::scope!("encode render pass");
- let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- label: Some("Render Pass"),
- color_attachments: &[Some(wgpu::RenderPassColorAttachment {
- view: &view,
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
- store: wgpu::StoreOp::Discard,
- },
- })],
- depth_stencil_attachment: None,
- timestamp_writes: None,
- occlusion_query_set: None,
- });
-
- render_pass.set_pipeline(&self.render_pipeline);
- render_pass.set_bind_group(0, self.camera.bind_group(), &[]);
- render_pass.set_bind_group(1, self.textures.bind_group(), &[]);
- render_pass.set_vertex_buffer(0, self.square_vertex_buffer.slice(..));
- render_pass.set_vertex_buffer(1, self.instances.buffer_slice());
- render_pass.draw(0..self.square_vertices, 0..num_instances);
- }
- // the encoder can't finish building the command buffer until the
- // render pass is dropped
-
- // submit the command buffer to the GPU
- profiling::scope!("submit render");
- self.queue.submit(std::iter::once(encoder.finish()));
- output.present();
-
- Ok(())
- }
-
- /// Take the event loop out of the Renderer, without moving it
- ///
- /// # Panics
- ///
- /// This method must only be called once
- // TODO This is a quick fix to get the event loop inside the renderer.
- // In the future, we should make a separate struct that contains the
- // renderer and the event loop, which we move the event loop out of
- // while still being able to move the renderer.
- fn event_loop(&mut self) -> EventLoop<()> {
- self.event_loop.take().unwrap()
- }
-
- /// Run the renderer indefinitely
- // TODO this needs to be smaller
- pub fn run<F: FnMut(&mut Self) + 'static>(mut self, mut f: F) -> ! {
- self.window.set_visible(true);
- let event_loop = self.event_loop();
- event_loop.run(move |event, _, control_flow| match event {
- Event::WindowEvent { window_id, event } => {
- if window_id == self.window.id() {
- match event {
- WindowEvent::Resized(size) => self.resize_renderer(size),
- WindowEvent::CloseRequested => {
- *control_flow = ControlFlow::ExitWithCode(0);
- }
- _ => (),
- }
- }
- }
- Event::MainEventsCleared => {
- f(&mut self);
-
- // a memory leak occurs if we render a zero-size window,
- // along with a `SurfaceError::Outdated`. I don't know why that
- // happens, but let's make wgpu happy.
- // https://github.com/gfx-rs/wgpu/issues/1783#issuecomment-1328463201
- if self.window.inner_size().width != 0 && self.window.inner_size().height != 0 {
- match self.render() {
- Ok(()) => {}
- // reconfigure the surface if it's been lost
- Err(wgpu::SurfaceError::Lost) => {
- self.reconfigure();
- }
- // if we ran out of memory, then we'll die
- Err(wgpu::SurfaceError::OutOfMemory) => {
- *control_flow = ControlFlow::ExitWithCode(1);
- }
- // otherwise, we'll just log the error
- Err(e) => log::error!("{}", e),
- }
- } else {
- *control_flow = ControlFlow::Wait;
- }
- profiling::finish_frame!();
- }
- _ => {}
- });
- }
-}
diff --git a/render/src/texture.rs b/render/src/texture.rs
deleted file mode 100644
index 90d23d1..0000000
--- a/render/src/texture.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-use std::error::Error;
-
-use image::{EncodableLayout, RgbaImage};
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub enum TextureError {
- #[error("Unexpected Error (this is a bug in alligator_render): {}", .0)]
- Unexpected(#[source] Box<dyn Error>),
-}
-
-/// Simpler constructor for a wgpu extent3d
-const fn extent_3d(width: u32, height: u32) -> wgpu::Extent3d {
- wgpu::Extent3d {
- width,
- height,
- depth_or_array_layers: 1,
- }
-}
-
-/// A texture atlas, usable by the renderer
-// TODO make these resizable
-#[derive(Debug)]
-pub struct TextureAtlas {
- diffuse_texture: wgpu::Texture,
- diffuse_bind_group: wgpu::BindGroup,
- image: RgbaImage,
-}
-
-impl TextureAtlas {
- /// Creates a new texture atlas, with the given size
- // TODO this is still too large
- pub fn new(device: &wgpu::Device, width: u32, height: u32) -> (Self, wgpu::BindGroupLayout) {
- let atlas_size = extent_3d(width, height);
- let diffuse_texture = device.create_texture(&wgpu::TextureDescriptor {
- label: Some("Diffuse Texture"),
- size: atlas_size,
- mip_level_count: 1,
- sample_count: 1,
- dimension: wgpu::TextureDimension::D2,
- format: wgpu::TextureFormat::Rgba8Unorm,
- usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
- view_formats: &[wgpu::TextureFormat::Rgba8UnormSrgb],
- });
-
- // TODO I don't think this refreshes anything
- let diffuse_texture_view =
- diffuse_texture.create_view(&wgpu::TextureViewDescriptor::default());
-
- let diffuse_sampler = device.create_sampler(&wgpu::SamplerDescriptor::default());
-
- let texture_bind_group_layout =
- device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
- label: Some("Texture Bind Group Layout"),
- entries: &[
- wgpu::BindGroupLayoutEntry {
- binding: 0,
- visibility: wgpu::ShaderStages::FRAGMENT,
- ty: wgpu::BindingType::Texture {
- sample_type: wgpu::TextureSampleType::Float { filterable: true },
- view_dimension: wgpu::TextureViewDimension::D2,
- multisampled: false,
- },
- count: None,
- },
- wgpu::BindGroupLayoutEntry {
- binding: 1,
- visibility: wgpu::ShaderStages::FRAGMENT,
- ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
- count: None,
- },
- ],
- });
-
- let diffuse_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
- label: Some("Diffuse Bind Group"),
- layout: &texture_bind_group_layout,
- entries: &[
- wgpu::BindGroupEntry {
- binding: 0,
- resource: wgpu::BindingResource::TextureView(&diffuse_texture_view),
- },
- wgpu::BindGroupEntry {
- binding: 1,
- resource: wgpu::BindingResource::Sampler(&diffuse_sampler),
- },
- ],
- });
-
- (
- Self {
- diffuse_texture,
- diffuse_bind_group,
- image: RgbaImage::from_raw(
- width,
- height,
- vec![0; 4 * width as usize * height as usize],
- )
- .unwrap(),
- },
- texture_bind_group_layout,
- )
- }
-
- /// get the bind group for the texture
- pub(crate) const fn bind_group(&self) -> &wgpu::BindGroup {
- &self.diffuse_bind_group
- }
-
- pub(crate) fn fill_textures(&self, queue: &wgpu::Queue) {
- queue.write_texture(
- wgpu::ImageCopyTexture {
- texture: &self.diffuse_texture,
- mip_level: 0,
- origin: wgpu::Origin3d::ZERO,
- aspect: wgpu::TextureAspect::All,
- },
- self.image.as_bytes(),
- wgpu::ImageDataLayout {
- offset: 0,
- bytes_per_row: Some(self.image.width() * 4),
- rows_per_image: Some(self.image.height()),
- },
- extent_3d(self.image.width(), self.image.height()),
- );
- }
-}
diff --git a/render/src/vertex.rs b/render/src/vertex.rs
deleted file mode 100644
index 570eec4..0000000
--- a/render/src/vertex.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-use std::mem::size_of;
-
-use bytemuck::{Pod, Zeroable};
-
-/// The vertices needed to form a square
-pub const SQUARE: [Vertex; 6] = [
- Vertex::new(-0.5, -0.5),
- Vertex::new(0.5, -0.5),
- Vertex::new(-0.5, 0.5),
- Vertex::new(0.5, 0.5),
- Vertex::new(-0.5, 0.5),
- Vertex::new(0.5, -0.5),
-];
-
-/// A vertex that is usable by the alligator shader
-#[repr(C)]
-#[derive(Copy, Clone, Debug, PartialEq, Pod, Zeroable)]
-pub struct Vertex {
- position: [f32; 2],
-}
-
-impl Vertex {
- // whenever this is updated, please also update `sprite.wgsl`
- pub(crate) const ATTRIBUTES: [wgpu::VertexAttribute; 1] =
- wgpu::vertex_attr_array![0 => Float32x2];
-
- /// Create a new vertex
- const fn new(x: f32, y: f32) -> Self {
- Self { position: [x, y] }
- }
-
- pub(crate) const fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
- wgpu::VertexBufferLayout {
- array_stride: size_of::<Self>() as wgpu::BufferAddress,
- step_mode: wgpu::VertexStepMode::Vertex,
- attributes: &Self::ATTRIBUTES,
- }
- }
-}
diff --git a/src/main.rs b/src/main.rs
index 717599d..ade657e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -7,7 +7,6 @@ use std::path::Path;
use alligator_scripts::ScriptManager;
use alligator_sprites::SpriteManager;
use alligator_sys::{Renderer, RendererConfig, Window, WindowConfig, WindowEvent};
-use alligator_textures::TextureManager;
use serde::Deserialize;
use sha3::{Digest, Sha3_256};
@@ -65,19 +64,6 @@ pub struct Config {
vsync: bool,
}
-fn texture_manager(config: &Config) -> TextureManager {
- let mut textures = TextureManager::new(config.default_textures_size_target);
- for (key, texture) in config.textures.iter() {
- textures.add_texture(
- key.clone().into(),
- texture.path.clone().into(),
- texture.size,
- );
- }
-
- textures
-}
-
fn sprite_manager(config: &Config) -> SpriteManager {
SpriteManager::with_capacity(config.sprite_manager_capacity as usize)
}
@@ -137,7 +123,6 @@ fn main() {
let config = File::open("game.json").unwrap();
let config: Config = serde_json::from_reader(config).unwrap();
- let textures = texture_manager(&config);
let sprites = sprite_manager(&config);
let scripts = script_manager(&config);
let mut window = window(&config);
diff --git a/textures/Cargo.toml b/textures/Cargo.toml
deleted file mode 100644
index e550a92..0000000
--- a/textures/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "alligator_textures"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-packer = { path = "../packer" }
-
-image = "0.24"
-exun = "0.2"
diff --git a/textures/src/lib.rs b/textures/src/lib.rs
deleted file mode 100644
index c1b56a8..0000000
--- a/textures/src/lib.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-use std::collections::HashMap;
-use std::path::Path;
-use std::sync::Arc;
-
-use exun::{RawUnexpected, ResultErrorExt};
-use image::RgbaImage;
-use packer::{RectanglePacker, TextureAtlas};
-
-type ExunResult<T> = Result<T, RawUnexpected>;
-
-pub struct TextureManager {
- textures: HashMap<Arc<str>, TextureMetadata>,
- loaded_textures: HashMap<Arc<str>, Arc<RgbaImage>>,
- packer: RectanglePacker,
- target_size: usize,
- current_size: usize,
-}
-
-struct TextureMetadata {
- path: Arc<Path>,
- size: usize,
-}
-
-impl TextureManager {
- pub fn new(target_size: usize) -> Self {
- Self {
- textures: HashMap::new(),
- loaded_textures: HashMap::new(),
- packer: RectanglePacker::new(),
- target_size,
- current_size: 0,
- }
- }
-
- pub fn add_texture(&mut self, name: Arc<str>, path: Arc<Path>, size: usize) {
- self.textures.insert(name, TextureMetadata { path, size });
- }
-
- pub fn try_preload(&mut self, name: Arc<str>) -> ExunResult<Option<bool>> {
- let Some(metadata) = self.textures.get(&name) else {
- return Ok(None);
- };
-
- if self.current_size + metadata.size < self.target_size {
- self.load(name)?;
- Ok(Some(true))
- } else {
- Ok(Some(false))
- }
- }
-
- pub fn load(&mut self, name: Arc<str>) -> ExunResult<Option<()>> {
- let Some(metadata) = self.textures.get(&name) else {
- return Ok(None);
- };
-
- self.current_size += metadata.size;
- let texture = image::open(&metadata.path).unexpect()?.to_rgba8();
- self.loaded_textures.insert(name, Arc::new(texture));
-
- Ok(Some(()))
- }
-
- pub fn unload(&mut self, name: Arc<str>) -> Option<()> {
- self.loaded_textures.remove(&name)?;
- Some(())
- }
-
- pub fn pack_texture(&mut self, name: Arc<str>) -> ExunResult<()> {
- if !self.loaded_textures.contains_key(&name) {
- self.load(name.clone())?;
- }
-
- self.packer.add_texture(
- name.clone(),
- self.loaded_textures
- .get(&name)
- .expect("we checked to make sure it was loaded")
- .clone(),
- );
-
- Ok(())
- }
-
- pub fn reset_packer(&mut self) {
- self.packer = RectanglePacker::new();
- }
-
- pub fn reload_texture_atlas(
- &mut self,
- min_width: u32,
- min_height: u32,
- ) -> ExunResult<TextureAtlas> {
- self.packer.output(min_width, min_height)
- }
-}
diff --git a/tvg/Cargo.toml b/tvg/Cargo.toml
deleted file mode 100644
index 385de09..0000000
--- a/tvg/Cargo.toml
+++ /dev/null
@@ -1,13 +0,0 @@
-[package]
-name = "alligator_tvg"
-version = "0.1.0"
-edition = "2021"
-publish = false
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-byteorder = "1"
-thiserror = "1"
-raise = "2"
-num_enum = "0.5"
diff --git a/tvg/src/colors.rs b/tvg/src/colors.rs
deleted file mode 100644
index 0dd8831..0000000
--- a/tvg/src/colors.rs
+++ /dev/null
@@ -1,517 +0,0 @@
-use std::io::{self, Read};
-
-use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
-use num_enum::TryFromPrimitive;
-
-use crate::TvgError;
-
-const GAMMA: f32 = 2.2;
-const INVERT_GAMMA: f32 = 1.0 / GAMMA;
-
-/// The color table encodes the palette for this file.
-///
-/// It’s binary content is defined by the `color_encoding` field in the header.
-/// For the three defined color encodings, each will yield a list of
-/// `color_count` RGBA tuples.
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ColorTable<C: Color> {
- colors: Box<[C]>,
-}
-
-impl<C: Color> ColorTable<C> {
- /// Read in one encoding, and convert it to another. If `encoding` is
- /// [`ColorEncoding::Custom`], then return
- /// [`TvgError::UnsupportedColorEncoding`].
- pub fn read_from_encoding(
- reader: &mut impl Read,
- color_count: u32,
- encoding: ColorEncoding,
- ) -> Result<Self, TvgError> {
- Ok(match encoding {
- ColorEncoding::Rgba8888 => (&ColorTable::<Rgba8888>::read(reader, color_count)?).into(),
- ColorEncoding::Rgb565 => (&ColorTable::<Rgb565>::read(reader, color_count)?).into(),
- ColorEncoding::RgbaF32 => (&ColorTable::<RgbaF32>::read(reader, color_count)?).into(),
- ColorEncoding::Custom => (&ColorTable::<Rgba16>::read(reader, color_count)?).into(),
- })
- }
-
- /// Read in one encoding, and convert it into another. If `encoding` is
- /// [`ColorEncoding::Custom`], then use the given encoding.
- pub fn read_from_encoding_with_custom<Custom: Color>(
- reader: &mut impl Read,
- color_count: u32,
- encoding: ColorEncoding,
- ) -> io::Result<Self> {
- Ok(match encoding {
- ColorEncoding::Rgba8888 => (&ColorTable::<Rgba8888>::read(reader, color_count)?).into(),
- ColorEncoding::Rgb565 => (&ColorTable::<Rgb565>::read(reader, color_count)?).into(),
- ColorEncoding::RgbaF32 => (&ColorTable::<RgbaF32>::read(reader, color_count)?).into(),
- ColorEncoding::Custom => (&ColorTable::<Custom>::read(reader, color_count)?).into(),
- })
- }
-
- /// Parse a color table.
- fn read(reader: &mut impl Read, color_count: u32) -> io::Result<Self> {
- let mut colors = Vec::with_capacity(color_count as usize);
- for _ in 0..color_count {
- colors.push(C::parse_bytes(reader)?);
- }
-
- let colors = colors.into_boxed_slice();
- Ok(Self { colors })
- }
-
- /// Returns the number of colors in the table.
- pub fn len(&self) -> usize {
- self.colors.len()
- }
-
- /// Returns `true` if the color table has no colors in it
- pub fn is_empty(&self) -> bool {
- self.colors.is_empty()
- }
-
- /// Returns a reference to a color, or `None` if out-of-bounds.
- pub fn get(&self, index: usize) -> Option<&C> {
- self.colors.get(index)
- }
-
- fn iter(&self) -> impl Iterator<Item = &C> {
- self.colors.iter()
- }
-}
-
-impl ColorTable<Rgba16> {}
-
-impl<Old: Color, New: Color> From<&ColorTable<Old>> for ColorTable<New> {
- fn from(value: &ColorTable<Old>) -> Self {
- let mut colors = Vec::with_capacity(value.len());
-
- for color in value.iter() {
- let r = color.red_u16();
- let g = color.green_u16();
- let b = color.blue_u16();
- let a = color.alpha_u16();
- colors.push(New::from_rgba16_lossy(r, g, b, a));
- }
-
- let colors = colors.into_boxed_slice();
- Self { colors }
- }
-}
-
-/// The color encoding defines which format the colors in the color table will
-/// have.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
-#[repr(u8)]
-pub enum ColorEncoding {
- /// Each color is a 4-tuple (red, green, blue, alpha) of bytes with the
- /// color channels encoded in sRGB and the alpha as linear alpha.
- Rgba8888 = 0,
- /// Each color is encoded as a 3-tuple (red, green, blue) with 16 bits per
- /// color.
- ///
- /// While red and blue both use 5 bits, the green channel uses 6 bits. Red
- /// uses bit range 0...4, green bits 5...10 and blue bits 11...15. This
- /// color also uses the sRGB color space.
- Rgb565 = 1,
- /// Each color is a 4-tuple (red, green, blue, alpha) of binary32 IEEE 754
- /// floating point value with the color channels encoded in scRGB and the
- /// alpha as linear alpha. A color value of 1.0 is full intensity, while a
- /// value of 0.0 is zero intensity.
- RgbaF32 = 2,
- /// The custom color encoding is defined *undefined*. The information how
- /// these colors are encoded must be implemented via external means.
- Custom = 3,
-}
-
-pub trait Color: Sized {
- /// The size of the color's representation in bits
- const SIZE: usize;
-
- /// Attempt to read the color. Returns `Err` if an error occurred while
- /// attempting to read [`SIZE`] bytes from `bytes`.
- fn parse_bytes(reader: &mut impl Read) -> io::Result<Self>;
-
- /// Convert from the RGBA16 format to this format. This may be lossy.
- fn from_rgba16_lossy(red: u16, green: u16, blue: u16, alpha: u16) -> Self;
-
- /// Convert from the RGBAF32 format to this format. This may be lossy.
- fn from_rgbaf32_lossy(red: f32, green: f32, blue: f32, alpha: f32) -> Self;
-
- fn red_u16(&self) -> u16;
- fn blue_u16(&self) -> u16;
- fn green_u16(&self) -> u16;
- fn alpha_u16(&self) -> u16;
-
- fn red_f32(&self) -> f32;
- fn green_f32(&self) -> f32;
- fn blue_f32(&self) -> f32;
- fn alpha_f32(&self) -> f32;
-}
-
-fn to_color_space(val: f32) -> f32 {
- val.powf(INVERT_GAMMA)
-}
-
-fn to_linear(val: f32) -> f32 {
- val.powf(GAMMA)
-}
-
-pub(crate) fn blend<C: Color + Clone>(dest: &mut C, src: &C) {
- fn lerp_color(src: f32, dst: f32, src_alpha: f32, dst_alpha: f32, alpha: f32) -> f32 {
- let src = to_linear(src);
- let dst = to_linear(dst);
-
- let val = (1.0 / alpha) * (src_alpha * src + (1.0 - src_alpha) * dst_alpha * dst);
-
- to_color_space(val)
- }
-
- if src.alpha_f32() == 1.0 || dest.alpha_u16() == 0 {
- *dest = src.clone();
- return;
- } else if src.alpha_u16() == 0 {
- return;
- }
-
- let src_a = src.alpha_f32();
- let dst_a = dest.alpha_f32();
- let alpha = src_a + (1.0 - src_a) * dst_a;
- let red = lerp_color(src.red_f32(), dest.red_f32(), src_a, dst_a, alpha);
- let green = lerp_color(src.green_f32(), dest.green_f32(), src_a, dst_a, alpha);
- let blue = lerp_color(src.blue_f32(), dest.blue_f32(), src_a, dst_a, alpha);
-
- *dest = C::from_rgbaf32_lossy(red, green, blue, alpha);
-}
-
-pub(crate) fn lerp<C: Color>(first: &C, second: &C, f: f64) -> C {
- fn lerp_color(a: f32, b: f32, f: f64) -> f32 {
- a + (b - a) * f as f32
- }
-
- let f = f.clamp(0.0, 1.0);
-
- let red = to_color_space(lerp_color(first.red_f32(), second.red_f32(), f));
- let green = to_color_space(lerp_color(first.green_f32(), second.green_f32(), f));
- let blue = to_color_space(lerp_color(first.blue_f32(), second.blue_f32(), f));
- let alpha = lerp_color(first.alpha_f32(), second.alpha_f32(), f);
-
- C::from_rgbaf32_lossy(red, green, blue, alpha)
-}
-
-/// Each color value is encoded as a sequence of four bytes.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct Rgba8888 {
- /// Red color channel between 0 and 100% intensity, mapped to byte values 0
- /// to 255.
- red: u8,
- /// Green color channel between 0 and 100% intensity, mapped to byte values
- /// 0 to 255.
- green: u8,
- /// Blue color channel between 0 and 100% intensity, mapped to byte values
- /// 0 to 255.
- blue: u8,
- /// Transparency channel between 0 and 100% transparency, mapped to byte
- /// values 0 to 255.
- alpha: u8,
-}
-
-impl Color for Rgba8888 {
- const SIZE: usize = 4;
-
- fn parse_bytes(reader: &mut impl Read) -> io::Result<Self> {
- Ok(Self {
- red: reader.read_u8()?,
- green: reader.read_u8()?,
- blue: reader.read_u8()?,
- alpha: reader.read_u8()?,
- })
- }
-
- fn from_rgba16_lossy(red: u16, green: u16, blue: u16, alpha: u16) -> Self {
- Self {
- red: (red >> 8) as u8,
- green: (green >> 8) as u8,
- blue: (blue >> 8) as u8,
- alpha: (alpha >> 8) as u8,
- }
- }
-
- fn from_rgbaf32_lossy(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
- Self {
- red: (red * u8::MAX as f32) as u8,
- green: (green * u8::MAX as f32) as u8,
- blue: (blue * u8::MAX as f32) as u8,
- alpha: (alpha * u8::MAX as f32) as u8,
- }
- }
-
- fn red_u16(&self) -> u16 {
- (self.red as u16) << 8
- }
-
- fn green_u16(&self) -> u16 {
- (self.green as u16) << 8
- }
-
- fn blue_u16(&self) -> u16 {
- (self.blue as u16) << 8
- }
-
- fn alpha_u16(&self) -> u16 {
- (self.alpha as u16) << 8
- }
-
- fn red_f32(&self) -> f32 {
- self.red as f32 / u8::MAX as f32
- }
-
- fn green_f32(&self) -> f32 {
- self.green as f32 / u8::MAX as f32
- }
-
- fn blue_f32(&self) -> f32 {
- self.blue as f32 / u8::MAX as f32
- }
-
- fn alpha_f32(&self) -> f32 {
- self.alpha as f32 / u8::MAX as f32
- }
-}
-
-/// Each color value is encoded as a sequence of 2 bytes.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct Rgb565 {
- /// Red color channel between 0 and 100% intensity, mapped to integer
- /// values 0 to 31.
- red: u8,
- /// Green color channel between 0 and 100% intensity, mapped to integer
- /// values 0 to 63.
- green: u8,
- /// Blue color channel between 0 and 100% intensity, mapped to integer
- /// values 0 to 31.
- blue: u8,
-}
-
-impl Color for Rgb565 {
- const SIZE: usize = 2;
-
- fn parse_bytes(reader: &mut impl Read) -> io::Result<Self> {
- let color = reader.read_u16::<LittleEndian>()?;
-
- let red = ((color & 0x001F) << 3) as u8;
- let green = ((color & 0x07E0) >> 3) as u8;
- let blue = ((color & 0xF800) >> 8) as u8;
-
- Ok(Self { red, blue, green })
- }
-
- fn from_rgba16_lossy(red: u16, green: u16, blue: u16, _a: u16) -> Self {
- Self {
- red: (red >> 11) as u8,
- green: (green >> 10) as u8,
- blue: (blue >> 11) as u8,
- }
- }
-
- fn from_rgbaf32_lossy(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
- Self {
- red: (red * (0b011111) as f32) as u8,
- green: (green * (0b111111) as f32) as u8,
- blue: (blue * (0b011111) as f32) as u8,
- }
- }
-
- fn red_u16(&self) -> u16 {
- (self.red as u16) << 11
- }
-
- fn green_u16(&self) -> u16 {
- (self.green as u16) << 11
- }
-
- fn blue_u16(&self) -> u16 {
- (self.blue as u16) << 10
- }
-
- fn alpha_u16(&self) -> u16 {
- 0
- }
-
- fn red_f32(&self) -> f32 {
- self.red as f32 / (0b011111) as f32
- }
-
- fn green_f32(&self) -> f32 {
- self.green as f32 / (0b111111) as f32
- }
-
- fn blue_f32(&self) -> f32 {
- self.blue as f32 / (0b011111) as f32
- }
-
- fn alpha_f32(&self) -> f32 {
- 0.0
- }
-}
-
-/// Each color value is encoded as a sequence of 16 bytes.
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub struct RgbaF32 {
- /// Red color channel, using 0.0 for 0% intensity and 1.0 for 100%
- /// intensity.
- red: f32,
- /// Green color channel, using 0.0 for 0% intensity and 1.0 for 100%
- /// intensity.
- green: f32,
- /// Blue color channel, using 0.0 for 0% intensity and 1.0 for 100%
- /// intensity.
- blue: f32,
- /// Transparency channel between 0 and 100% transparency, mapped to byte
- /// values 0.0 to 1.0.
- alpha: f32,
-}
-
-impl Color for RgbaF32 {
- const SIZE: usize = 16;
-
- fn parse_bytes(reader: &mut impl Read) -> io::Result<Self> {
- Ok(Self {
- red: reader.read_f32::<LittleEndian>()?,
- green: reader.read_f32::<LittleEndian>()?,
- blue: reader.read_f32::<LittleEndian>()?,
- alpha: reader.read_f32::<LittleEndian>()?,
- })
- }
-
- fn from_rgba16_lossy(red: u16, green: u16, blue: u16, alpha: u16) -> Self {
- Self {
- red: (red as f32) / (u16::MAX as f32),
- green: (green as f32) / (u16::MAX as f32),
- blue: (blue as f32) / (u16::MAX as f32),
- alpha: (alpha as f32) / (u16::MAX as f32),
- }
- }
-
- fn from_rgbaf32_lossy(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
- Self {
- red,
- green,
- blue,
- alpha,
- }
- }
-
- fn red_u16(&self) -> u16 {
- (self.red * (u16::MAX as f32)) as u16
- }
-
- fn green_u16(&self) -> u16 {
- (self.green * (u16::MAX as f32)) as u16
- }
-
- fn blue_u16(&self) -> u16 {
- (self.blue * (u16::MAX as f32)) as u16
- }
-
- fn alpha_u16(&self) -> u16 {
- (self.alpha * (u16::MAX as f32)) as u16
- }
-
- fn red_f32(&self) -> f32 {
- self.red
- }
-
- fn green_f32(&self) -> f32 {
- self.green
- }
-
- fn blue_f32(&self) -> f32 {
- self.blue
- }
-
- fn alpha_f32(&self) -> f32 {
- self.alpha
- }
-}
-
-/// Each color value is encoded as a sequence of 8 bytes.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct Rgba16 {
- /// Red color channel between 0 and 100% intensity, mapped to a big-endian
- /// 16-bit integer.
- red: u16,
- /// Green color channel between 0 and 100% intensity, mapped to a
- /// big-endian 16-bit integer.
- green: u16,
- /// Blue color channel between 0 and 100% intensity, mapped to a big-endian
- /// 16-bit integer.
- blue: u16,
- /// Transparency channel between 0 and 100% intensity, mapped to a
- /// big-endian 16-bit integer.
- alpha: u16,
-}
-
-impl Color for Rgba16 {
- const SIZE: usize = 8;
-
- fn parse_bytes(reader: &mut impl Read) -> io::Result<Self> {
- Ok(Self {
- red: reader.read_u16::<BigEndian>()?,
- green: reader.read_u16::<BigEndian>()?,
- blue: reader.read_u16::<BigEndian>()?,
- alpha: reader.read_u16::<BigEndian>()?,
- })
- }
-
- fn from_rgba16_lossy(red: u16, green: u16, blue: u16, alpha: u16) -> Self {
- Self {
- red,
- green,
- blue,
- alpha,
- }
- }
-
- fn from_rgbaf32_lossy(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
- Self {
- red: (red * u16::MAX as f32) as u16,
- green: (green * u16::MAX as f32) as u16,
- blue: (blue * u16::MAX as f32) as u16,
- alpha: (alpha * u16::MAX as f32) as u16,
- }
- }
-
- fn red_u16(&self) -> u16 {
- self.red
- }
-
- fn green_u16(&self) -> u16 {
- self.green
- }
-
- fn blue_u16(&self) -> u16 {
- self.blue
- }
-
- fn alpha_u16(&self) -> u16 {
- self.alpha
- }
-
- fn red_f32(&self) -> f32 {
- self.red as f32 / u16::MAX as f32
- }
-
- fn green_f32(&self) -> f32 {
- self.green as f32 / u16::MAX as f32
- }
-
- fn blue_f32(&self) -> f32 {
- self.blue as f32 / u16::MAX as f32
- }
-
- fn alpha_f32(&self) -> f32 {
- self.alpha as f32 / u16::MAX as f32
- }
-}
diff --git a/tvg/src/commands.rs b/tvg/src/commands.rs
deleted file mode 100644
index c21099b..0000000
--- a/tvg/src/commands.rs
+++ /dev/null
@@ -1,756 +0,0 @@
-use std::io::{self, Read};
-use std::ops::{Add, Mul, Sub};
-
-use byteorder::ReadBytesExt;
-use raise::yeet;
-
-use crate::{
- colors::{self, Color, ColorTable},
- header::TvgHeader,
- path::Path,
- read_unit, read_varuint, Decode, TvgError,
-};
-
-/// A X and Y coordinate pair.
-#[derive(Debug, Clone, Copy)]
-pub struct Vector {
- /// Horizontal distance of the point to the origin.
- pub x: f64,
- /// Vertical distance of the point to the origin.
- pub y: f64,
-}
-
-impl Vector {
- pub fn magnitude(&self) -> f64 {
- (self.x * self.x + self.y * self.y).sqrt()
- }
-
- pub fn scale(&self, scale: f64) -> Vector {
- Vector {
- x: self.x * scale,
- y: self.y * scale,
- }
- }
-}
-
-impl Mul for Vector {
- type Output = f64;
-
- fn mul(self, rhs: Self) -> Self::Output {
- self.x * rhs.x + self.y * rhs.y
- }
-}
-
-/// A X and Y coordinate pair.
-#[derive(Debug, Clone, Copy)]
-pub struct Point {
- /// Horizontal distance of the point to the origin.
- pub x: f64,
- /// Vertical distance of the point to the origin.
- pub y: f64,
-}
-
-impl Sub for Point {
- type Output = Vector;
-
- fn sub(self, rhs: Self) -> Self::Output {
- Vector {
- x: self.x - rhs.x,
- y: self.y - rhs.y,
- }
- }
-}
-
-impl Add<Vector> for Point {
- type Output = Self;
-
- fn add(self, vector: Vector) -> Self::Output {
- Self {
- x: self.x + vector.x,
- y: self.y + vector.y,
- }
- }
-}
-
-impl Decode for Point {
- fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result<Self> {
- Ok(Self {
- x: read_unit(reader, header)?,
- y: read_unit(reader, header)?,
- })
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq)]
-pub struct Rectangle {
- /// Horizontal distance of the left side to the origin.
- pub x: f64,
- /// Vertical distance of the upper side to the origin.
- pub y: f64,
- /// Horizontal extent of the rectangle.
- pub width: f64,
- /// Vertical extent of the rectangle.
- pub height: f64,
-}
-
-impl Decode for Rectangle {
- fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result<Self> {
- let x = 5;
- Ok(Self {
- x: read_unit(reader, header)?,
- y: read_unit(reader, header)?,
- width: read_unit(reader, header)?,
- height: read_unit(reader, header)?,
- })
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub struct Line {
- /// Start point of the line.
- start: Point,
- /// End point of the line.
- end: Point,
-}
-
-impl Decode for Line {
- fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result<Self> {
- Ok(Self {
- start: Point::read(reader, header)?,
- end: Point::read(reader, header)?,
- })
- }
-}
-
-/// A command that can be encoded.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[repr(u8)]
-enum CommandName {
- /// Determines end of file.
- EndOfDocument = 0,
- /// Fills an N-gon.
- FillPolygon = 1,
- /// Fills a set of [`Rectangle`]s.
- FillRectangles = 2,
- /// Fills a free-form [`Path`].
- FillPath = 3,
- /// Draws a set of lines.
- DrawLines = 4,
- /// Draws the outline of a polygon.
- DrawLineLoop = 5,
- /// Draws a list of end-to-end lines.
- DrawLineStrip = 6,
- /// Draws a free-form [`Path`].
- DrawLinePath = 7,
- /// Draws a filled polygon with an outline.
- OutlineFillPolygon = 8,
- /// Draws several filled [`Rectangle`]s with an outline.
- OutlineFillRectangles = 9,
- /// This command combines the [`FillPath`] and [`DrawLinePath`] command
- /// into one.
- OutlineFillPath = 10,
-}
-
-impl TryFrom<u8> for CommandName {
- type Error = TvgError;
-
- fn try_from(value: u8) -> Result<Self, Self::Error> {
- match value {
- 0 => Ok(Self::EndOfDocument),
- 1 => Ok(Self::FillPolygon),
- 2 => Ok(Self::FillRectangles),
- 3 => Ok(Self::FillPath),
- 4 => Ok(Self::DrawLines),
- 5 => Ok(Self::DrawLineLoop),
- 6 => Ok(Self::DrawLineStrip),
- 7 => Ok(Self::DrawLinePath),
- 8 => Ok(Self::OutlineFillPolygon),
- 9 => Ok(Self::OutlineFillRectangles),
- 10 => Ok(Self::OutlineFillPath),
- v => Err(TvgError::InvalidCommand(v)),
- }
- }
-}
-
-/// The type of style the command uses as a primary style.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-#[repr(u8)]
-pub enum StyleKind {
- /// The shape is uniformly colored with a single color.
- FlatColored = 0,
- /// The shape is colored with a linear gradient.
- LinearGradient = 1,
- /// The shape is colored with a radial gradient.
- RadialGradient = 2,
-}
-
-impl TryFrom<u8> for StyleKind {
- type Error = TvgError;
-
- fn try_from(value: u8) -> Result<Self, Self::Error> {
- match value {
- 0 => Ok(Self::FlatColored),
- 1 => Ok(Self::LinearGradient),
- 2 => Ok(Self::RadialGradient),
- _ => Err(TvgError::InvalidStyleKind),
- }
- }
-}
-
-/// The style kind, along with the colors and points used to render the style.
-#[derive(Debug, Clone, Copy)]
-pub enum Style {
- /// The shape is uniformly colored with the color at `color_index` in the
- /// [`ColorTable`].
- FlatColored {
- /// The index in the [`ColorTable`].
- color_index: u32,
- },
- /// The gradient is formed by a mental line between `point_0` and
- /// `point_1`.
- ///
- /// The color at `point_0` is the color at `color_index_0` in the color
- /// table. The color at `point_1` is the color at `color_index_1` in the
- /// [`ColorTable`]. On the line, the color is interpolated between the two
- /// points. Each point that is not on the line is orthogonally projected to
- /// the line and the color at that point is sampled. Points that are not
- /// projectable onto the line have either the color at `point_0` if they
- /// are closed to `point_0` or vice versa for `point_1`.
- LinearGradient {
- /// The start point of the gradient.
- point_0: Point,
- /// The end point of the gradient.
- point_1: Point,
- /// The color at [`point_0`].
- color_index_0: u32,
- /// The color at [`point_1`].
- color_index_1: u32,
- },
- /// The gradient is formed by a mental circle with the center at `point_0`
- /// and `point_1` being somewhere on the circle outline. Thus, the radius
- /// of said circle is the distance between `point_0` and `point_1`.
- ///
- /// The color at `point_0` is the color at `color_index_0` in the color
- /// table. The color on the circle outline is the color at `color_index_1`
- /// in the [`ColorTable`]. If a sampled point is inside the circle, the
- /// color is interpolated based on the distance to the center and the
- /// radius. If the point is not in the circle itself, the color at
- /// `color_index_1` is always taken.
- RadialGradient {
- /// The center point of the mental circle.
- point_0: Point,
- /// The end point of the gradient.
- point_1: Point,
- /// The color at `point_0`.
- color_index_0: u32,
- /// The color at `point_1`.
- color_index_1: u32,
- },
-}
-
-impl Style {
- fn read(reader: &mut impl Read, header: &TvgHeader, kind: StyleKind) -> io::Result<Self> {
- match kind {
- StyleKind::FlatColored => Self::read_flat_colored(reader),
- StyleKind::LinearGradient => Self::read_linear_gradient(reader, header),
- StyleKind::RadialGradient => Self::read_radial_gradient(reader, header),
- }
- }
-
- fn read_flat_colored(reader: &mut impl Read) -> io::Result<Self> {
- Ok(Self::FlatColored {
- color_index: read_varuint(reader)?,
- })
- }
-
- fn read_linear_gradient(reader: &mut impl Read, header: &TvgHeader) -> io::Result<Self> {
- Ok(Self::LinearGradient {
- point_0: Point::read(reader, header)?,
- point_1: Point::read(reader, header)?,
- color_index_0: read_varuint(reader)?,
- color_index_1: read_varuint(reader)?,
- })
- }
-
- fn read_radial_gradient(reader: &mut impl Read, header: &TvgHeader) -> io::Result<Self> {
- Ok(Self::RadialGradient {
- point_0: Point::read(reader, header)?,
- point_1: Point::read(reader, header)?,
- color_index_0: read_varuint(reader)?,
- color_index_1: read_varuint(reader)?,
- })
- }
-
- fn linear_get_color_at<C: Color + Clone>(
- &self,
- color_table: &ColorTable<C>,
- point: Point,
- ) -> Option<C> {
- let Self::LinearGradient {
- point_0,
- point_1,
- color_index_0,
- color_index_1 } = self else { panic!() };
-
- // TODO remove these unwraps
- let color_0 = color_table.get(*color_index_0 as usize)?;
- let color_1 = color_table.get(*color_index_1 as usize)?;
-
- let direction = *point_1 - *point_0;
- let delta = point - *point_0;
-
- if direction * delta <= 0.0 {
- return Some(color_0.clone());
- } else if direction * (point - *point_1) >= 0.0 {
- return Some(color_1.clone());
- }
-
- let gradient_length = direction.magnitude();
- let proj = (direction * delta) / (direction * direction);
- let gradient_position = direction.scale(proj).magnitude();
- let f = gradient_position / gradient_length;
-
- Some(colors::lerp(color_0, color_1, f))
- }
-
- fn radial_get_color_at<C: Color>(
- &self,
- color_table: &ColorTable<C>,
- point: Point,
- ) -> Option<C> {
- let Self::RadialGradient {
- point_0,
- point_1,
- color_index_0,
- color_index_1 } = self else { panic!() };
-
- // TODO remove these unwraps
- let color_0 = color_table.get(*color_index_0 as usize)?;
- let color_1 = color_table.get(*color_index_1 as usize)?;
-
- let distance_max = (*point_1 - *point_0).magnitude();
- let distance_is = (point - *point_0).magnitude();
- let f = distance_is / distance_max;
-
- Some(colors::lerp(color_0, color_1, f))
- }
-
- pub fn get_color_at<C: Color + Clone>(
- &self,
- color_table: &ColorTable<C>,
- point: Point,
- ) -> Option<C> {
- match self {
- Self::FlatColored { color_index } => color_table.get(*color_index as usize).cloned(),
- Self::LinearGradient { .. } => self.linear_get_color_at(color_table, point),
- Self::RadialGradient { .. } => self.radial_get_color_at(color_table, point),
- }
- }
-}
-
-/// TinyVG files contain a sequence of draw commands that must be executed in
-/// the defined order to get the final result. Each draw command adds a new 2D
-/// primitive to the graphic.
-#[derive(Debug, Clone)]
-pub enum Command {
- /// If this command is read, the TinyVG file has ended.
- ///
- /// This command must have prim_style_kind to be set to 0, so the last byte
- /// of every TinyVG file is `0x00`. Every byte after this command is
- /// considered not part of the TinyVG data and can be used for other
- /// purposes like metadata or similar.
- EndOfDocument,
- /// Fills a polygon with N [`Point`]s.
- ///
- /// The number of points must be at least 3. Files that encode a lower
- /// value must be discarded as ”invalid” by a conforming implementation.
- ///
- /// The polygon specified in polygon must be drawn using the even-odd rule.
- /// That means that if for any point to be inside the polygon, a line to
- /// infinity must cross an odd number of polygon segments.
- FillPolygon {
- /// The style that is used to fill the polygon.
- fill_style: Style,
- /// The points of the polygon.
- polygon: Box<[Point]>,
- },
- /// Fills a list of [`Rectangle`]s.
- ///
- /// The rectangles must be drawn first to last, which is the order they
- /// appear in the file.
- FillRectangles {
- /// The style that is used to fill all rectangles.
- fill_style: Style,
- /// The list of rectangles to be filled.
- rectangles: Box<[Rectangle]>,
- },
- /// Fills a [`Path`].
- ///
- /// For the filling, all path segments are considered a polygon each (drawn
- /// with even-odd rule) that, when overlap, also perform the even odd rule.
- /// This allows the user to carve out parts of the path and create
- /// arbitrarily shaped surfaces.
- FillPath {
- /// The style that is used to fill the path.
- fill_style: Style,
- /// A [`Path`] with `segment_count` segments.
- path: Path,
- },
- /// Draws a set of [`Line`]s.
- ///
- /// Each line is `line_width` units wide, and at least a single display
- /// pixel. This means that line_width of 0 is still visible, even though
- /// only marginally. This allows very thin outlines.
- DrawLines {
- /// The style that is used to draw the all lines.
- line_style: Style,
- /// The width of the lines.
- line_width: f64,
- /// The list of lines.
- lines: Box<[Line]>,
- },
- /// Draws a polygon.
- ///
- /// Each line is `line_width` units wide. The lines are drawn between
- /// consecutive points as well as the first and the last point.
- DrawLineLoop {
- /// The style that is used to draw the all lines.
- line_style: Style,
- /// The width of the line.
- line_width: f64,
- /// The points of the polygon.
- points: Box<[Point]>,
- },
- /// Draws a list of consecutive lines.
- ///
- /// The lines are drawn between consecutive points, but contrary to
- /// [`DrawLineLoop`], the first and the last point are not connected.
- DrawLineStrip {
- /// The style that is used to draw the all rectangles.
- line_style: Style,
- /// The width of the line.
- line_width: f64,
- /// The points of the line strip.
- points: Box<[Point]>,
- },
- /// Draws a [`Path`].
- ///
- /// The outline of the path is `line_width` units wide.
- DrawLinePath {
- /// The style that is used to draw the path.
- line_style: Style,
- /// The width of the line.
- line_width: f64,
- /// A path with `segment_count` segments.
- path: Path,
- },
- /// Fills a polygon and draws an outline at the same time.
- ///
- /// This command is a combination of [`FillPolygon`] and [`DrawLineLoop`].
- /// It first performs a [`FillPolygon`] with the `fill_style`, then
- /// performs [`DrawLineLoop`] with `line_style` and `line_width`.
- ///
- /// The outline commands use a reduced number of elements. The maximum
- /// number of points is 64.
- OutlineFillPolygon {
- /// The style that is used to fill the polygon.
- fill_style: Style,
- /// The style that is used to draw the outline of the polygon.
- line_style: Style,
- /// The width of the line.
- line_width: f64,
- /// The set of points of this polygon.
- points: Box<[Point]>,
- },
- /// Fills and outlines a list of [`Rectangle`]s.
- ///
- /// For each rectangle, it is first filled, then its outline is drawn, then
- /// the next rectangle is drawn.
- ///
- /// The outline commands use a reduced number of elements, the maximum
- /// number of points is 64.
- OutlineFillRectangles {
- /// The style that is used to fill the rectangles.
- fill_style: Style,
- /// The style that is used to draw the outline of the rectangles.
- line_style: Style,
- /// The width of the line.
- line_width: f64,
- /// The list of rectangles to be drawn.
- rectangles: Box<[Rectangle]>,
- },
- /// Fills a path and draws an outline at the same time.
- ///
- /// This command is a combination of [`FillPath`] and [`DrawLinePath`]. It
- /// first performs a [`FillPath`] with the `fill_style`, then performs
- /// [`DrawLinePath`] with `line_style` and `line_width`.
- OutlineFillPath {
- /// The style that is used to fill the path.
- fill_style: Style,
- /// The style that is used to draw the outline of the path.
- line_style: Style,
- /// The width of the line.
- line_width: f64,
- /// The path that should be drawn.
- path: Path,
- },
-}
-
-/// The header is different for outline commands, so we use this as a helper
-struct OutlineHeader {
- count: u32,
- fill_style: Style,
- line_style: Style,
- line_width: f64,
-}
-
-impl OutlineHeader {
- fn read(
- reader: &mut impl Read,
- header: &TvgHeader,
- prim_style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- // the count and secondary style kind are stores in the same byte
- let byte = reader.read_u8()?;
- let count = (byte & 0b0011_1111) as u32 + 1;
- let sec_style_kind = StyleKind::try_from((byte & 0b1100_0000) >> 6)?;
-
- let fill_style = Style::read(reader, header, prim_style_kind)?;
- let line_style = Style::read(reader, header, sec_style_kind)?;
-
- let line_width = read_unit(reader, header)?;
-
- Ok(Self {
- count,
- fill_style,
- line_style,
- line_width,
- })
- }
-}
-
-impl Command {
- pub fn read(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- // the command name and primary style kind are stores in the same byte
- let byte = reader.read_u8()?;
- let command = CommandName::try_from(byte & 0b0011_1111)?;
- let style_kind = StyleKind::try_from((byte & 0b1100_0000) >> 6)?;
-
- match command {
- CommandName::EndOfDocument => Self::end_of_document(style_kind),
- CommandName::FillPolygon => Self::read_fill_polygon(reader, header, style_kind),
- CommandName::FillRectangles => Self::read_fill_rectangles(reader, header, style_kind),
- CommandName::FillPath => Self::read_fill_path(reader, header, style_kind),
- CommandName::DrawLines => Self::read_draw_lines(reader, header, style_kind),
- CommandName::DrawLineLoop => Self::read_draw_line_loop(reader, header, style_kind),
- CommandName::DrawLineStrip => Self::read_draw_line_strip(reader, header, style_kind),
- CommandName::DrawLinePath => Self::read_draw_line_path(reader, header, style_kind),
- CommandName::OutlineFillPolygon => {
- Self::read_outline_fill_polygon(reader, header, style_kind)
- }
- CommandName::OutlineFillRectangles => {
- Self::read_outline_fill_rectangles(reader, header, style_kind)
- }
- CommandName::OutlineFillPath => {
- Self::read_outline_fill_path(reader, header, style_kind)
- }
- }
- }
-
- pub fn is_end_of_document(&self) -> bool {
- matches!(self, Self::EndOfDocument)
- }
-
- fn read_command_header(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> io::Result<(u32, Style)> {
- // every command adds one to the count
- let count = read_varuint(reader)? + 1;
- let style = Style::read(reader, header, style_kind)?;
-
- Ok((count, style))
- }
-
- fn end_of_document(style_kind: StyleKind) -> Result<Self, TvgError> {
- if style_kind != StyleKind::FlatColored {
- Err(TvgError::InvalidEndOfDocument(style_kind as u8))
- } else {
- Ok(Self::EndOfDocument)
- }
- }
-
- fn read_fill_polygon(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let (point_count, fill_style) = Self::read_command_header(reader, header, style_kind)?;
- if point_count < 3 {
- yeet!(TvgError::InvalidPolygon(point_count));
- }
-
- let polygon = Point::read_multiple(reader, header, point_count)?;
-
- Ok(Self::FillPolygon {
- fill_style,
- polygon,
- })
- }
-
- fn read_fill_rectangles(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let (rectangle_count, fill_style) = Self::read_command_header(reader, header, style_kind)?;
- let rectangles = Rectangle::read_multiple(reader, header, rectangle_count)?;
-
- Ok(Self::FillRectangles {
- fill_style,
- rectangles,
- })
- }
-
- fn read_fill_path(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let (segment_count, fill_style) = Self::read_command_header(reader, header, style_kind)?;
- let path = Path::read(reader, header, segment_count)?;
-
- Ok(Self::FillPath { fill_style, path })
- }
-
- fn read_draw_lines(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let (line_count, line_style) = Self::read_command_header(reader, header, style_kind)?;
- let line_width = read_unit(reader, header)?;
- let lines = Line::read_multiple(reader, header, line_count)?;
-
- Ok(Self::DrawLines {
- line_style,
- line_width,
- lines,
- })
- }
-
- fn read_draw_line_loop(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let (point_count, line_style) = Self::read_command_header(reader, header, style_kind)?;
- let line_width = read_unit(reader, header)?;
- let points = Point::read_multiple(reader, header, point_count)?;
-
- Ok(Self::DrawLineLoop {
- line_style,
- line_width,
- points,
- })
- }
-
- fn read_draw_line_strip(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let (point_count, line_style) = Self::read_command_header(reader, header, style_kind)?;
- let line_width = read_unit(reader, header)?;
- let points = Point::read_multiple(reader, header, point_count)?;
-
- Ok(Self::DrawLineStrip {
- line_style,
- line_width,
- points,
- })
- }
-
- fn read_draw_line_path(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let (segment_count, line_style) = Self::read_command_header(reader, header, style_kind)?;
- let line_width = read_unit(reader, header)?;
- let path = Path::read(reader, header, segment_count)?;
-
- Ok(Self::DrawLinePath {
- line_style,
- line_width,
- path,
- })
- }
-
- fn read_outline_fill_polygon(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let OutlineHeader {
- count: segment_count,
- fill_style,
- line_style,
- line_width,
- } = OutlineHeader::read(reader, header, style_kind)?;
-
- let points = Point::read_multiple(reader, header, segment_count)?;
-
- Ok(Self::OutlineFillPolygon {
- fill_style,
- line_style,
- line_width,
- points,
- })
- }
-
- fn read_outline_fill_rectangles(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let OutlineHeader {
- count: rect_count,
- fill_style,
- line_style,
- line_width,
- } = OutlineHeader::read(reader, header, style_kind)?;
-
- let rectangles = Rectangle::read_multiple(reader, header, rect_count)?;
-
- Ok(Self::OutlineFillRectangles {
- fill_style,
- line_style,
- line_width,
- rectangles,
- })
- }
-
- fn read_outline_fill_path(
- reader: &mut impl Read,
- header: &TvgHeader,
- style_kind: StyleKind,
- ) -> Result<Self, TvgError> {
- let OutlineHeader {
- count: segment_count,
- fill_style,
- line_style,
- line_width,
- } = OutlineHeader::read(reader, header, style_kind)?;
-
- let path = Path::read(reader, header, segment_count)?;
-
- Ok(Self::OutlineFillPath {
- fill_style,
- line_style,
- line_width,
- path,
- })
- }
-}
diff --git a/tvg/src/header.rs b/tvg/src/header.rs
deleted file mode 100644
index d444f66..0000000
--- a/tvg/src/header.rs
+++ /dev/null
@@ -1,157 +0,0 @@
-use std::io::{self, Read};
-
-use byteorder::{LittleEndian, ReadBytesExt};
-use num_enum::TryFromPrimitive;
-use raise::yeet;
-
-use crate::colors::ColorEncoding;
-use crate::read_varuint;
-use crate::TvgError;
-
-const MAGIC: [u8; 2] = [0x72, 0x56];
-pub const SUPPORTED_VERSION: u8 = 1;
-
-/// The coordinate range defines how many bits a Unit value uses.
-#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
-#[repr(u8)]
-pub enum CoordinateRange {
- /// Each [`Unit`] takes up 16 bits.
- #[default]
- Default = 0,
- /// Each [`Unit`] takes up 8 bits.
- Reduced = 1,
- /// Each [`Unit`] takes up 32 bits.
- Enhanced = 2,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
-#[repr(u8)]
-pub enum Scale {
- _1 = 0,
- _2 = 1,
- _4 = 2,
- _8 = 3,
- _16 = 4,
- _32 = 5,
- _64 = 6,
- _128 = 7,
- _256 = 8,
- _512 = 9,
- _1024 = 10,
- _2048 = 11,
- _4096 = 12,
- _8192 = 13,
- _16384 = 14,
- _32768 = 15,
-}
-
-/// Each TVG file starts with a header defining some global values for the file
-/// like scale and image size. This is a representation of the header, but not
-/// necessarily an exact representation of the bits of a TVG header.
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct TvgHeader {
- /// Must always be [0x72, 0x56]
- magic: [u8; 2],
- /// Must be 1. For future versions, this field might decide how the rest of
- /// the format looks like.
- version: u8,
- /// Defines the number of fraction bits in a Unit value.
- scale: Scale,
- /// Defines the type of color information that is used in the
- /// [`ColorTable`].
- color_encoding: ColorEncoding,
- /// Defines the number of total bits in a Unit value and thus the overall
- /// precision of the file.
- coordinate_range: CoordinateRange,
- /// Encodes the maximum width of the output file in *display units*.
- ///
- /// A value of 0 indicates that the image has the maximum possible width.
- width: u32,
- /// Encodes the maximum height of the output file in *display units*.
- ///
- /// A value of 0 indicates that the image has the maximum possible height.
- height: u32,
- /// The number of colors in the color table.
- color_count: u32,
-}
-
-impl TvgHeader {
- pub fn read<R: Read>(reader: &mut R) -> Result<Self, TvgError> {
- // magic number is used as a first line defense against invalid data
- let magic = [reader.read_u8()?, reader.read_u8()?];
- if magic != MAGIC {
- yeet!(TvgError::InvalidFile);
- }
-
- // the version of tvg being used
- let version = reader.read_u8()?;
- if version != SUPPORTED_VERSION {
- yeet!(TvgError::UnsupportedVersion(version))
- }
-
- // scale, color_encoding, and coordinate_range are stored in one byte
- let byte = reader.read_u8()?;
- let scale = Scale::try_from_primitive(byte & 0b0000_1111).expect("invalid scale");
- let color_encoding = ColorEncoding::try_from_primitive((byte & 0b0011_0000) >> 4)
- .expect("invalid color encoding");
- let coordinate_range = CoordinateRange::try_from_primitive((byte & 0b1100_0000) >> 6)
- .expect("invalid coordinate range");
-
- // width and height depend on the coordinate range
- let width = read_unsigned_unit(coordinate_range, reader)?;
- let height = read_unsigned_unit(coordinate_range, reader)?;
-
- let color_count = read_varuint(reader)?;
-
- Ok(Self {
- magic,
- version,
- scale,
- color_encoding,
- coordinate_range,
- width,
- height,
- color_count,
- })
- }
-
- /// Defines the number of total bits in a Unit value and thus the overall
- /// precision of the file.
- pub fn coordinate_range(&self) -> CoordinateRange {
- self.coordinate_range
- }
-
- /// Defines the type of color information that is used in the [`ColorTable`].
- pub fn color_encoding(&self) -> ColorEncoding {
- self.color_encoding
- }
-
- /// Defines the number of fraction bits in a Unit value.
- pub fn scale(&self) -> Scale {
- self.scale
- }
-
- /// The number of colors in the [`ColorTable`].
- pub fn color_count(&self) -> u32 {
- self.color_count
- }
-
- pub fn width(&self) -> u32 {
- self.width
- }
-
- pub fn height(&self) -> u32 {
- self.height
- }
-}
-
-fn read_unsigned_unit<R: Read>(
- coordinate_range: CoordinateRange,
- bytes: &mut R,
-) -> io::Result<u32> {
- Ok(match coordinate_range {
- CoordinateRange::Reduced => bytes.read_u8()? as u32,
- CoordinateRange::Default => bytes.read_u16::<LittleEndian>()? as u32,
- CoordinateRange::Enhanced => bytes.read_u32::<LittleEndian>()?,
- })
-}
diff --git a/tvg/src/lib.rs b/tvg/src/lib.rs
deleted file mode 100644
index 16a95bd..0000000
--- a/tvg/src/lib.rs
+++ /dev/null
@@ -1,167 +0,0 @@
-use std::io::{self, Read};
-
-use byteorder::{LittleEndian, ReadBytesExt};
-use colors::{Color, ColorTable};
-use commands::Command;
-use header::{CoordinateRange, Scale, TvgHeader};
-use thiserror::Error;
-
-pub mod colors;
-mod commands;
-mod header;
-mod path;
-mod render;
-
-pub use header::SUPPORTED_VERSION;
-
-#[derive(Debug, Clone)]
-pub struct TvgFile<C: Color> {
- header: TvgHeader,
- color_table: ColorTable<C>,
- commands: Box<[Command]>,
-}
-
-impl<C: Color> TvgFile<C> {
- /// Read a TinyVG file.
- pub fn read_from(reader: &mut impl Read) -> Result<Self, TvgError> {
- let header = TvgHeader::read(reader)?;
- let color_table =
- ColorTable::read_from_encoding(reader, header.color_count(), header.color_encoding())?;
-
- let mut commands = Vec::new();
- loop {
- let command = Command::read(reader, &header)?;
- commands.push(command.clone());
-
- if command.is_end_of_document() {
- break;
- }
- }
-
- Ok(Self {
- header,
- color_table,
- commands: commands.into_boxed_slice(),
- })
- }
-
- /// Read a TinyVG file. If a Custom color encoding if found, use the specified encoding.
- pub fn read_with_custom_encoding<Custom: Color>(
- reader: &mut impl Read,
- ) -> Result<Self, TvgError> {
- let header = TvgHeader::read(reader)?;
- let color_table = ColorTable::read_from_encoding_with_custom::<Custom>(
- reader,
- header.color_count(),
- header.color_encoding(),
- )?;
-
- let mut commands = Vec::new();
- loop {
- let command = Command::read(reader, &header)?;
- commands.push(command.clone());
-
- if command.is_end_of_document() {
- break;
- }
- }
-
- Ok(Self {
- header,
- color_table,
- commands: commands.into_boxed_slice(),
- })
- }
-}
-
-#[derive(Debug, Error)]
-pub enum TvgError {
- #[error("Not a valid TVG file. The magic number was invalid.")]
- InvalidFile,
- #[error("Expected version 1, but found version {}.", .0)]
- UnsupportedVersion(u8),
- #[error("Found a coordinate range with an index of 3, which is invalid.")]
- InvalidCoordinateRange,
- #[error("Found a Custom color encoding, which is unsupported.")]
- UnsupportedColorEncoding,
- #[error("Found a command with an index of {}, which is invalid.", .0)]
- InvalidCommand(u8),
- #[error("Found a style kind with an index of 3, which is invalid.")]
- InvalidStyleKind,
- #[error("Polygons must have at least 3 points, found {}.", .0)]
- InvalidPolygon(u32),
- #[error("All padding bits must be zero. Found {}.", .0)]
- NonZeroPadding(u8),
- #[error("The end of the document must have a `prim_style_kind` value of 0. Found {}.", .0)]
- InvalidEndOfDocument(u8),
- #[error("{}", .0)]
- IoError(#[from] io::Error),
-}
-
-trait Decode: Sized {
- fn read(reader: &mut impl Read, header: &TvgHeader) -> io::Result<Self>;
-
- fn read_multiple(
- reader: &mut impl Read,
- header: &TvgHeader,
- count: u32,
- ) -> io::Result<Box<[Self]>> {
- let mut vec = Vec::with_capacity(count as usize);
- for _ in 0..count {
- vec.push(Self::read(reader, header)?);
- }
-
- Ok(vec.into_boxed_slice())
- }
-}
-
-/// The unit is the common type for both positions and sizes in the vector
-/// graphic. It is encoded as a signed integer with a configurable amount of
-/// bits (see [`CoordinateRange`]) and fractional bits.
-fn read_unit(reader: &mut impl Read, header: &TvgHeader) -> io::Result<f64> {
- let value = match header.coordinate_range() {
- CoordinateRange::Reduced => reader.read_i8()? as i32,
- CoordinateRange::Default => reader.read_i16::<LittleEndian>()? as i32,
- CoordinateRange::Enhanced => reader.read_i32::<LittleEndian>()?,
- };
-
- let fractional = match header.scale() {
- Scale::_1 => 1.0,
- Scale::_2 => 2.0,
- Scale::_4 => 4.0,
- Scale::_8 => 8.0,
- Scale::_16 => 16.0,
- Scale::_32 => 32.0,
- Scale::_64 => 64.0,
- Scale::_128 => 128.0,
- Scale::_256 => 256.0,
- Scale::_512 => 512.0,
- Scale::_1024 => 1024.0,
- Scale::_2048 => 2048.0,
- Scale::_4096 => 4096.0,
- Scale::_8192 => 8192.0,
- Scale::_16384 => 16_384.0,
- Scale::_32768 => 32_768.0,
- };
-
- Ok((value as f64) / fractional)
-}
-
-fn read_varuint(reader: &mut impl Read) -> io::Result<u32> {
- let mut count = 0;
- let mut result = 0;
-
- loop {
- let byte = reader.read_u8()? as u32;
- let value = (byte & 0x7F) << (7 * count);
- result |= value;
-
- if (byte & 0x80) == 0 {
- break;
- }
-
- count += 1;
- }
-
- Ok(result)
-}
diff --git a/tvg/src/path.rs b/tvg/src/path.rs
deleted file mode 100644
index a576eb8..0000000
--- a/tvg/src/path.rs
+++ /dev/null
@@ -1,320 +0,0 @@
-use std::io::Read;
-
-use byteorder::ReadBytesExt;
-use num_enum::TryFromPrimitive;
-use raise::yeet;
-
-use crate::{commands::Point, header::TvgHeader, read_unit, read_varuint, Decode, TvgError};
-
-/// Returns an error if the padding isn't zero
-fn check_padding(padding: u8) -> Result<(), TvgError> {
- if padding != 0 {
- yeet!(TvgError::NonZeroPadding(padding))
- }
-
- Ok(())
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
-#[repr(u8)]
-pub(crate) enum Sweep {
- Right = 0,
- Left = 1,
-}
-
-/// An instruction to move a hypothetical "pen".
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)]
-#[repr(u8)]
-enum InstructionKind {
- /// A straight line is drawn from the current point to a new point.
- Line = 0,
- /// A straight horizontal line is drawn from the current point to a new x
- /// coordinate.
- HorizontalLine = 1,
- /// A straight vertical line is drawn from the current point to a new y
- /// coordiante.
- VerticalLine = 2,
- /// A cubic Bézier curve is drawn from the current point to a new point.
- CubicBezier = 3,
- /// A circle segment is drawn from current point to a new point.
- ArcCircle = 4,
- /// An ellipse segment is drawn from current point to a new point.
- ArcEllipse = 5,
- /// The path is closed, and a straight line is drawn to the starting point.
- ClosePath = 6,
- /// A quadratic Bézier curve is drawn from the current point to a new point.
- QuadraticBezier = 7,
-}
-
-#[derive(Debug, Clone, Copy)]
-pub(crate) enum InstructionData {
- /// The line instruction draws a straight line to the position.
- Line {
- /// The end point of the line.
- position: Point,
- },
- /// The horizontal line instruction draws a straight horizontal line to a
- /// given x coordinate.
- HorizontalLine {
- /// The new x coordinate.
- x: f64,
- },
- /// The vertical line instruction draws a straight vertical line to a given
- /// y coordinate.
- VerticalLine {
- /// The new y coordinate.
- y: f64,
- },
- /// The cubic bezier instruction draws a Bézier curve with two control
- /// points.
- ///
- /// The curve is drawn between the current location and `point_1` with
- /// `control_0` being the first control point and `control_1` being the
- /// second one.
- CubicBezier {
- /// The first control point.
- control_0: Point,
- /// The second control point.
- control_1: Point,
- /// The end point of the Bézier curve.
- point_1: Point,
- },
- /// Draws a circle segment between the current and the target point.
- ///
- /// The `radius` field determines the radius of the circle. If the distance
- /// between the current point and `target` is larger than `radius`, the
- /// distance is used as the radius.
- ArcCircle {
- /// If `true`, the large portion of the circle segment is drawn.
- large_arc: bool,
- /// Determines if the circle segment is left- or right bending.
- sweep: Sweep,
- /// The radius of the circle.
- radius: f64,
- /// The end point of the circle segment.
- target: Point,
- },
- /// Draws an ellipse segment between the current and the target point.
- ///
- /// The `radius_x` and `radius_y` fields determine the both radii of the
- /// ellipse. If the distance between the current point and target is not
- /// enough to fit any ellipse segment between the two points, `radius_x`
- /// and `radius_y` are scaled uniformly so that it fits exactly.
- ArcEllipse {
- /// If `true`, the large portion of the ellipse segment is drawn.
- large_arc: bool,
- /// Determines if the ellipse segment is left- or right bending.
- sweep: Sweep,
- /// The radius of the ellipse segment in the horizontal direction.
- radius_x: f64,
- /// The radius of the ellipse segment in the vertical direction.
- radius_y: f64,
- /// The rotation of the ellipse in mathematical negative direction, in
- /// degrees.
- rotation: f64,
- /// The end point of the ellipse segment.
- target: Point,
- },
- /// A straight line is drawn to the start location of the current segment.
- /// This instruction doesn’t have additional data encoded.
- ClosePath,
- /// The quadratic bezier instruction draws a Bézier curve with a single
- /// control point.
- ///
- /// The curve is drawn between the current location and `point_1` with
- /// control being the control point.
- QuadraticBezier {
- /// The control point.
- control: Point,
- /// The end point of the Bézier curve.
- target: Point,
- },
-}
-
-impl InstructionData {
- fn read(
- reader: &mut impl Read,
- header: &TvgHeader,
- kind: InstructionKind,
- ) -> Result<Self, TvgError> {
- match kind {
- InstructionKind::Line => Self::read_line(reader, header),
- InstructionKind::HorizontalLine => Self::read_horizontal_line(reader, header),
- InstructionKind::VerticalLine => Self::read_vertical_line(reader, header),
- InstructionKind::CubicBezier => Self::read_cubic_bezier(reader, header),
- InstructionKind::ArcCircle => Self::read_arc_circle(reader, header),
- InstructionKind::ArcEllipse => Self::read_arc_ellipse(reader, header),
- InstructionKind::ClosePath => Ok(Self::ClosePath),
- InstructionKind::QuadraticBezier => Self::read_quadratic_bezier(reader, header),
- }
- }
-
- fn read_line(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- Ok(Self::Line {
- position: Point::read(reader, header)?,
- })
- }
-
- fn read_horizontal_line(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- Ok(Self::HorizontalLine {
- x: read_unit(reader, header)?,
- })
- }
-
- fn read_vertical_line(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- Ok(Self::VerticalLine {
- y: read_unit(reader, header)?,
- })
- }
-
- fn read_cubic_bezier(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- Ok(Self::CubicBezier {
- control_0: Point::read(reader, header)?,
- control_1: Point::read(reader, header)?,
- point_1: Point::read(reader, header)?,
- })
- }
-
- fn read_arc_header(
- reader: &mut impl Read,
- header: &TvgHeader,
- ) -> Result<(bool, Sweep), TvgError> {
- // large_arc and sweep are stored in the same byte
- let byte = reader.read_u8()?;
- let large_arc = (byte & 1) != 0;
- let sweep = match byte & 2 {
- 0 => Sweep::Left,
- _ => Sweep::Right,
- };
-
- check_padding((byte & 0b1111_1100) >> 2)?;
-
- Ok((large_arc, sweep))
- }
-
- fn read_arc_circle(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- let (large_arc, sweep) = Self::read_arc_header(reader, header)?;
- let radius = read_unit(reader, header)?;
- let target = Point::read(reader, header)?;
-
- Ok(Self::ArcCircle {
- large_arc,
- sweep,
- radius,
- target,
- })
- }
-
- fn read_arc_ellipse(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- let (large_arc, sweep) = Self::read_arc_header(reader, header)?;
- let radius_x = read_unit(reader, header)?;
- let radius_y = read_unit(reader, header)?;
- let rotation = read_unit(reader, header)?;
- let target = Point::read(reader, header)?;
-
- Ok(Self::ArcEllipse {
- large_arc,
- sweep,
- radius_x,
- radius_y,
- rotation,
- target,
- })
- }
-
- fn read_quadratic_bezier(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- Ok(Self::QuadraticBezier {
- control: Point::read(reader, header)?,
- target: Point::read(reader, header)?,
- })
- }
-}
-
-#[derive(Debug, Clone)]
-pub(crate) struct Instruction {
- /// The width of the line the "pen" makes, if it makes one at all.
- pub(crate) line_width: Option<f64>,
- /// The arguments to the instruction.
- pub(crate) data: InstructionData,
-}
-
-impl Instruction {
- fn read(reader: &mut impl Read, header: &TvgHeader) -> Result<Self, TvgError> {
- let byte = reader.read_u8()?;
- let instruction_kind =
- InstructionKind::try_from_primitive(byte & 0b0000_0111).expect("invalid instruction");
- let has_line_width = (byte & 0b0001_0000) != 0;
-
- check_padding((byte & 0b0000_1000) >> 3)?;
- check_padding((byte & 0b1110_0000) >> 5)?;
-
- let line_width = has_line_width
- .then(|| read_unit(reader, header))
- .transpose()?;
- let data = InstructionData::read(reader, header, instruction_kind)?;
-
- Ok(Self { line_width, data })
- }
-}
-
-#[derive(Debug, Clone)]
-pub(crate) struct Segment {
- /// The starting point of the segment.
- pub(crate) start: Point,
- /// The list of instructions for tha segment.
- pub(crate) instructions: Box<[Instruction]>,
-}
-
-impl Segment {
- fn read(
- reader: &mut impl Read,
- header: &TvgHeader,
- segment_length: u32,
- ) -> Result<Self, TvgError> {
- let start = Point::read(reader, header)?;
-
- let mut instructions = Vec::with_capacity(segment_length as usize);
- for _ in 0..segment_length {
- instructions.push(Instruction::read(reader, header)?)
- }
-
- Ok(Segment {
- start,
- instructions: instructions.into_boxed_slice(),
- })
- }
-}
-
-/// Paths describe instructions to create complex 2D graphics.
-///
-/// Each path segment generates a shape by moving a ”pen” around. The path this
-/// ”pen” takes is the outline of our segment. Each segment, the ”pen” starts
-/// at a defined position and is moved by instructions. Each instruction will
-/// leave the ”pen” at a new position. The line drawn by our ”pen” is the
-/// outline of the shape.
-#[derive(Debug, Clone)]
-pub struct Path {
- pub(crate) segments: Box<[Segment]>,
-}
-
-impl Path {
- pub(crate) fn read(
- reader: &mut impl Read,
- header: &TvgHeader,
- segment_count: u32,
- ) -> Result<Self, TvgError> {
- let mut segment_lengths = Vec::with_capacity(segment_count as usize);
- for _ in 0..segment_count {
- segment_lengths.push(read_varuint(reader)? + 1);
- }
-
- let mut segments = Vec::with_capacity(segment_count as usize);
- for segment_length in segment_lengths {
- segments.push(Segment::read(reader, header, segment_length)?);
- }
-
- Ok(Self {
- segments: segments.into_boxed_slice(),
- })
- }
-}
diff --git a/tvg/src/render.rs b/tvg/src/render.rs
deleted file mode 100644
index f8c15a1..0000000
--- a/tvg/src/render.rs
+++ /dev/null
@@ -1,506 +0,0 @@
-use crate::{
- colors::{self, blend, lerp, Color, ColorTable},
- commands::{Command, Point, Rectangle, Style, Vector},
- header::TvgHeader,
- path::{Instruction, InstructionData, Path, Sweep},
- TvgFile,
-};
-
-fn distance(p0: Point, p1: Point) -> f64 {
- (p0 - p1).magnitude().abs()
-}
-
-fn rotation_matrix(angle: f64) -> [[f64; 2]; 2] {
- let s = angle.sin();
- let c = angle.cos();
- [[c, -s], [s, c]]
-}
-
-fn apply_matrix(matrix: [[f64; 2]; 2], vector: Vector) -> Vector {
- Vector {
- x: vector.x * matrix[0][0] + vector.y * matrix[0][1],
- y: vector.x * matrix[1][0] + vector.y * matrix[1][1],
- }
-}
-
-fn apply_matrix_point(matrix: [[f64; 2]; 2], point: Point) -> Point {
- Point {
- x: point.x * matrix[0][0] + point.y * matrix[0][1],
- y: point.x * matrix[1][0] + point.y * matrix[1][1],
- }
-}
-
-fn lerp_f64(a: f64, b: f64, x: f64) -> f64 {
- a + (b - a) * x
-}
-
-fn lerp_and_reduce(vals: &[f64], f: f64) -> Vec<f64> {
- let mut result = Vec::with_capacity(vals.len() - 1);
- for i in 0..(vals.len() - 1) {
- result.push(lerp_f64(vals[i], vals[i + 1], f));
- }
- result
-}
-
-fn lerp_and_reduce_to_one(vals: &[f64], f: f64) -> f64 {
- if vals.len() == 1 {
- vals[0]
- } else {
- lerp_and_reduce_to_one(&lerp_and_reduce(vals, f), f)
- }
-}
-
-/// A version of [`Point`] that uses usizes for a PixMap
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-struct UPoint {
- x: usize,
- y: usize,
-}
-
-impl UPoint {
- fn new(x: usize, y: usize) -> UPoint {
- Self { x, y }
- }
-}
-
-struct FrameBuffer<C: Color> {
- width: usize,
- height: usize,
- pixels: Box<[C]>,
- scale_x: f64,
- scale_y: f64,
-}
-
-impl<C: Color + Clone + Default> FrameBuffer<C> {
- fn new(width: usize, height: usize, scale_x: f64, scale_y: f64) -> Self {
- let pixel_count = width * height;
- Self {
- width,
- height,
- pixels: vec![C::default(); pixel_count].into_boxed_slice(),
- scale_x,
- scale_y,
- }
- }
-
- fn point_to_upoint(&self, point: Point) -> UPoint {
- todo!()
- }
-
- fn upoint_to_point(&self, upoint: UPoint) -> Point {
- todo!()
- }
-
- /// Blends the new color with the given pixel. Returns `None` if the destination is invalid
- fn set_pixel(&mut self, x: usize, y: usize, color: C) -> Option<()> {
- if x >= self.width || y >= self.height {
- return None;
- }
-
- let offset = y * self.width + x;
- let destination_pixel = self.pixels.get_mut(offset)?;
-
- blend(destination_pixel, &color);
-
- Some(())
- }
-
- fn draw_line(
- &mut self,
- color_table: ColorTable<C>,
- style: Style,
- width_start: f64,
- width_end: f64,
- line_start: Point,
- line_end: Point,
- ) -> Option<()> {
- let mut min_x = usize::MAX;
- let mut min_y = usize::MAX;
- let mut max_x = usize::MIN;
- let mut max_y = usize::MIN;
-
- let max_width = f64::max(width_start, width_end);
-
- let points = [line_start, line_end];
- for pt in points {
- min_x = usize::min(min_x, (self.scale_x * (pt.x - max_width)).floor() as usize);
- min_y = usize::min(min_y, (self.scale_y * (pt.y - max_width)).floor() as usize);
- max_x = usize::max(max_x, (self.scale_x * (pt.x - max_width)).floor() as usize);
- max_y = usize::max(max_y, (self.scale_y * (pt.y - max_width)).floor() as usize);
- }
-
- // limit to framebuffer size
- min_x = usize::min(min_x, self.width);
- min_y = usize::min(min_y, self.height);
- max_x = usize::min(max_x, self.width);
- max_y = usize::min(max_y, self.height);
-
- for y in min_y..=max_y {
- for x in min_x..=max_x {
- let point = self.upoint_to_point(UPoint { x, y });
- let dist = todo!() as f64;
-
- if dist >= 0.0 {
- self.set_pixel(x, y, style.get_color_at(&color_table, point)?);
- }
- }
- }
-
- Some(())
- }
-}
-
-#[derive(Debug, Default)]
-struct PathMaker {
- points: Vec<Point>,
- width: Vec<f64>,
-}
-
-impl PathMaker {
- fn new(width: f64, start: Point) -> Self {
- let points = vec![start];
- let width = vec![width];
-
- Self { points, width }
- }
-
- fn render_line(&mut self, width: f64, to_point: Point) {
- self.points.push(to_point);
- self.width.push(width);
- }
-
- fn render_horizontal_line(&mut self, width: f64, x: f64) {
- self.points.push(Point {
- x,
- y: self.points.last().unwrap().y,
- });
- self.width.push(width);
- }
-
- fn render_vertical_line(&mut self, width: f64, y: f64) {
- self.points.push(Point {
- x: self.points.last().unwrap().x,
- y,
- });
- self.width.push(width);
- }
-
- fn render_cubic_bezier(
- &mut self,
- control_0: Point,
- control_1: Point,
- point: Point,
- start_width: f64,
- end_width: f64,
- ) {
- const BEZIER_POLY_COUNT: usize = 16;
-
- let previous = self.points.last().unwrap();
- let oct0x = [previous.x, control_0.x, control_1.x, point.x];
- let oct0y = [previous.y, control_0.y, control_1.y, point.y];
-
- for i in 1..BEZIER_POLY_COUNT {
- let f = i as f64 / BEZIER_POLY_COUNT as f64;
- let x = lerp_and_reduce_to_one(&oct0x, f);
- let y = lerp_and_reduce_to_one(&oct0y, f);
-
- self.points.push(Point { x, y });
- self.width.push(lerp_f64(start_width, end_width, f));
- }
-
- self.points.push(point);
- self.width.push(end_width);
- }
-
- fn render_quadratic_bezier(
- &mut self,
- control: Point,
- target: Point,
- start_width: f64,
- end_width: f64,
- ) {
- const BEZIER_POLY_COUNT: usize = 16;
-
- let previous = self.points.last().unwrap();
- let oct0x = [previous.x, control.x, target.x];
- let oct0y = [previous.y, control.y, target.y];
-
- for i in 1..BEZIER_POLY_COUNT {
- let f = i as f64 / BEZIER_POLY_COUNT as f64;
- let x = lerp_and_reduce_to_one(&oct0x, f);
- let y = lerp_and_reduce_to_one(&oct0y, f);
-
- self.points.push(Point { x, y });
- self.width.push(lerp_f64(start_width, end_width, f));
- }
-
- self.points.push(target);
- self.width.push(end_width);
- }
-
- fn render_circle(
- &mut self,
- p0: Point,
- p1: Point,
- mut radius: f64,
- large_arc: bool,
- turn_left: bool,
- end_width: f64,
- ) {
- const CIRCLE_POLY_COUNT: usize = 100;
-
- let start_width = *self.width.last().unwrap();
- let left_side = turn_left == large_arc;
- let delta = (p1 - p0).scale(0.5);
- let midpoint = p0 + delta;
-
- let radius_vec = if left_side {
- Vector {
- x: -delta.y,
- y: delta.x,
- }
- } else {
- Vector {
- x: delta.y,
- y: -delta.x,
- }
- };
-
- let len_squared = radius_vec.x * radius_vec.x + radius_vec.y * radius_vec.y;
- if (len_squared - 0.03 > radius * radius) || radius < 0.0 {
- radius = len_squared.sqrt();
- }
-
- let to_center = radius_vec.scale(f64::max(0.0, radius * radius / len_squared - 1.0).sqrt());
- let center = midpoint + to_center;
- let angle = len_squared.sqrt().clamp(-1.0, 1.0).asin() * 2.0;
- let arc = if large_arc {
- std::f64::consts::TAU - angle
- } else {
- angle
- };
-
- let position = p0 - center;
- for i in 0..CIRCLE_POLY_COUNT {
- let arc = if turn_left { -arc } else { arc };
- let step_matrix = rotation_matrix(i as f64 * arc / CIRCLE_POLY_COUNT as f64);
- let point = center + apply_matrix(step_matrix, position);
- self.points.push(point);
- self.width.push(lerp_f64(
- start_width,
- end_width,
- i as f64 / CIRCLE_POLY_COUNT as f64,
- ));
- }
-
- self.points.push(p1);
- }
-
- fn render_ellipse(
- &mut self,
- p0: Point,
- p1: Point,
- radius_x: f64,
- radius_y: f64,
- rotation: f64,
- large_arc: bool,
- turn_left: bool,
- end_width: f64,
- ) {
- let radius_min = distance(p0, p1) / 2.0;
- let radius_max = (radius_x * radius_x + radius_y * radius_y).sqrt();
- let upscale = if radius_max < radius_min {
- radius_min / radius_max
- } else {
- 1.0
- };
-
- let ratio = radius_x / radius_y;
- let rotation = rotation_matrix(-rotation.to_radians());
- let transform = [
- [rotation[0][0] / upscale, rotation[0][1] / upscale],
- [
- rotation[1][0] / upscale * ratio,
- rotation[1][1] / upscale * ratio,
- ],
- ];
- let transform_back = [
- [rotation[1][1] * upscale, -rotation[0][1] / ratio * upscale],
- [-rotation[1][0] * upscale, rotation[0][0] / ratio * upscale],
- ];
-
- let mut tmp = PathMaker::default();
- tmp.render_circle(
- apply_matrix_point(transform, p0),
- apply_matrix_point(transform, p1),
- radius_x * upscale,
- large_arc,
- turn_left,
- end_width,
- );
-
- for i in 0..tmp.points.len() {
- let point = tmp.points[i];
- self.points.push(apply_matrix_point(transform_back, point));
- self.width.push(tmp.width[i]);
- }
- }
-
- fn close(&mut self, width: f64) {
- self.points.push(self.points[0]);
- self.width.push(width)
- }
-}
-
-fn render_path(path: Path, width: f64) {
- for segment in path.segments.iter() {
- let mut path_maker = PathMaker::new(width, segment.start);
- for instruction in segment.instructions.iter() {
- let line_width = instruction
- .line_width
- .unwrap_or(*path_maker.width.last().unwrap());
- let data = instruction.data;
- match data {
- InstructionData::Line { position } => path_maker.render_line(line_width, position),
- InstructionData::HorizontalLine { x } => {
- path_maker.render_horizontal_line(line_width, x)
- }
- InstructionData::VerticalLine { y } => {
- path_maker.render_vertical_line(line_width, y)
- }
- InstructionData::CubicBezier {
- control_0,
- control_1,
- point_1,
- } => path_maker.render_cubic_bezier(
- control_0,
- control_1,
- point_1,
- *path_maker.width.last().unwrap(),
- line_width,
- ),
- InstructionData::ArcCircle {
- large_arc,
- sweep,
- radius,
- target,
- } => path_maker.render_circle(
- *path_maker.points.last().unwrap(),
- target,
- radius,
- large_arc,
- sweep == Sweep::Left,
- line_width,
- ),
- InstructionData::ArcEllipse {
- large_arc,
- sweep,
- radius_x,
- radius_y,
- rotation,
- target,
- } => path_maker.render_ellipse(
- *path_maker.points.last().unwrap(),
- target,
- radius_x,
- radius_y,
- rotation,
- large_arc,
- sweep == Sweep::Left,
- line_width,
- ),
- InstructionData::ClosePath => path_maker.close(line_width),
- InstructionData::QuadraticBezier { control, target } => path_maker
- .render_quadratic_bezier(
- control,
- target,
- *path_maker.width.last().unwrap(),
- line_width,
- ),
- }
- }
- }
-}
-
-pub enum AntiAliasing {
- X1 = 1,
- X4 = 2,
- X9 = 3,
- X16 = 4,
- X25 = 6,
- X49 = 7,
- X64 = 8,
-}
-
-pub fn render<C: Color + Clone + Default>(
- file: &TvgFile<C>,
- width: u32,
- height: u32,
- scale_x: f32,
- scale_y: f32,
- anti_alias: AntiAliasing,
-) {
- let mut framebuffer: FrameBuffer<C> = FrameBuffer::new(
- width as usize,
- height as usize,
- scale_x.into(),
- scale_y.into(),
- );
- let header = &file.header;
- let color_table = &file.color_table;
-
- for command in file.commands.iter() {
- match command {
- Command::EndOfDocument => break,
- Command::FillPolygon {
- fill_style,
- polygon,
- } => {
- todo!()
- }
- Command::FillRectangles {
- fill_style,
- rectangles,
- } => todo!(),
- Command::FillPath { fill_style, path } => todo!(),
- Command::DrawLines {
- line_style,
- line_width,
- lines,
- } => todo!(),
- Command::DrawLineLoop {
- line_style,
- line_width,
- points,
- } => todo!(),
- Command::DrawLineStrip {
- line_style,
- line_width,
- points,
- } => todo!(),
- Command::DrawLinePath {
- line_style,
- line_width,
- path,
- } => todo!(),
- Command::OutlineFillPolygon {
- fill_style,
- line_style,
- line_width,
- points,
- } => todo!(),
- Command::OutlineFillRectangles {
- fill_style,
- line_style,
- line_width,
- rectangles,
- } => todo!(),
- Command::OutlineFillPath {
- fill_style,
- line_style,
- line_width,
- path,
- } => todo!(),
- }
- }
-}
diff --git a/tvg/tests/examples/tvg/everything-32.tvg b/tvg/tests/examples/tvg/everything-32.tvg
deleted file mode 100644
index 7ea4bdd..0000000
--- a/tvg/tests/examples/tvg/everything-32.tvg
+++ /dev/null
Binary files differ
diff --git a/tvg/tests/examples/tvg/everything.tvg b/tvg/tests/examples/tvg/everything.tvg
deleted file mode 100644
index b211c53..0000000
--- a/tvg/tests/examples/tvg/everything.tvg
+++ /dev/null
Binary files differ
diff --git a/tvg/tests/examples/tvg/shield-16.tvg b/tvg/tests/examples/tvg/shield-16.tvg
deleted file mode 100644
index aacd3ea..0000000
--- a/tvg/tests/examples/tvg/shield-16.tvg
+++ /dev/null
Binary files differ
diff --git a/tvg/tests/examples/tvg/shield-32.tvg b/tvg/tests/examples/tvg/shield-32.tvg
deleted file mode 100644
index a2abc92..0000000
--- a/tvg/tests/examples/tvg/shield-32.tvg
+++ /dev/null
Binary files differ
diff --git a/tvg/tests/examples/tvg/shield-8.tvg b/tvg/tests/examples/tvg/shield-8.tvg
deleted file mode 100644
index 57033be..0000000
--- a/tvg/tests/examples/tvg/shield-8.tvg
+++ /dev/null
Binary files differ
diff --git a/tvg/tests/parse.rs b/tvg/tests/parse.rs
deleted file mode 100644
index 017ea2c..0000000
--- a/tvg/tests/parse.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-use std::fs::File;
-
-use alligator_tvg::{colors::Rgba16, TvgFile};
-
-#[test]
-fn main() {
- for entry in std::fs::read_dir("tests/examples/tvg").unwrap() {
- let entry = entry.unwrap().file_name();
- let entry = entry.to_string_lossy();
- let mut file = File::open(format!("./tests/examples/tvg/{}", &entry)).unwrap();
- let start = std::time::Instant::now();
- let _: TvgFile<Rgba16> = TvgFile::read_from(&mut file).unwrap();
- println!(
- "{:?} successfully pased in {} seconds!",
- entry,
- start.elapsed().as_secs_f32()
- );
- }
-}