diff options
| author | Micha White <botahamec@outlook.com> | 2024-08-15 20:16:32 -0400 |
|---|---|---|
| committer | Micha White <botahamec@outlook.com> | 2024-08-15 20:16:32 -0400 |
| commit | db9aa9f1bf49e8bede384b9ceb1e1fb82b522799 (patch) | |
| tree | 0d60727acf481f59b42ef0f74ed07c16ec562bcf | |
| parent | f8a80039c74332e2101a177ef3fde31ef2077224 (diff) | |
Delete stuff
44 files changed, 1 insertions, 19750 deletions
@@ -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 Binary files differdeleted file mode 100644 index 9602cdb..0000000 --- a/packer/packed.png +++ /dev/null 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 Binary files differdeleted file mode 100644 index 64c5a69..0000000 --- a/packer/src/bin/res/bunny.ff +++ /dev/null diff --git a/packer/src/bin/res/bunny.png b/packer/src/bin/res/bunny.png Binary files differdeleted file mode 100644 index 87ba72d..0000000 --- a/packer/src/bin/res/bunny.png +++ /dev/null diff --git a/packer/src/bin/res/gator.bmp b/packer/src/bin/res/gator.bmp Binary files differdeleted file mode 100644 index e752b56..0000000 --- a/packer/src/bin/res/gator.bmp +++ /dev/null diff --git a/packer/src/bin/res/gator.ff b/packer/src/bin/res/gator.ff Binary files differdeleted file mode 100644 index aac1bcb..0000000 --- a/packer/src/bin/res/gator.ff +++ /dev/null diff --git a/packer/src/bin/res/ghost.ico b/packer/src/bin/res/ghost.ico Binary files differdeleted file mode 100644 index 102de00..0000000 --- a/packer/src/bin/res/ghost.ico +++ /dev/null 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 Binary files differdeleted file mode 100644 index 64c5a69..0000000 --- a/render/examples/res/bunny.ff +++ /dev/null diff --git a/render/examples/res/bunny.png b/render/examples/res/bunny.png Binary files differdeleted file mode 100644 index 87ba72d..0000000 --- a/render/examples/res/bunny.png +++ /dev/null diff --git a/render/examples/res/gator.bmp b/render/examples/res/gator.bmp Binary files differdeleted file mode 100644 index e752b56..0000000 --- a/render/examples/res/gator.bmp +++ /dev/null diff --git a/render/examples/res/gator.ff b/render/examples/res/gator.ff Binary files differdeleted file mode 100644 index aac1bcb..0000000 --- a/render/examples/res/gator.ff +++ /dev/null diff --git a/render/examples/res/ghost.ico b/render/examples/res/ghost.ico Binary files differdeleted file mode 100644 index 102de00..0000000 --- a/render/examples/res/ghost.ico +++ /dev/null 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 Binary files differdeleted file mode 100644 index 7ea4bdd..0000000 --- a/tvg/tests/examples/tvg/everything-32.tvg +++ /dev/null diff --git a/tvg/tests/examples/tvg/everything.tvg b/tvg/tests/examples/tvg/everything.tvg Binary files differdeleted file mode 100644 index b211c53..0000000 --- a/tvg/tests/examples/tvg/everything.tvg +++ /dev/null diff --git a/tvg/tests/examples/tvg/shield-16.tvg b/tvg/tests/examples/tvg/shield-16.tvg Binary files differdeleted file mode 100644 index aacd3ea..0000000 --- a/tvg/tests/examples/tvg/shield-16.tvg +++ /dev/null diff --git a/tvg/tests/examples/tvg/shield-32.tvg b/tvg/tests/examples/tvg/shield-32.tvg Binary files differdeleted file mode 100644 index a2abc92..0000000 --- a/tvg/tests/examples/tvg/shield-32.tvg +++ /dev/null diff --git a/tvg/tests/examples/tvg/shield-8.tvg b/tvg/tests/examples/tvg/shield-8.tvg Binary files differdeleted file mode 100644 index 57033be..0000000 --- a/tvg/tests/examples/tvg/shield-8.tvg +++ /dev/null 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() - ); - } -} |
