From 946e7d962118366ae979641666dda199529ec2bd Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 20 Jan 2025 12:59:40 +0100 Subject: [PATCH] push minetest server --- README.md | 17 + conf/minetest.conf | 3497 +++++++++++++++++ data/games/garage/LICENSE.txt | 4 + data/games/garage/README.md | 50 + data/games/garage/game.conf | 4 + data/games/garage/menu/background.png | Bin 0 -> 139 bytes data/games/garage/menu/header.png | Bin 0 -> 209 bytes data/games/garage/menu/icon.png | Bin 0 -> 217 bytes data/games/garage/mods/basenodes/init.lua | 361 ++ data/games/garage/mods/basenodes/mod.conf | 2 + .../basenodes_dirt_with_grass_bottom.png | Bin 0 -> 187 bytes .../textures/basenodes_dirt_with_snow.png | Bin 0 -> 166 bytes .../basenodes_dirt_with_snow_bottom.png | Bin 0 -> 177 bytes .../textures/basenodes_snow_sheet.png | Bin 0 -> 166 bytes .../mods/basenodes/textures/default_apple.png | Bin 0 -> 102 bytes .../basenodes/textures/default_cobble.png | Bin 0 -> 340 bytes .../textures/default_desert_sand.png | Bin 0 -> 293 bytes .../textures/default_desert_stone.png | Bin 0 -> 584 bytes .../mods/basenodes/textures/default_dirt.png | Bin 0 -> 782 bytes .../mods/basenodes/textures/default_grass.png | Bin 0 -> 697 bytes .../basenodes/textures/default_gravel.png | Bin 0 -> 171 bytes .../mods/basenodes/textures/default_ice.png | Bin 0 -> 369 bytes .../textures/default_junglegrass.png | Bin 0 -> 201 bytes .../textures/default_jungleleaves.png | Bin 0 -> 399 bytes .../basenodes/textures/default_jungletree.png | Bin 0 -> 730 bytes .../textures/default_jungletree_top.png | Bin 0 -> 714 bytes .../mods/basenodes/textures/default_lava.png | Bin 0 -> 172 bytes .../textures/default_lava_flowing.png | Bin 0 -> 91 bytes .../basenodes/textures/default_leaves.png | Bin 0 -> 883 bytes .../textures/default_mossycobble.png | Bin 0 -> 574 bytes .../textures/default_pine_needles.png | Bin 0 -> 648 bytes .../basenodes/textures/default_pine_tree.png | Bin 0 -> 604 bytes .../textures/default_pine_tree_top.png | Bin 0 -> 174 bytes .../textures/default_river_water.png | Bin 0 -> 496 bytes .../textures/default_river_water_flowing.png | Bin 0 -> 99 bytes .../mods/basenodes/textures/default_sand.png | Bin 0 -> 554 bytes .../mods/basenodes/textures/default_snow.png | Bin 0 -> 166 bytes .../basenodes/textures/default_snow_side.png | Bin 0 -> 152 bytes .../mods/basenodes/textures/default_stone.png | Bin 0 -> 313 bytes .../mods/basenodes/textures/default_tree.png | Bin 0 -> 659 bytes .../basenodes/textures/default_tree_top.png | Bin 0 -> 175 bytes .../mods/basenodes/textures/default_water.png | Bin 0 -> 302 bytes .../textures/default_water_flowing.png | Bin 0 -> 115 bytes .../dirt_with_grass/default_grass.png | Bin 0 -> 760 bytes .../dirt_with_grass/default_grass_side.png | Bin 0 -> 796 bytes .../garage/mods/basenodes/textures/info.txt | 7 + data/games/garage/mods/basetools/init.lua | 582 +++ data/games/garage/mods/basetools/mod.conf | 2 + .../textures/basetools_bloodsword.png | Bin 0 -> 165 bytes .../textures/basetools_elementalsword.png | Bin 0 -> 177 bytes .../textures/basetools_firesword.png | Bin 0 -> 166 bytes .../textures/basetools_healdagger.png | Bin 0 -> 162 bytes .../textures/basetools_healsword.png | Bin 0 -> 170 bytes .../basetools/textures/basetools_icesword.png | Bin 0 -> 170 bytes .../basetools/textures/basetools_mesepick.png | Bin 0 -> 156 bytes .../textures/basetools_mesepick_no_delay.png | Bin 0 -> 169 bytes .../textures/basetools_mesesword.png | Bin 0 -> 163 bytes .../basetools/textures/basetools_steelaxe.png | Bin 0 -> 131 bytes .../textures/basetools_steeldagger.png | Bin 0 -> 154 bytes .../textures/basetools_steelpick.png | Bin 0 -> 159 bytes .../textures/basetools_steelpick_l1.png | Bin 0 -> 190 bytes .../textures/basetools_steelpick_l2.png | Bin 0 -> 177 bytes .../textures/basetools_steelshears.png | Bin 0 -> 208 bytes .../textures/basetools_steelshovel.png | Bin 0 -> 140 bytes .../textures/basetools_steelsword.png | Bin 0 -> 163 bytes .../basetools/textures/basetools_stoneaxe.png | Bin 0 -> 130 bytes .../textures/basetools_stonepick.png | Bin 0 -> 155 bytes .../textures/basetools_stoneshears.png | Bin 0 -> 224 bytes .../textures/basetools_stoneshovel.png | Bin 0 -> 134 bytes .../textures/basetools_stonesword.png | Bin 0 -> 159 bytes .../textures/basetools_superhealsword.png | Bin 0 -> 192 bytes .../textures/basetools_titaniumsword.png | Bin 0 -> 160 bytes .../basetools/textures/basetools_usespick.png | Bin 0 -> 161 bytes .../textures/basetools_usessword.png | Bin 0 -> 133 bytes .../basetools/textures/basetools_woodaxe.png | Bin 0 -> 121 bytes .../textures/basetools_wooddagger.png | Bin 0 -> 139 bytes .../basetools/textures/basetools_woodpick.png | Bin 0 -> 149 bytes .../textures/basetools_woodshears.png | Bin 0 -> 212 bytes .../textures/basetools_woodshovel.png | Bin 0 -> 133 bytes .../textures/basetools_woodsword.png | Bin 0 -> 139 bytes data/games/garage/mods/benchmarks/init.lua | 189 + data/games/garage/mods/benchmarks/mod.conf | 2 + data/games/garage/mods/broken/init.lua | 11 + data/games/garage/mods/broken/mod.conf | 2 + data/games/garage/mods/bucket/init.lua | 27 + data/games/garage/mods/bucket/mod.conf | 2 + .../garage/mods/bucket/textures/bucket.png | Bin 0 -> 163 bytes .../mods/bucket/textures/bucket_lava.png | Bin 0 -> 168 bytes .../mods/bucket/textures/bucket_water.png | Bin 0 -> 168 bytes data/games/garage/mods/callbacks/entities.lua | 101 + data/games/garage/mods/callbacks/init.lua | 4 + data/games/garage/mods/callbacks/items.lua | 120 + data/games/garage/mods/callbacks/mod.conf | 2 + data/games/garage/mods/callbacks/nodes.lua | 51 + data/games/garage/mods/callbacks/players.lua | 11 + .../textures/callbacks_callback_entity.png | Bin 0 -> 142 bytes .../callbacks_callback_entity_step.png | Bin 0 -> 139 bytes .../textures/callbacks_callback_item_1.png | Bin 0 -> 129 bytes .../textures/callbacks_callback_item_2.png | Bin 0 -> 130 bytes .../textures/callbacks_callback_node.png | Bin 0 -> 139 bytes data/games/garage/mods/chest/chest.lua | 52 + data/games/garage/mods/chest/detached.lua | 58 + data/games/garage/mods/chest/init.lua | 2 + data/games/garage/mods/chest/mod.conf | 2 + .../mods/chest/textures/chest_chest.png | Bin 0 -> 163 bytes .../chest/textures/chest_detached_chest.png | Bin 0 -> 240 bytes .../garage/mods/chest_of_everything/init.lua | 353 ++ .../garage/mods/chest_of_everything/mod.conf | 2 + .../textures/chest_of_everything_bag.png | Bin 0 -> 197 bytes .../textures/chest_of_everything_chest.png | Bin 0 -> 210 bytes data/games/garage/mods/dignodes/init.lua | 39 + data/games/garage/mods/dignodes/mod.conf | 2 + .../dignodes/textures/dignodes_choppy.png | Bin 0 -> 187 bytes .../dignodes/textures/dignodes_cracky.png | Bin 0 -> 193 bytes .../dignodes/textures/dignodes_crumbly.png | Bin 0 -> 172 bytes .../textures/dignodes_dig_immediate.png | Bin 0 -> 170 bytes .../mods/dignodes/textures/dignodes_none.png | Bin 0 -> 201 bytes .../dignodes/textures/dignodes_rating1.png | Bin 0 -> 94 bytes .../dignodes/textures/dignodes_rating2.png | Bin 0 -> 92 bytes .../dignodes/textures/dignodes_rating3.png | Bin 0 -> 93 bytes data/games/garage/mods/first_mod/init.lua | 1 + data/games/garage/mods/first_mod/mod.conf | 2 + .../garage/mods/give_initial_stuff/init.lua | 37 + .../garage/mods/give_initial_stuff/mod.conf | 3 + data/games/garage/mods/gltf/LICENSE.md | 14 + data/games/garage/mods/gltf/init.lua | 95 + .../games/garage/mods/gltf/invalid/empty.gltf | 0 .../invalid/invalid_bufferview_bounds.gltf | 1 + .../mods/gltf/invalid/json_missing_brace.gltf | 1 + data/games/garage/mods/gltf/mod.conf | 2 + .../mods/gltf/models/gltf_blender_cube.glb | Bin 0 -> 1752 bytes .../mods/gltf/models/gltf_blender_cube.gltf | 1 + .../gltf_blender_cube_matrix_transform.gltf | 1 + .../gltf/models/gltf_blender_cube_scaled.gltf | 1 + .../garage/mods/gltf/models/gltf_frog.gltf | 1 + .../gltf/models/gltf_minimal_triangle.gltf | 1 + .../mods/gltf/models/gltf_simple_skin.gltf | 1 + .../models/gltf_simple_sparse_accessor.gltf | 1 + .../mods/gltf/models/gltf_snow_man.gltf | 1 + .../garage/mods/gltf/models/gltf_spider.gltf | 1 + .../gltf/models/gltf_spider_animated.gltf | 1 + .../gltf_triangle_with_vertex_stride.gltf | 1 + .../models/gltf_triangle_without_indices.gltf | 1 + .../garage/mods/gltf/textures/gltf_cube.png | Bin 0 -> 203 bytes .../garage/mods/gltf/textures/gltf_frog.png | Bin 0 -> 272 bytes .../mods/gltf/textures/gltf_snow_man.png | Bin 0 -> 205 bytes .../garage/mods/gltf/textures/gltf_spider.png | Bin 0 -> 10957 bytes .../garage/mods/initial_message/init.lua | 9 + .../garage/mods/initial_message/mod.conf | 2 + data/games/garage/mods/last_mod/init.lua | 1 + data/games/garage/mods/last_mod/mod.conf | 5 + data/games/garage/mods/lighting/init.lua | 156 + data/games/garage/mods/lighting/mod.conf | 2 + data/games/garage/mods/log/init.lua | 16 + data/games/garage/mods/log/mod.conf | 2 + data/games/garage/mods/mapgen/init.lua | 104 + data/games/garage/mods/mapgen/mod.conf | 3 + data/games/garage/mods/modchannels/init.lua | 14 + data/games/garage/mods/modchannels/mod.conf | 2 + data/games/garage/mods/soundstuff/bigfoot.lua | 48 + data/games/garage/mods/soundstuff/init.lua | 6 + data/games/garage/mods/soundstuff/jukebox.lua | 331 ++ data/games/garage/mods/soundstuff/mod.conf | 3 + data/games/garage/mods/soundstuff/racecar.lua | 31 + .../mods/soundstuff/sound_event_items.lua | 209 + .../gitignored_sounds/custom_sounds_here.txt | 2 + .../soundstuff/sounds/soundstuff_mono.ogg | Bin 0 -> 4362 bytes .../soundstuff/sounds/soundstuff_sinus.ogg | Bin 0 -> 4455 bytes .../textures/soundstuff_bigfoot.png | Bin 0 -> 169 bytes .../soundstuff/textures/soundstuff_eat.png | Bin 0 -> 113 bytes .../textures/soundstuff_jukebox.png | Bin 0 -> 123 bytes .../textures/soundstuff_node_blank.png | Bin 0 -> 83 bytes .../textures/soundstuff_node_climbable.png | Bin 0 -> 189 bytes .../textures/soundstuff_node_dig.png | Bin 0 -> 126 bytes .../textures/soundstuff_node_dug.png | Bin 0 -> 132 bytes .../textures/soundstuff_node_fall.png | Bin 0 -> 100 bytes .../textures/soundstuff_node_footstep.png | Bin 0 -> 120 bytes .../textures/soundstuff_node_place.png | Bin 0 -> 115 bytes .../textures/soundstuff_node_place_failed.png | Bin 0 -> 143 bytes .../textures/soundstuff_node_sound.png | Bin 0 -> 116 bytes .../textures/soundstuff_racecar.png | Bin 0 -> 129 bytes data/games/garage/mods/stairs/init.lua | 66 + data/games/garage/mods/stairs/mod.conf | 3 + data/games/garage/mods/testabms/README.md | 6 + .../games/garage/mods/testabms/after_node.lua | 12 + data/games/garage/mods/testabms/chances.lua | 56 + data/games/garage/mods/testabms/init.lua | 7 + data/games/garage/mods/testabms/intervals.lua | 56 + data/games/garage/mods/testabms/min_max.lua | 58 + data/games/garage/mods/testabms/mod.conf | 2 + data/games/garage/mods/testabms/neighbors.lua | 99 + .../testabms/textures/testabms_after_node.png | Bin 0 -> 179 bytes .../testabms/textures/testabms_wait_node.png | Bin 0 -> 183 bytes data/games/garage/mods/testentities/armor.lua | 61 + data/games/garage/mods/testentities/init.lua | 5 + data/games/garage/mods/testentities/mod.conf | 2 + .../mods/testentities/models/LICENSE.txt | 7 + .../testentities/models/testentities_sam.b3d | Bin 0 -> 73433 bytes .../testentities/models/testentities_sam.png | Bin 0 -> 2754 bytes .../garage/mods/testentities/observers.lua | 37 + .../garage/mods/testentities/pointable.lua | 23 + .../garage/mods/testentities/selectionbox.lua | 96 + .../textures/testentities_armorball.png | Bin 0 -> 1351 bytes .../textures/testentities_cube1.png | Bin 0 -> 130 bytes .../textures/testentities_cube2.png | Bin 0 -> 128 bytes .../textures/testentities_cube3.png | Bin 0 -> 124 bytes .../textures/testentities_cube4.png | Bin 0 -> 126 bytes .../textures/testentities_cube5.png | Bin 0 -> 126 bytes .../textures/testentities_cube6.png | Bin 0 -> 126 bytes .../textures/testentities_dungeon_master.png | Bin 0 -> 2855 bytes .../textures/testentities_sprite.png | Bin 0 -> 120 bytes .../textures/testentities_upright_sprite1.png | Bin 0 -> 114 bytes .../textures/testentities_upright_sprite2.png | Bin 0 -> 119 bytes .../garage/mods/testentities/visuals.lua | 150 + data/games/garage/mods/testfood/init.lua | 35 + data/games/garage/mods/testfood/mod.conf | 2 + .../mods/testfood/textures/testfood_bad.png | Bin 0 -> 126 bytes .../mods/testfood/textures/testfood_bad2.png | Bin 0 -> 133 bytes .../mods/testfood/textures/testfood_good.png | Bin 0 -> 129 bytes .../mods/testfood/textures/testfood_good2.png | Bin 0 -> 145 bytes .../testfood/textures/testfood_replace.png | Bin 0 -> 135 bytes .../garage/mods/testformspec/LICENSE.txt | 14 + .../garage/mods/testformspec/callbacks.lua | 51 + .../garage/mods/testformspec/dummy_items.lua | 14 + .../garage/mods/testformspec/formspec.lua | 591 +++ data/games/garage/mods/testformspec/init.lua | 3 + data/games/garage/mods/testformspec/mod.conf | 2 + .../models/testformspec_character.b3d | Bin 0 -> 73433 bytes .../models/testformspec_chest.obj | 79 + .../textures/default_chest_front.png | Bin 0 -> 421 bytes .../textures/default_chest_inside.png | Bin 0 -> 94 bytes .../textures/default_chest_side.png | Bin 0 -> 375 bytes .../textures/default_chest_top.png | Bin 0 -> 418 bytes .../textures/testformspec_9slice.png | Bin 0 -> 513 bytes .../textures/testformspec_animation.jpg | Bin 0 -> 4376 bytes .../textures/testformspec_animation.png | Bin 0 -> 214 bytes .../testformspec/textures/testformspec_bg.png | Bin 0 -> 92 bytes .../textures/testformspec_bg_9slice.png | Bin 0 -> 146 bytes .../testformspec_bg_9slice_focused.png | Bin 0 -> 162 bytes .../testformspec_bg_9slice_hovered.png | Bin 0 -> 146 bytes .../testformspec_bg_9slice_pressed.png | Bin 0 -> 146 bytes .../textures/testformspec_bg_focused.png | Bin 0 -> 127 bytes .../textures/testformspec_bg_hovered.png | Bin 0 -> 92 bytes .../textures/testformspec_bg_pressed.png | Bin 0 -> 91 bytes .../textures/testformspec_button_image.png | Bin 0 -> 146 bytes .../textures/testformspec_character.png | Bin 0 -> 2754 bytes .../textures/testformspec_hovered.png | Bin 0 -> 195 bytes .../textures/testformspec_item.png | Bin 0 -> 182 bytes .../textures/testformspec_node.png | Bin 0 -> 113 bytes .../textures/testformspec_pressed.png | Bin 0 -> 165 bytes .../garage/mods/testfullscreenfs/init.lua | 71 + .../garage/mods/testfullscreenfs/mod.conf | 2 + data/games/garage/mods/testhud/init.lua | 393 ++ data/games/garage/mods/testhud/mod.conf | 2 + .../testhud/textures/testhud_waypoint.png | Bin 0 -> 111 bytes data/games/garage/mods/testitems/init.lua | 107 + data/games/garage/mods/testitems/mod.conf | 2 + .../textures/testitems_overlay_base.png | Bin 0 -> 106 bytes .../textures/testitems_overlay_overlay.png | Bin 0 -> 220 bytes .../textures/testitems_overridden.png | Bin 0 -> 110 bytes .../textures/testitems_telescope_stick.png | Bin 0 -> 170 bytes data/games/garage/mods/testnodes/README.md | 11 + data/games/garage/mods/testnodes/commands.lua | 139 + .../games/garage/mods/testnodes/drawtypes.lua | 727 ++++ data/games/garage/mods/testnodes/init.lua | 13 + data/games/garage/mods/testnodes/light.lua | 50 + data/games/garage/mods/testnodes/liquids.lua | 157 + data/games/garage/mods/testnodes/meshes.lua | 179 + data/games/garage/mods/testnodes/mod.conf | 3 + .../models/testnodes_marble_glass.obj | 1619 ++++++++ .../models/testnodes_marble_metal.obj | 2470 ++++++++++++ .../testnodes/models/testnodes_ocorner.obj | 23 + .../testnodes/models/testnodes_pyramid.obj | 24 + .../games/garage/mods/testnodes/nodeboxes.lua | 242 ++ data/games/garage/mods/testnodes/overlays.lua | 93 + data/games/garage/mods/testnodes/param2.lua | 321 ++ .../mods/testnodes/performance_test_nodes.lua | 59 + .../garage/mods/testnodes/properties.lua | 685 ++++ data/games/garage/mods/testnodes/textures.lua | 369 ++ .../mods/testnodes/textures/testnodes_1.png | Bin 0 -> 107 bytes .../textures/testnodes_128x128_rgb.png | Bin 0 -> 1870 bytes .../mods/testnodes/textures/testnodes_1f.png | Bin 0 -> 153 bytes .../mods/testnodes/textures/testnodes_1fg.png | Bin 0 -> 108 bytes .../mods/testnodes/textures/testnodes_1g.png | Bin 0 -> 104 bytes .../mods/testnodes/textures/testnodes_1w.png | Bin 0 -> 121 bytes .../mods/testnodes/textures/testnodes_1wg.png | Bin 0 -> 122 bytes .../mods/testnodes/textures/testnodes_2.png | Bin 0 -> 112 bytes .../mods/testnodes/textures/testnodes_2f.png | Bin 0 -> 141 bytes .../mods/testnodes/textures/testnodes_2fg.png | Bin 0 -> 118 bytes .../mods/testnodes/textures/testnodes_2g.png | Bin 0 -> 110 bytes .../mods/testnodes/textures/testnodes_2w.png | Bin 0 -> 134 bytes .../mods/testnodes/textures/testnodes_2wg.png | Bin 0 -> 135 bytes .../mods/testnodes/textures/testnodes_3.png | Bin 0 -> 105 bytes .../mods/testnodes/textures/testnodes_3f.png | Bin 0 -> 158 bytes .../mods/testnodes/textures/testnodes_3fg.png | Bin 0 -> 114 bytes .../mods/testnodes/textures/testnodes_3g.png | Bin 0 -> 103 bytes .../mods/testnodes/textures/testnodes_3w.png | Bin 0 -> 112 bytes .../mods/testnodes/textures/testnodes_3wg.png | Bin 0 -> 112 bytes .../mods/testnodes/textures/testnodes_4.png | Bin 0 -> 97 bytes .../mods/testnodes/textures/testnodes_4f.png | Bin 0 -> 152 bytes .../mods/testnodes/textures/testnodes_4fg.png | Bin 0 -> 103 bytes .../mods/testnodes/textures/testnodes_4g.png | Bin 0 -> 95 bytes .../mods/testnodes/textures/testnodes_4w.png | Bin 0 -> 128 bytes .../mods/testnodes/textures/testnodes_4wg.png | Bin 0 -> 128 bytes .../mods/testnodes/textures/testnodes_5.png | Bin 0 -> 98 bytes .../mods/testnodes/textures/testnodes_5f.png | Bin 0 -> 156 bytes .../mods/testnodes/textures/testnodes_5fg.png | Bin 0 -> 109 bytes .../mods/testnodes/textures/testnodes_5g.png | Bin 0 -> 98 bytes .../mods/testnodes/textures/testnodes_5w.png | Bin 0 -> 117 bytes .../mods/testnodes/textures/testnodes_5wg.png | Bin 0 -> 117 bytes .../mods/testnodes/textures/testnodes_6.png | Bin 0 -> 100 bytes .../mods/testnodes/textures/testnodes_6f.png | Bin 0 -> 158 bytes .../mods/testnodes/textures/testnodes_6fg.png | Bin 0 -> 111 bytes .../mods/testnodes/textures/testnodes_6g.png | Bin 0 -> 98 bytes .../mods/testnodes/textures/testnodes_6w.png | Bin 0 -> 117 bytes .../mods/testnodes/textures/testnodes_6wg.png | Bin 0 -> 117 bytes .../testnodes/textures/testnodes_airlike.png | Bin 0 -> 92 bytes .../testnodes/textures/testnodes_allfaces.png | Bin 0 -> 150 bytes .../textures/testnodes_allfaces_optional.png | Bin 0 -> 150 bytes .../testnodes/textures/testnodes_alpha.png | Bin 0 -> 96 bytes .../testnodes/textures/testnodes_alpha128.png | Bin 0 -> 136 bytes .../testnodes/textures/testnodes_alpha191.png | Bin 0 -> 132 bytes .../testnodes/textures/testnodes_alpha64.png | Bin 0 -> 134 bytes .../testnodes_alpha_compositing_bottom.png | Bin 0 -> 265 bytes .../testnodes_alpha_compositing_top.png | Bin 0 -> 160 bytes .../testnodes/textures/testnodes_anim.png | Bin 0 -> 274 bytes .../textures/testnodes_attached4_bottom.png | Bin 0 -> 123 bytes .../textures/testnodes_attached4_side.png | Bin 0 -> 111 bytes .../textures/testnodes_attached4_top.png | Bin 0 -> 100 bytes .../textures/testnodes_attached_bottom.png | Bin 0 -> 86 bytes .../textures/testnodes_attached_side.png | Bin 0 -> 98 bytes .../textures/testnodes_attached_top.png | Bin 0 -> 87 bytes .../textures/testnodes_attachedf_bottom.png | Bin 0 -> 124 bytes .../textures/testnodes_attachedf_side.png | Bin 0 -> 112 bytes .../textures/testnodes_attachedf_top.png | Bin 0 -> 103 bytes .../textures/testnodes_attachedfr_bottom.png | Bin 0 -> 106 bytes .../textures/testnodes_attachedfr_side.png | Bin 0 -> 103 bytes .../textures/testnodes_attachedfr_top.png | Bin 0 -> 93 bytes .../textures/testnodes_attachedw_bottom.png | Bin 0 -> 130 bytes .../textures/testnodes_attachedw_side.png | Bin 0 -> 122 bytes .../textures/testnodes_attachedw_top.png | Bin 0 -> 109 bytes .../textures/testnodes_attachedwr_bottom.png | Bin 0 -> 265 bytes .../textures/testnodes_attachedwr_side.png | Bin 0 -> 173 bytes .../textures/testnodes_attachedwr_top.png | Bin 0 -> 153 bytes .../textures/testnodes_blocking_pointable.png | Bin 0 -> 150 bytes .../testnodes/textures/testnodes_bouncy.png | Bin 0 -> 106 bytes .../textures/testnodes_buildable_to.png | Bin 0 -> 89 bytes .../testnodes_climbable_noclimb_side.png | Bin 0 -> 174 bytes .../testnodes_climbable_noclimb_top.png | Bin 0 -> 101 bytes .../testnodes_climbable_nodescend_side.png | Bin 0 -> 175 bytes .../testnodes_climbable_nodescend_top.png | Bin 0 -> 101 bytes .../testnodes_climbable_nojump_side.png | Bin 0 -> 164 bytes .../testnodes_climbable_nojump_top.png | Bin 0 -> 101 bytes .../testnodes_climbable_resistance_side.png | Bin 0 -> 176 bytes .../textures/testnodes_climbable_side.png | Bin 0 -> 150 bytes .../textures/testnodes_climbable_top.png | Bin 0 -> 101 bytes .../testnodes/textures/testnodes_damage.png | Bin 0 -> 108 bytes .../textures/testnodes_damage_neg.png | Bin 0 -> 121 bytes .../testnodes/textures/testnodes_drowning.png | Bin 0 -> 127 bytes .../textures/testnodes_fall_damage_minus.png | Bin 0 -> 116 bytes .../textures/testnodes_fall_damage_plus.png | Bin 0 -> 117 bytes .../textures/testnodes_fencelike.png | Bin 0 -> 90 bytes .../testnodes_fill_positioning_reference.png | Bin 0 -> 92 bytes .../testnodes/textures/testnodes_firelike.png | Bin 0 -> 149 bytes .../textures/testnodes_glasslike.png | Bin 0 -> 117 bytes .../textures/testnodes_glasslike_detail.png | Bin 0 -> 167 bytes .../textures/testnodes_glasslike_framed.png | Bin 0 -> 88 bytes .../textures/testnodes_glasslike_framed2.png | Bin 0 -> 118 bytes .../testnodes_glasslike_framed_optional.png | Bin 0 -> 128 bytes .../textures/testnodes_glasslikeliquid.png | Bin 0 -> 122 bytes .../testnodes/textures/testnodes_light.png | Bin 0 -> 117 bytes .../testnodes/textures/testnodes_light_1.png | Bin 0 -> 158 bytes .../testnodes/textures/testnodes_light_10.png | Bin 0 -> 147 bytes .../testnodes/textures/testnodes_light_11.png | Bin 0 -> 149 bytes .../testnodes/textures/testnodes_light_12.png | Bin 0 -> 138 bytes .../testnodes/textures/testnodes_light_13.png | Bin 0 -> 137 bytes .../testnodes/textures/testnodes_light_14.png | Bin 0 -> 132 bytes .../testnodes/textures/testnodes_light_2.png | Bin 0 -> 152 bytes .../testnodes/textures/testnodes_light_3.png | Bin 0 -> 150 bytes .../testnodes/textures/testnodes_light_4.png | Bin 0 -> 157 bytes .../testnodes/textures/testnodes_light_5.png | Bin 0 -> 150 bytes .../testnodes/textures/testnodes_light_6.png | Bin 0 -> 154 bytes .../testnodes/textures/testnodes_light_7.png | Bin 0 -> 146 bytes .../testnodes/textures/testnodes_light_8.png | Bin 0 -> 139 bytes .../testnodes/textures/testnodes_light_9.png | Bin 0 -> 149 bytes .../textures/testnodes_line_crossing.png | Bin 0 -> 130 bytes .../textures/testnodes_line_curved.png | Bin 0 -> 123 bytes .../textures/testnodes_line_straight.png | Bin 0 -> 115 bytes .../textures/testnodes_line_t_junction.png | Bin 0 -> 128 bytes .../testnodes/textures/testnodes_liquid.png | Bin 0 -> 95 bytes .../textures/testnodes_liquidflowing.png | Bin 0 -> 132 bytes .../textures/testnodes_liquidflowing_r0.png | Bin 0 -> 162 bytes .../textures/testnodes_liquidflowing_r1.png | Bin 0 -> 160 bytes .../textures/testnodes_liquidflowing_r2.png | Bin 0 -> 154 bytes .../textures/testnodes_liquidflowing_r3.png | Bin 0 -> 155 bytes .../textures/testnodes_liquidflowing_r4.png | Bin 0 -> 154 bytes .../textures/testnodes_liquidflowing_r5.png | Bin 0 -> 155 bytes .../textures/testnodes_liquidflowing_r6.png | Bin 0 -> 155 bytes .../textures/testnodes_liquidflowing_r7.png | Bin 0 -> 157 bytes .../textures/testnodes_liquidflowing_r8.png | Bin 0 -> 152 bytes .../textures/testnodes_liquidsource.png | Bin 0 -> 128 bytes .../textures/testnodes_liquidsource_r0.png | Bin 0 -> 149 bytes .../textures/testnodes_liquidsource_r1.png | Bin 0 -> 152 bytes .../textures/testnodes_liquidsource_r2.png | Bin 0 -> 152 bytes .../textures/testnodes_liquidsource_r3.png | Bin 0 -> 152 bytes .../textures/testnodes_liquidsource_r4.png | Bin 0 -> 155 bytes .../textures/testnodes_liquidsource_r5.png | Bin 0 -> 150 bytes .../textures/testnodes_liquidsource_r6.png | Bin 0 -> 148 bytes .../textures/testnodes_liquidsource_r7.png | Bin 0 -> 154 bytes .../textures/testnodes_liquidsource_r8.png | Bin 0 -> 148 bytes .../textures/testnodes_marble_glass.png | Bin 0 -> 9871 bytes .../textures/testnodes_marble_metal.png | Bin 0 -> 595 bytes .../testnodes_marble_metal_overlay.png | Bin 0 -> 526 bytes .../textures/testnodes_mask_WRGBKW.png | Bin 0 -> 148 bytes .../textures/testnodes_mesh_stripes.png | Bin 0 -> 150 bytes .../textures/testnodes_mesh_stripes10.png | Bin 0 -> 84 bytes .../textures/testnodes_mesh_stripes2.png | Bin 0 -> 144 bytes .../textures/testnodes_mesh_stripes3.png | Bin 0 -> 85 bytes .../textures/testnodes_mesh_stripes4.png | Bin 0 -> 93 bytes .../textures/testnodes_mesh_stripes5.png | Bin 0 -> 108 bytes .../textures/testnodes_mesh_stripes6.png | Bin 0 -> 86 bytes .../textures/testnodes_mesh_stripes7.png | Bin 0 -> 96 bytes .../textures/testnodes_mesh_stripes8.png | Bin 0 -> 86 bytes .../textures/testnodes_mesh_stripes9.png | Bin 0 -> 99 bytes .../textures/testnodes_move_resistance.png | Bin 0 -> 130 bytes .../testnodes/textures/testnodes_node.png | Bin 0 -> 89 bytes .../textures/testnodes_node_falling.png | Bin 0 -> 112 bytes .../textures/testnodes_node_falling_1.png | Bin 0 -> 126 bytes .../textures/testnodes_node_falling_2.png | Bin 0 -> 135 bytes .../textures/testnodes_node_falling_3.png | Bin 0 -> 125 bytes .../textures/testnodes_node_falling_4.png | Bin 0 -> 123 bytes .../textures/testnodes_node_falling_5.png | Bin 0 -> 123 bytes .../textures/testnodes_node_falling_6.png | Bin 0 -> 122 bytes .../testnodes/textures/testnodes_nodebox.png | Bin 0 -> 112 bytes .../textures/testnodes_nojump_side.png | Bin 0 -> 94 bytes .../textures/testnodes_nojump_top.png | Bin 0 -> 121 bytes .../testnodes/textures/testnodes_normal.png | Bin 0 -> 92 bytes .../testnodes/textures/testnodes_normal1.png | Bin 0 -> 114 bytes .../testnodes/textures/testnodes_normal2.png | Bin 0 -> 122 bytes .../testnodes/textures/testnodes_normal3.png | Bin 0 -> 114 bytes .../testnodes/textures/testnodes_normal4.png | Bin 0 -> 106 bytes .../testnodes/textures/testnodes_normal5.png | Bin 0 -> 109 bytes .../testnodes/textures/testnodes_normal6.png | Bin 0 -> 111 bytes .../textures/testnodes_not_pointable.png | Bin 0 -> 152 bytes .../testnodes/textures/testnodes_overlay.png | Bin 0 -> 153 bytes .../textures/testnodes_overlayable.png | Bin 0 -> 87 bytes .../textures/testnodes_palette_4dir.png | Bin 0 -> 133 bytes .../textures/testnodes_palette_facedir.png | Bin 0 -> 87 bytes .../textures/testnodes_palette_full.png | Bin 0 -> 568 bytes .../textures/testnodes_palette_metal.png | Bin 0 -> 109 bytes .../testnodes_palette_wallmounted.png | Bin 0 -> 136 bytes .../textures/testnodes_plantlike.png | Bin 0 -> 183 bytes .../testnodes_plantlike_degrotate.png | Bin 0 -> 176 bytes .../textures/testnodes_plantlike_leveled.png | Bin 0 -> 163 bytes .../testnodes_plantlike_meshoptions.png | Bin 0 -> 164 bytes .../textures/testnodes_plantlike_rooted.png | Bin 0 -> 182 bytes .../testnodes_plantlike_rooted_base.png | Bin 0 -> 101 bytes ...s_plantlike_rooted_base_side_degrotate.png | Bin 0 -> 145 bytes ...des_plantlike_rooted_base_side_leveled.png | Bin 0 -> 127 bytes ...plantlike_rooted_base_side_meshoptions.png | Bin 0 -> 128 bytes ...plantlike_rooted_base_side_wallmounted.png | Bin 0 -> 143 bytes ...odes_plantlike_rooted_base_side_waving.png | Bin 0 -> 126 bytes .../testnodes_plantlike_rooted_degrotate.png | Bin 0 -> 176 bytes .../testnodes_plantlike_rooted_leveled.png | Bin 0 -> 162 bytes ...testnodes_plantlike_rooted_meshoptions.png | Bin 0 -> 162 bytes ...testnodes_plantlike_rooted_wallmounted.png | Bin 0 -> 160 bytes .../testnodes_plantlike_rooted_waving.png | Bin 0 -> 125 bytes .../testnodes_plantlike_wallmounted.png | Bin 0 -> 162 bytes .../textures/testnodes_plantlike_waving.png | Bin 0 -> 127 bytes .../textures/testnodes_pointable.png | Bin 0 -> 144 bytes ...stnodes_post_effect_color_shaded_false.png | Bin 0 -> 107 bytes ...estnodes_post_effect_color_shaded_true.png | Bin 0 -> 105 bytes .../textures/testnodes_rail2_crossing.png | Bin 0 -> 246 bytes .../textures/testnodes_rail2_curved.png | Bin 0 -> 253 bytes .../textures/testnodes_rail2_straight.png | Bin 0 -> 246 bytes .../textures/testnodes_rail2_t_junction.png | Bin 0 -> 254 bytes .../textures/testnodes_rail_crossing.png | Bin 0 -> 151 bytes .../textures/testnodes_rail_curved.png | Bin 0 -> 164 bytes .../textures/testnodes_rail_straight.png | Bin 0 -> 133 bytes .../textures/testnodes_rail_t_junction.png | Bin 0 -> 202 bytes .../testnodes/textures/testnodes_sign3d.png | Bin 0 -> 214 bytes .../testnodes/textures/testnodes_signlike.png | Bin 0 -> 150 bytes .../testnodes/textures/testnodes_slippery.png | Bin 0 -> 111 bytes .../textures/testnodes_street_crossing.png | Bin 0 -> 137 bytes .../textures/testnodes_street_curved.png | Bin 0 -> 115 bytes .../textures/testnodes_street_straight.png | Bin 0 -> 101 bytes .../textures/testnodes_street_t_junction.png | Bin 0 -> 126 bytes .../textures/testnodes_sunlight_filter.png | Bin 0 -> 113 bytes .../testnodes_tga_type10_32bpp_bt.tga | Bin 0 -> 179 bytes .../testnodes_tga_type10_32bpp_tb.tga | Bin 0 -> 179 bytes .../textures/testnodes_tga_type1_24bpp_bt.tga | Bin 0 -> 120 bytes .../textures/testnodes_tga_type1_24bpp_tb.tga | Bin 0 -> 120 bytes .../textures/testnodes_tga_type2_16bpp_bt.tga | Bin 0 -> 172 bytes .../textures/testnodes_tga_type2_16bpp_tb.tga | Bin 0 -> 172 bytes .../textures/testnodes_tga_type2_32bpp_bt.tga | Bin 0 -> 300 bytes .../textures/testnodes_tga_type2_32bpp_tb.tga | Bin 0 -> 300 bytes .../textures/testnodes_tga_type3_16bpp_bt.tga | Bin 0 -> 172 bytes .../textures/testnodes_tga_type3_16bpp_tb.tga | Bin 0 -> 172 bytes .../textures/testnodes_torchlike_ceiling.png | Bin 0 -> 157 bytes .../textures/testnodes_torchlike_floor.png | Bin 0 -> 141 bytes .../textures/testnodes_torchlike_wall.png | Bin 0 -> 158 bytes .../garage/mods/testpathfinder/README.md | 15 + .../games/garage/mods/testpathfinder/init.lua | 136 + .../games/garage/mods/testpathfinder/mod.conf | 2 + .../testpathfinder_testpathfinder.png | Bin 0 -> 159 bytes .../textures/testpathfinder_waypoint.png | Bin 0 -> 99 bytes .../textures/testpathfinder_waypoint_end.png | Bin 0 -> 147 bytes .../testpathfinder_waypoint_start.png | Bin 0 -> 139 bytes data/games/garage/mods/testtools/README.md | 154 + data/games/garage/mods/testtools/init.lua | 1067 +++++ data/games/garage/mods/testtools/light.lua | 37 + data/games/garage/mods/testtools/mod.conf | 2 + .../mods/testtools/node_box_visualizer.lua | 79 + .../games/garage/mods/testtools/particles.lua | 36 + .../garage/mods/testtools/privatizer.lua | 29 + .../testtools_blocked_pointing_staff.png | Bin 0 -> 136 bytes .../textures/testtools_branding_iron.png | Bin 0 -> 117 bytes .../textures/testtools_children_getter.png | Bin 0 -> 159 bytes .../textures/testtools_entity_rotator.png | Bin 0 -> 151 bytes .../textures/testtools_entity_scaler.png | Bin 0 -> 182 bytes .../textures/testtools_entity_spawner.png | Bin 0 -> 189 bytes .../textures/testtools_falling_node_tool.png | Bin 0 -> 140 bytes .../textures/testtools_item_meta_editor.png | Bin 0 -> 114 bytes .../textures/testtools_lighttool.png | Bin 0 -> 167 bytes .../testtools_node_box_visualizer.png | Bin 0 -> 108 bytes .../textures/testtools_node_meta_editor.png | Bin 0 -> 135 bytes .../textures/testtools_node_setter.png | Bin 0 -> 146 bytes .../textures/testtools_object_attacher.png | Bin 0 -> 173 bytes .../textures/testtools_object_editor.png | Bin 0 -> 180 bytes .../textures/testtools_object_mover.png | Bin 0 -> 175 bytes .../textures/testtools_param2tool.png | Bin 0 -> 127 bytes .../textures/testtools_particle_sheet.png | Bin 0 -> 208 bytes .../textures/testtools_particle_spawner.png | Bin 0 -> 121 bytes .../textures/testtools_particle_vertical.png | Bin 0 -> 308 bytes .../textures/testtools_privatizer.png | Bin 0 -> 115 bytes .../testtools/textures/testtools_remover.png | Bin 0 -> 129 bytes .../testtools_ultimate_pointing_staff.png | Bin 0 -> 136 bytes .../testtools_visual_collision_box.png | Bin 0 -> 119 bytes .../textures/testtools_visual_node_box.png | Bin 0 -> 124 bytes .../testtools_visual_selection_box.png | Bin 0 -> 121 bytes .../garage/mods/testtranslations/init.lua | 26 + .../locale/testtranslations.fr.po | 9 + .../locale/translation_mo.fr.mo | Bin 0 -> 494 bytes .../locale/translation_po.fr.po | 22 + .../locale/translation_tr.fr.tr | 2 + .../garage/mods/testtranslations/mod.conf | 3 + .../testtranslations/test_locale/readme.txt | 4 + .../test_locale/translation_mo.de.mo | Bin 0 -> 446 bytes .../test_locale/translation_po.de.po | 42 + .../testtranslations/translation_mo.de.po | 26 + .../testtranslations/translation_mo.fr.po | 18 + data/games/garage/mods/tiled/init.lua | 50 + data/games/garage/mods/tiled/mod.conf | 3 + .../mods/tiled/textures/tiled_tiled.png | Bin 0 -> 410 bytes .../mods/tiled/textures/tiled_tiled_node.png | Bin 0 -> 249 bytes .../games/garage/mods/unittests/async_env.lua | 209 + data/games/garage/mods/unittests/color.lua | 17 + .../garage/mods/unittests/content_ids.lua | 37 + data/games/garage/mods/unittests/crafting.lua | 112 + .../mods/unittests/crafting_prepare.lua | 94 + data/games/garage/mods/unittests/entity.lua | 236 ++ .../garage/mods/unittests/get_version.lua | 16 + data/games/garage/mods/unittests/init.lua | 235 ++ .../mods/unittests/inside_async_env.lua | 35 + .../mods/unittests/inside_mapgen_env.lua | 34 + .../games/garage/mods/unittests/inventory.lua | 73 + .../garage/mods/unittests/itemdescription.lua | 43 + .../mods/unittests/itemstack_equals.lua | 74 + .../games/garage/mods/unittests/load_time.lua | 13 + data/games/garage/mods/unittests/metadata.lua | 121 + data/games/garage/mods/unittests/misc.lua | 332 ++ data/games/garage/mods/unittests/mod.conf | 4 + .../garage/mods/unittests/on_shutdown.lua | 22 + data/games/garage/mods/unittests/player.lua | 206 + data/games/garage/mods/unittests/raycast.lua | 36 + .../mods/unittests/textures/default_dirt.png | Bin 0 -> 790 bytes .../unittests/textures/unittests_callback.png | Bin 0 -> 157 bytes .../textures/unittests_coal_lump.png | Bin 0 -> 160 bytes .../textures/unittests_description_test.png | Bin 0 -> 209 bytes .../textures/unittests_iron_lump.png | Bin 0 -> 154 bytes .../textures/unittests_repairable_tool.png | Bin 0 -> 160 bytes .../textures/unittests_steel_ingot.png | Bin 0 -> 159 bytes .../unittests/textures/unittests_stick.png | Bin 0 -> 147 bytes .../unittests/textures/unittests_torch.png | Bin 0 -> 155 bytes .../textures/unittests_unrepairable_tool.png | Bin 0 -> 157 bytes data/games/garage/mods/util_commands/init.lua | 243 ++ data/games/garage/mods/util_commands/mod.conf | 2 + data/games/garage/screenshot.png | Bin 0 -> 133364 bytes data/games/garage/settingtypes.txt | 32 + docker-compose.yml | 15 + 590 files changed, 19973 insertions(+) create mode 100644 README.md create mode 100644 conf/minetest.conf create mode 100644 data/games/garage/LICENSE.txt create mode 100644 data/games/garage/README.md create mode 100644 data/games/garage/game.conf create mode 100644 data/games/garage/menu/background.png create mode 100644 data/games/garage/menu/header.png create mode 100644 data/games/garage/menu/icon.png create mode 100644 data/games/garage/mods/basenodes/init.lua create mode 100644 data/games/garage/mods/basenodes/mod.conf create mode 100644 data/games/garage/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png create mode 100644 data/games/garage/mods/basenodes/textures/basenodes_dirt_with_snow.png create mode 100644 data/games/garage/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png create mode 100644 data/games/garage/mods/basenodes/textures/basenodes_snow_sheet.png create mode 100644 data/games/garage/mods/basenodes/textures/default_apple.png create mode 100644 data/games/garage/mods/basenodes/textures/default_cobble.png create mode 100644 data/games/garage/mods/basenodes/textures/default_desert_sand.png create mode 100644 data/games/garage/mods/basenodes/textures/default_desert_stone.png create mode 100644 data/games/garage/mods/basenodes/textures/default_dirt.png create mode 100644 data/games/garage/mods/basenodes/textures/default_grass.png create mode 100644 data/games/garage/mods/basenodes/textures/default_gravel.png create mode 100644 data/games/garage/mods/basenodes/textures/default_ice.png create mode 100644 data/games/garage/mods/basenodes/textures/default_junglegrass.png create mode 100644 data/games/garage/mods/basenodes/textures/default_jungleleaves.png create mode 100644 data/games/garage/mods/basenodes/textures/default_jungletree.png create mode 100644 data/games/garage/mods/basenodes/textures/default_jungletree_top.png create mode 100644 data/games/garage/mods/basenodes/textures/default_lava.png create mode 100644 data/games/garage/mods/basenodes/textures/default_lava_flowing.png create mode 100644 data/games/garage/mods/basenodes/textures/default_leaves.png create mode 100644 data/games/garage/mods/basenodes/textures/default_mossycobble.png create mode 100644 data/games/garage/mods/basenodes/textures/default_pine_needles.png create mode 100644 data/games/garage/mods/basenodes/textures/default_pine_tree.png create mode 100644 data/games/garage/mods/basenodes/textures/default_pine_tree_top.png create mode 100644 data/games/garage/mods/basenodes/textures/default_river_water.png create mode 100644 data/games/garage/mods/basenodes/textures/default_river_water_flowing.png create mode 100644 data/games/garage/mods/basenodes/textures/default_sand.png create mode 100644 data/games/garage/mods/basenodes/textures/default_snow.png create mode 100644 data/games/garage/mods/basenodes/textures/default_snow_side.png create mode 100644 data/games/garage/mods/basenodes/textures/default_stone.png create mode 100644 data/games/garage/mods/basenodes/textures/default_tree.png create mode 100644 data/games/garage/mods/basenodes/textures/default_tree_top.png create mode 100644 data/games/garage/mods/basenodes/textures/default_water.png create mode 100644 data/games/garage/mods/basenodes/textures/default_water_flowing.png create mode 100644 data/games/garage/mods/basenodes/textures/dirt_with_grass/default_grass.png create mode 100644 data/games/garage/mods/basenodes/textures/dirt_with_grass/default_grass_side.png create mode 100644 data/games/garage/mods/basenodes/textures/info.txt create mode 100644 data/games/garage/mods/basetools/init.lua create mode 100644 data/games/garage/mods/basetools/mod.conf create mode 100644 data/games/garage/mods/basetools/textures/basetools_bloodsword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_elementalsword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_firesword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_healdagger.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_healsword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_icesword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_mesepick.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_mesepick_no_delay.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_mesesword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_steelaxe.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_steeldagger.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_steelpick.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_steelpick_l1.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_steelpick_l2.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_steelshears.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_steelshovel.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_steelsword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_stoneaxe.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_stonepick.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_stoneshears.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_stoneshovel.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_stonesword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_superhealsword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_titaniumsword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_usespick.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_usessword.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_woodaxe.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_wooddagger.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_woodpick.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_woodshears.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_woodshovel.png create mode 100644 data/games/garage/mods/basetools/textures/basetools_woodsword.png create mode 100644 data/games/garage/mods/benchmarks/init.lua create mode 100644 data/games/garage/mods/benchmarks/mod.conf create mode 100644 data/games/garage/mods/broken/init.lua create mode 100644 data/games/garage/mods/broken/mod.conf create mode 100644 data/games/garage/mods/bucket/init.lua create mode 100644 data/games/garage/mods/bucket/mod.conf create mode 100644 data/games/garage/mods/bucket/textures/bucket.png create mode 100644 data/games/garage/mods/bucket/textures/bucket_lava.png create mode 100644 data/games/garage/mods/bucket/textures/bucket_water.png create mode 100644 data/games/garage/mods/callbacks/entities.lua create mode 100644 data/games/garage/mods/callbacks/init.lua create mode 100644 data/games/garage/mods/callbacks/items.lua create mode 100644 data/games/garage/mods/callbacks/mod.conf create mode 100644 data/games/garage/mods/callbacks/nodes.lua create mode 100644 data/games/garage/mods/callbacks/players.lua create mode 100644 data/games/garage/mods/callbacks/textures/callbacks_callback_entity.png create mode 100644 data/games/garage/mods/callbacks/textures/callbacks_callback_entity_step.png create mode 100644 data/games/garage/mods/callbacks/textures/callbacks_callback_item_1.png create mode 100644 data/games/garage/mods/callbacks/textures/callbacks_callback_item_2.png create mode 100644 data/games/garage/mods/callbacks/textures/callbacks_callback_node.png create mode 100644 data/games/garage/mods/chest/chest.lua create mode 100644 data/games/garage/mods/chest/detached.lua create mode 100644 data/games/garage/mods/chest/init.lua create mode 100644 data/games/garage/mods/chest/mod.conf create mode 100644 data/games/garage/mods/chest/textures/chest_chest.png create mode 100644 data/games/garage/mods/chest/textures/chest_detached_chest.png create mode 100644 data/games/garage/mods/chest_of_everything/init.lua create mode 100644 data/games/garage/mods/chest_of_everything/mod.conf create mode 100644 data/games/garage/mods/chest_of_everything/textures/chest_of_everything_bag.png create mode 100644 data/games/garage/mods/chest_of_everything/textures/chest_of_everything_chest.png create mode 100644 data/games/garage/mods/dignodes/init.lua create mode 100644 data/games/garage/mods/dignodes/mod.conf create mode 100644 data/games/garage/mods/dignodes/textures/dignodes_choppy.png create mode 100644 data/games/garage/mods/dignodes/textures/dignodes_cracky.png create mode 100644 data/games/garage/mods/dignodes/textures/dignodes_crumbly.png create mode 100644 data/games/garage/mods/dignodes/textures/dignodes_dig_immediate.png create mode 100644 data/games/garage/mods/dignodes/textures/dignodes_none.png create mode 100644 data/games/garage/mods/dignodes/textures/dignodes_rating1.png create mode 100644 data/games/garage/mods/dignodes/textures/dignodes_rating2.png create mode 100644 data/games/garage/mods/dignodes/textures/dignodes_rating3.png create mode 100644 data/games/garage/mods/first_mod/init.lua create mode 100644 data/games/garage/mods/first_mod/mod.conf create mode 100644 data/games/garage/mods/give_initial_stuff/init.lua create mode 100644 data/games/garage/mods/give_initial_stuff/mod.conf create mode 100644 data/games/garage/mods/gltf/LICENSE.md create mode 100644 data/games/garage/mods/gltf/init.lua create mode 100644 data/games/garage/mods/gltf/invalid/empty.gltf create mode 100644 data/games/garage/mods/gltf/invalid/invalid_bufferview_bounds.gltf create mode 100644 data/games/garage/mods/gltf/invalid/json_missing_brace.gltf create mode 100644 data/games/garage/mods/gltf/mod.conf create mode 100644 data/games/garage/mods/gltf/models/gltf_blender_cube.glb create mode 100644 data/games/garage/mods/gltf/models/gltf_blender_cube.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_blender_cube_matrix_transform.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_blender_cube_scaled.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_frog.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_minimal_triangle.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_simple_skin.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_simple_sparse_accessor.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_snow_man.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_spider.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_spider_animated.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_triangle_with_vertex_stride.gltf create mode 100644 data/games/garage/mods/gltf/models/gltf_triangle_without_indices.gltf create mode 100644 data/games/garage/mods/gltf/textures/gltf_cube.png create mode 100644 data/games/garage/mods/gltf/textures/gltf_frog.png create mode 100644 data/games/garage/mods/gltf/textures/gltf_snow_man.png create mode 100644 data/games/garage/mods/gltf/textures/gltf_spider.png create mode 100644 data/games/garage/mods/initial_message/init.lua create mode 100644 data/games/garage/mods/initial_message/mod.conf create mode 100644 data/games/garage/mods/last_mod/init.lua create mode 100644 data/games/garage/mods/last_mod/mod.conf create mode 100644 data/games/garage/mods/lighting/init.lua create mode 100644 data/games/garage/mods/lighting/mod.conf create mode 100644 data/games/garage/mods/log/init.lua create mode 100644 data/games/garage/mods/log/mod.conf create mode 100644 data/games/garage/mods/mapgen/init.lua create mode 100644 data/games/garage/mods/mapgen/mod.conf create mode 100644 data/games/garage/mods/modchannels/init.lua create mode 100644 data/games/garage/mods/modchannels/mod.conf create mode 100644 data/games/garage/mods/soundstuff/bigfoot.lua create mode 100644 data/games/garage/mods/soundstuff/init.lua create mode 100644 data/games/garage/mods/soundstuff/jukebox.lua create mode 100644 data/games/garage/mods/soundstuff/mod.conf create mode 100644 data/games/garage/mods/soundstuff/racecar.lua create mode 100644 data/games/garage/mods/soundstuff/sound_event_items.lua create mode 100644 data/games/garage/mods/soundstuff/sounds/gitignored_sounds/custom_sounds_here.txt create mode 100644 data/games/garage/mods/soundstuff/sounds/soundstuff_mono.ogg create mode 100644 data/games/garage/mods/soundstuff/sounds/soundstuff_sinus.ogg create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_bigfoot.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_eat.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_jukebox.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_blank.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_climbable.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_dig.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_dug.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_fall.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_footstep.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_place.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_place_failed.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_node_sound.png create mode 100644 data/games/garage/mods/soundstuff/textures/soundstuff_racecar.png create mode 100644 data/games/garage/mods/stairs/init.lua create mode 100644 data/games/garage/mods/stairs/mod.conf create mode 100644 data/games/garage/mods/testabms/README.md create mode 100644 data/games/garage/mods/testabms/after_node.lua create mode 100644 data/games/garage/mods/testabms/chances.lua create mode 100644 data/games/garage/mods/testabms/init.lua create mode 100644 data/games/garage/mods/testabms/intervals.lua create mode 100644 data/games/garage/mods/testabms/min_max.lua create mode 100644 data/games/garage/mods/testabms/mod.conf create mode 100644 data/games/garage/mods/testabms/neighbors.lua create mode 100644 data/games/garage/mods/testabms/textures/testabms_after_node.png create mode 100644 data/games/garage/mods/testabms/textures/testabms_wait_node.png create mode 100644 data/games/garage/mods/testentities/armor.lua create mode 100644 data/games/garage/mods/testentities/init.lua create mode 100644 data/games/garage/mods/testentities/mod.conf create mode 100644 data/games/garage/mods/testentities/models/LICENSE.txt create mode 100644 data/games/garage/mods/testentities/models/testentities_sam.b3d create mode 100644 data/games/garage/mods/testentities/models/testentities_sam.png create mode 100644 data/games/garage/mods/testentities/observers.lua create mode 100644 data/games/garage/mods/testentities/pointable.lua create mode 100644 data/games/garage/mods/testentities/selectionbox.lua create mode 100644 data/games/garage/mods/testentities/textures/testentities_armorball.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_cube1.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_cube2.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_cube3.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_cube4.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_cube5.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_cube6.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_dungeon_master.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_sprite.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_upright_sprite1.png create mode 100644 data/games/garage/mods/testentities/textures/testentities_upright_sprite2.png create mode 100644 data/games/garage/mods/testentities/visuals.lua create mode 100644 data/games/garage/mods/testfood/init.lua create mode 100644 data/games/garage/mods/testfood/mod.conf create mode 100644 data/games/garage/mods/testfood/textures/testfood_bad.png create mode 100644 data/games/garage/mods/testfood/textures/testfood_bad2.png create mode 100644 data/games/garage/mods/testfood/textures/testfood_good.png create mode 100644 data/games/garage/mods/testfood/textures/testfood_good2.png create mode 100644 data/games/garage/mods/testfood/textures/testfood_replace.png create mode 100644 data/games/garage/mods/testformspec/LICENSE.txt create mode 100644 data/games/garage/mods/testformspec/callbacks.lua create mode 100644 data/games/garage/mods/testformspec/dummy_items.lua create mode 100644 data/games/garage/mods/testformspec/formspec.lua create mode 100644 data/games/garage/mods/testformspec/init.lua create mode 100644 data/games/garage/mods/testformspec/mod.conf create mode 100644 data/games/garage/mods/testformspec/models/testformspec_character.b3d create mode 100644 data/games/garage/mods/testformspec/models/testformspec_chest.obj create mode 100644 data/games/garage/mods/testformspec/textures/default_chest_front.png create mode 100644 data/games/garage/mods/testformspec/textures/default_chest_inside.png create mode 100644 data/games/garage/mods/testformspec/textures/default_chest_side.png create mode 100644 data/games/garage/mods/testformspec/textures/default_chest_top.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_9slice.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_animation.jpg create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_animation.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_bg.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_bg_9slice.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_bg_9slice_focused.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_bg_9slice_hovered.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_bg_9slice_pressed.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_bg_focused.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_bg_hovered.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_bg_pressed.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_button_image.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_character.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_hovered.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_item.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_node.png create mode 100644 data/games/garage/mods/testformspec/textures/testformspec_pressed.png create mode 100644 data/games/garage/mods/testfullscreenfs/init.lua create mode 100644 data/games/garage/mods/testfullscreenfs/mod.conf create mode 100644 data/games/garage/mods/testhud/init.lua create mode 100644 data/games/garage/mods/testhud/mod.conf create mode 100644 data/games/garage/mods/testhud/textures/testhud_waypoint.png create mode 100644 data/games/garage/mods/testitems/init.lua create mode 100644 data/games/garage/mods/testitems/mod.conf create mode 100644 data/games/garage/mods/testitems/textures/testitems_overlay_base.png create mode 100644 data/games/garage/mods/testitems/textures/testitems_overlay_overlay.png create mode 100644 data/games/garage/mods/testitems/textures/testitems_overridden.png create mode 100644 data/games/garage/mods/testitems/textures/testitems_telescope_stick.png create mode 100644 data/games/garage/mods/testnodes/README.md create mode 100644 data/games/garage/mods/testnodes/commands.lua create mode 100644 data/games/garage/mods/testnodes/drawtypes.lua create mode 100644 data/games/garage/mods/testnodes/init.lua create mode 100644 data/games/garage/mods/testnodes/light.lua create mode 100644 data/games/garage/mods/testnodes/liquids.lua create mode 100644 data/games/garage/mods/testnodes/meshes.lua create mode 100644 data/games/garage/mods/testnodes/mod.conf create mode 100644 data/games/garage/mods/testnodes/models/testnodes_marble_glass.obj create mode 100644 data/games/garage/mods/testnodes/models/testnodes_marble_metal.obj create mode 100644 data/games/garage/mods/testnodes/models/testnodes_ocorner.obj create mode 100644 data/games/garage/mods/testnodes/models/testnodes_pyramid.obj create mode 100644 data/games/garage/mods/testnodes/nodeboxes.lua create mode 100644 data/games/garage/mods/testnodes/overlays.lua create mode 100644 data/games/garage/mods/testnodes/param2.lua create mode 100644 data/games/garage/mods/testnodes/performance_test_nodes.lua create mode 100644 data/games/garage/mods/testnodes/properties.lua create mode 100644 data/games/garage/mods/testnodes/textures.lua create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_1.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_128x128_rgb.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_1f.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_1fg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_1g.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_1w.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_1wg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_2.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_2f.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_2fg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_2g.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_2w.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_2wg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_3.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_3f.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_3fg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_3g.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_3w.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_3wg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_4.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_4f.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_4fg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_4g.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_4w.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_4wg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_5.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_5f.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_5fg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_5g.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_5w.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_5wg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_6.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_6f.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_6fg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_6g.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_6w.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_6wg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_airlike.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_allfaces.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_allfaces_optional.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_alpha.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_alpha128.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_alpha191.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_alpha64.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_alpha_compositing_bottom.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_alpha_compositing_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_anim.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attached4_bottom.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attached4_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attached4_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attached_bottom.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attached_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attached_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedf_bottom.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedf_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedf_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedfr_bottom.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedfr_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedfr_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedw_bottom.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedw_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedw_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedwr_bottom.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedwr_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_attachedwr_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_blocking_pointable.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_bouncy.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_buildable_to.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_noclimb_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_noclimb_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_nodescend_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_nodescend_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_nojump_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_nojump_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_resistance_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_climbable_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_damage.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_damage_neg.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_drowning.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_fall_damage_minus.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_fall_damage_plus.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_fencelike.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_fill_positioning_reference.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_firelike.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_glasslike.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_glasslike_detail.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_glasslike_framed.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_glasslike_framed2.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_glasslike_framed_optional.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_glasslikeliquid.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_1.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_10.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_11.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_12.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_13.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_14.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_2.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_3.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_4.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_5.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_6.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_7.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_8.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_light_9.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_line_crossing.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_line_curved.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_line_straight.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_line_t_junction.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquid.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r0.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r1.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r2.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r3.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r4.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r5.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r6.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r7.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r8.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r0.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r1.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r2.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r3.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r4.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r5.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r6.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r7.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r8.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_marble_glass.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_marble_metal.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_marble_metal_overlay.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mask_WRGBKW.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes10.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes2.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes3.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes4.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes5.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes6.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes7.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes8.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes9.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_move_resistance.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_node.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_node_falling.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_node_falling_1.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_node_falling_2.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_node_falling_3.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_node_falling_4.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_node_falling_5.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_node_falling_6.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_nodebox.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_nojump_side.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_nojump_top.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_normal.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_normal1.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_normal2.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_normal3.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_normal4.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_normal5.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_normal6.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_not_pointable.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_overlay.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_overlayable.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_palette_4dir.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_palette_facedir.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_palette_full.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_palette_metal.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_palette_wallmounted.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_degrotate.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_leveled.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_meshoptions.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_leveled.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_wallmounted.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_waving.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_meshoptions.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_waving.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_wallmounted.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_plantlike_waving.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_pointable.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_post_effect_color_shaded_false.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_post_effect_color_shaded_true.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_rail2_crossing.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_rail2_curved.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_rail2_straight.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_rail2_t_junction.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_rail_crossing.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_rail_curved.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_rail_straight.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_rail_t_junction.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_sign3d.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_signlike.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_slippery.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_street_crossing.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_street_curved.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_street_straight.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_street_t_junction.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_sunlight_filter.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type1_24bpp_bt.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type1_24bpp_tb.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type2_16bpp_tb.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type2_32bpp_bt.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type3_16bpp_bt.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_tga_type3_16bpp_tb.tga create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_torchlike_ceiling.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_torchlike_floor.png create mode 100644 data/games/garage/mods/testnodes/textures/testnodes_torchlike_wall.png create mode 100644 data/games/garage/mods/testpathfinder/README.md create mode 100644 data/games/garage/mods/testpathfinder/init.lua create mode 100644 data/games/garage/mods/testpathfinder/mod.conf create mode 100644 data/games/garage/mods/testpathfinder/textures/testpathfinder_testpathfinder.png create mode 100644 data/games/garage/mods/testpathfinder/textures/testpathfinder_waypoint.png create mode 100644 data/games/garage/mods/testpathfinder/textures/testpathfinder_waypoint_end.png create mode 100644 data/games/garage/mods/testpathfinder/textures/testpathfinder_waypoint_start.png create mode 100644 data/games/garage/mods/testtools/README.md create mode 100644 data/games/garage/mods/testtools/init.lua create mode 100644 data/games/garage/mods/testtools/light.lua create mode 100644 data/games/garage/mods/testtools/mod.conf create mode 100644 data/games/garage/mods/testtools/node_box_visualizer.lua create mode 100644 data/games/garage/mods/testtools/particles.lua create mode 100644 data/games/garage/mods/testtools/privatizer.lua create mode 100644 data/games/garage/mods/testtools/textures/testtools_blocked_pointing_staff.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_branding_iron.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_children_getter.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_entity_rotator.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_entity_scaler.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_entity_spawner.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_falling_node_tool.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_item_meta_editor.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_lighttool.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_node_box_visualizer.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_node_meta_editor.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_node_setter.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_object_attacher.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_object_editor.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_object_mover.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_param2tool.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_particle_sheet.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_particle_spawner.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_particle_vertical.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_privatizer.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_remover.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_ultimate_pointing_staff.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_visual_collision_box.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_visual_node_box.png create mode 100644 data/games/garage/mods/testtools/textures/testtools_visual_selection_box.png create mode 100644 data/games/garage/mods/testtranslations/init.lua create mode 100644 data/games/garage/mods/testtranslations/locale/testtranslations.fr.po create mode 100644 data/games/garage/mods/testtranslations/locale/translation_mo.fr.mo create mode 100644 data/games/garage/mods/testtranslations/locale/translation_po.fr.po create mode 100644 data/games/garage/mods/testtranslations/locale/translation_tr.fr.tr create mode 100644 data/games/garage/mods/testtranslations/mod.conf create mode 100644 data/games/garage/mods/testtranslations/test_locale/readme.txt create mode 100644 data/games/garage/mods/testtranslations/test_locale/translation_mo.de.mo create mode 100644 data/games/garage/mods/testtranslations/test_locale/translation_po.de.po create mode 100644 data/games/garage/mods/testtranslations/translation_mo.de.po create mode 100644 data/games/garage/mods/testtranslations/translation_mo.fr.po create mode 100644 data/games/garage/mods/tiled/init.lua create mode 100644 data/games/garage/mods/tiled/mod.conf create mode 100644 data/games/garage/mods/tiled/textures/tiled_tiled.png create mode 100644 data/games/garage/mods/tiled/textures/tiled_tiled_node.png create mode 100644 data/games/garage/mods/unittests/async_env.lua create mode 100644 data/games/garage/mods/unittests/color.lua create mode 100644 data/games/garage/mods/unittests/content_ids.lua create mode 100644 data/games/garage/mods/unittests/crafting.lua create mode 100644 data/games/garage/mods/unittests/crafting_prepare.lua create mode 100644 data/games/garage/mods/unittests/entity.lua create mode 100644 data/games/garage/mods/unittests/get_version.lua create mode 100644 data/games/garage/mods/unittests/init.lua create mode 100644 data/games/garage/mods/unittests/inside_async_env.lua create mode 100644 data/games/garage/mods/unittests/inside_mapgen_env.lua create mode 100644 data/games/garage/mods/unittests/inventory.lua create mode 100644 data/games/garage/mods/unittests/itemdescription.lua create mode 100644 data/games/garage/mods/unittests/itemstack_equals.lua create mode 100644 data/games/garage/mods/unittests/load_time.lua create mode 100644 data/games/garage/mods/unittests/metadata.lua create mode 100644 data/games/garage/mods/unittests/misc.lua create mode 100644 data/games/garage/mods/unittests/mod.conf create mode 100644 data/games/garage/mods/unittests/on_shutdown.lua create mode 100644 data/games/garage/mods/unittests/player.lua create mode 100644 data/games/garage/mods/unittests/raycast.lua create mode 100644 data/games/garage/mods/unittests/textures/default_dirt.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_callback.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_coal_lump.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_description_test.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_iron_lump.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_repairable_tool.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_steel_ingot.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_stick.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_torch.png create mode 100644 data/games/garage/mods/unittests/textures/unittests_unrepairable_tool.png create mode 100644 data/games/garage/mods/util_commands/init.lua create mode 100644 data/games/garage/mods/util_commands/mod.conf create mode 100644 data/games/garage/screenshot.png create mode 100644 data/games/garage/settingtypes.txt create mode 100644 docker-compose.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..02fd0e1 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# MINETEST SERVER + +## PRE REQUIS + +- docker + +### DEPLOYER LOCALEMENT + +```bash + +``` + +### DEPLOYER SUR INTERNET + +```bash + +``` \ No newline at end of file diff --git a/conf/minetest.conf b/conf/minetest.conf new file mode 100644 index 0000000..e34711f --- /dev/null +++ b/conf/minetest.conf @@ -0,0 +1,3497 @@ +# NAME + MOTD (MESSAGE D'ENTREE) +server_name = "Minetest Garage" +server_description = "Minetest server du Garage!" +motd = Bienvenue sur les serveur Minetest du Garage Enjoy! + +# password +# type: string +default_password = LeGarage + +# ADMIN +name = garage + +# MSG +kick_msg_shutdown = "Le serveur du Garage ferme!" +kick_msg_crash = "Le serveur a crasher... sorry!" + +# A CHANGER ( TOUT LE MONDE AVEC GOD MODE) +default_privs = admin + +# AU CAS OU! +enable_rollback_recording = true + +# Server / Singleplayer +# + +# Name of the server, to be displayed when players join and in the serverlist. +# type: string +# server_name = Minetest server + +# Description of server, to be displayed when players join and in the serverlist. +# type: string +# server_description = mine here + +# Domain name of server, to be displayed in the serverlist. +# type: string +# server_address = game.minetest.net + +# Homepage of server, to be displayed in the serverlist. +# type: string +# server_url = https://minetest.net + +# Automatically report to the serverlist. +# type: bool +# server_announce = false + +# Announce to this serverlist. +# type: string +# serverlist_url = servers.minetest.net + +# Remove color codes from incoming chat messages +# Use this to stop players from being able to use color in their messages +# type: bool +# strip_color_codes = false + +## Network + +# Network port to listen (UDP). +# This value will be overridden when starting from the main menu. +# type: int +# port = 30000 + +# The network interface that the server listens on. +# type: string +# bind_address = + +# Enable to disallow old clients from connecting. +# Older clients are compatible in the sense that they will not crash when connecting +# to new servers, but they may not support all new features that you are expecting. +# type: bool +# strict_protocol_version_checking = false + +# Specifies URL from which client fetches media instead of using UDP. +# $filename should be accessible from $remote_media$filename via cURL +# (obviously, remote_media should end with a slash). +# Files that are not present will be fetched the usual way. +# type: string +# remote_media = + +# Enable/disable running an IPv6 server. +# Ignored if bind_address is set. +# Needs enable_ipv6 to be enabled. +# type: bool +# ipv6_server = false + +### Advanced + +# Maximum number of blocks that are simultaneously sent per client. +# The maximum total count is calculated dynamically: +# max_total = ceil((#clients + max_users) * per_client / 4) +# type: int +# max_simultaneous_block_sends_per_client = 40 + +# To reduce lag, block transfers are slowed down when a player is building something. +# This determines how long they are slowed down after placing or removing a node. +# type: float +# full_block_send_enable_min_time_from_building = 2.0 + +# Maximum number of packets sent per send step, if you have a slow connection +# try reducing it, but don't reduce it to a number below double of targeted +# client number. +# type: int +# max_packets_per_iteration = 1024 + +# Compression level to use when sending mapblocks to the client. +# -1 - use default compression level +# 0 - least compression, fastest +# 9 - best compression, slowest +# type: int min: -1 max: 9 +# map_compression_level_net = -1 + +## Game + +# Default game when creating a new world. +# This will be overridden when creating a world from the main menu. +# type: string +# default_game = garage + +# Message of the day displayed to players connecting. +# type: string +# motd = + +# Maximum number of players that can be connected simultaneously. +# type: int +# max_users = 15 + +# World directory (everything in the world is stored here). +# Not needed if starting from the main menu. +# type: path +# map-dir = + +# Time in seconds for item entity (dropped items) to live. +# Setting it to -1 disables the feature. +# type: int +# item_entity_ttl = 900 + +# Specifies the default stack size of nodes, items and tools. +# Note that mods or games may explicitly set a stack for certain (or all) items. +# type: int +# default_stack_max = 99 + +# Enable players getting damage and dying. +# type: bool +# enable_damage = false + +# Enable creative mode for all players +# type: bool +# creative_mode = false + +# A chosen map seed for a new map, leave empty for random. +# Will be overridden when creating a new world in the main menu. +# type: string +# fixed_map_seed = + +# New users need to input this password. +# type: string +# default_password = + +# The privileges that new users automatically get. +# See /privs in game for a full list on your server and mod configuration. +# type: string +# default_privs = interact, shout + +# Privileges that players with basic_privs can grant +# type: string +# basic_privs = interact, shout + +# Whether players are shown to clients without any range limit. +# Deprecated, use the setting player_transfer_distance instead. +# type: bool +# unlimited_player_transfer_distance = true + +# Defines the maximal player transfer distance in blocks (0 = unlimited). +# type: int +# player_transfer_distance = 0 + +# Whether to allow players to damage and kill each other. +# type: bool +# enable_pvp = true + +# Enable mod channels support. +# type: bool +# enable_mod_channels = false + +# If this is set, players will always (re)spawn at the given position. +# type: string +# static_spawnpoint = + +# If enabled, new players cannot join with an empty password. +# type: bool +disallow_empty_password = true + +# If enabled, disable cheat prevention in multiplayer. +# type: bool +# disable_anticheat = false + +# If enabled, actions are recorded for rollback. +# This option is only read when server starts. +# type: bool +# enable_rollback_recording = false + +# Format of player chat messages. The following strings are valid placeholders: +# @name, @message, @timestamp (optional) +# type: string +# chat_message_format = <@name> @message + +# If the execution of a chat command takes longer than this specified time in +# seconds, add the time information to the chat command message +# type: float +# chatcommand_msg_time_threshold = 0.1 + +# A message to be displayed to all clients when the server shuts down. +# type: string +# kick_msg_shutdown = Server shutting down. + +# A message to be displayed to all clients when the server crashes. +# type: string +# kick_msg_crash = This server has experienced an internal error. You will now be disconnected. + +# Whether to ask clients to reconnect after a (Lua) crash. +# Set this to true if your server is set up to restart automatically. +# type: bool +# ask_reconnect_on_crash = false + +# From how far clients know about objects, stated in mapblocks (16 nodes). +# +# Setting this larger than active_block_range will also cause the server +# to maintain active objects up to this distance in the direction the +# player is looking. (This can avoid mobs suddenly disappearing from view) +# type: int +# active_object_send_range_blocks = 8 + +# The radius of the volume of blocks around every player that is subject to the +# active block stuff, stated in mapblocks (16 nodes). +# In active blocks objects are loaded and ABMs run. +# This is also the minimum range in which active objects (mobs) are maintained. +# This should be configured together with active_object_send_range_blocks. +# type: int +# active_block_range = 4 + +# From how far blocks are sent to clients, stated in mapblocks (16 nodes). +# type: int +# max_block_send_distance = 12 + +# Maximum number of forceloaded mapblocks. +# type: int +# max_forceloaded_blocks = 16 + +# Interval of sending time of day to clients. +# type: int +# time_send_interval = 5 + +# Controls length of day/night cycle. +# Examples: +# 72 = 20min, 360 = 4min, 1 = 24hour, 0 = day/night/whatever stays unchanged. +# type: int +# time_speed = 72 + +# Time of day when a new world is started, in millihours (0-23999). +# type: int min: 0 max: 23999 +# world_start_time = 6125 + +# Interval of saving important changes in the world, stated in seconds. +# type: float +# server_map_save_interval = 5.3 + +# Set the maximum character length of a chat message sent by clients. +# type: int +# chat_message_max_size = 500 + +# Amount of messages a player may send per 10 seconds. +# type: float +# chat_message_limit_per_10sec = 10.0 + +# Kick players who sent more than X messages per 10 seconds. +# type: int +# chat_message_limit_trigger_kick = 50 + +# DEFAULT CONF EXEMPLE: +# This file contains a list of all available settings and their default value for minetest.conf + +# By default, all the settings are commented and not functional. +# Uncomment settings by removing the preceding #. + +# minetest.conf is read by default from: +# ../minetest.conf +# ../../minetest.conf +# Any other path can be chosen by passing the path as a parameter +# to the program, eg. "minetest.exe --config ../minetest.conf.example". + +# Further documentation: +# http://wiki.minetest.net/ + +# +# Controls +# + +# If enabled, you can place blocks at the position (feet + eye level) where you stand. +# This is helpful when working with nodeboxes in small areas. +# type: bool +# enable_build_where_you_stand = false + +# Player is able to fly without being affected by gravity. +# This requires the "fly" privilege on the server. +# type: bool +# free_move = false + +# If enabled, makes move directions relative to the player's pitch when flying or swimming. +# type: bool +# pitch_move = false + +# Fast movement (via the "Aux1" key). +# This requires the "fast" privilege on the server. +# type: bool +# fast_move = false + +# If enabled together with fly mode, player is able to fly through solid nodes. +# This requires the "noclip" privilege on the server. +# type: bool +# noclip = false + +# Smooths camera when looking around. Also called look or mouse smoothing. +# Useful for recording videos. +# type: bool +# cinematic = false + +# Smooths rotation of camera. 0 to disable. +# type: float min: 0 max: 0.99 +# camera_smoothing = 0.0 + +# Smooths rotation of camera in cinematic mode. 0 to disable. +# type: float min: 0 max: 0.99 +# cinematic_camera_smoothing = 0.7 + +# Invert vertical mouse movement. +# type: bool +# invert_mouse = false + +# Mouse sensitivity multiplier. +# type: float +# mouse_sensitivity = 0.2 + +# If enabled, "Aux1" key instead of "Sneak" key is used for climbing down and +# descending. +# type: bool +# aux1_descends = false + +# Double-tapping the jump key toggles fly mode. +# type: bool +# doubletap_jump = false + +# If disabled, "Aux1" key is used to fly fast if both fly and fast mode are +# enabled. +# type: bool +# always_fly_fast = true + +# The time in seconds it takes between repeated node placements when holding +# the place button. +# type: float min: 0.001 +# repeat_place_time = 0.25 + +# Automatically jump up single-node obstacles. +# type: bool +# autojump = false + +# Prevent digging and placing from repeating when holding the mouse buttons. +# Enable this when you dig or place too often by accident. +# type: bool +# safe_dig_and_place = false + +# Enable random user input (only used for testing). +# type: bool +# random_input = false + +# Continuous forward movement, toggled by autoforward key. +# Press the autoforward key again or the backwards movement to disable. +# type: bool +# continuous_forward = false + +# The length in pixels it takes for touch screen interaction to start. +# type: int min: 0 max: 100 +# touchscreen_threshold = 20 + +# (Android) Fixes the position of virtual joystick. +# If disabled, virtual joystick will center to first-touch's position. +# type: bool +# fixed_virtual_joystick = false + +# (Android) Use virtual joystick to trigger "Aux1" button. +# If enabled, virtual joystick will also tap "Aux1" button when out of main circle. +# type: bool +# virtual_joystick_triggers_aux1 = false + +# Enable joysticks +# type: bool +# enable_joysticks = false + +# The identifier of the joystick to use +# type: int +# joystick_id = 0 + +# The type of joystick +# type: enum values: auto, generic, xbox, dragonrise_gamecube +# joystick_type = auto + +# The time in seconds it takes between repeated events +# when holding down a joystick button combination. +# type: float min: 0.001 +# repeat_joystick_button_time = 0.17 + +# The dead zone of the joystick +# type: int +# joystick_deadzone = 2048 + +# The sensitivity of the joystick axes for moving the +# in-game view frustum around. +# type: float +# joystick_frustum_sensitivity = 170 + +# Key for moving the player forward. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_forward = KEY_KEY_W + +# Key for moving the player backward. +# Will also disable autoforward, when active. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_backward = KEY_KEY_S + +# Key for moving the player left. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_left = KEY_KEY_A + +# Key for moving the player right. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_right = KEY_KEY_D + +# Key for jumping. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_jump = KEY_SPACE + +# Key for sneaking. +# Also used for climbing down and descending in water if aux1_descends is disabled. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_sneak = KEY_LSHIFT + +# Key for digging. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_dig = KEY_LBUTTON + +# Key for placing. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_place = KEY_RBUTTON + +# Key for opening the inventory. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_inventory = KEY_KEY_I + +# Key for moving fast in fast mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_aux1 = KEY_KEY_E + +# Key for opening the chat window. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_chat = KEY_KEY_T + +# Key for opening the chat window to type commands. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_cmd = / + +# Key for opening the chat window to type local commands. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_cmd_local = . + +# Key for toggling unlimited view range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_rangeselect = KEY_KEY_R + +# Key for toggling flying. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_freemove = KEY_KEY_K + +# Key for toggling pitch move mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_pitchmove = KEY_KEY_P + +# Key for toggling fast mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_fastmove = KEY_KEY_J + +# Key for toggling noclip mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_noclip = KEY_KEY_H + +# Key for selecting the next item in the hotbar. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_hotbar_next = KEY_KEY_N + +# Key for selecting the previous item in the hotbar. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_hotbar_previous = KEY_KEY_B + +# Key for muting the game. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_mute = KEY_KEY_M + +# Key for increasing the volume. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_increase_volume = + +# Key for decreasing the volume. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_decrease_volume = + +# Key for toggling autoforward. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_autoforward = + +# Key for toggling cinematic mode. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_cinematic = + +# Key for toggling display of minimap. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_minimap = KEY_KEY_V + +# Key for taking screenshots. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_screenshot = KEY_F12 + +# Key for dropping the currently selected item. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_drop = KEY_KEY_Q + +# Key to use view zoom when possible. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_zoom = KEY_KEY_Z + +# Key for selecting the first hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot1 = KEY_KEY_1 + +# Key for selecting the second hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot2 = KEY_KEY_2 + +# Key for selecting the third hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot3 = KEY_KEY_3 + +# Key for selecting the fourth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot4 = KEY_KEY_4 + +# Key for selecting the fifth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot5 = KEY_KEY_5 + +# Key for selecting the sixth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot6 = KEY_KEY_6 + +# Key for selecting the seventh hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot7 = KEY_KEY_7 + +# Key for selecting the eighth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot8 = KEY_KEY_8 + +# Key for selecting the ninth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot9 = KEY_KEY_9 + +# Key for selecting the tenth hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot10 = KEY_KEY_0 + +# Key for selecting the 11th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot11 = + +# Key for selecting the 12th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot12 = + +# Key for selecting the 13th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot13 = + +# Key for selecting the 14th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot14 = + +# Key for selecting the 15th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot15 = + +# Key for selecting the 16th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot16 = + +# Key for selecting the 17th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot17 = + +# Key for selecting the 18th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot18 = + +# Key for selecting the 19th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot19 = + +# Key for selecting the 20th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot20 = + +# Key for selecting the 21st hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot21 = + +# Key for selecting the 22nd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot22 = + +# Key for selecting the 23rd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot23 = + +# Key for selecting the 24th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot24 = + +# Key for selecting the 25th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot25 = + +# Key for selecting the 26th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot26 = + +# Key for selecting the 27th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot27 = + +# Key for selecting the 28th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot28 = + +# Key for selecting the 29th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot29 = + +# Key for selecting the 30th hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot30 = + +# Key for selecting the 31st hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot31 = + +# Key for selecting the 32nd hotbar slot. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_slot32 = + +# Key for toggling the display of the HUD. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_hud = KEY_F1 + +# Key for toggling the display of chat. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_chat = KEY_F2 + +# Key for toggling the display of the large chat console. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_console = KEY_F10 + +# Key for toggling the display of fog. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_force_fog_off = KEY_F3 + +# Key for toggling the camera update. Only used for development +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_update_camera = + +# Key for toggling the display of debug info. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_debug = KEY_F5 + +# Key for toggling the display of the profiler. Used for development. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_toggle_profiler = KEY_F6 + +# Key for switching between first- and third-person camera. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_camera_mode = KEY_KEY_C + +# Key for increasing the viewing range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_increase_viewing_range_min = + + +# Key for decreasing the viewing range. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +# type: key +# keymap_decrease_viewing_range_min = - + +# +# Graphics +# + +## In-Game + +### Basic + +# Whether name tag backgrounds should be shown by default. +# Mods may still set a background. +# type: bool +# show_nametag_backgrounds = true + +# Enable vertex buffer objects. +# This should greatly improve graphics performance. +# type: bool +# enable_vbo = true + +# Whether to fog out the end of the visible area. +# type: bool +# enable_fog = true + +# Leaves style: +# - Fancy: all faces visible +# - Simple: only outer faces, if defined special_tiles are used +# - Opaque: disable transparency +# type: enum values: fancy, simple, opaque +# leaves_style = fancy + +# Connects glass if supported by node. +# type: bool +# connected_glass = false + +# Enable smooth lighting with simple ambient occlusion. +# Disable for speed or for different looks. +# type: bool +# smooth_lighting = true + +# Enables tradeoffs that reduce CPU load or increase rendering performance +# at the expense of minor visual glitches that do not impact game playability. +# type: bool +# performance_tradeoffs = false + +# Clouds are a client side effect. +# type: bool +# enable_clouds = true + +# Use 3D cloud look instead of flat. +# type: bool +# enable_3d_clouds = true + +# Method used to highlight selected object. +# type: enum values: box, halo, none +# node_highlighting = box + +# Adds particles when digging a node. +# type: bool +# enable_particles = true + +### Filtering + +# Use mipmapping to scale textures. May slightly increase performance, +# especially when using a high resolution texture pack. +# Gamma correct downscaling is not supported. +# type: bool +# mip_map = false + +# Use anisotropic filtering when viewing at textures from an angle. +# type: bool +# anisotropic_filter = false + +# Use bilinear filtering when scaling textures. +# type: bool +# bilinear_filter = false + +# Use trilinear filtering when scaling textures. +# type: bool +# trilinear_filter = false + +# Filtered textures can blend RGB values with fully-transparent neighbors, +# which PNG optimizers usually discard, often resulting in dark or +# light edges to transparent textures. Apply a filter to clean that up +# at texture load time. This is automatically enabled if mipmapping is enabled. +# type: bool +# texture_clean_transparent = false + +# When using bilinear/trilinear/anisotropic filters, low-resolution textures +# can be blurred, so automatically upscale them with nearest-neighbor +# interpolation to preserve crisp pixels. This sets the minimum texture size +# for the upscaled textures; higher values look sharper, but require more +# memory. Powers of 2 are recommended. This setting is ONLY applied if +# bilinear/trilinear/anisotropic filtering is enabled. +# This is also used as the base node texture size for world-aligned +# texture autoscaling. +# type: int +# texture_min_size = 64 + +# Use multi-sample antialiasing (MSAA) to smooth out block edges. +# This algorithm smooths out the 3D viewport while keeping the image sharp, +# but it doesn't affect the insides of textures +# (which is especially noticeable with transparent textures). +# Visible spaces appear between nodes when shaders are disabled. +# If set to 0, MSAA is disabled. +# A restart is required after changing this option. +# type: enum values: 0, 1, 2, 4, 8, 16 +# fsaa = 0 + +# Undersampling is similar to using a lower screen resolution, but it applies +# to the game world only, keeping the GUI intact. +# It should give a significant performance boost at the cost of less detailed image. +# Higher values result in a less detailed image. +# type: int min: 1 max: 8 +# undersampling = 1 + +### Shaders + +# Shaders allow advanced visual effects and may increase performance on some video +# cards. +# This only works with the OpenGL video backend. +# type: bool +# enable_shaders = true + +# Path to shader directory. If no path is defined, default location will be used. +# type: path +# shader_path = + +#### Tone Mapping + +# Enables Hable's 'Uncharted 2' filmic tone mapping. +# Simulates the tone curve of photographic film and how this approximates the +# appearance of high dynamic range images. Mid-range contrast is slightly +# enhanced, highlights and shadows are gradually compressed. +# type: bool +# tone_mapping = false + +#### Waving Nodes + +# Set to true to enable waving liquids (like water). +# Requires shaders to be enabled. +# type: bool +# enable_waving_water = false + +# The maximum height of the surface of waving liquids. +# 4.0 = Wave height is two nodes. +# 0.0 = Wave doesn't move at all. +# Default is 1.0 (1/2 node). +# Requires waving liquids to be enabled. +# type: float min: 0 max: 4 +# water_wave_height = 1.0 + +# Length of liquid waves. +# Requires waving liquids to be enabled. +# type: float min: 0.1 +# water_wave_length = 20.0 + +# How fast liquid waves will move. Higher = faster. +# If negative, liquid waves will move backwards. +# Requires waving liquids to be enabled. +# type: float +# water_wave_speed = 5.0 + +# Set to true to enable waving leaves. +# Requires shaders to be enabled. +# type: bool +# enable_waving_leaves = false + +# Set to true to enable waving plants. +# Requires shaders to be enabled. +# type: bool +# enable_waving_plants = false + +#### Dynamic shadows + +# Set to true to enable Shadow Mapping. +# Requires shaders to be enabled. +# type: bool +# enable_dynamic_shadows = false + +# Set the shadow strength gamma. +# Adjusts the intensity of in-game dynamic shadows. +# Lower value means lighter shadows, higher value means darker shadows. +# type: float min: 0.1 max: 10 +# shadow_strength_gamma = 1.0 + +# Maximum distance to render shadows. +# type: float min: 10 max: 1000 +# shadow_map_max_distance = 120.0 + +# Texture size to render the shadow map on. +# This must be a power of two. +# Bigger numbers create better shadows but it is also more expensive. +# type: int min: 128 max: 8192 +# shadow_map_texture_size = 1024 + +# Sets shadow texture quality to 32 bits. +# On false, 16 bits texture will be used. +# This can cause much more artifacts in the shadow. +# type: bool +# shadow_map_texture_32bit = true + +# Enable Poisson disk filtering. +# On true uses Poisson disk to make "soft shadows". Otherwise uses PCF filtering. +# type: bool +# shadow_poisson_filter = true + +# Define shadow filtering quality. +# This simulates the soft shadows effect by applying a PCF or Poisson disk +# but also uses more resources. +# type: enum values: 0, 1, 2 +# shadow_filters = 1 + +# Enable colored shadows. +# On true translucent nodes cast colored shadows. This is expensive. +# type: bool +# shadow_map_color = false + +# Spread a complete update of shadow map over given amount of frames. +# Higher values might make shadows laggy, lower values +# will consume more resources. +# Minimum value: 1; maximum value: 16 +# type: int min: 1 max: 16 +# shadow_update_frames = 8 + +# Set the soft shadow radius size. +# Lower values mean sharper shadows, bigger values mean softer shadows. +# Minimum value: 1.0; maximum value: 10.0 +# type: float min: 1 max: 10 +# shadow_soft_radius = 1.0 + +# Set the tilt of Sun/Moon orbit in degrees. +# Value of 0 means no tilt / vertical orbit. +# Minimum value: 0.0; maximum value: 60.0 +# type: float min: 0 max: 60 +# shadow_sky_body_orbit_tilt = 0.0 + +### Advanced + +# Arm inertia, gives a more realistic movement of +# the arm when the camera moves. +# type: bool +# arm_inertia = true + +# If FPS would go higher than this, limit it by sleeping +# to not waste CPU power for no benefit. +# type: int min: 1 +# fps_max = 60 + +# Maximum FPS when the window is not focused, or when the game is paused. +# type: int min: 1 +# fps_max_unfocused = 20 + +# Open the pause menu when the window's focus is lost. Does not pause if a formspec is +# open. +# type: bool +# pause_on_lost_focus = false + +# View distance in nodes. +# type: int min: 20 max: 4000 +# viewing_range = 190 + +# Camera 'near clipping plane' distance in nodes, between 0 and 0.25 +# Only works on GLES platforms. Most users will not need to change this. +# Increasing can reduce artifacting on weaker GPUs. +# 0.1 = Default, 0.25 = Good value for weaker tablets. +# type: float min: 0 max: 0.25 +# near_plane = 0.1 + +# Width component of the initial window size. Ignored in fullscreen mode. +# type: int min: 1 +# screen_w = 1024 + +# Height component of the initial window size. Ignored in fullscreen mode. +# type: int min: 1 +# screen_h = 600 + +# Save window size automatically when modified. +# type: bool +# autosave_screensize = true + +# Fullscreen mode. +# type: bool +# fullscreen = false + +# Vertical screen synchronization. +# type: bool +# vsync = false + +# Field of view in degrees. +# type: int min: 45 max: 160 +# fov = 72 + +# Alters the light curve by applying 'gamma correction' to it. +# Higher values make middle and lower light levels brighter. +# Value '1.0' leaves the light curve unaltered. +# This only has significant effect on daylight and artificial +# light, it has very little effect on natural night light. +# type: float min: 0.33 max: 3 +# display_gamma = 1.0 + +# Gradient of light curve at minimum light level. +# Controls the contrast of the lowest light levels. +# type: float min: 0 max: 3 +# lighting_alpha = 0.0 + +# Gradient of light curve at maximum light level. +# Controls the contrast of the highest light levels. +# type: float min: 0 max: 3 +# lighting_beta = 1.5 + +# Strength of light curve boost. +# The 3 'boost' parameters define a range of the light +# curve that is boosted in brightness. +# type: float min: 0 max: 0.4 +# lighting_boost = 0.2 + +# Center of light curve boost range. +# Where 0.0 is minimum light level, 1.0 is maximum light level. +# type: float min: 0 max: 1 +# lighting_boost_center = 0.5 + +# Spread of light curve boost range. +# Controls the width of the range to be boosted. +# Standard deviation of the light curve boost Gaussian. +# type: float min: 0 max: 0.4 +# lighting_boost_spread = 0.2 + +# Path to texture directory. All textures are first searched from here. +# type: path +# texture_path = + +# The rendering back-end. +# A restart is required after changing this. +# Note: On Android, stick with OGLES1 if unsure! App may fail to start otherwise. +# On other platforms, OpenGL is recommended. +# Shaders are supported by OpenGL (desktop only) and OGLES2 (experimental) +# type: enum values: opengl, ogles1, ogles2 +# video_driver = opengl + +# Radius of cloud area stated in number of 64 node cloud squares. +# Values larger than 26 will start to produce sharp cutoffs at cloud area corners. +# type: int +# cloud_radius = 12 + +# Enable view bobbing and amount of view bobbing. +# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double. +# type: float +# view_bobbing_amount = 1.0 + +# Multiplier for fall bobbing. +# For example: 0 for no view bobbing; 1.0 for normal; 2.0 for double. +# type: float +# fall_bobbing_amount = 0.03 + +# 3D support. +# Currently supported: +# - none: no 3d output. +# - anaglyph: cyan/magenta color 3d. +# - interlaced: odd/even line based polarisation screen support. +# - topbottom: split screen top/bottom. +# - sidebyside: split screen side by side. +# - crossview: Cross-eyed 3d +# - pageflip: quadbuffer based 3d. +# Note that the interlaced mode requires shaders to be enabled. +# type: enum values: none, anaglyph, interlaced, topbottom, sidebyside, crossview, pageflip +# 3d_mode = none + +# Strength of 3D mode parallax. +# type: float +# 3d_paralax_strength = 0.025 + +# In-game chat console height, between 0.1 (10%) and 1.0 (100%). +# type: float min: 0.1 max: 1 +# console_height = 0.6 + +# In-game chat console background color (R,G,B). +# type: string +# console_color = (0,0,0) + +# In-game chat console background alpha (opaqueness, between 0 and 255). +# type: int min: 0 max: 255 +# console_alpha = 200 + +# Formspec full-screen background opacity (between 0 and 255). +# type: int min: 0 max: 255 +# formspec_fullscreen_bg_opacity = 140 + +# Formspec full-screen background color (R,G,B). +# type: string +# formspec_fullscreen_bg_color = (0,0,0) + +# Formspec default background opacity (between 0 and 255). +# type: int min: 0 max: 255 +# formspec_default_bg_opacity = 140 + +# Formspec default background color (R,G,B). +# type: string +# formspec_default_bg_color = (0,0,0) + +# Selection box border color (R,G,B). +# type: string +# selectionbox_color = (0,0,0) + +# Width of the selection box lines around nodes. +# type: int min: 1 max: 5 +# selectionbox_width = 2 + +# Crosshair color (R,G,B). +# Also controls the object crosshair color +# type: string +# crosshair_color = (255,255,255) + +# Crosshair alpha (opaqueness, between 0 and 255). +# This also applies to the object crosshair. +# type: int min: 0 max: 255 +# crosshair_alpha = 255 + +# Maximum number of recent chat messages to show +# type: int min: 2 max: 20 +# recent_chat_messages = 6 + +# Whether node texture animations should be desynchronized per mapblock. +# type: bool +# desynchronize_mapblock_texture_animation = true + +# Maximum proportion of current window to be used for hotbar. +# Useful if there's something to be displayed right or left of hotbar. +# type: float +# hud_hotbar_max_width = 1.0 + +# Modifies the size of the HUD elements. +# type: float +# hud_scaling = 1.0 + +# Enables caching of facedir rotated meshes. +# type: bool +# enable_mesh_cache = false + +# Delay between mesh updates on the client in ms. Increasing this will slow +# down the rate of mesh updates, thus reducing jitter on slower clients. +# type: int min: 0 max: 50 +# mesh_generation_interval = 0 + +# Size of the MapBlock cache of the mesh generator. Increasing this will +# increase the cache hit %, reducing the data being copied from the main +# thread, thus reducing jitter. +# type: int min: 0 max: 1000 +# meshgen_block_cache_size = 20 + +# Enables minimap. +# type: bool +# enable_minimap = true + +# Shape of the minimap. Enabled = round, disabled = square. +# type: bool +# minimap_shape_round = true + +# True = 256 +# False = 128 +# Usable to make minimap smoother on slower machines. +# type: bool +# minimap_double_scan_height = true + +# Make fog and sky colors depend on daytime (dawn/sunset) and view direction. +# type: bool +# directional_colored_fog = true + +# The strength (darkness) of node ambient-occlusion shading. +# Lower is darker, Higher is lighter. The valid range of values for this +# setting is 0.25 to 4.0 inclusive. If the value is out of range it will be +# set to the nearest valid value. +# type: float min: 0.25 max: 4 +# ambient_occlusion_gamma = 2.2 + +# Enables animation of inventory items. +# type: bool +# inventory_items_animations = false + +# Fraction of the visible distance at which fog starts to be rendered +# type: float min: 0 max: 0.99 +# fog_start = 0.4 + +# Makes all liquids opaque +# type: bool +# opaque_water = false + +# Textures on a node may be aligned either to the node or to the world. +# The former mode suits better things like machines, furniture, etc., while +# the latter makes stairs and microblocks fit surroundings better. +# However, as this possibility is new, thus may not be used by older servers, +# this option allows enforcing it for certain node types. Note though that +# that is considered EXPERIMENTAL and may not work properly. +# type: enum values: disable, enable, force_solid, force_nodebox +# world_aligned_mode = enable + +# World-aligned textures may be scaled to span several nodes. However, +# the server may not send the scale you want, especially if you use +# a specially-designed texture pack; with this option, the client tries +# to determine the scale automatically basing on the texture size. +# See also texture_min_size. +# Warning: This option is EXPERIMENTAL! +# type: enum values: disable, enable, force +# autoscale_mode = disable + +# Show entity selection boxes +# A restart is required after changing this. +# type: bool +# show_entity_selectionbox = false + +# Distance in nodes at which transparency depth sorting is enabled +# Use this to limit the performance impact of transparency depth sorting +# type: int min: 0 max: 128 +# transparency_sorting_distance = 16 + +## Menus + +# Use a cloud animation for the main menu background. +# type: bool +# menu_clouds = true + +# Scale GUI by a user specified value. +# Use a nearest-neighbor-anti-alias filter to scale the GUI. +# This will smooth over some of the rough edges, and blend +# pixels when scaling down, at the cost of blurring some +# edge pixels when images are scaled by non-integer sizes. +# type: float min: 0.001 +# gui_scaling = 1.0 + +# When gui_scaling_filter is true, all GUI images need to be +# filtered in software, but some images are generated directly +# to hardware (e.g. render-to-texture for nodes in inventory). +# type: bool +# gui_scaling_filter = false + +# When gui_scaling_filter_txr2img is true, copy those images +# from hardware to software for scaling. When false, fall back +# to the old scaling method, for video drivers that don't +# properly support downloading textures back from hardware. +# type: bool +# gui_scaling_filter_txr2img = true + +# Delay showing tooltips, stated in milliseconds. +# type: int +# tooltip_show_delay = 400 + +# Append item name to tooltip. +# type: bool +# tooltip_append_itemname = false + +# type: bool +# font_bold = false + +# type: bool +# font_italic = false + +# Shadow offset (in pixels) of the default font. If 0, then shadow will not be drawn. +# type: int +# font_shadow = 1 + +# Opaqueness (alpha) of the shadow behind the default font, between 0 and 255. +# type: int min: 0 max: 255 +# font_shadow_alpha = 127 + +# Font size of the default font where 1 unit = 1 pixel at 96 DPI +# type: int min: 1 +# font_size = 16 + +# For pixel-style fonts that do not scale well, this ensures that font sizes used +# with this font will always be divisible by this value, in pixels. For instance, +# a pixel font 16 pixels tall should have this set to 16, so it will only ever be +# sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32. +# type: int min: 1 +# font_size_divisible_by = 1 + +# Path to the default font. Must be a TrueType font. +# The fallback font will be used if the font cannot be loaded. +# type: filepath +# font_path = fonts/Arimo-Regular.ttf + +# type: filepath +# font_path_bold = fonts/Arimo-Bold.ttf + +# type: filepath +# font_path_italic = fonts/Arimo-Italic.ttf + +# type: filepath +# font_path_bold_italic = fonts/Arimo-BoldItalic.ttf + +# Font size of the monospace font where 1 unit = 1 pixel at 96 DPI +# type: int min: 1 +# mono_font_size = 16 + +# For pixel-style fonts that do not scale well, this ensures that font sizes used +# with this font will always be divisible by this value, in pixels. For instance, +# a pixel font 16 pixels tall should have this set to 16, so it will only ever be +# sized 16, 32, 48, etc., so a mod requesting a size of 25 will get 32. +# type: int min: 1 +# mono_font_size_divisible_by = 1 + +# Path to the monospace font. Must be a TrueType font. +# This font is used for e.g. the console and profiler screen. +# type: filepath +# mono_font_path = fonts/Cousine-Regular.ttf + +# type: filepath +# mono_font_path_bold = fonts/Cousine-Bold.ttf + +# type: filepath +# mono_font_path_italic = fonts/Cousine-Italic.ttf + +# type: filepath +# mono_font_path_bold_italic = fonts/Cousine-BoldItalic.ttf + +# Path of the fallback font. Must be a TrueType font. +# This font will be used for certain languages or if the default font is unavailable. +# type: filepath +# fallback_font_path = fonts/DroidSansFallbackFull.ttf + +# Font size of the recent chat text and chat prompt in point (pt). +# Value 0 will use the default font size. +# type: int +# chat_font_size = 0 + +# Path to save screenshots at. Can be an absolute or relative path. +# The folder will be created if it doesn't already exist. +# type: path +# screenshot_path = screenshots + +# Format of screenshots. +# type: enum values: png, jpg +# screenshot_format = png + +# Screenshot quality. Only used for JPEG format. +# 1 means worst quality; 100 means best quality. +# Use 0 for default quality. +# type: int min: 0 max: 100 +# screenshot_quality = 0 + +## Advanced + +# Adjust dpi configuration to your screen (non X11/Android only) e.g. for 4k screens. +# type: int min: 1 +# screen_dpi = 72 + +# Adjust the detected display density, used for scaling UI elements. +# type: float +# display_density_factor = 1 + +# Windows systems only: Start Minetest with the command line window in the background. +# Contains the same information as the file debug.txt (default name). +# type: bool +# enable_console = false + +# +# Sound +# + +# Enables the sound system. +# If disabled, this completely disables all sounds everywhere and the in-game +# sound controls will be non-functional. +# Changing this setting requires a restart. +# type: bool +# enable_sound = true + +# Volume of all sounds. +# Requires the sound system to be enabled. +# type: float min: 0 max: 1 +# sound_volume = 0.7 + +# Whether to mute sounds. You can unmute sounds at any time, unless the +# sound system is disabled (enable_sound=false). +# In-game, you can toggle the mute state with the mute key or by using the +# pause menu. +# type: bool +# mute_sound = false + +# +# Client +# + +# Clickable weblinks (middle-click or Ctrl+left-click) enabled in chat console output. +# type: bool +# clickable_chat_weblinks = true + +# Optional override for chat weblink color. +# type: string +# chat_weblink_color = + +## Network + +# Address to connect to. +# Leave this blank to start a local server. +# Note that the address field in the main menu overrides this setting. +# type: string +# address = + +# Port to connect to (UDP). +# Note that the port field in the main menu overrides this setting. +# type: int min: 1 max: 65535 +# remote_port = 30000 + +# Prometheus listener address. +# If Minetest is compiled with ENABLE_PROMETHEUS option enabled, +# enable metrics listener for Prometheus on that address. +# Metrics can be fetched on http://127.0.0.1:30000/metrics +# type: string +# prometheus_listener_address = 127.0.0.1:30000 + +# Save the map received by the client on disk. +# type: bool +# enable_local_map_saving = false + +# Enable usage of remote media server (if provided by server). +# Remote servers offer a significantly faster way to download media (e.g. textures) +# when connecting to the server. +# type: bool +# enable_remote_media_server = true + +# Enable Lua modding support on client. +# This support is experimental and API can change. +# type: bool +# enable_client_modding = false + +# URL to the server list displayed in the Multiplayer Tab. +# type: string +# serverlist_url = servers.minetest.net + +# File in client/serverlist/ that contains your favorite servers displayed in the +# Multiplayer Tab. +# type: string +# serverlist_file = favoriteservers.json + +# Maximum size of the out chat queue. +# 0 to disable queueing and -1 to make the queue size unlimited. +# type: int +# max_out_chat_queue_size = 20 + +# Enable register confirmation when connecting to server. +# If disabled, new account will be registered automatically. +# type: bool +# enable_register_confirmation = true + +## Advanced + +# Timeout for client to remove unused map data from memory. +# type: int +# client_unload_unused_data_timeout = 600 + +# Maximum number of mapblocks for client to be kept in memory. +# Set to -1 for unlimited amount. +# type: int +# client_mapblock_limit = 7500 + +# Whether to show the client debug info (has the same effect as hitting F5). +# type: bool +# show_debug = false + +### Physics + +# Horizontal and vertical acceleration on ground or when climbing, +# in nodes per second per second. +# type: float +# movement_acceleration_default = 3 + +# Horizontal acceleration in air when jumping or falling, +# in nodes per second per second. +# type: float +# movement_acceleration_air = 2 + +# Horizontal and vertical acceleration in fast mode, +# in nodes per second per second. +# type: float +# movement_acceleration_fast = 10 + +# Walking and flying speed, in nodes per second. +# type: float +# movement_speed_walk = 4 + +# Sneaking speed, in nodes per second. +# type: float +# movement_speed_crouch = 1.35 + +# Walking, flying and climbing speed in fast mode, in nodes per second. +# type: float +# movement_speed_fast = 20 + +# Vertical climbing speed, in nodes per second. +# type: float +# movement_speed_climb = 3 + +# Initial vertical speed when jumping, in nodes per second. +# type: float +# movement_speed_jump = 6.5 + +# Decrease this to increase liquid resistance to movement. +# type: float +# movement_liquid_fluidity = 1 + +# Maximum liquid resistance. Controls deceleration when entering liquid at +# high speed. +# type: float +# movement_liquid_fluidity_smooth = 0.5 + +# Controls sinking speed in liquid. +# type: float +# movement_liquid_sink = 10 + +# Acceleration of gravity, in nodes per second per second. +# type: float +# movement_gravity = 9.81 + +### Advanced + +# Handling for deprecated Lua API calls: +# - none: Do not log deprecated calls +# - log: mimic and log backtrace of deprecated call (default). +# - error: abort on usage of deprecated call (suggested for mod developers). +# type: enum values: none, log, error +# deprecated_lua_api_handling = log + +# Number of extra blocks that can be loaded by /clearobjects at once. +# This is a trade-off between SQLite transaction overhead and +# memory consumption (4096=100MB, as a rule of thumb). +# type: int +# max_clearobjects_extra_loaded_blocks = 4096 + +# How much the server will wait before unloading unused mapblocks. +# Higher value is smoother, but will use more RAM. +# type: int +# server_unload_unused_data_timeout = 29 + +# Maximum number of statically stored objects in a block. +# type: int +# max_objects_per_block = 256 + +# See https://www.sqlite.org/pragma.html#pragma_synchronous +# type: enum values: 0, 1, 2 +# sqlite_synchronous = 2 + +# Compression level to use when saving mapblocks to disk. +# -1 - use default compression level +# 0 - least compression, fastest +# 9 - best compression, slowest +# type: int min: -1 max: 9 +# map_compression_level_disk = -1 + +# Length of a server tick and the interval at which objects are generally updated over +# network. +# type: float +# dedicated_server_step = 0.09 + +# Length of time between active block management cycles +# type: float +# active_block_mgmt_interval = 2.0 + +# Length of time between Active Block Modifier (ABM) execution cycles +# type: float +# abm_interval = 1.0 + +# The time budget allowed for ABMs to execute on each step +# (as a fraction of the ABM Interval) +# type: float min: 0.1 max: 0.9 +# abm_time_budget = 0.2 + +# Length of time between NodeTimer execution cycles +# type: float +# nodetimer_interval = 0.2 + +# If enabled, invalid world data won't cause the server to shut down. +# Only enable this if you know what you are doing. +# type: bool +# ignore_world_load_errors = false + +# Max liquids processed per step. +# type: int +# liquid_loop_max = 100000 + +# The time (in seconds) that the liquids queue may grow beyond processing +# capacity until an attempt is made to decrease its size by dumping old queue +# items. A value of 0 disables the functionality. +# type: int +# liquid_queue_purge_time = 0 + +# Liquid update interval in seconds. +# type: float +# liquid_update = 1.0 + +# At this distance the server will aggressively optimize which blocks are sent to +# clients. +# Small values potentially improve performance a lot, at the expense of visible +# rendering glitches (some blocks will not be rendered under water and in caves, +# as well as sometimes on land). +# Setting this to a value greater than max_block_send_distance disables this +# optimization. +# Stated in mapblocks (16 nodes). +# type: int min: 2 +# block_send_optimize_distance = 4 + +# If enabled the server will perform map block occlusion culling based on +# on the eye position of the player. This can reduce the number of blocks +# sent to the client 50-80%. The client will not longer receive most invisible +# so that the utility of noclip mode is reduced. +# type: bool +# server_side_occlusion_culling = true + +# Restricts the access of certain client-side functions on servers. +# Combine the byteflags below to restrict client-side features, or set to 0 +# for no restrictions: +# LOAD_CLIENT_MODS: 1 (disable loading client-provided mods) +# CHAT_MESSAGES: 2 (disable send_chat_message call client-side) +# READ_ITEMDEFS: 4 (disable get_item_def call client-side) +# READ_NODEDEFS: 8 (disable get_node_def call client-side) +# LOOKUP_NODES_LIMIT: 16 (limits get_node call client-side to +# csm_restriction_noderange) +# READ_PLAYERINFO: 32 (disable get_player_names call client-side) +# type: int +# csm_restriction_flags = 62 + +# If the CSM restriction for node range is enabled, get_node calls are limited +# to this distance from the player to the node. +# type: int +# csm_restriction_noderange = 0 + +## Security + +# Prevent mods from doing insecure things like running shell commands. +# type: bool +# secure.enable_security = true + +# Comma-separated list of trusted mods that are allowed to access insecure +# functions even when mod security is on (via request_insecure_environment()). +# type: string +# secure.trusted_mods = + +# Comma-separated list of mods that are allowed to access HTTP APIs, which +# allow them to upload and download data to/from the internet. +# type: string +# secure.http_mods = + +## Advanced + +### Profiling + +# Load the game profiler to collect game profiling data. +# Provides a /profiler command to access the compiled profile. +# Useful for mod developers and server operators. +# type: bool +# profiler.load = false + +# The default format in which profiles are being saved, +# when calling `/profiler save [format]` without format. +# type: enum values: txt, csv, lua, json, json_pretty +# profiler.default_report_format = txt + +# The file path relative to your worldpath in which profiles will be saved to. +# type: string +# profiler.report_path = "" + +#### Instrumentation + +# Instrument the methods of entities on registration. +# type: bool +# instrument.entity = true + +# Instrument the action function of Active Block Modifiers on registration. +# type: bool +# instrument.abm = true + +# Instrument the action function of Loading Block Modifiers on registration. +# type: bool +# instrument.lbm = true + +# Instrument chat commands on registration. +# type: bool +# instrument.chatcommand = true + +# Instrument global callback functions on registration. +# (anything you pass to a minetest.register_*() function) +# type: bool +# instrument.global_callback = true + +##### Advanced + +# Instrument builtin. +# This is usually only needed by core/builtin contributors +# type: bool +# instrument.builtin = false + +# Have the profiler instrument itself: +# * Instrument an empty function. +# This estimates the overhead, that instrumentation is adding (+1 function call). +# * Instrument the sampler being used to update the statistics. +# type: bool +# instrument.profiler = false + +# +# Client and Server +# + +# Name of the player. +# When running a server, clients connecting with this name are admins. +# When starting from the main menu, this is overridden. +# type: string +# name = + +# Set the language. Leave empty to use the system language. +# A restart is required after changing this. +# type: enum values: , be, bg, ca, cs, da, de, el, en, eo, es, et, eu, fi, fr, gd, gl, hu, id, it, ja, jbo, kk, ko, lt, lv, ms, nb, nl, nn, pl, pt, pt_BR, ro, ru, sk, sl, sr_Cyrl, sr_Latn, sv, sw, tr, uk, vi, zh_CN, zh_TW +# language = + +# Level of logging to be written to debug.txt: +# - (no logging) +# - none (messages with no level) +# - error +# - warning +# - action +# - info +# - verbose +# - trace +# type: enum values: , none, error, warning, action, info, verbose, trace +# debug_log_level = action + +# If the file size of debug.txt exceeds the number of megabytes specified in +# this setting when it is opened, the file is moved to debug.txt.1, +# deleting an older debug.txt.1 if it exists. +# debug.txt is only moved if this setting is positive. +# type: int +# debug_log_size_max = 50 + +# Minimal level of logging to be written to chat. +# type: enum values: , none, error, warning, action, info, verbose, trace +# chat_log_level = error + +# Enable IPv6 support (for both client and server). +# Required for IPv6 connections to work at all. +# type: bool +# enable_ipv6 = true + +## Advanced + +# Maximum time an interactive request (e.g. server list fetch) may take, stated in milliseconds. +# type: int +# curl_timeout = 20000 + +# Limits number of parallel HTTP requests. Affects: +# - Media fetch if server uses remote_media setting. +# - Serverlist download and server announcement. +# - Downloads performed by main menu (e.g. mod manager). +# Only has an effect if compiled with cURL. +# type: int +# curl_parallel_limit = 8 + +# Maximum time a file download (e.g. a mod download) may take, stated in milliseconds. +# type: int +# curl_file_download_timeout = 300000 + +# Replaces the default main menu with a custom one. +# type: string +# main_menu_script = + +# Print the engine's profiling data in regular intervals (in seconds). +# 0 = disable. Useful for developers. +# type: int +# profiler_print_interval = 0 + +# +# Mapgen +# + +# Name of map generator to be used when creating a new world. +# Creating a world in the main menu will override this. +# Current mapgens in a highly unstable state: +# - The optional floatlands of v7 (disabled by default). +# type: enum values: v7, valleys, carpathian, v5, flat, fractal, singlenode, v6 +# mg_name = v7 + +# Water surface level of the world. +# type: int +# water_level = 1 + +# From how far blocks are generated for clients, stated in mapblocks (16 nodes). +# type: int +# max_block_generate_distance = 10 + +# Limit of map generation, in nodes, in all 6 directions from (0, 0, 0). +# Only mapchunks completely within the mapgen limit are generated. +# Value is stored per-world. +# type: int min: 0 max: 31007 +# mapgen_limit = 31007 + +# Global map generation attributes. +# In Mapgen v6 the 'decorations' flag controls all decorations except trees +# and jungle grass, in all other mapgens this flag controls all decorations. +# type: flags possible values: caves, dungeons, light, decorations, biomes, ores, nocaves, nodungeons, nolight, nodecorations, nobiomes, noores +# mg_flags = caves,dungeons,light,decorations,biomes,ores + +## Biome API temperature and humidity noise parameters + +# Temperature variation for biomes. +# type: noise_params_2d +# mg_biome_np_heat = { +# offset = 50, +# scale = 50, +# spread = (1000, 1000, 1000), +# seed = 5349, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Small-scale temperature variation for blending biomes on borders. +# type: noise_params_2d +# mg_biome_np_heat_blend = { +# offset = 0, +# scale = 1.5, +# spread = (8, 8, 8), +# seed = 13, +# octaves = 2, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +# Humidity variation for biomes. +# type: noise_params_2d +# mg_biome_np_humidity = { +# offset = 50, +# scale = 50, +# spread = (1000, 1000, 1000), +# seed = 842, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Small-scale humidity variation for blending biomes on borders. +# type: noise_params_2d +# mg_biome_np_humidity_blend = { +# offset = 0, +# scale = 1.5, +# spread = (8, 8, 8), +# seed = 90003, +# octaves = 2, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +## Mapgen V5 + +# Map generation attributes specific to Mapgen v5. +# type: flags possible values: caverns, nocaverns +# mgv5_spflags = caverns + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgv5_cave_width = 0.09 + +# Y of upper limit of large caves. +# type: int +# mgv5_large_cave_depth = -256 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgv5_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgv5_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgv5_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgv5_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgv5_large_cave_flooded = 0.5 + +# Y-level of cavern upper limit. +# type: int +# mgv5_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int +# mgv5_cavern_taper = 256 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgv5_cavern_threshold = 0.7 + +# Lower Y limit of dungeons. +# type: int +# mgv5_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int +# mgv5_dungeon_ymax = 31000 + +### Noises + +# Variation of biome filler depth. +# type: noise_params_2d +# mgv5_np_filler_depth = { +# offset = 0, +# scale = 1, +# spread = (150, 150, 150), +# seed = 261, +# octaves = 4, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of terrain vertical scale. +# When noise is < -0.55 terrain is near-flat. +# type: noise_params_2d +# mgv5_np_factor = { +# offset = 0, +# scale = 1, +# spread = (250, 250, 250), +# seed = 920381, +# octaves = 3, +# persistence = 0.45, +# lacunarity = 2.0, +# flags = eased +# } + +# Y-level of average terrain surface. +# type: noise_params_2d +# mgv5_np_height = { +# offset = 0, +# scale = 10, +# spread = (250, 250, 250), +# seed = 84174, +# octaves = 4, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgv5_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgv5_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgv5_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (384, 128, 384), +# seed = 723, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining terrain. +# type: noise_params_3d +# mgv5_np_ground = { +# offset = 0, +# scale = 40, +# spread = (80, 80, 80), +# seed = 983240, +# octaves = 4, +# persistence = 0.55, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgv5_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen V6 + +# Map generation attributes specific to Mapgen v6. +# The 'snowbiomes' flag enables the new 5 biome system. +# When the 'snowbiomes' flag is enabled jungles are automatically enabled and +# the 'jungles' flag is ignored. +# type: flags possible values: jungles, biomeblend, mudflow, snowbiomes, flat, trees, nojungles, nobiomeblend, nomudflow, nosnowbiomes, noflat, notrees +# mgv6_spflags = jungles,biomeblend,mudflow,snowbiomes,noflat,trees + +# Deserts occur when np_biome exceeds this value. +# When the 'snowbiomes' flag is enabled, this is ignored. +# type: float +# mgv6_freq_desert = 0.45 + +# Sandy beaches occur when np_beach exceeds this value. +# type: float +# mgv6_freq_beach = 0.15 + +# Lower Y limit of dungeons. +# type: int +# mgv6_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int +# mgv6_dungeon_ymax = 31000 + +### Noises + +# Y-level of lower terrain and seabed. +# type: noise_params_2d +# mgv6_np_terrain_base = { +# offset = -4, +# scale = 20, +# spread = (250, 250, 250), +# seed = 82341, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Y-level of higher terrain that creates cliffs. +# type: noise_params_2d +# mgv6_np_terrain_higher = { +# offset = 20, +# scale = 16, +# spread = (500, 500, 500), +# seed = 85039, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Varies steepness of cliffs. +# type: noise_params_2d +# mgv6_np_steepness = { +# offset = 0.85, +# scale = 0.5, +# spread = (125, 125, 125), +# seed = -932, +# octaves = 5, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines distribution of higher terrain. +# type: noise_params_2d +# mgv6_np_height_select = { +# offset = 0.5, +# scale = 1, +# spread = (250, 250, 250), +# seed = 4213, +# octaves = 5, +# persistence = 0.69, +# lacunarity = 2.0, +# flags = eased +# } + +# Varies depth of biome surface nodes. +# type: noise_params_2d +# mgv6_np_mud = { +# offset = 4, +# scale = 2, +# spread = (200, 200, 200), +# seed = 91013, +# octaves = 3, +# persistence = 0.55, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines areas with sandy beaches. +# type: noise_params_2d +# mgv6_np_beach = { +# offset = 0, +# scale = 1, +# spread = (250, 250, 250), +# seed = 59420, +# octaves = 3, +# persistence = 0.50, +# lacunarity = 2.0, +# flags = eased +# } + +# Temperature variation for biomes. +# type: noise_params_2d +# mgv6_np_biome = { +# offset = 0, +# scale = 1, +# spread = (500, 500, 500), +# seed = 9130, +# octaves = 3, +# persistence = 0.50, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of number of caves. +# type: noise_params_2d +# mgv6_np_cave = { +# offset = 6, +# scale = 6, +# spread = (250, 250, 250), +# seed = 34329, +# octaves = 3, +# persistence = 0.50, +# lacunarity = 2.0, +# flags = eased +# } + +# Humidity variation for biomes. +# type: noise_params_2d +# mgv6_np_humidity = { +# offset = 0.5, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 72384, +# octaves = 3, +# persistence = 0.50, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines tree areas and tree density. +# type: noise_params_2d +# mgv6_np_trees = { +# offset = 0, +# scale = 1, +# spread = (125, 125, 125), +# seed = 2, +# octaves = 4, +# persistence = 0.66, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines areas where trees have apples. +# type: noise_params_2d +# mgv6_np_apple_trees = { +# offset = 0, +# scale = 1, +# spread = (100, 100, 100), +# seed = 342902, +# octaves = 3, +# persistence = 0.45, +# lacunarity = 2.0, +# flags = eased +# } + +## Mapgen V7 + +# Map generation attributes specific to Mapgen v7. +# 'ridges': Rivers. +# 'floatlands': Floating land masses in the atmosphere. +# 'caverns': Giant caves deep underground. +# type: flags possible values: mountains, ridges, floatlands, caverns, nomountains, noridges, nofloatlands, nocaverns +# mgv7_spflags = mountains,ridges,nofloatlands,caverns + +# Y of mountain density gradient zero level. Used to shift mountains vertically. +# type: int +# mgv7_mount_zero_level = 0 + +# Lower Y limit of floatlands. +# type: int +# mgv7_floatland_ymin = 1024 + +# Upper Y limit of floatlands. +# type: int +# mgv7_floatland_ymax = 4096 + +# Y-distance over which floatlands taper from full density to nothing. +# Tapering starts at this distance from the Y limit. +# For a solid floatland layer, this controls the height of hills/mountains. +# Must be less than or equal to half the distance between the Y limits. +# type: int +# mgv7_floatland_taper = 256 + +# Exponent of the floatland tapering. Alters the tapering behaviour. +# Value = 1.0 creates a uniform, linear tapering. +# Values > 1.0 create a smooth tapering suitable for the default separated +# floatlands. +# Values < 1.0 (for example 0.25) create a more defined surface level with +# flatter lowlands, suitable for a solid floatland layer. +# type: float +# mgv7_float_taper_exp = 2.0 + +# Adjusts the density of the floatland layer. +# Increase value to increase density. Can be positive or negative. +# Value = 0.0: 50% of volume is floatland. +# Value = 2.0 (can be higher depending on 'mgv7_np_floatland', always test +# to be sure) creates a solid floatland layer. +# type: float +# mgv7_floatland_density = -0.6 + +# Surface level of optional water placed on a solid floatland layer. +# Water is disabled by default and will only be placed if this value is set +# to above 'mgv7_floatland_ymax' - 'mgv7_floatland_taper' (the start of the +# upper tapering). +# ***WARNING, POTENTIAL DANGER TO WORLDS AND SERVER PERFORMANCE***: +# When enabling water placement the floatlands must be configured and tested +# to be a solid layer by setting 'mgv7_floatland_density' to 2.0 (or other +# required value depending on 'mgv7_np_floatland'), to avoid +# server-intensive extreme water flow and to avoid vast flooding of the +# world surface below. +# type: int +# mgv7_floatland_ywater = -31000 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgv7_cave_width = 0.09 + +# Y of upper limit of large caves. +# type: int +# mgv7_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgv7_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgv7_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgv7_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgv7_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgv7_large_cave_flooded = 0.5 + +# Y-level of cavern upper limit. +# type: int +# mgv7_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int +# mgv7_cavern_taper = 256 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgv7_cavern_threshold = 0.7 + +# Lower Y limit of dungeons. +# type: int +# mgv7_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int +# mgv7_dungeon_ymax = 31000 + +### Noises + +# Y-level of higher terrain that creates cliffs. +# type: noise_params_2d +# mgv7_np_terrain_base = { +# offset = 4, +# scale = 70, +# spread = (600, 600, 600), +# seed = 82341, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Y-level of lower terrain and seabed. +# type: noise_params_2d +# mgv7_np_terrain_alt = { +# offset = 4, +# scale = 25, +# spread = (600, 600, 600), +# seed = 5934, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Varies roughness of terrain. +# Defines the 'persistence' value for terrain_base and terrain_alt noises. +# type: noise_params_2d +# mgv7_np_terrain_persist = { +# offset = 0.6, +# scale = 0.1, +# spread = (2000, 2000, 2000), +# seed = 539, +# octaves = 3, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines distribution of higher terrain and steepness of cliffs. +# type: noise_params_2d +# mgv7_np_height_select = { +# offset = -8, +# scale = 16, +# spread = (500, 500, 500), +# seed = 4213, +# octaves = 6, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of biome filler depth. +# type: noise_params_2d +# mgv7_np_filler_depth = { +# offset = 0, +# scale = 1.2, +# spread = (150, 150, 150), +# seed = 261, +# octaves = 3, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of maximum mountain height (in nodes). +# type: noise_params_2d +# mgv7_np_mount_height = { +# offset = 256, +# scale = 112, +# spread = (1000, 1000, 1000), +# seed = 72449, +# octaves = 3, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Defines large-scale river channel structure. +# type: noise_params_2d +# mgv7_np_ridge_uwater = { +# offset = 0, +# scale = 1, +# spread = (1000, 1000, 1000), +# seed = 85039, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise defining mountain structure and height. +# Also defines structure of floatland mountain terrain. +# type: noise_params_3d +# mgv7_np_mountain = { +# offset = -0.6, +# scale = 1, +# spread = (250, 350, 250), +# seed = 5333, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining structure of river canyon walls. +# type: noise_params_3d +# mgv7_np_ridge = { +# offset = 0, +# scale = 1, +# spread = (100, 100, 100), +# seed = 6467, +# octaves = 4, +# persistence = 0.75, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining structure of floatlands. +# If altered from the default, the noise 'scale' (0.7 by default) may need +# to be adjusted, as floatland tapering functions best when this noise has +# a value range of approximately -2.0 to 2.0. +# type: noise_params_3d +# mgv7_np_floatland = { +# offset = 0, +# scale = 0.7, +# spread = (384, 96, 384), +# seed = 1009, +# octaves = 4, +# persistence = 0.75, +# lacunarity = 1.618, +# flags = +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgv7_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (384, 128, 384), +# seed = 723, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgv7_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgv7_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgv7_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen Carpathian + +# Map generation attributes specific to Mapgen Carpathian. +# type: flags possible values: caverns, rivers, nocaverns, norivers +# mgcarpathian_spflags = caverns,norivers + +# Defines the base ground level. +# type: float +# mgcarpathian_base_level = 12.0 + +# Defines the width of the river channel. +# type: float +# mgcarpathian_river_width = 0.05 + +# Defines the depth of the river channel. +# type: float +# mgcarpathian_river_depth = 24.0 + +# Defines the width of the river valley. +# type: float +# mgcarpathian_valley_width = 0.25 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgcarpathian_cave_width = 0.09 + +# Y of upper limit of large caves. +# type: int +# mgcarpathian_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgcarpathian_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgcarpathian_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgcarpathian_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgcarpathian_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgcarpathian_large_cave_flooded = 0.5 + +# Y-level of cavern upper limit. +# type: int +# mgcarpathian_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int +# mgcarpathian_cavern_taper = 256 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgcarpathian_cavern_threshold = 0.7 + +# Lower Y limit of dungeons. +# type: int +# mgcarpathian_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int +# mgcarpathian_dungeon_ymax = 31000 + +### Noises + +# Variation of biome filler depth. +# type: noise_params_2d +# mgcarpathian_np_filler_depth = { +# offset = 0, +# scale = 1, +# spread = (128, 128, 128), +# seed = 261, +# octaves = 3, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# First of 4 2D noises that together define hill/mountain range height. +# type: noise_params_2d +# mgcarpathian_np_height1 = { +# offset = 0, +# scale = 5, +# spread = (251, 251, 251), +# seed = 9613, +# octaves = 5, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Second of 4 2D noises that together define hill/mountain range height. +# type: noise_params_2d +# mgcarpathian_np_height2 = { +# offset = 0, +# scale = 5, +# spread = (383, 383, 383), +# seed = 1949, +# octaves = 5, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Third of 4 2D noises that together define hill/mountain range height. +# type: noise_params_2d +# mgcarpathian_np_height3 = { +# offset = 0, +# scale = 5, +# spread = (509, 509, 509), +# seed = 3211, +# octaves = 5, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# Fourth of 4 2D noises that together define hill/mountain range height. +# type: noise_params_2d +# mgcarpathian_np_height4 = { +# offset = 0, +# scale = 5, +# spread = (631, 631, 631), +# seed = 1583, +# octaves = 5, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the size/occurrence of rolling hills. +# type: noise_params_2d +# mgcarpathian_np_hills_terrain = { +# offset = 1, +# scale = 1, +# spread = (1301, 1301, 1301), +# seed = 1692, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the size/occurrence of ridged mountain ranges. +# type: noise_params_2d +# mgcarpathian_np_ridge_terrain = { +# offset = 1, +# scale = 1, +# spread = (1889, 1889, 1889), +# seed = 3568, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the size/occurrence of step mountain ranges. +# type: noise_params_2d +# mgcarpathian_np_step_terrain = { +# offset = 1, +# scale = 1, +# spread = (1889, 1889, 1889), +# seed = 4157, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the shape/size of rolling hills. +# type: noise_params_2d +# mgcarpathian_np_hills = { +# offset = 0, +# scale = 3, +# spread = (257, 257, 257), +# seed = 6604, +# octaves = 6, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the shape/size of ridged mountains. +# type: noise_params_2d +# mgcarpathian_np_ridge_mnt = { +# offset = 0, +# scale = 12, +# spread = (743, 743, 743), +# seed = 5520, +# octaves = 6, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that controls the shape/size of step mountains. +# type: noise_params_2d +# mgcarpathian_np_step_mnt = { +# offset = 0, +# scale = 8, +# spread = (509, 509, 509), +# seed = 2590, +# octaves = 6, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# 2D noise that locates the river valleys and channels. +# type: noise_params_2d +# mgcarpathian_np_rivers = { +# offset = 0, +# scale = 1, +# spread = (1000, 1000, 1000), +# seed = 85039, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise for mountain overhangs, cliffs, etc. Usually small variations. +# type: noise_params_3d +# mgcarpathian_np_mnt_var = { +# offset = 0, +# scale = 1, +# spread = (499, 499, 499), +# seed = 2490, +# octaves = 5, +# persistence = 0.55, +# lacunarity = 2.0, +# flags = +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgcarpathian_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgcarpathian_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgcarpathian_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (384, 128, 384), +# seed = 723, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgcarpathian_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen Flat + +# Map generation attributes specific to Mapgen Flat. +# Occasional lakes and hills can be added to the flat world. +# type: flags possible values: lakes, hills, caverns, nolakes, nohills, nocaverns +# mgflat_spflags = nolakes,nohills,nocaverns + +# Y of flat ground. +# type: int +# mgflat_ground_level = 8 + +# Y of upper limit of large caves. +# type: int +# mgflat_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgflat_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgflat_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgflat_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgflat_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgflat_large_cave_flooded = 0.5 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgflat_cave_width = 0.09 + +# Terrain noise threshold for lakes. +# Controls proportion of world area covered by lakes. +# Adjust towards 0.0 for a larger proportion. +# type: float +# mgflat_lake_threshold = -0.45 + +# Controls steepness/depth of lake depressions. +# type: float +# mgflat_lake_steepness = 48.0 + +# Terrain noise threshold for hills. +# Controls proportion of world area covered by hills. +# Adjust towards 0.0 for a larger proportion. +# type: float +# mgflat_hill_threshold = 0.45 + +# Controls steepness/height of hills. +# type: float +# mgflat_hill_steepness = 64.0 + +# Y-level of cavern upper limit. +# type: int +# mgflat_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int +# mgflat_cavern_taper = 256 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgflat_cavern_threshold = 0.7 + +# Lower Y limit of dungeons. +# type: int +# mgflat_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int +# mgflat_dungeon_ymax = 31000 + +### Noises + +# Defines location and terrain of optional hills and lakes. +# type: noise_params_2d +# mgflat_np_terrain = { +# offset = 0, +# scale = 1, +# spread = (600, 600, 600), +# seed = 7244, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of biome filler depth. +# type: noise_params_2d +# mgflat_np_filler_depth = { +# offset = 0, +# scale = 1.2, +# spread = (150, 150, 150), +# seed = 261, +# octaves = 3, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgflat_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgflat_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgflat_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (384, 128, 384), +# seed = 723, +# octaves = 5, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgflat_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen Fractal + +# Map generation attributes specific to Mapgen Fractal. +# 'terrain' enables the generation of non-fractal terrain: +# ocean, islands and underground. +# type: flags possible values: terrain, noterrain +# mgfractal_spflags = terrain + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgfractal_cave_width = 0.09 + +# Y of upper limit of large caves. +# type: int +# mgfractal_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgfractal_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgfractal_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgfractal_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgfractal_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgfractal_large_cave_flooded = 0.5 + +# Lower Y limit of dungeons. +# type: int +# mgfractal_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int +# mgfractal_dungeon_ymax = 31000 + +# Selects one of 18 fractal types. +# 1 = 4D "Roundy" Mandelbrot set. +# 2 = 4D "Roundy" Julia set. +# 3 = 4D "Squarry" Mandelbrot set. +# 4 = 4D "Squarry" Julia set. +# 5 = 4D "Mandy Cousin" Mandelbrot set. +# 6 = 4D "Mandy Cousin" Julia set. +# 7 = 4D "Variation" Mandelbrot set. +# 8 = 4D "Variation" Julia set. +# 9 = 3D "Mandelbrot/Mandelbar" Mandelbrot set. +# 10 = 3D "Mandelbrot/Mandelbar" Julia set. +# 11 = 3D "Christmas Tree" Mandelbrot set. +# 12 = 3D "Christmas Tree" Julia set. +# 13 = 3D "Mandelbulb" Mandelbrot set. +# 14 = 3D "Mandelbulb" Julia set. +# 15 = 3D "Cosine Mandelbulb" Mandelbrot set. +# 16 = 3D "Cosine Mandelbulb" Julia set. +# 17 = 4D "Mandelbulb" Mandelbrot set. +# 18 = 4D "Mandelbulb" Julia set. +# type: int min: 1 max: 18 +# mgfractal_fractal = 1 + +# Iterations of the recursive function. +# Increasing this increases the amount of fine detail, but also +# increases processing load. +# At iterations = 20 this mapgen has a similar load to mapgen V7. +# type: int +# mgfractal_iterations = 11 + +# (X,Y,Z) scale of fractal in nodes. +# Actual fractal size will be 2 to 3 times larger. +# These numbers can be made very large, the fractal does +# not have to fit inside the world. +# Increase these to 'zoom' into the detail of the fractal. +# Default is for a vertically-squashed shape suitable for +# an island, set all 3 numbers equal for the raw shape. +# type: v3f +# mgfractal_scale = (4096.0, 1024.0, 4096.0) + +# (X,Y,Z) offset of fractal from world center in units of 'scale'. +# Can be used to move a desired point to (0, 0) to create a +# suitable spawn point, or to allow 'zooming in' on a desired +# point by increasing 'scale'. +# The default is tuned for a suitable spawn point for Mandelbrot +# sets with default parameters, it may need altering in other +# situations. +# Range roughly -2 to 2. Multiply by 'scale' for offset in nodes. +# type: v3f +# mgfractal_offset = (1.79, 0.0, 0.0) + +# W coordinate of the generated 3D slice of a 4D fractal. +# Determines which 3D slice of the 4D shape is generated. +# Alters the shape of the fractal. +# Has no effect on 3D fractals. +# Range roughly -2 to 2. +# type: float +# mgfractal_slice_w = 0.0 + +# Julia set only. +# X component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +# type: float +# mgfractal_julia_x = 0.33 + +# Julia set only. +# Y component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +# type: float +# mgfractal_julia_y = 0.33 + +# Julia set only. +# Z component of hypercomplex constant. +# Alters the shape of the fractal. +# Range roughly -2 to 2. +# type: float +# mgfractal_julia_z = 0.33 + +# Julia set only. +# W component of hypercomplex constant. +# Alters the shape of the fractal. +# Has no effect on 3D fractals. +# Range roughly -2 to 2. +# type: float +# mgfractal_julia_w = 0.33 + +### Noises + +# Y-level of seabed. +# type: noise_params_2d +# mgfractal_np_seabed = { +# offset = -14, +# scale = 9, +# spread = (600, 600, 600), +# seed = 41900, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Variation of biome filler depth. +# type: noise_params_2d +# mgfractal_np_filler_depth = { +# offset = 0, +# scale = 1.2, +# spread = (150, 150, 150), +# seed = 261, +# octaves = 3, +# persistence = 0.7, +# lacunarity = 2.0, +# flags = eased +# } + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgfractal_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgfractal_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgfractal_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Mapgen Valleys + +# Map generation attributes specific to Mapgen Valleys. +# 'altitude_chill': Reduces heat with altitude. +# 'humid_rivers': Increases humidity around rivers. +# 'vary_river_depth': If enabled, low humidity and high heat causes rivers +# to become shallower and occasionally dry. +# 'altitude_dry': Reduces humidity with altitude. +# type: flags possible values: altitude_chill, humid_rivers, vary_river_depth, altitude_dry, noaltitude_chill, nohumid_rivers, novary_river_depth, noaltitude_dry +# mgvalleys_spflags = altitude_chill,humid_rivers,vary_river_depth,altitude_dry + +# The vertical distance over which heat drops by 20 if 'altitude_chill' is +# enabled. Also the vertical distance over which humidity drops by 10 if +# 'altitude_dry' is enabled. +# type: int +# mgvalleys_altitude_chill = 90 + +# Depth below which you'll find large caves. +# type: int +# mgvalleys_large_cave_depth = -33 + +# Minimum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgvalleys_small_cave_num_min = 0 + +# Maximum limit of random number of small caves per mapchunk. +# type: int min: 0 max: 256 +# mgvalleys_small_cave_num_max = 0 + +# Minimum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgvalleys_large_cave_num_min = 0 + +# Maximum limit of random number of large caves per mapchunk. +# type: int min: 0 max: 64 +# mgvalleys_large_cave_num_max = 2 + +# Proportion of large caves that contain liquid. +# type: float min: 0 max: 1 +# mgvalleys_large_cave_flooded = 0.5 + +# Depth below which you'll find giant caverns. +# type: int +# mgvalleys_cavern_limit = -256 + +# Y-distance over which caverns expand to full size. +# type: int +# mgvalleys_cavern_taper = 192 + +# Defines full size of caverns, smaller values create larger caverns. +# type: float +# mgvalleys_cavern_threshold = 0.6 + +# How deep to make rivers. +# type: int +# mgvalleys_river_depth = 4 + +# How wide to make rivers. +# type: int +# mgvalleys_river_size = 5 + +# Controls width of tunnels, a smaller value creates wider tunnels. +# Value >= 10.0 completely disables generation of tunnels and avoids the +# intensive noise calculations. +# type: float +# mgvalleys_cave_width = 0.09 + +# Lower Y limit of dungeons. +# type: int +# mgvalleys_dungeon_ymin = -31000 + +# Upper Y limit of dungeons. +# type: int +# mgvalleys_dungeon_ymax = 63 + +### Noises + +# First of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgvalleys_np_cave1 = { +# offset = 0, +# scale = 12, +# spread = (61, 61, 61), +# seed = 52534, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# Second of two 3D noises that together define tunnels. +# type: noise_params_3d +# mgvalleys_np_cave2 = { +# offset = 0, +# scale = 12, +# spread = (67, 67, 67), +# seed = 10325, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = +# } + +# The depth of dirt or other biome filler node. +# type: noise_params_2d +# mgvalleys_np_filler_depth = { +# offset = 0, +# scale = 1.2, +# spread = (256, 256, 256), +# seed = 1605, +# octaves = 3, +# persistence = 0.5, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise defining giant caverns. +# type: noise_params_3d +# mgvalleys_np_cavern = { +# offset = 0, +# scale = 1, +# spread = (768, 256, 768), +# seed = 59033, +# octaves = 6, +# persistence = 0.63, +# lacunarity = 2.0, +# flags = +# } + +# Defines large-scale river channel structure. +# type: noise_params_2d +# mgvalleys_np_rivers = { +# offset = 0, +# scale = 1, +# spread = (256, 256, 256), +# seed = -6050, +# octaves = 5, +# persistence = 0.6, +# lacunarity = 2.0, +# flags = eased +# } + +# Base terrain height. +# type: noise_params_2d +# mgvalleys_np_terrain_height = { +# offset = -10, +# scale = 50, +# spread = (1024, 1024, 1024), +# seed = 5202, +# octaves = 6, +# persistence = 0.4, +# lacunarity = 2.0, +# flags = eased +# } + +# Raises terrain to make valleys around the rivers. +# type: noise_params_2d +# mgvalleys_np_valley_depth = { +# offset = 5, +# scale = 4, +# spread = (512, 512, 512), +# seed = -1914, +# octaves = 1, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +# Slope and fill work together to modify the heights. +# type: noise_params_3d +# mgvalleys_np_inter_valley_fill = { +# offset = 0, +# scale = 1, +# spread = (256, 512, 256), +# seed = 1993, +# octaves = 6, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +# Amplifies the valleys. +# type: noise_params_2d +# mgvalleys_np_valley_profile = { +# offset = 0.6, +# scale = 0.5, +# spread = (512, 512, 512), +# seed = 777, +# octaves = 1, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +# Slope and fill work together to modify the heights. +# type: noise_params_2d +# mgvalleys_np_inter_valley_slope = { +# offset = 0.5, +# scale = 0.5, +# spread = (128, 128, 128), +# seed = 746, +# octaves = 1, +# persistence = 1.0, +# lacunarity = 2.0, +# flags = eased +# } + +# 3D noise that determines number of dungeons per mapchunk. +# type: noise_params_3d +# mgvalleys_np_dungeons = { +# offset = 0.9, +# scale = 0.5, +# spread = (500, 500, 500), +# seed = 0, +# octaves = 2, +# persistence = 0.8, +# lacunarity = 2.0, +# flags = +# } + +## Advanced + +# Size of mapchunks generated by mapgen, stated in mapblocks (16 nodes). +# WARNING!: There is no benefit, and there are several dangers, in +# increasing this value above 5. +# Reducing this value increases cave and dungeon density. +# Altering this value is for special usage, leaving it unchanged is +# recommended. +# type: int +# chunksize = 5 + +# Dump the mapgen debug information. +# type: bool +# enable_mapgen_debug_info = false + +# Maximum number of blocks that can be queued for loading. +# type: int min: 1 max: 1000000 +# emergequeue_limit_total = 1024 + +# Maximum number of blocks to be queued that are to be loaded from file. +# This limit is enforced per player. +# type: int min: 1 max: 1000000 +# emergequeue_limit_diskonly = 128 + +# Maximum number of blocks to be queued that are to be generated. +# This limit is enforced per player. +# type: int min: 1 max: 1000000 +# emergequeue_limit_generate = 128 + +# Number of emerge threads to use. +# Value 0: +# - Automatic selection. The number of emerge threads will be +# - 'number of processors - 2', with a lower limit of 1. +# Any other value: +# - Specifies the number of emerge threads, with a lower limit of 1. +# WARNING: Increasing the number of emerge threads increases engine mapgen +# speed, but this may harm game performance by interfering with other +# processes, especially in singleplayer and/or when running Lua code in +# 'on_generated'. For many users the optimum setting may be '1'. +# type: int +# num_emerge_threads = 1 + +# +# Online Content Repository +# + +# The URL for the content repository +# type: string +# contentdb_url = https://content.minetest.net + +# Comma-separated list of flags to hide in the content repository. +# "nonfree" can be used to hide packages which do not qualify as 'free software', +# as defined by the Free Software Foundation. +# You can also specify content ratings. +# These flags are independent from Minetest versions, +# so see a full list at https://content.minetest.net/help/content_flags/ +# type: string +# contentdb_flag_blacklist = nonfree, desktop_default + +# Maximum number of concurrent downloads. Downloads exceeding this limit will be queued. +# This should be lower than curl_parallel_limit. +# type: int +# contentdb_max_concurrent_downloads = 3 + +#bind_address = 192.168.1.76 +#port = 30000 diff --git a/data/games/garage/LICENSE.txt b/data/games/garage/LICENSE.txt new file mode 100644 index 0000000..a76b0a1 --- /dev/null +++ b/data/games/garage/LICENSE.txt @@ -0,0 +1,4 @@ +License information for Development Test +---------------------------------------- + +The same license as for Luanti applies. diff --git a/data/games/garage/README.md b/data/games/garage/README.md new file mode 100644 index 0000000..4b5fb73 --- /dev/null +++ b/data/games/garage/README.md @@ -0,0 +1,50 @@ +# Development Test (devtest) + +This is a basic testing environment that contains a bunch of things to test the engine, but it could also be used as a minimal testbed for testing out mods. + +## Features + +* Basic nodes for mapgen +* Basic, minimal map generator +* Lots of example nodes for testing drawtypes, param2, light level, and many other node properties +* Example entities +* Other example items +* Formspec test (via `/test_formspec` command) +* Automated unit tests (disabled by default) +* Tools for manipulating nodes and entities, like the "Param2 Tool" + +## Getting started + +Basically, just create a world and start. A few important things to note: + +* Items are gotten from the “Chest of Everything” (`chest_of_everything:chest`) +* When you lost your initial items, type in `/stuff` command to get them back +* By default, Creative Mode activates infinite node placement. This behavior can be changed with the `devtest_infplace` setting +* Use the `/infplace` command to toggle infinite node placement in-game +* Use the Param2 Tool to change the param2 of nodes; it's useful to experiment with the various drawtype test nodes +* Check out the game settings and server commands for additional tests and features + +Confused by a certain node or item? Check out for inline code comments. The usages of most tools are explained in their tooltips. + +### Example tests + +* You can use this to test what happens if a player is simultaneously in 2 nodes with `damage_per_second` but with a different value. +* Or use the Falling Node Tool on various test nodes to see how they behave when falling. +* You could also use this as a testbed for dependency-free mods, e.g. to test out how your formspecs behave without theming. + +## Random notes + +* Textures of drawtype test nodes have a red dot at the top left corner. This is to see whether the textures are oriented properly + +## Design philosophy + +This should loosely follow the following principles: + +* Engine testing: The main focus of this is to aid testing of *engine* features, such as mapgen or node drawtypes +* Mod testing: The secondary focus is to help modders as well, either as a minimal testbed for mods or even as a code example +* Minimal interference: Under default settings, it shall not interfere with APIs except on explicit user wish. Non-trivial tests and features need to be enabled by a setting first +* Convenience: Have various tools to make usage easier and more convenient +* Reproducing engine bugs: When an engine bug was found, consider creating a test case +* Clarity: Textures and names need to be designed to keep different things clearly visually apart at a glance +* Low loading time: It must load blazing-fast so stuff can be tested quickly + diff --git a/data/games/garage/game.conf b/data/games/garage/game.conf new file mode 100644 index 0000000..e79cc94 --- /dev/null +++ b/data/games/garage/game.conf @@ -0,0 +1,4 @@ +title = Development Test +description = Testing environment to help with testing the engine features of Luanti. It can also be helpful in mod development. +first_mod = first_mod +last_mod = last_mod diff --git a/data/games/garage/menu/background.png b/data/games/garage/menu/background.png new file mode 100644 index 0000000000000000000000000000000000000000..e69c4d03f2d9f061c89a19999bf3d2e20dc152ed GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^A3&Iq8A!6suD%GQ*aCb)ToW1sER$qU@NaShia2<> zIEF;DzCCX!$iTpH#6af3eN~}?57OMz*Ub%*U47Yh6?_7oiX5_U6}d9Fh9dn?9?irAF3LhreAnu153Jc+`YR) zR&;bZ+`0HrcTet_0G1CsO3Z(kSGC7G_Y0j`$|k_Tu-zmhHH$Aa1?UI{Pgg&ebxsLQ E04Hlq*8l(j literal 0 HcmV?d00001 diff --git a/data/games/garage/menu/icon.png b/data/games/garage/menu/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f854b9c319242b2f5a3d5cb8d4c89a6ffe448859 GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDD3?#L31Vw-pPk>K|E0AtzXs}F@{r~^}tJ}>l zfqcf2AirP+hi5m^fShVi7srqa#-s&C9IcH4Y;4Cu4K_?_Y|Isvu`uvZv=C<4d$E!A zfCCTfg}>pRI~e~>d^b6-VCmW=+^4^GeCGeF|p{bAQt1#DMXL0o#ch~QnpIvFVdQ&MBb@0M^@1`Tzg` literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/init.lua b/data/games/garage/mods/basenodes/init.lua new file mode 100644 index 0000000..a6cc680 --- /dev/null +++ b/data/games/garage/mods/basenodes/init.lua @@ -0,0 +1,361 @@ +local WATER_ALPHA = "^[opacity:" .. 160 +local WATER_VISC = 1 +local LAVA_VISC = 7 + +-- +-- Node definitions +-- + +-- Register nodes + +core.register_node("basenodes:stone", { + description = "Stone", + tiles = {"default_stone.png"}, + groups = {cracky=3}, +}) + +core.register_node("basenodes:desert_stone", { + description = "Desert Stone", + tiles = {"default_desert_stone.png"}, + groups = {cracky=3}, +}) + +core.register_node("basenodes:dirt_with_grass", { + description = "Dirt with Grass", + tiles ={"default_grass.png", + -- a little dot on the bottom to distinguish it from dirt + "default_dirt.png^basenodes_dirt_with_grass_bottom.png", + {name = "default_dirt.png^default_grass_side.png", + tileable_vertical = false}}, + groups = {crumbly=3, soil=1}, +}) + +core.register_node("basenodes:dirt_with_snow", { + description = "Dirt with Snow", + tiles ={"basenodes_dirt_with_snow.png", + -- a little dot on the bottom to distinguish it from dirt + "default_dirt.png^basenodes_dirt_with_snow_bottom.png", + {name = "default_dirt.png^default_snow_side.png", + tileable_vertical = false}}, + groups = {crumbly=3, soil=1}, +}) + +core.register_node("basenodes:dirt", { + description = "Dirt", + tiles ={"default_dirt.png"}, + groups = {crumbly=3, soil=1}, +}) + +core.register_node("basenodes:sand", { + description = "Sand", + tiles ={"default_sand.png"}, + groups = {crumbly=3}, +}) + +core.register_node("basenodes:desert_sand", { + description = "Desert Sand", + tiles ={"default_desert_sand.png"}, + groups = {crumbly=3}, +}) + +core.register_node("basenodes:gravel", { + description = "Gravel", + tiles ={"default_gravel.png"}, + groups = {crumbly=2}, +}) + +core.register_node("basenodes:junglegrass", { + description = "Jungle Grass", + drawtype = "plantlike", + tiles ={"default_junglegrass.png"}, + inventory_image = "default_junglegrass.png", + wield_image = "default_junglegrass.png", + paramtype = "light", + walkable = false, + groups = {snappy=3}, +}) + +core.register_node("basenodes:tree", { + description = "Normal Tree Trunk", + tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"}, + is_ground_content = false, + groups = {choppy=2,oddly_breakable_by_hand=1}, +}) + +core.register_node("basenodes:leaves", { + description = "Normal Leaves", + drawtype = "allfaces_optional", + tiles = {"default_leaves.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3}, +}) + +core.register_node("basenodes:jungletree", { + description = "Jungle Tree Trunk", + tiles = {"default_jungletree_top.png", "default_jungletree_top.png", "default_jungletree.png"}, + is_ground_content = false, + groups = {choppy=2,oddly_breakable_by_hand=1}, +}) + +core.register_node("basenodes:jungleleaves", { + description = "Jungle Leaves", + drawtype = "allfaces_optional", + tiles = {"default_jungleleaves.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3}, +}) + +core.register_node("basenodes:pine_tree", { + description = "Pine Tree Trunk", + tiles = {"default_pine_tree_top.png", "default_pine_tree_top.png", "default_pine_tree.png"}, + is_ground_content = false, + groups = {choppy=2,oddly_breakable_by_hand=1}, +}) + +core.register_node("basenodes:pine_needles", { + description = "Pine Needles", + drawtype = "allfaces_optional", + tiles = {"default_pine_needles.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy=3}, +}) + +core.register_node("basenodes:water_source", { + description = "Water Source".."\n".. + "Swimmable, spreading, renewable liquid".."\n".. + "Drowning damage: 1", + drawtype = "liquid", + waving = 3, + tiles = {"default_water.png"..WATER_ALPHA}, + special_tiles = { + {name = "default_water.png"..WATER_ALPHA, backface_culling = false}, + {name = "default_water.png"..WATER_ALPHA, backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "basenodes:water_flowing", + liquid_alternative_source = "basenodes:water_source", + liquid_viscosity = WATER_VISC, + post_effect_color = {a = 64, r = 100, g = 100, b = 200}, + post_effect_color_shaded = true, + groups = {water = 3, liquid = 3}, +}) + +core.register_node("basenodes:water_flowing", { + description = "Flowing Water".."\n".. + "Swimmable, spreading, renewable liquid".."\n".. + "Drowning damage: 1", + drawtype = "flowingliquid", + waving = 3, + tiles = {"default_water_flowing.png"}, + special_tiles = { + {name = "default_water_flowing.png"..WATER_ALPHA, + backface_culling = false}, + {name = "default_water_flowing.png"..WATER_ALPHA, + backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "basenodes:water_flowing", + liquid_alternative_source = "basenodes:water_source", + liquid_viscosity = WATER_VISC, + post_effect_color = {a = 64, r = 100, g = 100, b = 200}, + post_effect_color_shaded = true, + groups = {water = 3, liquid = 3}, +}) + +core.register_node("basenodes:river_water_source", { + description = "River Water Source".."\n".. + "Swimmable, spreading, non-renewable liquid".."\n".. + "Drowning damage: 1", + drawtype = "liquid", + waving = 3, + tiles = { "default_river_water.png"..WATER_ALPHA }, + special_tiles = { + {name = "default_river_water.png"..WATER_ALPHA, backface_culling = false}, + {name = "default_river_water.png"..WATER_ALPHA, backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "basenodes:river_water_flowing", + liquid_alternative_source = "basenodes:river_water_source", + liquid_viscosity = 1, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + post_effect_color_shaded = true, + groups = {water = 3, liquid = 3, }, +}) + +core.register_node("basenodes:river_water_flowing", { + description = "Flowing River Water".."\n".. + "Swimmable, spreading, non-renewable liquid".."\n".. + "Drowning damage: 1", + drawtype = "flowingliquid", + waving = 3, + tiles = {"default_river_water_flowing.png"..WATER_ALPHA}, + special_tiles = { + {name = "default_river_water_flowing.png"..WATER_ALPHA, + backface_culling = false}, + {name = "default_river_water_flowing.png"..WATER_ALPHA, + backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "basenodes:river_water_flowing", + liquid_alternative_source = "basenodes:river_water_source", + liquid_viscosity = 1, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + post_effect_color_shaded = true, + groups = {water = 3, liquid = 3, }, +}) + +core.register_node("basenodes:lava_flowing", { + description = "Flowing Lava".."\n".. + "Swimmable, spreading, renewable liquid".."\n".. + "4 damage per second".."\n".. + "Drowning damage: 1", + drawtype = "flowingliquid", + tiles = {"default_lava_flowing.png"}, + special_tiles = { + {name="default_lava_flowing.png", backface_culling = false}, + {name="default_lava_flowing.png", backface_culling = false}, + }, + paramtype = "light", + light_source = core.LIGHT_MAX, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + damage_per_second = 4, + liquidtype = "flowing", + liquid_alternative_flowing = "basenodes:lava_flowing", + liquid_alternative_source = "basenodes:lava_source", + liquid_viscosity = LAVA_VISC, + post_effect_color = {a=192, r=255, g=64, b=0}, + groups = {lava=3, liquid=1}, +}) + +core.register_node("basenodes:lava_source", { + description = "Lava Source".."\n".. + "Swimmable, spreading, renewable liquid".."\n".. + "4 damage per second".."\n".. + "Drowning damage: 1", + drawtype = "liquid", + tiles = { "default_lava.png" }, + special_tiles = { + {name = "default_lava.png", backface_culling = false}, + {name = "default_lava.png", backface_culling = true}, + }, + paramtype = "light", + light_source = core.LIGHT_MAX, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drowning = 1, + damage_per_second = 4, + liquidtype = "source", + liquid_alternative_flowing = "basenodes:lava_flowing", + liquid_alternative_source = "basenodes:lava_source", + liquid_viscosity = LAVA_VISC, + post_effect_color = {a=192, r=255, g=64, b=0}, + groups = {lava=3, liquid=1}, +}) + +core.register_node("basenodes:cobble", { + description = "Cobblestone", + tiles ={"default_cobble.png"}, + is_ground_content = false, + groups = {cracky=3}, +}) + +core.register_node("basenodes:mossycobble", { + description = "Mossy Cobblestone", + tiles ={"default_mossycobble.png"}, + is_ground_content = false, + groups = {cracky=3}, +}) + +core.register_node("basenodes:apple", { + description = "Apple".."\n".. + "Punch: Eat (+2)", + drawtype = "plantlike", + tiles ={"default_apple.png"}, + inventory_image = "default_apple.png", + paramtype = "light", + is_ground_content = false, + sunlight_propagates = true, + walkable = false, + groups = {dig_immediate=3}, + + -- Make eatable because why not? + on_use = core.item_eat(2), +}) + +core.register_node("basenodes:ice", { + description = "Ice", + tiles ={"default_ice.png"}, + groups = {cracky=3}, +}) + +-- The snow nodes intentionally have different tints to make them more +-- distinguishable +core.register_node("basenodes:snow", { + description = "Snow Sheet", + tiles = {"basenodes_snow_sheet.png"}, + groups = {crumbly=3}, + walkable = false, + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + }, +}) + +core.register_node("basenodes:snowblock", { + description = "Snow Block", + tiles ={"default_snow.png"}, + groups = {crumbly=3}, +}) + + diff --git a/data/games/garage/mods/basenodes/mod.conf b/data/games/garage/mods/basenodes/mod.conf new file mode 100644 index 0000000..25024dc --- /dev/null +++ b/data/games/garage/mods/basenodes/mod.conf @@ -0,0 +1,2 @@ +name = basenodes +description = Contains basic nodes for mapgen diff --git a/data/games/garage/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png b/data/games/garage/mods/basenodes/textures/basenodes_dirt_with_grass_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..5e8fc41a951f6d48cb260110ef67048a5232361c GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZ1=4@sJoxwR!~g&Pv->O> zW_r%v7@j-#e=ksiwIs+d7)UcP9Li?f2&4i$T^vIy7){SyOE=Xm%DI@@Q_jol-E6SNMo~3SdG0E+&(98jni_FYfi1rHKjTg&i92D>cP$6n O!QkoY=d#Wzp$P!-!ae^0 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png b/data/games/garage/mods/basenodes/textures/basenodes_dirt_with_snow_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..447c94e9860cd8d7a8510ecf768141c4da33f952 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`6`n4RAr*{C2iX7ZscdNaU;CTk z#T=dx1{NoYU;pFx3RD@K%2{p@w4?X!p19BJ8@=*3zbn`x(x~FIsZ0N@n3! b-WmGsS2s=H8>;FIbOVE@tDnm{r-UW|q%=ig literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/basenodes_snow_sheet.png b/data/games/garage/mods/basenodes/textures/basenodes_snow_sheet.png new file mode 100644 index 0000000000000000000000000000000000000000..455332093d1a834e621b648ac62cdf69976c17f0 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|u1~+d`v3p`v6q*{Dq3d) z1tUCN978x{Sq~a=H7JNQJhXRL@ASK%a6{M1sk?-&|DnJ`i5u%eZ0>3Pw!5Qx$mE@M znjP!crJL#&%iK~xwS1;GJg1R)3n!CpmSW%S6I{Qs+|0-i?i*2naK z7Z&kkSSJ)Y65B_u_jaOd#Y*7eW6>22rXM_?J;DiV3KW!nHdFwMZ$X4zlh=q#lZ4*o zDk;`mf(uac6wkYE6aF>7EK2GB%!&t}&LQ_100000NkvXXu0mjfG{T9{ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_desert_stone.png b/data/games/garage/mods/basenodes/textures/default_desert_stone.png new file mode 100644 index 0000000000000000000000000000000000000000..5126fb61ce84f5c023753a39ed47107c1e69e233 GIT binary patch literal 584 zcmV-O0=NB%P)M=+sNIGj;8$$w_Zdtta= zL483iqEtDzUqH29K#NE*lT0*#LM_5>QG7rvt64mmPd2(>LB3=~o>Di*dSJ$PTfk~f zs#rXTMlii&M5tFgkxMhQT|b*pHpO*Xa5^W&bXbN(FR@%c%7SUgePh6BOU8Iz%!O^x zk9o3OKf7T2VISv`3_D$$dDmQFR2Of%AzfPX?P zbUZ26o{C4ZE5HB%0QE^kK~#7F4a(DDMFA85uybvj&$eyb+JBKY-vK~Sz;J@3Xolr@ zK?F%g6;;y>)3P1c(|rg+I^suTVLTB{x?Cy^nPfJX&lO~{h#;jBQwF1gnq;+B|8L1i zgRB5WH(R0HRNHB(Lza;)C|Iu_3<4@MjEu(igopZc(wRl-!@1c`Q45cRrLtPjHrw8= z#zuyneFkXbAg1#ExQ837MX#`fX(E4IN76@(tgORMhJ#bJkU3XYG1*R~BW;d?@v2@+ zkQX8mki)HU6(N_u-HC_$6ww!SyKfOni`9X7G!O8(O*lH~0`d)iG#_U>hjyHaBx-*H WxFrOtm=sh10000*fu~F01^m9M- zXSPF3PEMZO+?<;EUQW5 zc-Y7X1$-kHWVNE4c2wUgfksZy2uT{pGdC6gW!w>W2-w$F3wTuI^D1``Nc=`zArS>>U?@k31kX6VC_=)#W}e{G8_;BFi5|tiMgPp5hEo_bae4gfc+Ez3z4}BYUel9YZdGJQ2QH z{f_X6a7>V`?|cm?^!n*eK}%Jfx!6Q6X9Q{c`ab|@(f{2uO+;OjCz#0T0X7>WY2|ut zb3{Wz#g&Dq__1Uz2l&8+u<7la;s$xlz6vRC(z`XitW`Dy5#htNKMgbLnW>lW;YwvY z9TX?FAkfWf-!6Q^l(biy&gVWhipWe26Y^eDO7mUA@P`@=^~eHfMwV!byA=dF0$MKn z$Z1`lN@(wPBeX|)n{PvK;S;}6r#d=y9-dAICTXaJq3b7%NPZZ_!HZkk(b`$e3W~V; z;!so1@_RWIwktnza&fPa@N0h5kXqhXi!!sGv9y;Lac(5h&C0&wKW2~MnQ+w{S^xk5 M07*qoM6N<$f*ZVN_W%F@ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_grass.png b/data/games/garage/mods/basenodes/textures/default_grass.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6397186fbaaceb56eea5c2c314546f09016a67 GIT binary patch literal 697 zcmV;q0!ICbP)l^t)Bw|+Aa?;hI|w<&kB=MGOsmJbTy3SC zm`gVDuG)4Mj$oW6m{?*n+K8RKani|YHZwx(>Z-{0LhemX(Kl5eL~)eoe(c~;07xMo z+tHK(WmjcuFyt0We7-CMbn(TT!90Va5UZPB$^kwX4^<(wWp(5D_*4yMq}+XelIL&c z)El0c4MwDsL+mmKsk1ji{J88FjtwSocTqeKR zMBn^$zMqFx(G!XS?k$%MgsKyAYs5S$mr%kXfmS<$-6#*j5PkT0rlE=BjNnPCmf6-Y zo1^4>)U#;X!!#i_yT5Dx`==P^7I6c&#iXQGs?$Bd8e`~~(faGJzxuk|&%Jzi|N4)O z%dIr^+y!9{#@IsGcJvr(Q`tU#eC#5hx(kMFSyp}5-6ng)jcfzEZkQ0^_`Ofl>nphw z+oRJcaNWS?lW8r0u6~oFWz;O=9X`WB)+)|pFt@nvWgHSO#gqcAtaV+BN!Xk~2Og!K zGL}u9vMw*rQ^U~B^$ITURl4xgFs#?&X|tO2&`aP@@9ZR#^Z2qs2$=@FlkZ>szIK^` zrpIyoDr^WAiQm;Iap<%)o|iWzTNeG#zx*eg>F<9ZUNG5Fg1-3fSgHxzBSOUUXp~aQ za94rJj5hE%cfi>7TCIx~QiQ36E2DvFol=*t$3hJG fj_32BDC_?LK=*Q2k?)<+00000NkvXXu0mjfB~n)> literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_gravel.png b/data/games/garage/mods/basenodes/textures/default_gravel.png new file mode 100644 index 0000000000000000000000000000000000000000..7e5ff616f05a9002e8e084ef353ea29f47651c55 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-t{#qNx|%ATwFP1R9jmX`L;&i0s?`>n0`v$OxNultsk_^hn=w6y=3nfuPp_mq_N z&CT}G()^j3{IRk9m6i6?)cy%!8J++D0Io?yK~#7F70Sh-#V`~@!4t{8K|f|@=)b@Z zvmU4<;go}nZA{&`4%$wAM;<`9kVhWVk|&9Qp=CUcnd;p9Co~ThId@A;$uL_b$_yrJ zHrpKr*gN77YmS^0RJ(J+7sFvT%-Sp5;yx~ssb|4Mpv37p+fb<7N`|2Aq1e&l7St~= zg_uneQ$#Zx&s^YjY4pwn%}1%Ns?!CxAqATBa2jr?_0C@r3`PQGFBJI~H3kTo{elut P00000NkvXXu0mjf&JVwF literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_junglegrass.png b/data/games/garage/mods/basenodes/textures/default_junglegrass.png new file mode 100644 index 0000000000000000000000000000000000000000..d64e33abce8cb5324f338f95d39842c1b6f5616d GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?bWysG_@nDba)38gGlrUha zxTxy|lwvFi@(X5gcy=QV$jR_@aSY**Wj)Bq*rFiddhmD=V~OGcaqbgY42-|icS#mB zT1M~*Oei^B!aVO$OIw}RTsE($wDiLfrd4bqHuD;uR26Szi{G6zHQ{+s3G3+qP{R>+klHA7}B_R4<;!pnCxKfxpafM_aW;@6uPtbV{#uNOwTM zWV{Fl^P2QKwN3j0dxjia3=C>=9Usa7VNIuX+6Z(yl547fvneFlsQu-Y_5jPw8O|@E zUXR6g!%OYaaXr+XXf&vaJ36U_y25|NIQc8^A{W&g&?g;Hu4RV~0$a>HhHOmMRqX?I zs2&$jbPNHFa)aA7A$zQt;)15e~Ia;0mP!?2Uu}-^F*WWg$ zY~N-+39{D?0MfkB8SP8o0B5zLY#p>w`_lt(&tk25H9DAWy-t^3xkCde1AxuqrtWA* zrXSSD@>dqioF^l!W1QBSZ|C3+ZPn89QG3NW+QX%*ZTan?|ZFIgX+c?zpQ-o z)4#4`^}5Y;K6Qgivu3+y<)!D33}{sx>u`MqWvW01DyAflz5$ zK#0=yJU?(1HRrh?M8|R8)k^AxbwbG`O?3l7u490ly2(rIna0WC(9~Tni_39>rehAJ zYg^5VJ3xpCB@jTbz2CcaI}S`-Fv-~xmiSh`eR6O*yna9?=yzLBUwMZM_Tg*y(~+PQ zEmN)EYYkUe)%36`2?dzyS(X-(6NJ(B-l^^m#wVvGFIo-Hv2i;L3PDS>V;gYJxPsOX zzx>3KG@Wr|>SmIH%i(l7JlH!pCjdv5T?8dLnkI8LF7r)AGq=JhxOI<(>?t#RWKhfY^rZhZx9d)BcmoBr_YZ&|(!ed~Ho zw{P~o*#46ZM|iNL5TG&3Br>*E|2!M>X5epZ%;q!MYJ|1AKDg&B7Cd9}!QBDEpvWdr zDguC(u;t#)Rx|Pdprg@6&hu7GEQby+im+{mhW_qLFZ;eJvP=Q_KaD<9=P>kPF#rGn M07*qoM6N<$f(y}N3;+NC literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_jungletree_top.png b/data/games/garage/mods/basenodes/textures/default_jungletree_top.png new file mode 100644 index 0000000000000000000000000000000000000000..e80de8a69ff4537e1d01388ca82186cc1a4b760b GIT binary patch literal 714 zcmV;*0yX`KP)x@d^Rd?TN)h-bdRysL@mQK#Ru-qg0|rE$+Eq(Ix{Wg`zry?2yA`cu(zsTwn2S* zsGd??6Z<8#EsX=o2|kMmeI3~`zzxucD*Xn;-VE)pIsU)P^8fzw(x46HiQm^}{R$BJ zvz?4Cw;X*_pf&mnR!tbKHkMkO#A?evzsybiJ-Cc%J6G+vwNXaSH*W=w{a~gT(>lr< z9G8>M|LNE`a$Sa7iLU|ABo{`9*KC8QJ}$2*RE@3TwqC+$z4 z;()V~Dv!8cHk4HwazPeMWx|>nxwB%P6xRjMk3RBn@U|qxj7%}qe`Oi|P0<}${>O(` zx{AWTUmv9|JLzs?FHjQy-3!k=5&ivp6NJKPc9}<5>6J8^Fhyk%-vBqzQ=Tlrl~DUK z02U;>I{I@KqHxiM-|=(z7NrMUrnLnN71w?ByCf|N)}CqOwgOj-#WW`b%mrd{>sltI wb=r}#vXo!01b+PJRUSN7_y6YSA6nN008DC23aufI_5c6?07*qoM6N<$f-JjNZvX%Q literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_lava.png b/data/games/garage/mods/basenodes/textures/default_lava.png new file mode 100644 index 0000000000000000000000000000000000000000..a4cf649f142ae0e8d7519390a0950ee2bd131b23 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-uBE)Z6J!|v8#DYr!_Zr~ zWED_6+SA1`ghQ4wfMNZA20Q%+4h(y^pM)`7SpSrb;nDt=Q4ELv{)l6E{Qp-JL&E-l zK@1Nze|BS7p#RU2VZr);t_%$ue?~Ge?SERy!1RCV1P1O^jV%n?dm2I*_Wggzz}Kz% UPGG5|70?<6Pgg&ebxsLQ0Fos<3;+NC literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_lava_flowing.png b/data/games/garage/mods/basenodes/textures/default_lava_flowing.png new file mode 100644 index 0000000000000000000000000000000000000000..07066a6e3911b347a77d3ecd74d93b3221f1fc96 GIT binary patch literal 91 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|N}eu`Ar*|tGZYSgI6vdze@TUA o4YRkV6PC=flXCOY=xq~Xh;|nhP@5CO22{=9>FVdQ&MBb@0JAq2wEzGB literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_leaves.png b/data/games/garage/mods/basenodes/textures/default_leaves.png new file mode 100644 index 0000000000000000000000000000000000000000..c0475d4d247346bbf4a20522b143cd281828cef4 GIT binary patch literal 883 zcmV-(1C0EMP)1uOZdd1lB%%XO z1$$iD^|3~^@f4=6=2Ed9q6ug_g1YznwfHPkb?ejRABCzl4mk8jhGrg^ioZ4(-rT6l zMpLncWJ=>61t(C|X1j*ZB@tURRJ_tqdKD^|b*p$ZO*LDA&HuG)=sMJFa?^R*Mp4{G zY{sViF68Ss6rFIYdACzVGfu2!thwGq>n_MEbrOH(hVgS~^ad=vg`7SV?sBMWL%t$Y z4nkw7e4SlIEg33`L(NXu_Cu)(tFjfD@F@NkQ6G;g@jP9{8w@q=O4i(K)PKvs8Xz*9 zqT(r!LKAj{CT;3Go=*EolwX&oz#_CP^+Cykn`K|D&A+0=7ejp)4T94sJZ7q7+KVsh z)|$_0syu`Wsx#?2>Y;otO|2U}${$7~p1E}TpEeHvX>#H3LI!Wb(1}coJVO=pUKO{c zGI}sb>rp2o*I?;8)N}+j9JDJug=pMwGIR?qel&IL_jIj&pULR)Z1o;bqU9heYfD$C z#jWrRG#!BKDYWFdUmd%0=s)9y*sPP{HHKDwLNhnK3eSJ7v>k$`?aA`TTuN_2fewSl zoem9O^DucEHviwv&?Priu0tdDAkb=IUXNmfp0Ahd)O5vs z&jGi(_BknAaEZ#Mh(>PNS@zbYt}~VrE0Ps%_7Wa;Y4DV(x*nf84<^%SEi1On6c|AD z+YHS=^N!AnXI!XpOs zZuD#5vYqHGn!V^#xXnr7QoADkF6CCZ6q`d;t4xaKZ1RO2vN)q=qYZzvsjLP>Mltw` zQds*Yz}ja~vYNkTz!iewqj_5XBwG~|S@PA`$!hyXdUlcJ%xX)WMxbkdrpyc!9ftfG zr+keL`FgO(GHBWi+0}-kon8x`o6*ar%2uPXt0_vYMdb;P{sqYCHbknK2}l3{002ov JPDHLkV1mTLr>+11 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_mossycobble.png b/data/games/garage/mods/basenodes/textures/default_mossycobble.png new file mode 100644 index 0000000000000000000000000000000000000000..69585e37b7d32e78afde08bac7ad714bf9eaeb1b GIT binary patch literal 574 zcmV-E0>S->P)+qrL8R4Ub%<42)TfF+;Lvsf&)-ERB+ zKHTH+xKgRCRx6{?Xfl~*vl)!JTn-5Uold7%EV5`c+G@3^UMiIu4u|LS88{RQRjbwG z@i?E)!H+{mhQH-GMK{QaJ^n13QYjk205CFy(r}*ip^&8dc884 z4CN3f&Th9u003woj|U?wYG5e~8)F?U$IpIa+gN*ltZjs~-LMQBw}0d5n>)$fYWz9Ypz?Ny zWJ7_dNc7Lk5qod`9sj>X#r+0a_ctlt%Wye%zn$cU{eB;zP>8Wva7joguvSuxm6AnT zBZ|4XInpu~OxI*`4Bj97mQ7CU6q3UT8v-eD9r2w!*Z=yB;@Jil1oa3Bl8Ai2$XJLe zWOfq>hr`@q=krM{E-sQ9H&A)DNyz51)O@fBt)HO8b^)a)8{Am6bm&Qwq__$(p^av7 zqDo6kOFSw6G5GQycNEhaq^Qbxa&nS-Z}wpPQ{;L(>mo78P}q@x#{Ko*dMh1kk~ch9 zIp?>Y>(4jg{#PRR?;^yMN*F4#H@j4OwT*+XCq{-xTkJdLWfcU0Z)O-EoK(@hzr&e* zXzdum8aAjg6kLl@Y@(2BlV_Ui3s)gB$4}Y*pYrQyAc$v9@w|DL!B~&Dj zRw(m#nX!>~FmzB6#$rlCnUe$kB}PS4)gQ#Y(_&aTxyfv ij-qtA#{yVIm%anv#9dWKp^SV00000(+G4G4IFYm2a&8 z=Nv`;`2DxP-u<)D?#Bfwm#gqHP2lv`>l8(AA-CGNqeA6gcQ#SKKZ`}@)BVrZUd?N(StpLU>f6A9@ZE(CiF2McN5^7|K_lJJ@EfeSsYktrH#J79+O#= z(ht*iwger1{{CfP3#k*)ZkFB!N-bxpV?cQ4HIH?NFEJQ0KD0dYnJzNK8c=B2+&o$M z`tCz3-unT8%LSB$ou0yB;X@;?5=YFYi8TwpVyNmMsm4F&7PnmfSN=xY`vS<_(QaeQ3o) zYUT3nf1j<~RxJlM$Cu_4>RSkCEOrvLGkjF)qm%o4Qb zUX$uP&#!xQ;tan->llR(ZhhFze&`^Vc+{oIZTID-Y`GF9(4n6x;=VXr0cf~~6GOrJ WEdIP%9kM_NFnGH9xvX+55Jk6%V+=E68ENvE*=&mP&F!#M4h(n@7LUUm0$nHngV!dnxY))xaC1K_*{D}-|AST6 zy}WDZ;H}-a2FUs|)kvZN{FesZ%OswVMkqK%@Z?g?OawO!ps2e3TphoxPG2`@#)Cr) z&f%snzMXS24)lm$6N`4RlT;Ao(tM;m-lc}%ENbD_k=S!`8)?Ni#d(ra#Z*%fi%{ZlNq&fjq{4hkZ= zX-PGCJ$YK*@x?LC8=P}{|GhbXTZbgf4>9;JmsDTh5+6Eyi5y%9lZJA>ma6M);6NteSMB(klaM1{7u9TFmHCq~kzIFF ms`*c&pqaINDKt>3-^fpLin5Z$9Ygj200005!<}#v)Vg w$kWUx^*~2SQY0flth8BOmIqR%9V3I4yVK6V2o*+ zMoL*q+3pS^<$PJ!TI(2^Mykrb7TLrl^&!@5LWwp+tZqS7DR%uBX zx{rjEOadiEFd;SfZOTT6^0v$gIKhG#~v150269L^)HwB#C7xZcA!PBBNN##%xJ#o9z7cD;+b+xO sy`QEDiE$nRyu7^NncyuSk4NFVdQ&MBb@0H{zsTmS$7 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_snow_side.png b/data/games/garage/mods/basenodes/textures/default_snow_side.png new file mode 100644 index 0000000000000000000000000000000000000000..f34d10991fcb11806073b212d444804e45052b9d GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-uK&J$`2YX^pEnPH0={84 zje!(PNswPKP>{hvYvmUp-`vy1F{FYqSzyMNB-ZAR02dbK$w9}t+CsBpgC%9AuZ=h= vAfa~Q$bltl8zv;q|F?cW&;P~-4km`ikGj$qmTwIK8o}V{>gTe~DWM4f=`S=) literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_stone.png b/data/games/garage/mods/basenodes/textures/default_stone.png new file mode 100644 index 0000000000000000000000000000000000000000..763b4396a9a4a38f079cfc8748791ae4d6955a3b GIT binary patch literal 313 zcmV-90mlA`P)j2QOYrA5t_Pxy)aKB zDfnb%G4+#W1MMeihHeE&B%jGI(l27Wv6$x>H$dYOg_ZN_UrUN<3P)nY)7S|D3{WnVWw+u@f023w!Se!lZxP3Pr!Agw@Mz zYI~ko@-=H}9k6h=|`)pdtr~ zPOBSHJ{~zhrS9+9u2Ns$tCBo~e0*qw-wuQ{H9JI_1HPWuJ4|hFtu4?*Ru{%Sxk8Fe zEI8yj{yMv0V}BY-EW;QUlf+|NsRE|J%MXg`Rlg!{8u?B`fiRqcVl;9wgtG4rHNmH8 zX!!cf3cJBD&ag`i`Pt?8@J>@>T@budsZ-wQ2A{prdJ@l5siZiPo%IA3@BWQBY<&1( zg6wba(_ga{iVQI-n4p#mNu<)WC1T&z ztpJx$8m)~8{_`o(YRvrC>C!gr40fk6)?`{tjnL*iz1YWBlmO}(Hme02B62j_A^S9$ z^2aYHh@v;+LtUH9hO3)_G1W}jiai`@1ur+6aWRFAAt!7vUinh`|6-}rn_AvK))fg4 zq*~S#M~7wvou*7UyGkkyFfW@YX;0vx)|=NcPrICH zNl%kc-jCi%n&h3xCa4-C$C*!0WvMfU_T5fxjt~+h4Lwpy-V?$&A4`$5-!SqszChY5 zeL16ZuyFO)qdH_l0ufO~ScmRiOI>FCUd4 tKpxn*C7L5BhA4fg&_B=H{eeLg{{!$!dKC+%@o@kE002ovPDHLkV1gz|HE#d_ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_tree_top.png b/data/games/garage/mods/basenodes/textures/default_tree_top.png new file mode 100644 index 0000000000000000000000000000000000000000..d1a4fa7042a17a55d7d3cdab9e3e078d66f4246b GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Wu7jMAr*|t1_4u)I2}zzeykL9 z;ox=fThW`;u#u&XC8X^FgZQD=4H*p+W^^>L*_bg1mhomBb3Ty~9y&+L;H+8#^RgiQ zXwI5CgAn1vB|>GqGdR}q#@h(+h3yEKwqB^NI^fczc}n*4N(5K%2RTPQa?ViTWMsHj Xu}=4>SHT3J3m80I{an^LB{Ts5I=nSk literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/default_water.png b/data/games/garage/mods/basenodes/textures/default_water.png new file mode 100644 index 0000000000000000000000000000000000000000..3e385ae8bd7c49eaf366af8e23a33eba5f7f990e GIT binary patch literal 302 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!cYsfbtGZK`1_)(qI_GG*=4iR) zYP;rZyX9%S15v(?2M`tLdKMb`ml+0D7zb4v2UnT|SDA!VnFd#zhE|(})|iFY*u*s3 z#+5XH1 zldoK_u6TOC#ogDynAte^Sf;uD_Z_`^vuFLhJJn+SdPzxk1(23fT|PoE)6y2%WQwDI4Wlq@lI(IdTYw_a|??LL-&LC>}C7o+JL4o Nc)I$ztaD0e0ss%}Admn6 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basenodes/textures/dirt_with_grass/default_grass.png b/data/games/garage/mods/basenodes/textures/dirt_with_grass/default_grass.png new file mode 100644 index 0000000000000000000000000000000000000000..47e50e836871333272423b67986ee67b68d5cd76 GIT binary patch literal 760 zcmVeg`wlY&D$!VFE$1S)k`(Y0QVoN4W0eAVh*v{OjDBgvFs%~EBFt~o3yBdztq z%$%PYQzJc*#}e0@(TbJeE%xy0A-QxAl4O`E25g~)eSE>qLa`whs%m^0>4!7IcCxRx qQ)~9PA~QBQ7&%c}k9Evm4*CxvHBIud(Nban00009;n+h7p>B+Crpq|D58fu5lEZimbKn4c+**;X~vp`T%QbrgsAONU7ds;3&y zwW*tqw?BA^p_}l9OEu3tKHrlB9xrWQG5$5z7b$Y{YRn{OP!5M=Pl&^tFE8*N#qI4g zT{-f2TaY~-sp}Cpw0W+t$d3&|Es^Wp24xGX=K;@hdGr0(X-wm!CoB`6ou%wvGz+7V zGHogImSnkRx!)771JqD~bfj@k3_2rm%usehD~T^GHnGn`S|LMaASFx_q$Ym6XsPQS zd7s{po5U;x%`k9#m(%M3#}B!`t9k2#JxSLzlqn%(n~F?L*7T5W@&p z7dh2wVz*o1YLBV=Xju$JVf5S3%Op|MBHCf)$G?#2%vi z8Rwq1hQNt<^YtC|G+6vTu14xsv0ne5@Fc7@F->8y2^_|wCW`iy znae}k^8FA0QkNrt{d0rigWanetZ%=2jk+6A-hgGsEz15MZQ&U5QxP^Jj{x3_1~WpHo0=l77L+d8=`y98+tt+Z!O|s5bQBn_ zI5%ZwXJ+n@W9n;M;l{}jbHFid+kqPrE7*Ny=CdgzEf8d2=v}S6Anf$YeIVOBUHx3v IIVCg!0QUPb*#H0l literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_elementalsword.png b/data/games/garage/mods/basetools/textures/basetools_elementalsword.png new file mode 100644 index 0000000000000000000000000000000000000000..d007217ee2bde93134c257926f4dfc6c7651a673 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X5|9E{-7; zjL8c)f2?P7vS*qvw076>Pxa@1zr6f^@`9?vZT}s3nG(N08cICnZ=ULt+t`Ut@ z0;@QinCyAgRnOhs?HMSWy_)H|^8rJFs{(ofrgFRsTt2OSVj93d%fgO#L5r(0(BkN# Uk8HaZSA%T!boFyt=akR{0NLL<9smFU literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_firesword.png b/data/games/garage/mods/basetools/textures/basetools_firesword.png new file mode 100644 index 0000000000000000000000000000000000000000..eca999ba16bc16eff8fed9471c0cf2d431c861b8 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X9tSE{-7; zjL8c)f2?P7JhJ-T%0Kg8ai&aIAhjlO!)mt{=ESQUyu6l6cDe+&h^}B?H_Jfd!{vgY zM=Y-t9ZT1&`knGY$X% literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_healdagger.png b/data/games/garage/mods/basetools/textures/basetools_healdagger.png new file mode 100644 index 0000000000000000000000000000000000000000..3e6eb9cd098a5acabe10bacb65ddf84521d735d5 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1XAIiE{-7; zjL8bpJxn`=BsrAUa2%TPHK*;rsQe+RD0#EPq0Xic*k>uNaj@mM%Hr5KziqORdH_G? zs^r|z2UQ#vY>T8+844Kr`TKY6vRWXQFVdQ&MBb@ E01mS(!vFvP literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_healsword.png b/data/games/garage/mods/basetools/textures/basetools_healsword.png new file mode 100644 index 0000000000000000000000000000000000000000..f93fddfb26c6815faf9a3a5c2aab13dbd25ef1e4 GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1XA&yE{-7; zjL8c)CumP>R7eUvUuAaqe;5A*$EK`~wu9@W#Q0i5l})zT<*1!iou#zK!ItAHi(}*b zw#h>30sNe+l5;~JRB>3aEs|1YC}8C0@87k{YJptR%hbR(q;`N0_&w#C2m;V*2Q{m1Hr?y@DU_}5cVm6N zt;qf6dVh`I7c*ubxMkA0)pAj;RDSbz$6E!==LOx_x2=1n46?-2)z4*}Q$iB}FRV2i literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_mesepick_no_delay.png b/data/games/garage/mods/basetools/textures/basetools_mesepick_no_delay.png new file mode 100644 index 0000000000000000000000000000000000000000..5a7db7e0a2e72eef50b28da4952e27014eb68d94 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`1)eUBAr`0CPCUqYz<`JO>szU% z)?cpre}6G6^8C@324Ss5OAKGEd_18sG@Y$`Cfib$&wtuP16p($d70oH5Ka&ylTS4 X@IBwOF+60_8<1I^u6{1-oD!M(LF2>af}lq&H<+IY xnaQoNx)#=|Ve9a6*Dk9CavalNC@d0WV0d~^bDqqt={G=Dc)I$ztaD0e0syW5FT?-< literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_steelpick.png b/data/games/garage/mods/basetools/textures/basetools_steelpick.png new file mode 100644 index 0000000000000000000000000000000000000000..bc02aac3e45d02f0335309aecbebadbc068d1f3a GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X3ZME{-7; zjC1=AayA6;9IYzlE#%dI_wYc|>??{>_}k<@OIP_+^s4zQ+I&ygwWn@YWZJ3+cecOJ z2q{>@ZGEbbQTf!m-mRQdcx#sCxUKPhoO|F~f_GezXxfy;x^kf)dpuqJT-G@yGywpe CKwqUoc&j zEwam4d^(SIcw*tx2o& zS8e?@>9>tQp{hvDhpqXH#@S68g4c>mx>FFVdQ&MBb@0EeMQ@c;k- literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_steelpick_l2.png b/data/games/garage/mods/basetools/textures/basetools_steelpick_l2.png new file mode 100644 index 0000000000000000000000000000000000000000..011df458460115f5b804abbfdb5c3fdb37c16604 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X5|9E{-7; zjJ!gIGHW`BRKyy3P&_BmVP Wq-pLGd8F@wZ1!~Zb6Mw<&;$U7h(Tij literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_steelshears.png b/data/games/garage/mods/basetools/textures/basetools_steelshears.png new file mode 100644 index 0000000000000000000000000000000000000000..04c86c3706021dc7b3ed35b19aead2c14823af3b GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv5AX?bWsqg`@bEZ%=Jp=fS?83{1OTuSC13ym literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_steelsword.png b/data/games/garage/mods/basetools/textures/basetools_steelsword.png new file mode 100644 index 0000000000000000000000000000000000000000..9909365c32b5646276532b73a63be841f650e478 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X2;6E{-7; zjL8c)KQu5Vg}%SPzy44Qrvn@3Dn%)_-B}S90%5%uHe_B_yA-oX^AOjS<^W#-ksp~B znuSbXCoHhK7RI`+y&+j))x&>^5AN>TWwk)=(j_tGUIvCo*8&VG?><}%vdh!e&t;uc GLK6T5Up65C literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_stoneaxe.png b/data/games/garage/mods/basetools/textures/basetools_stoneaxe.png new file mode 100644 index 0000000000000000000000000000000000000000..a374c547d7570d417f66b234b1b14811f9c9eb32 GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1XAXnE{-7; zjL8xf7cO3Oob~F@pBe?vEm;N%j{E_dC#!^ngdS9NToTA${bBRNmU`05Zzc)z4*}Q$iB}-NGee literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_stonepick.png b/data/games/garage/mods/basetools/textures/basetools_stonepick.png new file mode 100644 index 0000000000000000000000000000000000000000..d9156ee3a230e0d4a462fe73dbe4b4b50e9f3b48 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJe}GSjE0A_l;*7Ob$<583G-=X` zk2k&mg&0eM{DK)Ap4~_Ta;!XE978H@<(_fmV^H8=c3k@B|Jks|snS)q6%%>0^*uJJ yW-54vdgOY(_%2=Bnwtg8<7nW~P>e`r4xDrw!7i4^4b`yZFX)QO&3NcLK6Yw_Ll@q$|3>=2*ZX zhDbJz@Anv=?rgRYIDO|a1Aiw+fzjf`2YS}5&z4&LOn*>x%V&qHQNgFz+d@wriR&!V zN?4zq`ntvFe{r)+UFY-F8Z92r_VL-se-_|VcacBvzPe`446cU5h3i!`AFsN2xaI-3 YYU{bX+m9}C1Ui|))78&qol`;+03(N5%m4rY literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_stoneshovel.png b/data/games/garage/mods/basetools/textures/basetools_stoneshovel.png new file mode 100644 index 0000000000000000000000000000000000000000..3c1bb48cb58e1a8f3f75ac8aa05ad0a6d7377d01 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X9+XE{-7; zjL8d(I$9Z%LZ>SL31t%jmJ_RX@7~RMGhsDTAbYrPMDt`J^$Ct$Sq2Lhz6!j`!4TvN Yv`1;D4ww9KRbh~Ep00i_>zopr0GYZW*8l(j literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_stonesword.png b/data/games/garage/mods/basetools/textures/basetools_stonesword.png new file mode 100644 index 0000000000000000000000000000000000000000..6f3e94cda2f7dc43247258e43ebb8e0558701343 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X3ZME{-7; zjL8c)KQu5VgSv%OOR=TmUa;{2z=n!G*dH4kxJaSi}-8|Sx87E%x3=UkPX8~Wk3qXpX{sS|BK*yoqq+St5$^{Sz&A!m!i kv4xC08&(}y*FVdQ&MBb@0Ik49DgXcg literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_titaniumsword.png b/data/games/garage/mods/basetools/textures/basetools_titaniumsword.png new file mode 100644 index 0000000000000000000000000000000000000000..55e22c7d5d08c6c1a1d365c01eda7863456566ec GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X7`%E{-7; zjL8c)1)3O>LZu}nR;*aTAgQvVEkokXs>Fv55vESf>(=RI>IEh~WPIhgLXAUc>Q)^~ zhi?-WSOv%}Y;Q8^DUt~L%%tqMEMyAfsx+XT44$rj JF6*2UngFbsIynFU literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_usessword.png b/data/games/garage/mods/basetools/textures/basetools_usessword.png new file mode 100644 index 0000000000000000000000000000000000000000..0eaf4cf380442e716dff8d4ef17805df912a2235 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`KAtX)Ar*|t3#>1QB>v?;oRX>c z;qs67OO9}wHN>1PV0JTo+#$EgL^*rW^38^fKE@N&;)~a;@k%SPtIas&~43p@G@z}N1(Y3p00i_>zopr0I(e|*Z=?k literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_woodaxe.png b/data/games/garage/mods/basetools/textures/basetools_woodaxe.png new file mode 100644 index 0000000000000000000000000000000000000000..4015e910f8ee3e85cef8923ba061887f7c3cb4cf GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X6mQE{-7; zjL8xf0S}ft&UzIQEvn$zlx3mh#UEqJ`E5dS=VT%E%vBpbdR8qHWMGK1ld#t0E_@F% N!PC{xWt~$(69Dfd9u5Ei literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_wooddagger.png b/data/games/garage/mods/basetools/textures/basetools_wooddagger.png new file mode 100644 index 0000000000000000000000000000000000000000..6e5ab0fd6fe684ec4821cc24631a2a5c3b3d4f93 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X2#3E{-7; zjL8dxC0J)Etr2jE5Nrv2u>9eYBc1-tF|skHAt-o5tYDj@vZ8NmsG=8tfYc(X gbE*p%Uu8%!GAvsvIJwEim=$EEr>mdKI;Vst0D%W2{r~^~ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_woodpick.png b/data/games/garage/mods/basetools/textures/basetools_woodpick.png new file mode 100644 index 0000000000000000000000000000000000000000..15c61f408a469d78566a0abd666ff8d9c2f5ea54 GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJPk>K|E0A_l;*7ObDe%)!;ykz$ z$Y(4G@(X5gcy=QV$T9bHaSW-rm3!hKCxZhIlcVY1?=_V&O_ORll>5@0kN$R6^PTy# sW5Ffs$!wzcLfDS~Tgh|lT-jT8tEUX{oiANWfkrTRy85}Sb4q9e00WXNGynhq literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_woodshears.png b/data/games/garage/mods/basetools/textures/basetools_woodshears.png new file mode 100644 index 0000000000000000000000000000000000000000..4ff92fd7cb24dd214e08b6a6dd34d9e85bc5be8b GIT binary patch literal 212 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF3h)VWox&y^WFeX7Ba`PXnddE$ z=PhNaB9QAPk?$jy>m{1&C6?nXBkq10`lF2<4|zhDN3XE)M-oCr@B$B+uf zWCzBcCMJQl37jnlB_18)Nb8)Y?$IF8V|-d7+L7mADyP#kg|-r=#YK`HY0}J(XR;VH z2Y!=cj&Q4zj&SHHESI{mh5KfvK=RH@3(S_OF4)Duz-`9Ak@2}$1<(!#Pgg&ebxsLQ E0P9gca{vGU literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/basetools/textures/basetools_woodshovel.png b/data/games/garage/mods/basetools/textures/basetools_woodshovel.png new file mode 100644 index 0000000000000000000000000000000000000000..6cc52f8a1607e0ed86566e19301d168eb0dada77 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X5O>E{-7; zjL8d(3W6TBC?tg*zqRUs;Ko&gQXEVvS6S<%SV9h8b@W)&)Ba1QB>v?;oRX>c z;qs67OO9}wHN>1PU~Ze5*1{&B7X7(?h1w+3#Wy_s?UR{iq$%{ik-cPc{MIT3X{JLi lma^+4J$owj5B#+TS|IZ$bvJL;O>>~>44$rjF6*2UngEbEFBkv- literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/benchmarks/init.lua b/data/games/garage/mods/benchmarks/init.lua new file mode 100644 index 0000000..8f6bb1e --- /dev/null +++ b/data/games/garage/mods/benchmarks/init.lua @@ -0,0 +1,189 @@ +-- Safeguard against too much optimization. This way the results cannot be optimized +-- away, but they can be garbage collected (due to __mode = "k"). +_G._bench_content_ids_data = setmetatable({}, {__mode = "k"}) + +local function bench_name2content() + local t = {} + _G._bench_content_ids_data[t] = true + + local get_content_id = core.get_content_id + + local start = core.get_us_time() + + for i = 1, 200 do + for name in pairs(core.registered_nodes) do + t[#t + 1] = get_content_id(name) + end + end + + local finish = core.get_us_time() + + return (finish - start) / 1000 +end + +local function bench_content2name() + local t = {} + _G._bench_content_ids_data[t] = true + + -- Try to estimate the highest content ID that's used + -- (not accurate but good enough for this test) + local n = 0 + for _ in pairs(core.registered_nodes) do + n = n + 1 + end + + local get_name_from_content_id = core.get_name_from_content_id + + local start = core.get_us_time() + + for i = 1, 200 do + for j = 0, n do + t[#t + 1] = get_name_from_content_id(j) + end + end + + local finish = core.get_us_time() + + return (finish - start) / 1000 +end + +core.register_chatcommand("bench_name2content", { + params = "", + description = "Benchmark: Conversion from node names to content IDs", + func = function(name, param) + core.chat_send_player(name, "Benchmarking core.get_content_id. Warming up ...") + bench_name2content() + core.chat_send_player(name, "Warming up finished, now benchmarking ...") + local time = bench_name2content() + return true, ("Time: %.2f ms"):format(time) + end, +}) + +core.register_chatcommand("bench_content2name", { + params = "", + description = "Benchmark: Conversion from content IDs to node names", + func = function(name, param) + core.chat_send_player(name, "Benchmarking core.get_name_from_content_id. Warming up ...") + bench_content2name() + core.chat_send_player(name, "Warming up finished, now benchmarking ...") + local time = bench_content2name() + return true, ("Time: %.2f ms"):format(time) + end, +}) + +local function get_positions_cube(ppos) + local pos_list = {} + + local i = 1 + for x=2,100 do + for y=2,100 do + for z=2,100 do + pos_list[i] = ppos:offset(x, y, z) + i = i + 1 + end + end + end + + return pos_list +end + +core.register_chatcommand("bench_bulk_set_node", { + params = "", + description = "Benchmark: Bulk-set 99×99×99 stone nodes", + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local pos_list = get_positions_cube(player:get_pos()) + + core.chat_send_player(name, "Benchmarking core.bulk_set_node. Warming up ...") + + -- warm up with stone to prevent having different callbacks + -- due to different node topology + core.bulk_set_node(pos_list, {name = "mapgen_stone"}) + + core.chat_send_player(name, "Warming up finished, now benchmarking ...") + + local start_time = core.get_us_time() + for i=1,#pos_list do + core.set_node(pos_list[i], {name = "mapgen_stone"}) + end + local middle_time = core.get_us_time() + core.bulk_set_node(pos_list, {name = "mapgen_stone"}) + local end_time = core.get_us_time() + local msg = string.format("Benchmark results: core.set_node loop: %.2f ms; core.bulk_set_node: %.2f ms", + ((middle_time - start_time)) / 1000, + ((end_time - middle_time)) / 1000 + ) + return true, msg + end, +}) + +core.register_chatcommand("bench_bulk_get_node", { + params = "", + description = "Benchmark: Bulk-get 99×99×99 nodes", + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local pos_list = get_positions_cube(player:get_pos()) + local function bench() + local start_time = core.get_us_time() + for i=1,#pos_list do + local n = core.get_node(pos_list[i]) + -- Make sure the name lookup is never optimized away. + -- Table allocation might still be omitted. But only accessing + -- the name of a node is a common pattern anyways. + if n.name == "benchmarks:nonexistent_node" then + error("should never happen") + end + end + return core.get_us_time() - start_time + end + + core.chat_send_player(name, "Benchmarking core.get_node. Warming up ...") + bench() + + core.chat_send_player(name, "Warming up finished, now benchmarking ...") + local result_us = bench() + + local msg = string.format("Benchmark results: core.get_node loop 1: %.2f ms", + result_us / 1000) + return true, msg + end, +}) + +core.register_chatcommand("bench_bulk_swap_node", { + params = "", + description = "Benchmark: Bulk-swap 99×99×99 stone nodes", + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local pos_list = get_positions_cube(player:get_pos()) + + core.chat_send_player(name, "Benchmarking core.bulk_swap_node. Warming up ...") + + -- warm up because first execution otherwise becomes + -- significantly slower + core.bulk_swap_node(pos_list, {name = "mapgen_stone"}) + + core.chat_send_player(name, "Warming up finished, now benchmarking ...") + + local start_time = core.get_us_time() + for i=1,#pos_list do + core.swap_node(pos_list[i], {name = "mapgen_stone"}) + end + local middle_time = core.get_us_time() + core.bulk_swap_node(pos_list, {name = "mapgen_stone"}) + local end_time = core.get_us_time() + local msg = string.format("Benchmark results: core.swap_node loop: %.2f ms; core.bulk_swap_node: %.2f ms", + ((middle_time - start_time)) / 1000, + ((end_time - middle_time)) / 1000 + ) + return true, msg + end, +}) diff --git a/data/games/garage/mods/benchmarks/mod.conf b/data/games/garage/mods/benchmarks/mod.conf new file mode 100644 index 0000000..fd8d039 --- /dev/null +++ b/data/games/garage/mods/benchmarks/mod.conf @@ -0,0 +1,2 @@ +name = benchmarks +description = Adds some benchmark chat commands diff --git a/data/games/garage/mods/broken/init.lua b/data/games/garage/mods/broken/init.lua new file mode 100644 index 0000000..dcbc47d --- /dev/null +++ b/data/games/garage/mods/broken/init.lua @@ -0,0 +1,11 @@ +-- Register stuff with empty definitions to test if Luanti fallback options +-- for these things work properly. + +-- The itemstrings are deliberately kept descriptive to keep them easy to +-- recognize. + +core.register_node("broken:node_with_empty_definition", {}) +core.register_tool("broken:tool_with_empty_definition", {}) +core.register_craftitem("broken:craftitem_with_empty_definition", {}) + +core.register_entity("broken:entity_with_empty_definition", {}) diff --git a/data/games/garage/mods/broken/mod.conf b/data/games/garage/mods/broken/mod.conf new file mode 100644 index 0000000..a24378a --- /dev/null +++ b/data/games/garage/mods/broken/mod.conf @@ -0,0 +1,2 @@ +name = broken +description = Register items and an entity with empty definitions to test fallback diff --git a/data/games/garage/mods/bucket/init.lua b/data/games/garage/mods/bucket/init.lua new file mode 100644 index 0000000..bce5843 --- /dev/null +++ b/data/games/garage/mods/bucket/init.lua @@ -0,0 +1,27 @@ +-- Bucket: Punch liquid source or flowing liquid to collect it + +core.register_tool("bucket:bucket", { + description = "Bucket".."\n".. + "Picks up liquid nodes", + inventory_image = "bucket.png", + stack_max = 1, + liquids_pointable = true, + groups = { disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + -- Must be pointing to node + if pointed_thing.type ~= "node" then + return + end + -- Check if pointing to a liquid + local n = core.get_node(pointed_thing.under) + local def = core.registered_nodes[n.name] + if def ~= nil and (def.liquidtype == "source" or def.liquidtype == "flowing") then + core.add_node(pointed_thing.under, {name="air"}) + local inv = user:get_inventory() + if inv then + inv:add_item("main", ItemStack(n.name)) + end + end + end, +}) + diff --git a/data/games/garage/mods/bucket/mod.conf b/data/games/garage/mods/bucket/mod.conf new file mode 100644 index 0000000..d14deb4 --- /dev/null +++ b/data/games/garage/mods/bucket/mod.conf @@ -0,0 +1,2 @@ +name = bucket +description = Minimal bucket to pick up liquids diff --git a/data/games/garage/mods/bucket/textures/bucket.png b/data/games/garage/mods/bucket/textures/bucket.png new file mode 100644 index 0000000000000000000000000000000000000000..6779528753716365ba2d722b3587280e82d3a0e0 GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`S)MMAAr*{gCtc)ZP~>sWHw`af zRxfDRyJWj7rvHz}gDGGB@$5Noqx@y3S>>{bImJd%hmPL+EhcvI=Gv|NS+2W&Cw;Fs zK5f`0=E8D1fF-Cw$8qnP@IS&0m;ZdyU2q~K{<)}z!LP5EG~;KAPnv(Zt|oBl44|zH Mp00i_>zopr0FmuKo&W#< literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/bucket/textures/bucket_lava.png b/data/games/garage/mods/bucket/textures/bucket_lava.png new file mode 100644 index 0000000000000000000000000000000000000000..dfcae65fb382d723c64abc12cd84930157d0812d GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%``JOJ0Ar*{C5?dbF>-lUs_W!L@ zL)ys$ObHroP0^+E*GzKVq5c{s#?;RL!vR1rj5MorGtvlg5WA6%{*U=6k+b)-KvmEu0pZjUzdq!^E8#PJt Sp(a4989ZJ6T-G@yGywqh>OU6% literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/bucket/textures/bucket_water.png b/data/games/garage/mods/bucket/textures/bucket_water.png new file mode 100644 index 0000000000000000000000000000000000000000..e164b0a50fe3a0f9ce5b022636f3445f34254a7a GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%``JOJ0Ar*{C5?dbF>-lUs_GHgq z4T(s;^=Z7T_co-RJiwHo!M12~+EkrMwwq#JFP!tMiao=E>HX6Q{T(N+ntg~gFn*$u z^#0xIReKW3=g(DO*v9lsm%%9^;WCqj*b0|Kq5n(^)b_5^Wia_y_2tz5Invepu2qK~ SGF1m!&EV|Ar*|t97=)>CN?pZ{Mv`6 zENWx(F;BSO@L(}>39H1P{|TYIJOONpya^1~-6ELP6c!|2TNBA4#M7~rab07EbV7rP o{e%?eLvmS1OcGlzI4ChN?6a77S5aQr6lej1r>mdKI;Vst0OIK=M*si- literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/callbacks/textures/callbacks_callback_entity_step.png b/data/games/garage/mods/callbacks/textures/callbacks_callback_entity_step.png new file mode 100644 index 0000000000000000000000000000000000000000..7676150a80c4a630f626536f50a8d57e8a3bea23 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|L7py-Ar*|t97=)>CNcK{dqfkx z0-c$cNpHw@`0#K+W8*{n4mK{Kg$o;1czKs(9AIHFIWx3DocT;GkCiCxvXunTrk;a@!#3`O8H)@QuCvb2TUhC} c#GZkn#dwK$=*P8rKr>)4-OoWHpsrV=6{9>$K;nxEsQC<8QL_tn2TZ?UJA`x d?(&P7L2vU?u^o$6ZU7p};OXk;vd$@?2>`z9C~E)! literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/callbacks/textures/callbacks_callback_node.png b/data/games/garage/mods/callbacks/textures/callbacks_callback_node.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d87434c04e6c7c9791b0ef469c41615a66b0ce GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|L7py-Ar*{kC$cg!C=qVQd1x)a`c3r4)d*rJPS<<4&7U~Qf}LExhL{fqAdxIgi& nQV!K9U-7;3{}vC`84-*cuP;7kyuM&E&~ye*S3j3^P6E@}T*#e}aWM1P15pKz4&&yN42x#4 zIw`X_`7BK1kaXJ8GGoz9L5(go0VyDE(-Y{^Q;_ml{egjDyNWdTOR2DKpot8gu6{1- HoD!M<-`X*p literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/chest/textures/chest_detached_chest.png b/data/games/garage/mods/chest/textures/chest_detached_chest.png new file mode 100644 index 0000000000000000000000000000000000000000..8e5dafed16487affc31b90202b13bd5507b54ef6 GIT binary patch literal 240 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv(Ey(iS0EkFkTlt$+TPf0NWd;CJwU&E0{FzcgC!9Xq3FBa5?qj9NRbMO$@QzWyUjP6}lo7 zO`H_2@@BPdPmdKI;Vst0LTqdiU0rr literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/chest_of_everything/init.lua b/data/games/garage/mods/chest_of_everything/init.lua new file mode 100644 index 0000000..e8a1728 --- /dev/null +++ b/data/games/garage/mods/chest_of_everything/init.lua @@ -0,0 +1,353 @@ +local F = core.formspec_escape +local S = core.get_translator("chest_of_everything") + +local detached_inventories = {} + +-- Per-player lists (indexed by player name) +local current_pages = {} -- current page number +local current_max_pages = {} -- current max. page number +local current_searches = {} -- current search string + +local SLOTS_W = 10 +local SLOTS_H = 5 +local SLOTS = SLOTS_W * SLOTS_H + +-- This determines how the items are sorted +-- "by_type": Sort by item type (tool/craftitem/node/"chest_of_everything" items), then alphabetically by itemstring +-- "abc": Alphabetically by itemstring +local SORT_MODE = "by_type" + +local all_items_list -- cached list of all items + +-- Create detached inventories +local function add_detached_inventories(player) + local name = player:get_player_name() + local inv_items = core.create_detached_inventory("chest_of_everything_items_"..name, { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + allow_put = function(inv, listname, index, stack, player) + return 0 + end, + allow_take = function(inv, listname, index, stack, player) + return -1 + end, + }, name) + local inv_trash = core.create_detached_inventory("chest_of_everything_trash_"..name, { + allow_take = function(inv, listname, index, stack, player) + return 0 + end, + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + on_put = function(inv, listname, index, stack, player) + inv:set_list(listname, {}) + end, + }, name) + inv_trash:set_size("main", 1) + detached_inventories[name] = { items = inv_items, trash = inv_trash } +end + +local sort_items_by_type = function(item1, item2) + --[[ Sort items in this order: + * Bag of Everything + * Chest of Everything + * Test tools + * Other tools + * Craftitems + * Other items + * Items from the 'broken' mod + * Dummy items ]] + local def1 = core.registered_items[item1] + local def2 = core.registered_items[item2] + local tool1 = def1.type == "tool" + local tool2 = def2.type == "tool" + local testtool1 = core.get_item_group(item1, "testtool") == 1 + local testtool2 = core.get_item_group(item2, "testtool") == 1 + local dummy1 = core.get_item_group(item1, "dummy") == 1 + local dummy2 = core.get_item_group(item2, "dummy") == 1 + local broken1 = def1.mod_origin == "broken" + local broken2 = def2.mod_origin == "broken" + local craftitem1 = def1.type == "craft" + local craftitem2 = def2.type == "craft" + if item1 == "chest_of_everything:bag" then + return true + elseif item2 == "chest_of_everything:bag" then + return false + elseif item1 == "chest_of_everything:chest" then + return true + elseif item2 == "chest_of_everything:chest" then + return false + elseif dummy1 and not dummy2 then + return false + elseif not dummy1 and dummy2 then + return true + elseif broken1 and not broken2 then + return false + elseif not broken1 and broken2 then + return true + elseif testtool1 and not testtool2 then + return true + elseif not testtool1 and testtool2 then + return false + elseif tool1 and not tool2 then + return true + elseif not tool1 and tool2 then + return false + elseif craftitem1 and not craftitem2 then + return true + elseif not craftitem1 and craftitem2 then + return false + else + return item1 < item2 + end +end + +local sort_items_alphabetically = function(item1, item2) + return item1 < item2 +end + +local collect_items = function(filter, lang_code) + local items = {} + if filter then + filter = string.trim(filter) + filter = string.lower(filter) -- to make sure the search is case-insensitive + end + for itemstring, def in pairs(core.registered_items) do + if itemstring ~= "" and itemstring ~= "unknown" and itemstring ~= "ignore" then + if filter and lang_code then + local desc = ItemStack(itemstring):get_description() + local matches + -- First, try to match original description + if desc ~= "" then + local ldesc = string.lower(desc) + matches = string.match(ldesc, filter) ~= nil + -- Second, try to match translated description + if not matches then + local tdesc = core.get_translated_string(lang_code, desc) + if tdesc ~= "" then + tdesc = string.lower(tdesc) + matches = string.match(tdesc, filter) ~= nil + end + end + -- Third, try to match translated short description + if not matches then + local sdesc = ItemStack(itemstring):get_short_description() + if sdesc ~= "" then + sdesc = core.get_translated_string(lang_code, sdesc) + sdesc = string.lower(sdesc) + matches = string.match(sdesc, filter) ~= nil + end + end + + end + -- Fourth, try to match itemstring + if not matches then + matches = string.match(itemstring, filter) ~= nil + end + + -- If item was matched, add to item list + if matches then + table.insert(items, itemstring) + end + else + table.insert(items, itemstring) + end + end + end + local compare + if SORT_MODE == "by_type" then + compare = sort_items_by_type + elseif SORT_MODE == "abc" then + compare = sort_items_alphabetically + end + table.sort(items, compare) + + return items +end + +local function update_inventory(name) + local search = current_searches[name] or "" + local items + if search == "" then + items = all_items_list + else + local lang_code = core.get_player_information(name).lang_code + items = collect_items(search, lang_code) + end + local max_page = math.ceil(#items / SLOTS) + current_max_pages[name] = max_page + + local inv = detached_inventories[name].items + inv:set_size("main", #items) + inv:set_list("main", items) + if not current_pages[name] then + current_pages[name] = 1 + end + if current_pages[name] > max_page then + current_pages[name] = max_page + end + if current_pages[name] < 1 then + current_pages[name] = 1 + end +end + +local function get_formspec(page, name) + local start = 0 + (page-1)*SLOTS + if not name then + return "" + end + local player = core.get_player_by_name(name) + local playerinvsize = player:get_inventory():get_size("main") + local hotbarsize = player:hud_get_hotbar_itemcount() + local pinv_w, pinv_h, pinv_x + pinv_w = hotbarsize + pinv_h = math.ceil(playerinvsize / pinv_w) + pinv_w = math.min(pinv_w, 10) + pinv_h = math.min(pinv_w, 4) + pinv_x = 0 + if pinv_w < 9 then + pinv_x = 1 + end + + local pagestr = "" + local max_page = current_max_pages[name] + if max_page > 1 then + pagestr = "button[0,5.45;1,1;chest_of_everything_prev;"..F(S("<")).."]".. + "button[1,5.45;1,1;chest_of_everything_next;"..F(S(">")).."]".. + "label[0,5.1;"..F(S("Page: @1/@2", page, max_page)).."]" + end + + local search_text = current_searches[name] or "" + + local inventory_list + if current_max_pages[name] > 0 then + inventory_list = "list[detached:chest_of_everything_items_"..name..";main;0,0;"..SLOTS_W..","..SLOTS_H..";"..start.."]" + else + inventory_list = "label[2.5,2.5;"..F(S("No items found.")).."]" + if search_text ~= "" then + inventory_list = inventory_list .. "button[2.5,3.25;3,0.8;search_button_reset_big;"..F(S("Reset search")).."]" + end + end + + return "size[10,10.5]".. + inventory_list .. + "list[current_player;main;"..pinv_x..",6.75;"..pinv_w..","..pinv_h..";]" .. + "label[9,5.1;"..F(S("Trash:")).."]" .. + "list[detached:chest_of_everything_trash_"..name..";main;9,5.5;1,1]" .. + "field[2.2,5.75;4,1;search;;"..F(search_text).."]" .. + "field_enter_after_edit[search;true]" .. + "field_close_on_enter[search;false]" .. + "button[6,5.45;1.6,1;search_button_start;"..F(S("Search")).."]" .. + "button[7.6,5.45;0.8,1;search_button_reset;"..F(S("X")).."]" .. + "tooltip[search_button_reset;"..F(S("Reset search")).."]" .. + pagestr .. + "listring[detached:chest_of_everything_items_"..name..";main]".. + "listring[current_player;main]".. + "listring[detached:chest_of_everything_trash_"..name..";main]" +end + +local show_formspec = function(name) + local page = current_pages[name] + local form = get_formspec(page, name) + core.show_formspec(name, "chest_of_everything:getitem", form) + return true +end + +core.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "chest_of_everything:getitem" then + return + end + local name = player:get_player_name() + local page = current_pages[name] + local old_page = page + -- Next page or previous page + if fields.chest_of_everything_next or fields.chest_of_everything_prev then + if fields.chest_of_everything_next then + page = page + 1 + elseif fields.chest_of_everything_prev then + page = page - 1 + end + -- Handle page change + if page < 1 then + page = 1 + end + local max_page = current_max_pages[name] + if page > max_page then + page = max_page + end + if page ~= old_page then + current_pages[name] = page + show_formspec(name) + end + return + -- Search + elseif (fields.search_button_start or (fields.key_enter and fields.key_enter_field == "search")) and fields.search then + current_searches[name] = fields.search + update_inventory(name) + show_formspec(name, fields.search) + return + -- Reset search + elseif (fields.search_button_reset or fields.search_button_reset_big) then + current_searches[name] = "" + update_inventory(name) + show_formspec(name) + return + end +end) + +core.register_tool("chest_of_everything:bag", { + description = S("Bag of Everything") .. "\n" .. + S("Grants access to all items"), + inventory_image = "chest_of_everything_bag.png", + wield_image = "chest_of_everything_bag.png", + groups = { disable_repair = 1 }, + on_use = function(itemstack, user) + if user and user:is_player() then + local name = user:get_player_name() + show_formspec(name) + end + end, +}) + +core.register_node("chest_of_everything:chest", { + description = S("Chest of Everything") .. "\n" .. + S("Grants access to all items"), + tiles ={"chest_of_everything_chest.png^[sheet:2x2:0,0", "chest_of_everything_chest.png^[sheet:2x2:0,0", + "chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:1,0", + "chest_of_everything_chest.png^[sheet:2x2:1,0", "chest_of_everything_chest.png^[sheet:2x2:0,1"}, + paramtype2 = "4dir", + groups = { dig_immediate=2, choppy=3 }, + is_ground_content = false, + on_construct = function(pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", S("Chest of Everything")) + end, + on_rightclick = function(pos, node, clicker) + if clicker and clicker:is_player() then + local name = clicker:get_player_name() + show_formspec(name) + end + end, +}) + + +core.register_on_mods_loaded(function() + all_items_list = collect_items() +end) + +core.register_on_joinplayer(function(player) + local name = player:get_player_name() + current_searches[name] = "" + current_pages[name] = 1 + current_max_pages[name] = 0 + add_detached_inventories(player) + update_inventory(name) +end) + +core.register_on_leaveplayer(function(player) + local name = player:get_player_name() + current_pages[name] = nil + current_max_pages[name] = nil + current_searches[name] = nil +end) diff --git a/data/games/garage/mods/chest_of_everything/mod.conf b/data/games/garage/mods/chest_of_everything/mod.conf new file mode 100644 index 0000000..50dc2d5 --- /dev/null +++ b/data/games/garage/mods/chest_of_everything/mod.conf @@ -0,0 +1,2 @@ +name = chest_of_everything +description = Adds the chest of everything and bag of everything from which you can take all items diff --git a/data/games/garage/mods/chest_of_everything/textures/chest_of_everything_bag.png b/data/games/garage/mods/chest_of_everything/textures/chest_of_everything_bag.png new file mode 100644 index 0000000000000000000000000000000000000000..7c189076d57d8349294c13db2cc688b43fd75e5e GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`J)SO(Ar*|t2bljYPB1#~|N7jv z|I?RfG#YfaDe^d&u^cv7#QSl}MYcp9XO5rp%LI=cJMhEgP)=i}n?#Gaf=SY6>qDv* z3^9*CZ|0CX$R^!z{k?{ny~UA+b84p;6x?o974tK5On$@E#lw&o6W4H3n8!n=(Idv^ vz?{y$#Fq^Xj2zAdiHklTsJ|m2%)szrj{NY#WV2&Ni$kQv6`qL> z9n&@ym>6>%WewaLAJ-?AB>FT%OY0)*5pGTvBaR88atuw60 or r==1)) then + local d + if l > 0 then + d = string.format("Dig Test Node: %s=%d, level=%d", gr, r, l) + else + d = string.format("Dig Test Node: %s=%d", gr, r) + end + local tile = "dignodes_"..gr..".png^dignodes_rating"..r..".png" + if l==1 then + tile = tile .. "^[colorize:#FFFF00:127" + elseif l==2 then + tile = tile .. "^[colorize:#FF0000:127" + end + core.register_node("dignodes:"..gr.."_"..r.."_"..l, { + description = d, + tiles = { tile }, + groups = { [gr] = r, level = l }, + }) + end + end + end +end + +-- Node without any digging groups +core.register_node("dignodes:none", { + description = "Dig Test Node: groupless".."\n".. + "Can't be dug by normal digging tools".."\n".. + "(use the Remover tool to remove)", + tiles = {"dignodes_none.png"}, +}) diff --git a/data/games/garage/mods/dignodes/mod.conf b/data/games/garage/mods/dignodes/mod.conf new file mode 100644 index 0000000..52a80d6 --- /dev/null +++ b/data/games/garage/mods/dignodes/mod.conf @@ -0,0 +1,2 @@ +name = dignodes +description = Nodes with different digging groups diff --git a/data/games/garage/mods/dignodes/textures/dignodes_choppy.png b/data/games/garage/mods/dignodes/textures/dignodes_choppy.png new file mode 100644 index 0000000000000000000000000000000000000000..a73fc2424140e0f429b274ac72f7f20dfa0e2679 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFv4DbnYU0GAJvbOfp)~y$}Z0YFe z$j{HexOHnnLPD&qijxxOikg}*;naAb;!sZ)$B+uf{?+H-_Ooy2~ z^2AooymRMcczj*LcQX&olv<{isJt-dt?5!e&krrHOnmX$!?^6Y!qo}Sns|?KCpB+$ p%$dM@yoBY??1e0;22OJs8MJSTiT2c9ybH96!PC{xWt~$(695yGNCp4^ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/dignodes/textures/dignodes_crumbly.png b/data/games/garage/mods/dignodes/textures/dignodes_crumbly.png new file mode 100644 index 0000000000000000000000000000000000000000..23f2f7c71997d29bdc50006a6161e2ad72770b24 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|#hxyXAr*|hliV2_3$9y!AC4Vz5>8yM*x-;Mz`@J3*zti0#~ilC3koJmEo_YU%xdp3=hr;d UT_6>-4ro1tr>mdKI;Vst0NN`!F8}}l literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/dignodes/textures/dignodes_dig_immediate.png b/data/games/garage/mods/dignodes/textures/dignodes_dig_immediate.png new file mode 100644 index 0000000000000000000000000000000000000000..a532ad90b20e7b7eb69c87721229852c5d5c3c4b GIT binary patch literal 170 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|g`O^sAr*{kCpmH*P~c&yUHD_c zSNpe-#ou_py7u1CwQUh{lz5R?KC7cmSmMbWCXQb(mCUyK=`Bj-n(yYl^5}{$L2`~q zggO)_m^vlQBopV($|DsyIK;3sOgOJ^=RaVP&+-FI)sV}UvbN}TM$WeFg{r3|) z53rT`IKH%Y>|3PVqsw&DRQ|Gb;`)y69m$Bq+#}VJFug`b_-NxYQ>gTe~DWM4foq|u| literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/dignodes/textures/dignodes_rating1.png b/data/games/garage/mods/dignodes/textures/dignodes_rating1.png new file mode 100644 index 0000000000000000000000000000000000000000..d2fee3a23269731a2c9e56a86e04df3c1b386e23 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`s-7;6Ar*|t61x&adYb+N!9thM q^&1$cFjz@9TwuA*b2x-EfMNDurIQCQ3tR$fVDNPHb6Mw<&;$T}$sKe6 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/dignodes/textures/dignodes_rating2.png b/data/games/garage/mods/dignodes/textures/dignodes_rating2.png new file mode 100644 index 0000000000000000000000000000000000000000..15329b93fa9b94075774044d3ec7af828362d072 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`%APKcAr*|t60;ISdYb+NL1SVU n@1h&5CEF$4{(ljBBJz$}iz#X|e(1wus&+upX zbDUXs?RrwE3%B$3JTp6UdxK%?-39>s+yRI;0X{UH`i!|z#A8;Pu>tpa=*B_FO6=oB z82CYC43J_R4Y}Xrp;3M57}IRZPUQ;BWK$kSUf?6xPFZYjvZ#v*Sjm!F#7gZM^W72p zSX0DI<_A4a0qbmjc4f`jh({NKD)E&`hhvSX>kg6LPFtq<3l?ETl0VrAowBSfGRC1d z@?vi)0d5?JUS|@MIb)xlX0=sy>Y`HJX?!ZzSSf9?*70e@aT;&GSgd4YC!XK)xhNVjoh$yAwe$Wu@9Y$H%1LX4nXU=n6>ai8SnAiJF3?4OZ>i&&+9ch#TDi{eWB&J zPFFc7zD!p>lB;wTUnLjvJSq>_NnP0_m+1=}lD24G`cfR-M>_fcl1bhYJDFSXB~Inj zeWCzv;taB$@(G;uDXx+VldLE1!m>PxGw6AKypp|=#D{EJ2Ie6gNm}P*%lI4e5e_Bc z$u{uOM9fZOmG_Hf^WTks6-!8Y#O@CbeZCD@ea literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/gltf/models/gltf_blender_cube.gltf b/data/games/garage/mods/gltf/models/gltf_blender_cube.gltf new file mode 100644 index 0000000..041b4a1 --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_blender_cube.gltf @@ -0,0 +1 @@ +{"asset":{"generator":"Khronos glTF Blender I/O v1.7.33","version":"2.0"},"scene":0,"scenes":[{"name":"Scene","nodes":[0]}],"nodes":[{"mesh":0,"name":"Cube","scale":[10,10,10]}],"meshes":[{"name":"Cube.004","primitives":[{"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3}]}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"type":"SCALAR"}],"bufferViews":[{"buffer":0,"byteLength":288,"byteOffset":0},{"buffer":0,"byteLength":288,"byteOffset":288},{"buffer":0,"byteLength":192,"byteOffset":576},{"buffer":0,"byteLength":72,"byteOffset":768}],"buffers":[{"byteLength":840,"uri":"data:application/octet-stream;base64,AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAADAPgAAgD8AAAA+AACAPgAAwD4AAAAAAAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AAADAAkAAAAJAAYACAAKABUACAAVABMAFAAXABEAFAARAA4ADQAPAAQADQAEAAIABwASAAwABwAMAAEAFgALAAUAFgAFABAA"}]} diff --git a/data/games/garage/mods/gltf/models/gltf_blender_cube_matrix_transform.gltf b/data/games/garage/mods/gltf/models/gltf_blender_cube_matrix_transform.gltf new file mode 100644 index 0000000..50235ce --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_blender_cube_matrix_transform.gltf @@ -0,0 +1 @@ +{"asset":{"generator":"Khronos glTF Blender I/O v1.7.33","version":"2.0"},"scene":0,"scenes":[{"name":"Scene","nodes":[0]}],"nodes":[{"mesh":0,"name":"Cube","matrix":[1,0,0,0,0,2,0,0,0,0,3,0,4,5,6,1]}],"meshes":[{"name":"Cube.004","primitives":[{"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3}]}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"type":"SCALAR"}],"bufferViews":[{"buffer":0,"byteLength":288,"byteOffset":0},{"buffer":0,"byteLength":288,"byteOffset":288},{"buffer":0,"byteLength":192,"byteOffset":576},{"buffer":0,"byteLength":72,"byteOffset":768}],"buffers":[{"byteLength":840,"uri":"data:application/octet-stream;base64,AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAADAPgAAgD8AAAA+AACAPgAAwD4AAAAAAAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AAADAAkAAAAJAAYACAAKABUACAAVABMAFAAXABEAFAARAA4ADQAPAAQADQAEAAIABwASAAwABwAMAAEAFgALAAUAFgAFABAA"}]} diff --git a/data/games/garage/mods/gltf/models/gltf_blender_cube_scaled.gltf b/data/games/garage/mods/gltf/models/gltf_blender_cube_scaled.gltf new file mode 100644 index 0000000..3b626b3 --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_blender_cube_scaled.gltf @@ -0,0 +1 @@ +{"asset":{"generator":"Khronos glTF Blender I/O v1.7.33","version":"2.0"},"scene":0,"scenes":[{"name":"Scene","nodes":[0]}],"nodes":[{"mesh":0,"name":"Cube","scale":[150,1,21.5]}],"meshes":[{"name":"Cube.004","primitives":[{"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3}]}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"type":"SCALAR"}],"bufferViews":[{"buffer":0,"byteLength":288,"byteOffset":0},{"buffer":0,"byteLength":288,"byteOffset":288},{"buffer":0,"byteLength":192,"byteOffset":576},{"buffer":0,"byteLength":72,"byteOffset":768}],"buffers":[{"byteLength":840,"uri":"data:application/octet-stream;base64,AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgL8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgD8AAIA/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgL8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAvwAAgD8AAIC/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgL8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgL8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAPwAAgD8AAIC/AACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAADAPgAAgD8AAAA+AACAPgAAwD4AAAAAAAAgPwAAgD8AACA/AAAAAAAAYD8AAIA+AADAPgAAQD8AAAA+AAAAPwAAwD4AAEA/AAAgPwAAQD8AACA/AABAPwAAYD8AAAA/AADAPgAAgD4AAMA+AACAPgAAwD4AAIA+AAAgPwAAgD4AACA/AACAPgAAID8AAIA+AADAPgAAAD8AAMA+AAAAPwAAwD4AAAA/AAAgPwAAAD8AACA/AAAAPwAAID8AAAA/AAADAAkAAAAJAAYACAAKABUACAAVABMAFAAXABEAFAARAA4ADQAPAAQADQAEAAIABwASAAwABwAMAAEAFgALAAUAFgAFABAA"}]} diff --git a/data/games/garage/mods/gltf/models/gltf_frog.gltf b/data/games/garage/mods/gltf/models/gltf_frog.gltf new file mode 100644 index 0000000..a41e9de --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_frog.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0","generator":"Blockbench 4.9.4 glTF exporter"},"scenes":[{"nodes":[20],"name":"blockbench_export"}],"scene":0,"nodes":[{"name":"cube","mesh":0},{"name":"cube","mesh":1},{"name":"cube","mesh":2},{"name":"body","children":[0,1,2]},{"translation":[0,0,-0.0625],"name":"cube","mesh":3},{"translation":[0.03125,0,-0.3125],"name":"cube","mesh":4},{"rotation":[0,-0.19509032201612825,0,0.9807852804032304],"translation":[0.01812248876854733,-0.0625,-0.25194388507103505],"name":"cube","mesh":5},{"translation":[0.0625,0,0.3125],"name":"leftleg","children":[4,5,6]},{"translation":[0.0625,0,-0.3125],"name":"cube","mesh":6},{"translation":[-0.03125,0,-0.3125],"name":"cube","mesh":7},{"rotation":[0,0.19509032201612825,0,0.9807852804032304],"translation":[-0.01812248876854733,-0.0625,-0.25194388507103505],"name":"cube","mesh":8},{"translation":[-0.0625,0,0.3125],"name":"rightleg","children":[8,9,10]},{"translation":[-0.125,-0.0625,0.125],"name":"cube","mesh":9},{"rotation":[0,0.5372996083468239,0,0.8433914458128857],"translation":[0.10431178959951112,-0.0625,0.2349474087973531],"name":"cube","mesh":10},{"rotation":[0,0.5372996083468239,0,0.8433914458128857],"translation":[0.10431178959951112,-0.0625,0.2349474087973531],"name":"cube","mesh":11},{"translation":[0.125,0.0625,-0.125],"name":"leftarm","children":[12,13,14]},{"translation":[0.125,-0.0625,0.125],"name":"cube","mesh":12},{"rotation":[0,-0.5372996083468239,0,0.8433914458128857],"translation":[-0.10431178959951112,-0.0625,0.2349474087973531],"name":"cube","mesh":13},{"rotation":[0,-0.5372996083468239,0,0.8433914458128857],"translation":[-0.10431178959951112,-0.0625,0.2349474087973531],"name":"cube","mesh":14},{"translation":[-0.125,0.0625,-0.125],"name":"rightarm","children":[16,17,18]},{"children":[3,7,11,15,19]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":288,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":576,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":768,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":840,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1128,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1416,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":1608,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":1680,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1968,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":2256,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":2448,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":2520,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":2808,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":3096,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":3288,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":3360,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":3648,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":3936,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":4128,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":4200,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":4488,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":4776,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":4968,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":5040,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":5328,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":5616,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":5808,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":5880,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":6168,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":6456,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":6648,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":6720,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":7008,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":7296,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":7488,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":7560,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":7848,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":8136,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":8328,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":8400,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":8688,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":8976,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":9168,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":9240,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":9528,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":9816,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":10008,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":10080,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":10368,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":10656,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":10848,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":10920,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":11208,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":11496,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":11688,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":11760,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":12048,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":12336,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":12528,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":12600,"byteLength":12},{"buffer":0,"byteOffset":12612,"byteLength":48},{"buffer":0,"byteOffset":12660,"byteLength":12},{"buffer":0,"byteOffset":12672,"byteLength":48},{"buffer":0,"byteOffset":12720,"byteLength":12},{"buffer":0,"byteOffset":12732,"byteLength":48},{"buffer":0,"byteOffset":12780,"byteLength":12},{"buffer":0,"byteOffset":12792,"byteLength":48},{"buffer":0,"byteOffset":12840,"byteLength":12},{"buffer":0,"byteOffset":12852,"byteLength":48},{"buffer":0,"byteOffset":12900,"byteLength":12},{"buffer":0,"byteOffset":12912,"byteLength":48},{"buffer":0,"byteOffset":12960,"byteLength":12},{"buffer":0,"byteOffset":12972,"byteLength":48},{"buffer":0,"byteOffset":13020,"byteLength":12},{"buffer":0,"byteOffset":13032,"byteLength":48},{"buffer":0,"byteOffset":13080,"byteLength":12},{"buffer":0,"byteOffset":13092,"byteLength":48},{"buffer":0,"byteOffset":13140,"byteLength":4},{"buffer":0,"byteOffset":13144,"byteLength":16},{"buffer":0,"byteOffset":13160,"byteLength":4},{"buffer":0,"byteOffset":13164,"byteLength":16}],"buffers":[{"byteLength":13180,"uri":"data:application/octet-stream;base64,AAAgPgAAAD4AAIA+AAAgPgAAAD4AAIC9AAAgPgAAAAAAAIA+AAAgPgAAAAAAAIC9AAAgvgAAAD4AAIC9AAAgvgAAAD4AAIA+AAAgvgAAAAAAAIC9AAAgvgAAAAAAAIA+AAAgvgAAAD4AAIC9AAAgPgAAAD4AAIC9AAAgvgAAAD4AAIA+AAAgPgAAAD4AAIA+AAAgvgAAAAAAAIA+AAAgPgAAAAAAAIA+AAAgvgAAAAAAAIC9AAAgPgAAAAAAAIC9AAAgvgAAAD4AAIA+AAAgPgAAAD4AAIA+AAAgvgAAAAAAAIA+AAAgPgAAAAAAAIA+AAAgPgAAAD4AAIC9AAAgvgAAAD4AAIC9AAAgPgAAAAAAAIC9AAAgvgAAAAAAAIC9AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAOgCAID4AgB8+AIAgPgAAADoAgF8+AIAfPgCAXz4AQKA+AIAgPgDA7z4AgCA+AECgPgCAXz4AwO8+AIBfPgDAnz4AgB8+AIAgPgCAHz4AwJ8+AAAAOgCAID4AAAA6AMDvPgAAADoAQKA+AAAAOgDA7z4AgB8+AECgPgCAHz4AQPA+AIAgPgDgHz8AgCA+AEDwPgCAXz4A4B8/AIBfPgCAID4AgCA+AMCfPgCAID4AgCA+AIBfPgDAnz4AgF8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAAPgAAAD4AAIC9AAAAPgAAAD4AAKC+AAAAPgAAAAAAAIC9AAAAPgAAAAAAAKC+AAAAvgAAAD4AAKC+AAAAvgAAAD4AAIC9AAAAvgAAAAAAAKC+AAAAvgAAAAAAAIC9AAAAvgAAAD4AAKC+AAAAPgAAAD4AAKC+AAAAvgAAAD4AAIC9AAAAPgAAAD4AAIC9AAAAvgAAAAAAAIC9AAAAPgAAAAAAAIC9AAAAvgAAAAAAAKC+AAAAPgAAAAAAAKC+AAAAvgAAAD4AAIC9AAAAPgAAAD4AAIC9AAAAvgAAAAAAAIC9AAAAPgAAAAAAAIC9AAAAPgAAAD4AAKC+AAAAvgAAAD4AAKC+AAAAPgAAAAAAAKC+AAAAvgAAAAAAAKC+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAOgBAsD4AAP89AECwPgAAADoAwM8+AAD/PQDAzz4AQIA+AECwPgDAvz4AQLA+AECAPgDAzz4AwL8+AMDPPgCAfz4AwK8+AIAAPgDArz4AgH8+AIBgPgCAAD4AgGA+AMC/PgCAYD4AQIA+AIBgPgDAvz4AwK8+AECAPgDArz4AQMA+AECwPgDA/z4AQLA+AEDAPgDAzz4AwP8+AMDPPgCAAD4AQLA+AIB/PgBAsD4AgAA+AMDPPgCAfz4AwM8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAAPQAAAD4AAKA+AAAAPQAAAD4AAIA+AAAAPQAAAAAAAKA+AAAAPQAAAAAAAIA+AAAAvQAAAD4AAIA+AAAAvQAAAD4AAKA+AAAAvQAAAAAAAIA+AAAAvQAAAAAAAKA+AAAAvQAAAD4AAIA+AAAAPQAAAD4AAIA+AAAAvQAAAD4AAKA+AAAAPQAAAD4AAKA+AAAAvQAAAAAAAKA+AAAAPQAAAAAAAKA+AAAAvQAAAAAAAIA+AAAAPQAAAAAAAIA+AAAAvQAAAD4AAKA+AAAAPQAAAD4AAKA+AAAAvQAAAAAAAKA+AAAAPQAAAAAAAKA+AAAAPQAAAD4AAIA+AAAAvQAAAD4AAIA+AAAAPQAAAAAAAIA+AAAAvQAAAAAAAIA+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AEDwPgAAAj0AwP8+AAACPQBA8D4AAL89AMD/PgAAvz0AIAg/AAACPQDgDz8AAAI9ACAIPwAAvz0A4A8/AAC/PQDgBz8AAPw8ACAAPwAA/DwA4Ac/AAAAOgAgAD8AAAA6AOAPPwAAADoAIAg/AAAAOgDgDz8AAPw8ACAIPwAA/DwAIBA/AAACPQDgFz8AAAI9ACAQPwAAvz0A4Bc/AAC/PQAgAD8AAAI9AOAHPwAAAj0AIAA/AAC/PQDgBz8AAL89AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAABgPgAAAD4AAEA+AABgPgAAAD4AAAAAAABgPgAAAAAAAEA+AABgPgAAAAAAAAAAAAAAvQAAAD4AAAAAAAAAvQAAAD4AAEA+AAAAvQAAAAAAAAAAAAAAvQAAAAAAAEA+AAAAvQAAAD4AAAAAAABgPgAAAD4AAAAAAAAAvQAAAD4AAEA+AABgPgAAAD4AAEA+AAAAvQAAAAAAAEA+AABgPgAAAAAAAEA+AAAAvQAAAAAAAAAAAABgPgAAAAAAAAAAAAAAvQAAAD4AAEA+AABgPgAAAD4AAEA+AAAAvQAAAAAAAEA+AABgPgAAAAAAAEA+AABgPgAAAD4AAAAAAAAAvQAAAD4AAAAAAABgPgAAAAAAAAAAAAAAvQAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AEDQPgBA0D4AwP8+AEDQPgBA0D4AwO8+AMD/PgDA7z4AICA/AEDQPgDgNz8AQNA+ACAgPwDA7z4A4Dc/AMDvPgDgHz8AwM8+ACAAPwDAzz4A4B8/AECgPgAgAD8AQKA+AOA/PwBAoD4AICA/AECgPgDgPz8AwM8+ACAgPwDAzz4AIDg/AEDQPgDgVz8AQNA+ACA4PwDA7z4A4Fc/AMDvPgAgAD8AQNA+AOAfPwBA0D4AIAA/AMDvPgDgHz8AwO8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAABgPgAAwD0AABA/AABgPgAAwD0AAKA+AABgPgAAAD0AABA/AABgPgAAAD0AAKA+AADAPQAAwD0AAKA+AADAPQAAwD0AABA/AADAPQAAAD0AAKA+AADAPQAAAD0AABA/AADAPQAAwD0AAKA+AABgPgAAwD0AAKA+AADAPQAAwD0AABA/AABgPgAAwD0AABA/AADAPQAAAD0AABA/AABgPgAAAD0AABA/AADAPQAAAD0AAKA+AABgPgAAAD0AAKA+AADAPQAAwD0AABA/AABgPgAAwD0AABA/AADAPQAAAD0AABA/AABgPgAAAD0AABA/AABgPgAAwD0AAKA+AADAPQAAwD0AAKA+AABgPgAAAD0AAKA+AADAPQAAAD0AAKA+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AECgPgAgGD8AwN8+ACAYPwBAoD4A4B8/AMDfPgDgHz8AIAA/ACAYPwDgHz8AIBg/ACAAPwDgHz8A4B8/AOAfPwDA/z4A4Bc/AEDgPgDgFz8AwP8+AEDwPgBA4D4AQPA+AOAPPwBA8D4AIAA/AEDwPgDgDz8A4Bc/ACAAPwDgFz8AICA/ACAYPwDgLz8AIBg/ACAgPwDgHz8A4C8/AOAfPwBA4D4AIBg/AMD/PgAgGD8AQOA+AOAfPwDA/z4A4B8/AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAMQjQPgAAQD4AAMA+MQjQPgAAQD4AAIA+MQjQPgAAgD0AAMA+MQjQPgAAgD0AAIA+AADQPgAAQD4AAIA+AADQPgAAQD4AAMA+AADQPgAAgD0AAIA+AADQPgAAgD0AAMA+AADQPgAAQD4AAIA+MQjQPgAAQD4AAIA+AADQPgAAQD4AAMA+MQjQPgAAQD4AAMA+AADQPgAAgD0AAMA+MQjQPgAAgD0AAMA+AADQPgAAgD0AAIA+MQjQPgAAgD0AAIA+AADQPgAAQD4AAMA+MQjQPgAAQD4AAMA+AADQPgAAgD0AAMA+MQjQPgAAgD0AAMA+MQjQPgAAQD4AAIA+AADQPgAAQD4AAIA+MQjQPgAAgD0AAIA+AADQPgAAgD0AAIA+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAOgCAYD4AAH49AIBgPgAAADoAwI8+AAB+PQDAjz4AAIE9AIBgPgAA/z0AgGA+AACBPQDAjz4AAP89AMCPPgAAgT0AgF8+AAB+PQCAXz4AAIE9AIAgPgAAfj0AgCA+AACBPQCAID4AAH49AIAgPgAAgT0AgF8+AAB+PQCAXz4AgAA+AIBgPgAA/z0AgGA+AIAAPgDAjz4AAP89AMCPPgAAgT0AgGA+AAB+PQCAYD4AAIE9AMCPPgAAfj0AwI8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAAvQAAAD4AAOA+AAAAvQAAAD4AAIA+AAAAvQAAAAAAAOA+AAAAvQAAAAAAAIA+AACQvgAAAD4AAIA+AACQvgAAAD4AAOA+AACQvgAAAAAAAIA+AACQvgAAAAAAAOA+AACQvgAAAD4AAIA+AAAAvQAAAD4AAIA+AACQvgAAAD4AAOA+AAAAvQAAAD4AAOA+AACQvgAAAAAAAOA+AAAAvQAAAAAAAOA+AACQvgAAAAAAAIA+AAAAvQAAAAAAAIA+AACQvgAAAD4AAOA+AAAAvQAAAD4AAOA+AACQvgAAAAAAAOA+AAAAvQAAAAAAAOA+AAAAvQAAAD4AAIA+AACQvgAAAD4AAIA+AAAAvQAAAAAAAIA+AACQvgAAAAAAAIA+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAOgAgAD8AAL89ACAAPwAAADoA4A8/AAC/PQDgDz8AgGA+ACAAPwDAnz4AIAA/AIBgPgDgDz8AwJ8+AOAPPwCAXz4AwP8+AADBPQDA/z4AgF8+AEDQPgAAwT0AQNA+AMCvPgBA0D4AgGA+AEDQPgDArz4AwP8+AIBgPgDA/z4AQKA+ACAAPwDA3z4AIAA/AECgPgDgDz8AwN8+AOAPPwAAwT0AIAA/AIBfPgAgAD8AAME9AOAPPwCAXz4A4A8/AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAADAvQAAwD0AABA/AADAvQAAwD0AAKA+AADAvQAAAD0AABA/AADAvQAAAD0AAKA+AABgvgAAwD0AAKA+AABgvgAAwD0AABA/AABgvgAAAD0AAKA+AABgvgAAAD0AABA/AABgvgAAwD0AAKA+AADAvQAAwD0AAKA+AABgvgAAwD0AABA/AADAvQAAwD0AABA/AABgvgAAAD0AABA/AADAvQAAAD0AABA/AABgvgAAAD0AAKA+AADAvQAAAD0AAKA+AABgvgAAwD0AABA/AADAvQAAwD0AABA/AABgvgAAAD0AABA/AADAvQAAAD0AABA/AADAvQAAwD0AAKA+AABgvgAAwD0AAKA+AADAvQAAAD0AAKA+AABgvgAAAD0AAKA+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AEDwPgCAAD4A4Bc/AIAAPgBA8D4AgB8+AOAXPwCAHz4AICg/AIAAPgDgRz8AgAA+ACAoPwCAHz4A4Ec/AIAfPgDgJz8AAP89ACAYPwAA/z0A4Cc/AAAAOgAgGD8AAAA6AOA3PwAAADoAICg/AAAAOgDgNz8AAP89ACAoPwAA/z0AIEg/AIAAPgDgVz8AgAA+ACBIPwCAHz4A4Fc/AIAfPgAgGD8AgAA+AOAnPwCAAD4AIBg/AIAfPgDgJz8AgB8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAz/fPvgAAQD4AAMA+z/fPvgAAQD4AAIA+z/fPvgAAgD0AAMA+z/fPvgAAgD0AAIA+AADQvgAAQD4AAIA+AADQvgAAQD4AAMA+AADQvgAAgD0AAIA+AADQvgAAgD0AAMA+AADQvgAAQD4AAIA+z/fPvgAAQD4AAIA+AADQvgAAQD4AAMA+z/fPvgAAQD4AAMA+AADQvgAAgD0AAMA+z/fPvgAAgD0AAMA+AADQvgAAgD0AAIA+z/fPvgAAgD0AAIA+AADQvgAAQD4AAMA+z/fPvgAAQD4AAMA+AADQvgAAgD0AAMA+z/fPvgAAgD0AAMA+z/fPvgAAQD4AAIA+AADQvgAAQD4AAIA+z/fPvgAAgD0AAIA+AADQvgAAgD0AAIA+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAOgAAgT0AAH49AACBPQAAADoAAP89AAB+PQAA/z0AAIE9AACBPQAA/z0AAIE9AACBPQAA/z0AAP89AAD/PQAAgT0AAH49AAB+PQAAfj0AAIE9AAAAOgAAfj0AAAA6AACBPQAAADoAAH49AAAAOgAAgT0AAH49AAB+PQAAfj0AgAA+AACBPQAA/z0AAIE9AIAAPgAA/z0AAP89AAD/PQAAgT0AAIE9AAB+PQAAgT0AAIE9AAD/PQAAfj0AAP89AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAACAPgAAwD0AAMC9AACAPgAAwD0AACC+AACAPgAAAD0AAMC9AACAPgAAAD0AACC+AAAAPgAAwD0AACC+AAAAPgAAwD0AAMC9AAAAPgAAAD0AACC+AAAAPgAAAD0AAMC9AAAAPgAAwD0AACC+AACAPgAAwD0AACC+AAAAPgAAwD0AAMC9AACAPgAAwD0AAMC9AAAAPgAAAD0AAMC9AACAPgAAAD0AAMC9AAAAPgAAAD0AACC+AACAPgAAAD0AACC+AAAAPgAAwD0AAMC9AACAPgAAwD0AAMC9AAAAPgAAAD0AAMC9AACAPgAAAD0AAMC9AACAPgAAwD0AACC+AAAAPgAAwD0AACC+AACAPgAAAD0AACC+AAAAPgAAAD0AACC+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/ACAIPwBAkD4A4A8/AECQPgAgCD8AwJ8+AOAPPwDAnz4AICA/AECQPgDgJz8AQJA+ACAgPwDAnz4A4Cc/AMCfPgDgHz8AwI8+ACAQPwDAjz4A4B8/AECAPgAgED8AQIA+AOAvPwBAgD4AICA/AECAPgDgLz8AwI8+ACAgPwDAjz4AICg/AECQPgDgNz8AQJA+ACAoPwDAnz4A4Dc/AMCfPgAgED8AQJA+AOAfPwBAkD4AIBA/AMCfPgDgHz8AwJ8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAACQPgAAwD0AAMC9AACQPgAAwD0AACC+AACQPgAAAD0AAMC9AACQPgAAAD0AACC+AABgPgAAwD0AACC+AABgPgAAwD0AAMC9AABgPgAAAD0AACC+AABgPgAAAD0AAMC9AABgPgAAwD0AACC+AACQPgAAwD0AACC+AABgPgAAwD0AAMC9AACQPgAAwD0AAMC9AABgPgAAAD0AAMC9AACQPgAAAD0AAMC9AABgPgAAAD0AACC+AACQPgAAAD0AACC+AABgPgAAwD0AAMC9AACQPgAAwD0AAMC9AABgPgAAAD0AAMC9AACQPgAAAD0AAMC9AACQPgAAwD0AACC+AABgPgAAwD0AACC+AACQPgAAAD0AACC+AABgPgAAAD0AACC+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAOgBAoD4AAPw8AECgPgAAADoAwK8+AAD8PADArz4AAIE9AECgPgAAvz0AQKA+AACBPQDArz4AAL89AMCvPgAAfj0AwJ8+AAACPQDAnz4AAH49AECQPgAAAj0AQJA+AAC/PQBAkD4AAIE9AECQPgAAvz0AwJ8+AACBPQDAnz4AAME9AECgPgAA/z0AQKA+AADBPQDArz4AAP89AMCvPgAAAj0AQKA+AAB+PQBAoD4AAAI9AMCvPgAAfj0AwK8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAACwPsUggD0AAMC9AACwPsUggD0AACC+AACwPgAAgD0AAMC9AACwPgAAgD0AACC+AACQPsUggD0AACC+AACQPsUggD0AAMC9AACQPgAAgD0AACC+AACQPgAAgD0AAMC9AACQPsUggD0AACC+AACwPsUggD0AACC+AACQPsUggD0AAMC9AACwPsUggD0AAMC9AACQPgAAgD0AAMC9AACwPgAAgD0AAMC9AACQPgAAgD0AACC+AACwPgAAgD0AACC+AACQPsUggD0AAMC9AACwPsUggD0AAMC9AACQPgAAgD0AAMC9AACwPgAAgD0AAMC9AACwPsUggD0AACC+AACQPsUggD0AACC+AACwPgAAgD0AACC+AACQPgAAgD0AACC+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAOgCAID4AAPw8AIAgPgAAADoAgB8+AAD8PACAHz4AAIE9AIAgPgAAvz0AgCA+AACBPQCAHz4AAL89AIAfPgAAfj0AgB8+AAACPQCAHz4AAH49AIAAPgAAAj0AgAA+AAC/PQCAAD4AAIE9AIAAPgAAvz0AgB8+AACBPQCAHz4AAME9AIAgPgAA/z0AgCA+AADBPQCAHz4AAP89AIAfPgAAAj0AgCA+AAB+PQCAID4AAAI9AIAfPgAAfj0AgB8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAAvgAAwD0AAMC9AAAAvgAAwD0AACC+AAAAvgAAAD0AAMC9AAAAvgAAAD0AACC+AACAvgAAwD0AACC+AACAvgAAwD0AAMC9AACAvgAAAD0AACC+AACAvgAAAD0AAMC9AACAvgAAwD0AACC+AAAAvgAAwD0AACC+AACAvgAAwD0AAMC9AAAAvgAAwD0AAMC9AACAvgAAAD0AAMC9AAAAvgAAAD0AAMC9AACAvgAAAD0AACC+AAAAvgAAAD0AACC+AACAvgAAwD0AAMC9AAAAvgAAwD0AAMC9AACAvgAAAD0AAMC9AAAAvgAAAD0AAMC9AAAAvgAAwD0AACC+AACAvgAAwD0AACC+AAAAvgAAAD0AACC+AACAvgAAAD0AACC+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AEDAPgBAgD4AwM8+AECAPgBAwD4AwI8+AMDPPgDAjz4AQPA+AECAPgDA/z4AQIA+AEDwPgDAjz4AwP8+AMCPPgDA7z4AgH8+AEDQPgCAfz4AwO8+AIBgPgBA0D4AgGA+AOAHPwCAYD4AQPA+AIBgPgDgBz8AgH8+AEDwPgCAfz4AIAA/AECAPgDgDz8AQIA+ACAAPwDAjz4A4A8/AMCPPgBA0D4AQIA+AMDvPgBAgD4AQNA+AMCPPgDA7z4AwI8+AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAABgvgAAwD0AAMC9AABgvgAAwD0AACC+AABgvgAAAD0AAMC9AABgvgAAAD0AACC+AACQvgAAwD0AACC+AACQvgAAwD0AAMC9AACQvgAAAD0AACC+AACQvgAAAD0AAMC9AACQvgAAwD0AACC+AABgvgAAwD0AACC+AACQvgAAwD0AAMC9AABgvgAAwD0AAMC9AACQvgAAAD0AAMC9AABgvgAAAD0AAMC9AACQvgAAAD0AACC+AABgvgAAAD0AACC+AACQvgAAwD0AAMC9AABgvgAAwD0AAMC9AACQvgAAAD0AAMC9AABgvgAAAD0AAMC9AABgvgAAwD0AACC+AACQvgAAwD0AACC+AABgvgAAAD0AACC+AACQvgAAAD0AACC+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAOgAAAj0AAPw8AAACPQAAADoAAH49AAD8PAAAfj0AAIE9AAACPQAAvz0AAAI9AACBPQAAfj0AAL89AAB+PQAAfj0AAPw8AAACPQAA/DwAAH49AAAAOgAAAj0AAAA6AAC/PQAAADoAAIE9AAAAOgAAvz0AAPw8AACBPQAA/DwAAME9AAACPQAA/z0AAAI9AADBPQAAfj0AAP89AAB+PQAAAj0AAAI9AAB+PQAAAj0AAAI9AAB+PQAAfj0AAH49AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAACQvsUggD0AAMC9AACQvsUggD0AACC+AACQvgAAgD0AAMC9AACQvgAAgD0AACC+AACwvsUggD0AACC+AACwvsUggD0AAMC9AACwvgAAgD0AACC+AACwvgAAgD0AAMC9AACwvsUggD0AACC+AACQvsUggD0AACC+AACwvsUggD0AAMC9AACQvsUggD0AAMC9AACwvgAAgD0AAMC9AACQvgAAgD0AAMC9AACwvgAAgD0AACC+AACQvgAAgD0AACC+AACwvsUggD0AAMC9AACQvsUggD0AAMC9AACwvgAAgD0AAMC9AACQvgAAgD0AAMC9AACQvsUggD0AACC+AACwvsUggD0AACC+AACQvgAAgD0AACC+AACwvgAAgD0AACC+AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AACBPQAAAj0AAL89AAACPQAAgT0AAPw8AAC/PQAA/DwAgAA+AAACPQCAHz4AAAI9AIAAPgAA/DwAgB8+AAD8PAAA/z0AAPw8AADBPQAA/DwAAP89AAAAOgAAwT0AAAA6AIAfPgAAADoAgAA+AAAAOgCAHz4AAPw8AIAAPgAA/DwAgCA+AAACPQCAPz4AAAI9AIAgPgAA/DwAgD8+AAD8PAAAwT0AAAI9AAD/PQAAAj0AAME9AAD8PAAA/z0AAPw8AAACAAEAAgADAAEABAAGAAUABgAHAAUACAAKAAkACgALAAkADAAOAA0ADgAPAA0AEAASABEAEgATABEAFAAWABUAFgAXABUAAAAAAAAAwD4AAEA/AAAAAAAAAAAAAAAAAACAPxPyhT0AAAAAAAAAAK9zfz8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAwD4AAEA/AAAAAAAAAAAAAAAAAACAPwAAAADug4Q+AAAAAOpGdz8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAwD4AAEA/AAAAAAAAAAAAAAAAAACAPwAAAADug4S+AAAAAOpGdz8AAAAAIbWyvAAAAABn8H8/AAAAAAAAwD4AAEA/AAAAAAAAAAAAAAAAAACAPwAAAACoqAU+AAAAAFXPfT8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAwD4AAEA/AAAAAAAAAAAAAAAAAACAPwAAAACoqAW+AAAAAFXPfT8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAD+rqko/AAAAAAAAAAAAAAAAAACAPwAAAAAhtbI8AAAAAGfwfz8AAAAAx71QPAAAAACu+n8/AAAAAAAAAD+rqko/AAAAAAAAAAAAAAAAAACAPwAAAAAhtbK8AAAAAGfwfz8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAQD8AAMA/AAAAAAAAAAAAAAAAAACAPwAAAAC2frK9AAAAAJ4Gfz8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAQD8AAMA/AAAAAAAAAAAAAAAAAACAPwAAAAC2frI9AAAAAJ4Gfz8AAAAAAAAAAAAAAAAAAIA/AAAAAKioBb4AAAAAAAAAAFXPfT8AAIA+qKgFvgAAAAAAAAAAVc99Pw=="}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[0.15625,0.125,0.25],"min":[-0.15625,0,-0.0625],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"max":[0.62451171875,0.21826171875],"min":[0.00048828125,0.00048828125],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":4,"componentType":5126,"count":24,"max":[0.125,0.125,-0.0625],"min":[-0.125,0,-0.3125],"type":"VEC3"},{"bufferView":5,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":6,"componentType":5126,"count":24,"max":[0.49951171875,0.40576171875],"min":[0.00048828125,0.21923828125],"type":"VEC2"},{"bufferView":7,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":8,"componentType":5126,"count":24,"max":[0.03125,0.125,0.3125],"min":[-0.03125,0,0.25],"type":"VEC3"},{"bufferView":9,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":10,"componentType":5126,"count":24,"max":[0.59326171875,0.09326171875],"min":[0.46923828125,0.00048828125],"type":"VEC2"},{"bufferView":11,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":12,"componentType":5126,"count":24,"max":[0.21875,0.125,0.1875],"min":[-0.03125,0,0],"type":"VEC3"},{"bufferView":13,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":14,"componentType":5126,"count":24,"max":[0.84326171875,0.46826171875],"min":[0.40673828125,0.31298828125],"type":"VEC2"},{"bufferView":15,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":16,"componentType":5126,"count":24,"max":[0.21875,0.09375,0.5625],"min":[0.09375,0.03125,0.3125],"type":"VEC3"},{"bufferView":17,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":18,"componentType":5126,"count":24,"max":[0.68701171875,0.62451171875],"min":[0.31298828125,0.46923828125],"type":"VEC2"},{"bufferView":19,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":20,"componentType":5126,"count":24,"max":[0.406312495470047,0.1875,0.375],"min":[0.40625,0.0625,0.25],"type":"VEC3"},{"bufferView":21,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":22,"componentType":5126,"count":24,"max":[0.12548828125,0.28076171875],"min":[0.00048828125,0.15673828125],"type":"VEC2"},{"bufferView":23,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":24,"componentType":5126,"count":24,"max":[-0.03125,0.125,0.4375],"min":[-0.28125,0,0.25],"type":"VEC3"},{"bufferView":25,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":26,"componentType":5126,"count":24,"max":[0.43701171875,0.56201171875],"min":[0.00048828125,0.40673828125],"type":"VEC2"},{"bufferView":27,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":28,"componentType":5126,"count":24,"max":[-0.09375,0.09375,0.5625],"min":[-0.21875,0.03125,0.3125],"type":"VEC3"},{"bufferView":29,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":30,"componentType":5126,"count":24,"max":[0.84326171875,0.15576171875],"min":[0.46923828125,0.00048828125],"type":"VEC2"},{"bufferView":31,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":32,"componentType":5126,"count":24,"max":[-0.406187504529953,0.1875,0.375],"min":[-0.40625,0.0625,0.25],"type":"VEC3"},{"bufferView":33,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":34,"componentType":5126,"count":24,"max":[0.12548828125,0.12451171875],"min":[0.00048828125,0.00048828125],"type":"VEC2"},{"bufferView":35,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":36,"componentType":5126,"count":24,"max":[0.25,0.09375,-0.09375],"min":[0.125,0.03125,-0.15625],"type":"VEC3"},{"bufferView":37,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":38,"componentType":5126,"count":24,"max":[0.71826171875,0.31201171875],"min":[0.53173828125,0.25048828125],"type":"VEC2"},{"bufferView":39,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":40,"componentType":5126,"count":24,"max":[0.28125,0.09375,-0.09375],"min":[0.21875,0.03125,-0.15625],"type":"VEC3"},{"bufferView":41,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":42,"componentType":5126,"count":24,"max":[0.12451171875,0.34326171875],"min":[0.00048828125,0.28173828125],"type":"VEC2"},{"bufferView":43,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":44,"componentType":5126,"count":24,"max":[0.34375,0.0625625029206276,-0.09375],"min":[0.28125,0.0625,-0.15625],"type":"VEC3"},{"bufferView":45,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":46,"componentType":5126,"count":24,"max":[0.12451171875,0.15673828125],"min":[0.00048828125,0.12548828125],"type":"VEC2"},{"bufferView":47,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":48,"componentType":5126,"count":24,"max":[-0.125,0.09375,-0.09375],"min":[-0.25,0.03125,-0.15625],"type":"VEC3"},{"bufferView":49,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":50,"componentType":5126,"count":24,"max":[0.56201171875,0.28076171875],"min":[0.37548828125,0.21923828125],"type":"VEC2"},{"bufferView":51,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":52,"componentType":5126,"count":24,"max":[-0.21875,0.09375,-0.09375],"min":[-0.28125,0.03125,-0.15625],"type":"VEC3"},{"bufferView":53,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":54,"componentType":5126,"count":24,"max":[0.12451171875,0.06201171875],"min":[0.00048828125,0.00048828125],"type":"VEC2"},{"bufferView":55,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":56,"componentType":5126,"count":24,"max":[-0.28125,0.0625625029206276,-0.09375],"min":[-0.34375,0.0625,-0.15625],"type":"VEC3"},{"bufferView":57,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":58,"componentType":5126,"count":24,"max":[0.18701171875,0.03173828125],"min":[0.06298828125,0.00048828125],"type":"VEC2"},{"bufferView":59,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":60,"componentType":5126,"count":3,"max":[0.75],"min":[0],"type":"SCALAR"},{"bufferView":61,"componentType":5126,"count":3,"max":[0.06540312618017197,0,0,1],"min":[0,0,0,0.9978589415550232],"type":"VEC4"},{"bufferView":62,"componentType":5126,"count":3,"max":[0.75],"min":[0],"type":"SCALAR"},{"bufferView":63,"componentType":5126,"count":3,"max":[0,0.258819043636322,0,1],"min":[0,0,0,0.9659258127212524],"type":"VEC4"},{"bufferView":64,"componentType":5126,"count":3,"max":[0.75],"min":[0],"type":"SCALAR"},{"bufferView":65,"componentType":5126,"count":3,"max":[0,0,0,1],"min":[0,-0.258819043636322,0,0.9659258127212524],"type":"VEC4"},{"bufferView":66,"componentType":5126,"count":3,"max":[0.75],"min":[0],"type":"SCALAR"},{"bufferView":67,"componentType":5126,"count":3,"max":[0,0.13052618503570557,0,1],"min":[0,0,0,0.9914448857307434],"type":"VEC4"},{"bufferView":68,"componentType":5126,"count":3,"max":[0.75],"min":[0],"type":"SCALAR"},{"bufferView":69,"componentType":5126,"count":3,"max":[0,0,0,1],"min":[0,-0.13052618503570557,0,0.9914448857307434],"type":"VEC4"}],"materials":[{"pbrMetallicRoughness":{"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0}},"alphaMode":"MASK","alphaCutoff":0.05,"doubleSided":true}],"textures":[{"sampler":0}],"samplers":[{"magFilter":9728,"minFilter":9728,"wrapS":33071,"wrapT":33071}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":4,"NORMAL":5,"TEXCOORD_0":6},"indices":7,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":8,"NORMAL":9,"TEXCOORD_0":10},"indices":11,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":12,"NORMAL":13,"TEXCOORD_0":14},"indices":15,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":16,"NORMAL":17,"TEXCOORD_0":18},"indices":19,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":20,"NORMAL":21,"TEXCOORD_0":22},"indices":23,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":24,"NORMAL":25,"TEXCOORD_0":26},"indices":27,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":28,"NORMAL":29,"TEXCOORD_0":30},"indices":31,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":32,"NORMAL":33,"TEXCOORD_0":34},"indices":35,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":36,"NORMAL":37,"TEXCOORD_0":38},"indices":39,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":40,"NORMAL":41,"TEXCOORD_0":42},"indices":43,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":44,"NORMAL":45,"TEXCOORD_0":46},"indices":47,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":48,"NORMAL":49,"TEXCOORD_0":50},"indices":51,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":52,"NORMAL":53,"TEXCOORD_0":54},"indices":55,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":56,"NORMAL":57,"TEXCOORD_0":58},"indices":59,"material":0}]}],"animations":[{"name":"animation.model.walk","samplers":[{"input":60,"output":61,"interpolation":"LINEAR"},{"input":62,"output":63,"interpolation":"LINEAR"},{"input":64,"output":65,"interpolation":"LINEAR"},{"input":66,"output":67,"interpolation":"LINEAR"},{"input":68,"output":69,"interpolation":"LINEAR"}],"channels":[{"sampler":0,"target":{"node":3,"path":"rotation"}},{"sampler":1,"target":{"node":7,"path":"rotation"}},{"sampler":2,"target":{"node":11,"path":"rotation"}},{"sampler":3,"target":{"node":15,"path":"rotation"}},{"sampler":4,"target":{"node":19,"path":"rotation"}}]}]} \ No newline at end of file diff --git a/data/games/garage/mods/gltf/models/gltf_minimal_triangle.gltf b/data/games/garage/mods/gltf/models/gltf_minimal_triangle.gltf new file mode 100644 index 0000000..9a624f0 --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_minimal_triangle.gltf @@ -0,0 +1 @@ +{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":1},"indices":0}]}],"buffers":[{"uri":"data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAA=","byteLength":44}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":6,"target":34963},{"buffer":0,"byteOffset":8,"byteLength":36,"target":34962}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5123,"count":3,"type":"SCALAR","max":[2],"min":[0]},{"bufferView":1,"byteOffset":0,"componentType":5126,"count":3,"type":"VEC3","max":[1,1,0],"min":[0,0,0]}],"asset":{"version":"2.0"}} diff --git a/data/games/garage/mods/gltf/models/gltf_simple_skin.gltf b/data/games/garage/mods/gltf/models/gltf_simple_skin.gltf new file mode 100644 index 0000000..3d6c24a --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_simple_skin.gltf @@ -0,0 +1 @@ +{"scene":0,"scenes":[{"nodes":[0,1]}],"nodes":[{"skin":0,"mesh":0},{"children":[2]},{"translation":[0.0,1.0,0.0],"rotation":[0.0,0.0,0.0,1.0]}],"meshes":[{"primitives":[{"attributes":{"POSITION":1,"JOINTS_0":2,"WEIGHTS_0":3},"indices":0}]}],"skins":[{"inverseBindMatrices":4,"joints":[1,2]}],"animations":[{"channels":[{"sampler":0,"target":{"node":2,"path":"rotation"}}],"samplers":[{"input":5,"interpolation":"LINEAR","output":6}]}],"buffers":[{"uri":"data:application/gltf-buffer;base64,AAABAAMAAAADAAIAAgADAAUAAgAFAAQABAAFAAcABAAHAAYABgAHAAkABgAJAAgAAAAAvwAAAAAAAAAAAAAAPwAAAAAAAAAAAAAAvwAAAD8AAAAAAAAAPwAAAD8AAAAAAAAAvwAAgD8AAAAAAAAAPwAAgD8AAAAAAAAAvwAAwD8AAAAAAAAAPwAAwD8AAAAAAAAAvwAAAEAAAAAAAAAAPwAAAEAAAAAA","byteLength":168},{"uri":"data:application/gltf-buffer;base64,AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAABAPwAAgD4AAAAAAAAAAAAAQD8AAIA+AAAAAAAAAAAAAAA/AAAAPwAAAAAAAAAAAAAAPwAAAD8AAAAAAAAAAAAAgD4AAEA/AAAAAAAAAAAAAIA+AABAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAA=","byteLength":320},{"uri":"data:application/gltf-buffer;base64,AACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAgD8=","byteLength":128},{"uri":"data:application/gltf-buffer;base64,AAAAAAAAAD8AAIA/AADAPwAAAEAAACBAAABAQAAAYEAAAIBAAACQQAAAoEAAALBAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAPT9ND/0/TQ/AAAAAAAAAAD0/TQ/9P00PwAAAAAAAAAAkxjEPkSLbD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAPT9NL/0/TQ/AAAAAAAAAAD0/TS/9P00PwAAAAAAAAAAkxjEvkSLbD8AAAAAAAAAAAAAAAAAAIA/","byteLength":240}],"bufferViews":[{"buffer":0,"byteLength":48,"target":34963},{"buffer":0,"byteOffset":48,"byteLength":120,"target":34962},{"buffer":1,"byteLength":320,"byteStride":16},{"buffer":2,"byteLength":128},{"buffer":3,"byteLength":240}],"accessors":[{"bufferView":0,"componentType":5123,"count":24,"type":"SCALAR"},{"bufferView":1,"componentType":5126,"count":10,"type":"VEC3","max":[0.5,2.0,0.0],"min":[-0.5,0.0,0.0]},{"bufferView":2,"componentType":5123,"count":10,"type":"VEC4"},{"bufferView":2,"byteOffset":160,"componentType":5126,"count":10,"type":"VEC4"},{"bufferView":3,"componentType":5126,"count":2,"type":"MAT4"},{"bufferView":4,"componentType":5126,"count":12,"type":"SCALAR","max":[5.5],"min":[0.0]},{"bufferView":4,"byteOffset":48,"componentType":5126,"count":12,"type":"VEC4","max":[0.0,0.0,0.707,1.0],"min":[0.0,0.0,-0.707,0.707]}],"asset":{"version":"2.0"}} diff --git a/data/games/garage/mods/gltf/models/gltf_simple_sparse_accessor.gltf b/data/games/garage/mods/gltf/models/gltf_simple_sparse_accessor.gltf new file mode 100644 index 0000000..9798968 --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_simple_sparse_accessor.gltf @@ -0,0 +1 @@ +{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":1},"indices":0}]}],"buffers":[{"uri":"data:application/gltf-buffer;base64,AAAIAAcAAAABAAgAAQAJAAgAAQACAAkAAgAKAAkAAgADAAoAAwALAAoAAwAEAAsABAAMAAsABAAFAAwABQANAAwABQAGAA0AAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAQAAAAAAAAAAAAABAQAAAAAAAAAAAAACAQAAAAAAAAAAAAACgQAAAAAAAAAAAAADAQAAAAAAAAAAAAAAAAAAAgD8AAAAAAACAPwAAgD8AAAAAAAAAQAAAgD8AAAAAAABAQAAAgD8AAAAAAACAQAAAgD8AAAAAAACgQAAAgD8AAAAAAADAQAAAgD8AAAAACAAKAAwAAAAAAIA/AAAAQAAAAAAAAEBAAABAQAAAAAAAAKBAAACAQAAAAAA=","byteLength":284}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":72,"byteLength":168},{"buffer":0,"byteOffset":240,"byteLength":6},{"buffer":0,"byteOffset":248,"byteLength":36}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5123,"count":36,"type":"SCALAR","max":[13],"min":[0]},{"bufferView":1,"byteOffset":0,"componentType":5126,"count":14,"type":"VEC3","max":[6,4,0],"min":[0,0,0],"sparse":{"count":3,"indices":{"bufferView":2,"byteOffset":0,"componentType":5123},"values":{"bufferView":3,"byteOffset":0}}}],"asset":{"version":"2.0"}} diff --git a/data/games/garage/mods/gltf/models/gltf_snow_man.gltf b/data/games/garage/mods/gltf/models/gltf_snow_man.gltf new file mode 100644 index 0000000..cd8c347 --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_snow_man.gltf @@ -0,0 +1 @@ +{"asset":{"version":"2.0","generator":"Blockbench 4.6.0 glTF exporter"},"scenes":[{"nodes":[3],"name":"blockbench_export"}],"scene":0,"nodes":[{"name":"cube","mesh":0},{"name":"cube","mesh":1},{"name":"cube","mesh":2},{"children":[0,1,2]}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":288,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":576,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":768,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":840,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1128,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1416,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":1608,"byteLength":72,"target":34963},{"buffer":0,"byteOffset":1680,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":1968,"byteLength":288,"target":34962,"byteStride":12},{"buffer":0,"byteOffset":2256,"byteLength":192,"target":34962,"byteStride":8},{"buffer":0,"byteOffset":2448,"byteLength":72,"target":34963}],"buffers":[{"byteLength":2520,"uri":"data:application/octet-stream;base64,AABAQAAAwEEAAEBAAABAQAAAkEEAAEBAAABAQAAAwEEAAEDAAABAQAAAkEEAAEDAAABAwAAAwEEAAEBAAABAwAAAwEEAAEDAAABAwAAAkEEAAEBAAABAwAAAkEEAAEDAAABAQAAAwEEAAEBAAABAQAAAwEEAAEDAAABAwAAAwEEAAEBAAABAwAAAwEEAAEDAAABAQAAAkEEAAEBAAABAwAAAkEEAAEBAAABAQAAAkEEAAEDAAABAwAAAkEEAAEDAAABAQAAAwEEAAEBAAABAwAAAwEEAAEBAAABAQAAAkEEAAEBAAABAwAAAkEEAAEBAAABAQAAAwEEAAEDAAABAQAAAkEEAAEDAAABAwAAAwEEAAEDAAABAwAAAkEEAAEDAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/VVUVP6uqSj9VVRU/q6oqP1VVNT+rqko/VVU1P6uqKj8AAAA/VVXVPgAAwD5VVdU+AAAAP1VVlT4AAMA+VVWVPgAAAD4AAIA+AAAAPgAAwD4AAAAAAACAPgAAAAAAAMA+AABAPwAAgD8AACA/AACAPwAAQD8AAGA/AAAgPwAAYD9VVVU/AABgP1VVNT8AAGA/VVVVPwAAQD9VVTU/AABAP1VVNT8AAEA/VVU1PwAAID9VVVU/AABAP1VVVT8AACA/AgAAAAEAAgABAAMABgAEAAUABgAFAAcACgAIAAkACgAJAAsADgAMAA0ADgANAA8AEgAQABEAEgARABMAFgAUABUAFgAVABcAAACgQAAAIEEAAKBAAACgQAAAAAAAAKBAAACgQAAAIEEAAKDAAACgQAAAAAAAAKDAAACgwAAAIEEAAKBAAACgwAAAIEEAAKDAAACgwAAAAAAAAKBAAACgwAAAAAAAAKDAAACgQAAAIEEAAKBAAACgQAAAIEEAAKDAAACgwAAAIEEAAKBAAACgwAAAIEEAAKDAAACgQAAAAAAAAKBAAACgwAAAAAAAAKBAAACgQAAAAAAAAKDAAACgwAAAAAAAAKDAAACgQAAAIEEAAKBAAACgwAAAIEEAAKBAAACgQAAAAAAAAKBAAACgwAAAAAAAAKBAAACgQAAAIEEAAKDAAACgQAAAAAAAAKDAAACgwAAAIEEAAKDAAACgwAAAAAAAAKDAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAAAAq6pKP1VVVT4AAIA/VVVVPquqSj9VVVU+q6pKPwAAAACrqko/VVVVPlVVFT8AAAAAVVUVP1VV1T6rqko/VVXVPgAAgD9VVVU+q6pKP1VVVT4AAIA/VVXVPquqSj9VVVU+q6pKP1VV1T5VVRU/VVVVPlVVFT9VVVU+VVUVPwAAAABVVRU/VVVVPgAAwD4AAAAAAADAPlVV1T4AAIA/VVXVPquqSj8AACA/AACAPwAAID+rqko/AgAAAAEAAgABAAMABgAEAAUABgAFAAcACgAIAAkACgAJAAsADgAMAA0ADgANAA8AEgAQABEAEgARABMAFgAUABUAFgAVABcAAACAQAAAkEEAAIBAAACAQAAAIEEAAIBAAACAQAAAkEEAAIDAAACAQAAAIEEAAIDAAACAwAAAkEEAAIBAAACAwAAAkEEAAIDAAACAwAAAIEEAAIBAAACAwAAAIEEAAIDAAACAQAAAkEEAAIBAAACAQAAAkEEAAIDAAACAwAAAkEEAAIBAAACAwAAAkEEAAIDAAACAQAAAIEEAAIBAAACAwAAAIEEAAIBAAACAQAAAIEEAAIDAAACAwAAAIEEAAIDAAACAQAAAkEEAAIBAAACAwAAAkEEAAIBAAACAQAAAIEEAAIBAAACAwAAAIEEAAIBAAACAQAAAkEEAAIDAAACAQAAAIEEAAIDAAACAwAAAkEEAAIDAAACAwAAAIEEAAIDAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/VVVVPlVVFT9VVVU+VVXVPgAAwD5VVRU/AADAPlVV1T5VVRU/q6pKP1VV1T6rqko/VVUVPwAAID9VVdU+AAAgP6uqCj9VVdU+q6oKP1VVFT8AAMA+VVXVPgAAwD5VVRU/VVU1PwAAID+rqgo/AAAgP1VVNT+rquo+q6oKP6uq6j5VVTU/q6rqPquqCj+rquo+VVU1P1VVlT6rqgo/VVWVPlVVVT5VVdU+VVVVPgAAgD4AAMA+VVXVPgAAwD4AAIA+AgAAAAEAAgABAAMABgAEAAUABgAFAAcACgAIAAkACgAJAAsADgAMAA0ADgANAA8AEgAQABEAEgARABMAFgAUABUAFgAVABcA"}],"accessors":[{"bufferView":0,"componentType":5126,"count":24,"max":[3,24,3],"min":[-3,18,-3],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":24,"max":[0.8333333134651184,1],"min":[0,0.25],"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":4,"componentType":5126,"count":24,"max":[5,10,5],"min":[-5,0,-5],"type":"VEC3"},{"bufferView":5,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":6,"componentType":5126,"count":24,"max":[0.625,1],"min":[0,0.375],"type":"VEC2"},{"bufferView":7,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"},{"bufferView":8,"componentType":5126,"count":24,"max":[4,18,4],"min":[-4,10,-4],"type":"VEC3"},{"bufferView":9,"componentType":5126,"count":24,"max":[1,1,1],"min":[-1,-1,-1],"type":"VEC3"},{"bufferView":10,"componentType":5126,"count":24,"max":[0.7083333134651184,0.7916666865348816],"min":[0.2083333283662796,0.25],"type":"VEC2"},{"bufferView":11,"componentType":5123,"count":36,"max":[23],"min":[0],"type":"SCALAR"}],"materials":[{"pbrMetallicRoughness":{"metallicFactor":0,"roughnessFactor":1,"baseColorTexture":{"index":0,"texCoord":0}},"alphaMode":"MASK","alphaCutoff":0.05,"doubleSided":true}],"textures":[{}],"meshes":[{"primitives":[{"mode":4,"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":4,"NORMAL":5,"TEXCOORD_0":6},"indices":7,"material":0}]},{"primitives":[{"mode":4,"attributes":{"POSITION":8,"NORMAL":9,"TEXCOORD_0":10},"indices":11,"material":0}]}]} diff --git a/data/games/garage/mods/gltf/models/gltf_spider.gltf b/data/games/garage/mods/gltf/models/gltf_spider.gltf new file mode 100644 index 0000000..6698b6b --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_spider.gltf @@ -0,0 +1 @@ +{"asset":{"generator":"Khronos glTF Blender I/O v1.7.33","version":"2.0"},"scene":0,"scenes":[{"name":"Scene","nodes":[0]}],"nodes":[{"mesh":0,"name":"Spider"}],"materials":[{"doubleSided":true,"name":"Material.001","pbrMetallicRoughness":{}}],"meshes":[{"name":"Cube","primitives":[{"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2},"indices":3,"material":0}]}],"accessors":[{"bufferView":0,"componentType":5126,"count":1000,"max":[2.742279291152954,1.4045029878616333,2.0192716121673584],"min":[-2.742279291152954,-0.6434623599052429,-3.534085512161255],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":1000,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":1000,"type":"VEC2"},{"bufferView":3,"componentType":5123,"count":1500,"type":"SCALAR"}],"bufferViews":[{"buffer":0,"byteLength":12000,"byteOffset":0},{"buffer":0,"byteLength":12000,"byteOffset":12000},{"buffer":0,"byteLength":8000,"byteOffset":24000},{"buffer":0,"byteLength":3000,"byteOffset":32000}],"buffers":[{"byteLength":35000,"uri":"data:application/octet-stream;base64,dfkpP+R6/z6QwIW/dfkpP+R6/z6QwIW/dfkpP+R6/z6QwIW/dfkpP+R6/76QwIW/dfkpP+R6/76QwIW/dfkpP+R6/76QwIW/dfkpP+R6/z6QwIU/dfkpP+R6/z6QwIU/dfkpP+R6/z6QwIU/dfkpP+R6/76QwIU/dfkpP+R6/76QwIU/dfkpP+R6/76QwIU/dfkpv+R6/z6QwIW/dfkpv+R6/z6QwIW/dfkpv+R6/z6QwIW/dfkpv+R6/76QwIW/dfkpv+R6/76QwIW/dfkpv+R6/76QwIW/dfkpv+R6/z6QwIU/dfkpv+R6/z6QwIU/dfkpv+R6/z6QwIU/dfkpv+R6/76QwIU/dfkpv+R6/76QwIU/dfkpv+R6/76QwIU/UoRdPwFMoz8qkU3AUoRdPwFMoz8qkU3AUoRdPwFMoz8qkU3AUoRdP+x7gDx1LmLAUoRdP+x7gDx1LmLAUoRdP+x7gDx1LmLAbCVCP/IRET8e1xe/bCVCP/IRET8e1xe/bCVCP/IRET8e1xe/bCVCP5SmCb8LHGC/bCVCP5SmCb8LHGC/bCVCP5SmCb8LHGC/UoRdvwFMoz8qkU3AUoRdvwFMoz8qkU3AUoRdvwFMoz8qkU3AUoRdv+x7gDx1LmLAUoRdv+x7gDx1LmLAUoRdv+x7gDx1LmLAbCVCv/IRET8e1xe/bCVCv/IRET8e1xe/bCVCv/IRET8e1xe/bCVCv5SmCb8LHGC/bCVCv5SmCb8LHGC/bCVCv5SmCb8LHGC/XiXDvkD14r7OlcU/XiXDvkD14r7OlcU/XiXDvkD14r7OlcU/XiXDvhwyo71XteY/XiXDvhwyo71XteY/XiXDvhwyo71XteY/XiXDvhwyoz1zEE8/XiXDvhwyoz1zEE8/XiXDvhwyoz1zEE8/XiXDvkD14j7Dp4g/XiXDvkD14j7Dp4g/XiXDvkD14j7Dp4g/XCXDPkD14r7OlcU/XCXDPkD14r7OlcU/XCXDPkD14r7OlcU/XCXDPhwyo71XteY/XCXDPhwyo71XteY/XCXDPhwyo71XteY/XCXDPhwyoz1zEE8/XCXDPhwyoz1zEE8/XCXDPhwyoz1zEE8/XCXDPkD14j7Dp4g/XCXDPkD14j7Dp4g/XCXDPkD14j7Dp4g/bi6Dv7og4L5LpA/Abi6Dv7og4L5LpA/Abi6Dv7og4L5LpA/Abi6Dv7og4L5LpA/Abi6DP27/hj/Sc+6/bi6DP27/hj/Sc+6/bi6DP27/hj/Sc+6/bi6DP27/hj/Sc+6/bi6Dv27/hj/Uc+6/bi6Dv27/hj/Uc+6/bi6Dv27/hj/Uc+6/bi6Dv27/hj/Uc+6/bi6DP7wg4L5LpA/Abi6DP7wg4L5LpA/Abi6DP7wg4L5LpA/Abi6DP7wg4L5LpA/AKXA/vg7sv76Nef0/KXA/vg7sv76Nef0/KXA/vg7sv76Nef0/KXA/voixaL6/OwFAKXA/voixaL6/OwFAKXA/voixaL6/OwFAMSWTvg+jir5UDss/MSWTvg+jir5UDss/MSWTvg+jir5UDss/MSWTvg4//L1HDNA/MSWTvg4//L1HDNA/MSWTvg4//L1HDNA/A5UevXQku77E8/g/A5UevXQku77E8/g/A5UevXQku77E8/g/A5UevVIiX7648f0/A5UevVIiX7648f0/A5UevVIiX7648f0/eH8OvnTbhb6MiMY/eH8OvnTbhb6MiMY/eH8OvnTbhb6MiMY/eH8Ovqcg6b1/hss/eH8Ovqcg6b1/hss/eH8Ovqcg6b1/hss/B61WvpRDlr0p2+w/B61WvpRDlr0p2+w/B61WvpRDlr0p2+w/B61WvoT9Ej6Ek98/B61WvoT9Ej6Ek98/B61WvoT9Ej6Ek98/B61Wvov9Er55E9o/B61Wvov9Er55E9o/B61Wvov9Er55E9o/B61WvodDlj3Vy8w/B61WvodDlj3Vy8w/B61WvodDlj3Vy8w/f4pAvZRDlr0p2+w/f4pAvZRDlr0p2+w/f4pAvZRDlr0p2+w/f4pAvYT9Ej6Ek98/f4pAvYT9Ej6Ek98/f4pAvYT9Ej6Ek98/f4pAvYv9Er55E9o/f4pAvYv9Er55E9o/f4pAvYv9Er55E9o/f4pAvYdDlj3Vy8w/f4pAvYdDlj3Vy8w/f4pAvYdDlj3Vy8w/8CCuvr/lGL1K++Q/8CCuvr/lGL1K++Q/8CCuvr/lGL1K++Q/8CCuvvWQlT2tOd4/8CCuvvWQlT2tOd4/8CCuvvWQlT2tOd4/8CCuvgGRlb1Rbds/8CCuvgGRlb1Rbds/8CCuvgGRlb1Rbds/8CCuvqTlGD20q9Q/8CCuvqTlGD20q9Q/8CCuvqTlGD20q9Q/jMODvr/lGL1K++Q/jMODvr/lGL1K++Q/jMODvr/lGL1K++Q/jMODvvWQlT2tOd4/jMODvvWQlT2tOd4/jMODvvWQlT2tOd4/jMODvgGRlb1Rbds/jMODvgGRlb1Rbds/jMODvgGRlb1Rbds/jMODvqTlGD20q9Q/jMODvqTlGD20q9Q/jMODvqTlGD20q9Q/KXA/Pg7sv76Nef0/KXA/Pg7sv76Nef0/KXA/Pg7sv76Nef0/KXA/PoixaL6/OwFAKXA/PoixaL6/OwFAKXA/PoixaL6/OwFAMSWTPg+jir5UDss/MSWTPg+jir5UDss/MSWTPg+jir5UDss/MSWTPg4//L1HDNA/MSWTPg4//L1HDNA/MSWTPg4//L1HDNA/A5UePXQku77E8/g/A5UePXQku77E8/g/A5UePXQku77E8/g/A5UePVIiX7648f0/A5UePVIiX7648f0/A5UePVIiX7648f0/eH8OPnTbhb6MiMY/eH8OPnTbhb6MiMY/eH8OPnTbhb6MiMY/eH8OPqcg6b1/hss/eH8OPqcg6b1/hss/eH8OPqcg6b1/hss/B61WPpRDlr0p2+w/B61WPpRDlr0p2+w/B61WPpRDlr0p2+w/B61WPoT9Ej6Ek98/B61WPoT9Ej6Ek98/B61WPoT9Ej6Ek98/B61WPov9Er55E9o/B61WPov9Er55E9o/B61WPov9Er55E9o/B61WPodDlj3Vy8w/B61WPodDlj3Vy8w/B61WPodDlj3Vy8w/f4pAPZRDlr0p2+w/f4pAPZRDlr0p2+w/f4pAPZRDlr0p2+w/f4pAPYT9Ej6Ek98/f4pAPYT9Ej6Ek98/f4pAPYT9Ej6Ek98/f4pAPYv9Er55E9o/f4pAPYv9Er55E9o/f4pAPYv9Er55E9o/f4pAPYdDlj3Vy8w/f4pAPYdDlj3Vy8w/f4pAPYdDlj3Vy8w/8CCuPr/lGL1K++Q/8CCuPr/lGL1K++Q/8CCuPr/lGL1K++Q/8CCuPvWQlT2tOd4/8CCuPvWQlT2tOd4/8CCuPvWQlT2tOd4/8CCuPgGRlb1Rbds/8CCuPgGRlb1Rbds/8CCuPgGRlb1Rbds/8CCuPqTlGD20q9Q/8CCuPqTlGD20q9Q/8CCuPqTlGD20q9Q/jMODPr/lGL1K++Q/jMODPr/lGL1K++Q/jMODPr/lGL1K++Q/jMODPvWQlT2tOd4/jMODPvWQlT2tOd4/jMODPvWQlT2tOd4/jMODPgGRlb1Rbds/jMODPgGRlb1Rbds/jMODPgGRlb1Rbds/jMODPqTlGD20q9Q/jMODPqTlGD20q9Q/jMODPqTlGD20q9Q/irGqvwXbij8FXqI/irGqvwXbij8FXqI/irGqvwXbij8FXqI/ORyOv3F4mT/sD5c/ORyOv3F4mT/sD5c/ORyOv3F4mT/sD5c/veG1vwXbij9MFIY/veG1vwXbij9MFIY/veG1vwXbij9MFIY/bEyZv3F4mT9jjHU/bEyZv3F4mT9jjHU/bEyZv3F4mT9jjHU/6Wwlv2yF8L6qI38/6Wwlv2yF8L6qI38/6Wwlv2yF8L6qI38/ioTYvrQPtr54h2g/ioTYvrQPtr54h2g/ioTYvrQPtr54h2g/T807v2yF8L43kEY/T807v2yF8L43kEY/T807v2yF8L43kEY/raICv7QPtr4D9C8/raICv7QPtr4D9C8/raICv7QPtr4D9C8/z+YCwI6slj+TWsQ/z+YCwI6slj+TWsQ/z+YCwI6slj+TWsQ/A/f/v8HGsz9xC8I/A/f/v8HGsz9xC8I/A/f/v8HGsz9xC8I/jMsHwI6slj/Wm6s/jMsHwI6slj/Wm6s/jMsHwI6slj/Wm6s/PuAEwMHGsz+yTKk/PuAEwMHGsz+yTKk/PuAEwMHGsz+yTKk/R9OVv6Pudz+mEJg/R9OVv6Pudz+mEJg/R9OVv6Pudz+mEJg/rfyPv4YRmT+EwZU/rfyPv4YRmT+EwZU/rfyPv4YRmT+EwZU/wZyfv6Pudz/So34/wZyfv6Pudz/So34/wZyfv6Pudz/So34/J8aZv4QRmT+MBXo/J8aZv4QRmT+MBXo/J8aZv4QRmT+MBXo/iI4EwFQ4sz8QDKk/iI4EwFQ4sz8QDKk/iI4EwFQ4sz8QDKk/dS/zv7wLoT/OX6A/dS/zv7wLoT/OX6A/dS/zv7wLoT/OX6A/mVP/v1I4sz/PysE/mVP/v1I4sz/PysE/mVP/v1I4sz/PysE/+2Xpv7wLoT+MHrk/+2Xpv7wLoT+MHrk/+2Xpv7wLoT+MHrk/6tMnwDbsIz+L8sQ/6tMnwDbsIz+L8sQ/6tMnwDbsIz+L8sQ/HN0cwAkm/z5JRrw/HN0cwAkm/z5JRrw/HN0cwAkm/z5JRrw/Le8iwDbsIz9Jsd0/Le8iwDbsIz9Jsd0/Le8iwDbsIz9Jsd0/YPgXwAkm/z4HBdU/YPgXwAkm/z4HBdU/YPgXwAkm/z4HBdU/GQohwGb1Jz9Bcto/GQohwGb1Jz9Bcto/GQohwGb1Jz9Bcto/pBcVwGyGMT/v/tA/pBcVwGyGMT/v/tA/pBcVwGyGMT/v/tA/2FUlwGb1Jz8jucQ/2FUlwGb1Jz8jucQ/2FUlwGb1Jz8jucQ/ZGMZwGyGMT/QRbs/ZGMZwGyGMT/QRbs/ZGMZwGyGMT/QRbs/W6QSwPO5JL+7Ds8/W6QSwPO5JL+7Ds8/W6QSwPO5JL+7Ds8/5LEGwOkoG79nm8U/5LEGwOkoG79nm8U/5LEGwOkoG79nm8U/G/AWwPO5JL+dVbk/G/AWwPO5JL+dVbk/G/AWwPO5JL+dVbk/pP0KwOkoG79I4q8/pP0KwOkoG79I4q8/pP0KwOkoG79I4q8/PSK3vwXbij/MHzo/PSK3vwXbij/MHzo/PSK3vwXbij/MHzo/E3+Yv3F4mT8FKTU/E3+Yv3F4mT8FKTU/E3+Yv3F4mT8FKTU/EJe5vwXbij8N9/o+EJe5vwXbij8N9/o+EJe5vwXbij8N9/o+5/Oav3F4mT96CfE+5/Oav3F4mT96CfE+5/Oav3F4mT96CfE+Jakxv2yF8L5F2Co/Jakxv2yF8L5F2Co/Jakxv2yF8L5F2Co/osXovrQPtr5/4SU/osXovrQPtr5/4SU/osXovrQPtr5/4SU/y5I2v2yF8L76Z9w+y5I2v2yF8L76Z9w+y5I2v2yF8L76Z9w+7pjyvrQPtr5petI+7pjyvrQPtr5petI+7pjyvrQPtr5petI+zBgMwI6slj8dB0Y/zBgMwI6slj8dB0Y/zBgMwI6slj8dB0Y/yfcIwMHGsz+QA0U/yfcIwMHGsz+QA0U/yfcIwMHGsz+QA0U/1CsNwI6slj8r+xA/1CsNwI6slj8r+xA/1CsNwI6slj8r+xA/0woKwMHGsz+Z9w8/0woKwMHGsz+Z9w8/0woKwMHGsz+Z9w8/MSugv6Pudz+2lDI/MSugv6Pudz+2lDI/MSugv6Pudz+2lDI/L+mZv4YRmT8nkTE/L+mZv4YRmT8nkTE/L+mZv4YRmT8nkTE/Q1Giv6Pudz+EEfs+Q1Giv6Pudz+EEfs+Q1Giv6Pudz+EEfs+QA+cv4QRmT9kCvk+QA+cv4QRmT9kCvk+QA+cv4QRmT9kCvk+PbMJwFQ4sz862w8/PbMJwFQ4sz862w8/PbMJwFQ4sz862w8/deX7v7wLoT9UDAw/deX7v7wLoT9UDAw/deX7v7wLoT9UDAw/NaAIwFI4sz8v50Q/NaAIwFI4sz8v50Q/NaAIwFI4sz8v50Q/ZL/5v7wLoT9HGEE/ZL/5v7wLoT9HGEE/ZL/5v7wLoT9HGEE/gYEvwDbsIz9wGxw/gYEvwDbsIz9wGxw/gYEvwDbsIz9wGxw//sAjwAkm/z6JTBg//sAjwAkm/z6JTBg//sAjwAkm/z6JTBg/d24uwDbsIz9jJ1E/d24uwDbsIz9jJ1E/d24uwDbsIz9jJ1E/9a0iwAkm/z58WE0/9a0iwAkm/z58WE0/9a0iwAkm/z58WE0/VSUswGb1Jz8eJ00/VSUswGb1Jz8eJ00/VSUswGb1Jz8eJ00/FVcfwGyGMT/PAEk/FVcfwGyGMT/PAEk/FVcfwGyGMT/PAEk/xxYtwGb1Jz+blR4/xxYtwGb1Jz+blR4/xxYtwGb1Jz+blR4/iEggwGyGMT9Lbxo/iEggwGyGMT9Lbxo/iEggwGyGMT9Lbxo/uLYcwPO5JL/uJkg/uLYcwPO5JL/uJkg/uLYcwPO5JL/uJkg/d+gPwOkoG7+dAEQ/d+gPwOkoG7+dAEQ/d+gPwOkoG7+dAEQ/K6gdwPO5JL9plRk/K6gdwPO5JL9plRk/K6gdwPO5JL9plRk/6dkQwOkoG78ZbxU/6dkQwOkoG78ZbxU/6dkQwOkoG78ZbxU/ZxC1vwXbij95yBg+ZxC1vwXbij95yBg+ZxC1vwXbij95yBg+kWOWv3F4mT8beCg+kWOWv3F4mT8beCg+kWOWv3F4mT8beCg+oh+zvwXbij9ZKrS9oh+zvwXbij9ZKrS9oh+zvwXbij9ZKrS9zXKUv3F4mT8jy5S9zXKUv3F4mT8jy5S9zXKUv3F4mT8jy5S98Ektv2yF8L7LEEk+8Ektv2yF8L7LEEk+8Ektv2yF8L7LEEk+jeDfvrQPtr5twFg+jeDfvrQPtr5twFg+jeDfvrQPtr5twFg+aGgpv2yF8L6LMye9aGgpv2yF8L6LMye9aGgpv2yF8L6LMye9fR3YvrQPtr4l6tC8fR3YvrQPtr4l6tC8fR3YvrQPtr4l6tC87fsKwI6slj8R66897fsKwI6slj8R66897fsKwI6slj8R668979kHwMHGsz+RU7Y979kHwMHGsz+RU7Y979kHwMHGsz+RU7Y9pyIKwI6slj97+vi9pyIKwI6slj97+vi9pyIKwI6slj97+vi9qAAHwMHGsz8LkvK9qAAHwMHGsz8LkvK9qAAHwMHGsz8LkvK9k8udv6Pudz82aRU+k8udv6Pudz82aRU+k8udv6Pudz82aRU+l4eXv4YRmT9xnRg+l4eXv4YRmT9xnRg+l4eXv4YRmT9xnRg+BRmcv6Pudz8/Jny9BRmcv6Pudz8/Jny9BRmcv6Pudz8/Jny9CdWVv4QRmT9fVW+9CdWVv4QRmT9fVW+9CdWVv4QRmT9fVW+996gGwFQ4sz+b3vG996gGwFQ4sz+b3vG996gGwFQ4sz+b3vG9fcn1v7wLoT9Hzdm9fcn1v7wLoT9Hzdm9fcn1v7wLoT9Hzdm9P4IHwFI4sz/3Brc9P4IHwFI4sz/3Brc9P4IHwFI4sz/3Brc9Cnz3v7wLoT9FGM89Cnz3v7wLoT9FGM89Cnz3v7wLoT9FGM89KYMswDbsIz+9pR++KYMswDbsIz+9pR++KYMswDbsIz+9pR++8b4gwAkm/z4TnRO+8b4gwAkm/z4TnRO+8b4gwAkm/z4TnRO+cFwtwDbsIz83NFM9cFwtwDbsIz83NFM9cFwtwDbsIz83NFM9N5ghwAkm/z5oq4E9N5ghwAkm/z5oq4E9N5ghwAkm/z5oq4E9f/QqwGb1Jz/a8Sg9f/QqwGb1Jz/a8Sg9f/QqwGb1Jz/a8Sg9NSIewGyGMT9XZV09NSIewGyGMT9XZV09NSIewGyGMT9XZV09wjUqwGb1Jz9iRBC+wjUqwGb1Jz9iRBC+wjUqwGb1Jz9iRBC+d2MdwGyGMT+HJwO+d2MdwGyGMT+HJwO+d2MdwGyGMT+HJwO+BIEbwPO5JL88J2g9BIEbwPO5JL88J2g9BIEbwPO5JL88J2g9uK4OwOkoG79hTY49uK4OwOkoG79hTY49uK4OwOkoG79hTY49RsIawPO5JL8NdwC+RsIawPO5JL8NdwC+RsIawPO5JL8NdwC++u8NwOkoG79ftOa9+u8NwOkoG79ftOa9+u8NwOkoG79ftOa9ofCqvwXbij9txb++ofCqvwXbij9txb++ofCqvwXbij9txb++kVKNv3F4mT854Z6+kVKNv3F4mT854Z6+kVKNv3F4mT854Z6+U82ivwXbij8ughq/U82ivwXbij8ughq/U82ivwXbij8ughq/Qy+Fv3F4mT8WEAq/Qy+Fv3F4mT8WEAq/Qy+Fv3F4mT8WEAq/RY0fv2yF8L44DzW+RY0fv2yF8L44DzW+RY0fv2yF8L44DzW+SqLIvrQPtr6bjea9SqLIvrQPtr6bjea9SqLIvrQPtr6bjea9rUYPv2yF8L6Rxs++rUYPv2yF8L6Rxs++rUYPv2yF8L6Rxs++FhWovrQPtr5e4q6+FhWovrQPtr5e4q6+FhWovrQPtr5e4q6+JQ4EwI6slj8Ykxe/JQ4EwI6slj8Ykxe/JQ4EwI6slj8Ykxe/zQcBwMHGsz8lNxS/zQcBwMHGsz8lNxS/zQcBwMHGsz8lNxS/9H4AwI6slj/32kq/9H4AwI6slj/32kq/9H4AwI6slj/32kq/OfH6v8HGsz8Hf0e/OfH6v8HGsz8Hf0e/OfH6v8HGsz8Hf0e/xRSUv6Pudz8rS66+xRSUv6Pudz8rS66+xRSUv6Pudz8rS66+GAiOv4YRmT9Kk6e+GAiOv4YRmT9Kk6e+GAiOv4YRmT9Kk6e+Y/aMv6Pudz92bQq/Y/aMv6Pudz92bQq/Y/aMv6Pudz92bQq/temGv4QRmT+GEQe/temGv4QRmT+GEQe/temGv4QRmT+GEQe/4kf6v1Q4sz/+IEe/4kf6v1Q4sz/+IEe/4kf6v1Q4sz/+IEe/K4/jv7wLoT8kgzq/K4/jv7wLoT8kgzq/K4/jv7wLoT8kgzq/I7MAwFI4sz8e2RO/I7MAwFI4sz8e2RO/I7MAwFI4sz8e2RO/ja3qv7wLoT9EOwe/ja3qv7wLoT9EOwe/ja3qv7wLoT9EOwe/BLAhwDbsIz9St2+/BLAhwDbsIz9St2+/BLAhwDbsIz9St2+/qFMWwAkm/z54GWO/qFMWwAkm/z54GWO/qFMWwAkm/z54GWO/NT8lwDbsIz9xbzy/NT8lwDbsIz9xbzy/NT8lwDbsIz9xbzy/2uIZwAkm/z6Y0S+/2uIZwAkm/z6Y0S+/2uIZwAkm/z6Y0S+/rMEiwGb1Jz/WCj2/rMEiwGb1Jz/WCj2/rMEiwGb1Jz/WCj2/j2AWwGyGMT9nSy+/j2AWwGyGMT9nSy+/j2AWwGyGMT9nSy+/w6EfwGb1Jz98D2q/w6EfwGb1Jz98D2q/w6EfwGb1Jz98D2q/pUATwGyGMT8OUFy/pUATwGyGMT8OUFy/pUATwGyGMT8OUFy/lNYTwPO5JL+UeSy/lNYTwPO5JL+UeSy/lNYTwPO5JL+UeSy/dXUHwOkoG78iuh6/dXUHwOkoG78iuh6/dXUHwOkoG78iuh6/qrYQwPO5JL85flm/qrYQwPO5JL85flm/qrYQwPO5JL85flm/i1UEwOkoG7/Ivku/i1UEwOkoG7/Ivku/i1UEwOkoG7/Ivku/irGqPwXbij8FXqI/irGqPwXbij8FXqI/irGqPwXbij8FXqI/ORyOP3F4mT/sD5c/ORyOP3F4mT/sD5c/ORyOP3F4mT/sD5c/veG1PwXbij9MFIY/veG1PwXbij9MFIY/veG1PwXbij9MFIY/bEyZP3F4mT9jjHU/bEyZP3F4mT9jjHU/bEyZP3F4mT9jjHU/6WwlP2yF8L6qI38/6WwlP2yF8L6qI38/6WwlP2yF8L6qI38/ioTYPrQPtr54h2g/ioTYPrQPtr54h2g/ioTYPrQPtr54h2g/T807P2yF8L43kEY/T807P2yF8L43kEY/T807P2yF8L43kEY/raICP7QPtr4D9C8/raICP7QPtr4D9C8/raICP7QPtr4D9C8/z+YCQI6slj+TWsQ/z+YCQI6slj+TWsQ/z+YCQI6slj+TWsQ/A/f/P8HGsz9xC8I/A/f/P8HGsz9xC8I/A/f/P8HGsz9xC8I/jMsHQI6slj/Wm6s/jMsHQI6slj/Wm6s/jMsHQI6slj/Wm6s/PuAEQMHGsz+yTKk/PuAEQMHGsz+yTKk/PuAEQMHGsz+yTKk/R9OVP6Pudz+mEJg/R9OVP6Pudz+mEJg/R9OVP6Pudz+mEJg/rfyPP4YRmT+EwZU/rfyPP4YRmT+EwZU/rfyPP4YRmT+EwZU/wZyfP6Pudz/So34/wZyfP6Pudz/So34/wZyfP6Pudz/So34/J8aZP4QRmT+MBXo/J8aZP4QRmT+MBXo/J8aZP4QRmT+MBXo/iI4EQFQ4sz8QDKk/iI4EQFQ4sz8QDKk/iI4EQFQ4sz8QDKk/dS/zP7wLoT/OX6A/dS/zP7wLoT/OX6A/dS/zP7wLoT/OX6A/mVP/P1I4sz/PysE/mVP/P1I4sz/PysE/mVP/P1I4sz/PysE/+2XpP7wLoT+MHrk/+2XpP7wLoT+MHrk/+2XpP7wLoT+MHrk/6tMnQDbsIz+L8sQ/6tMnQDbsIz+L8sQ/6tMnQDbsIz+L8sQ/HN0cQAkm/z5JRrw/HN0cQAkm/z5JRrw/HN0cQAkm/z5JRrw/Le8iQDbsIz9Jsd0/Le8iQDbsIz9Jsd0/Le8iQDbsIz9Jsd0/YPgXQAkm/z4HBdU/YPgXQAkm/z4HBdU/YPgXQAkm/z4HBdU/GQohQGb1Jz9Bcto/GQohQGb1Jz9Bcto/GQohQGb1Jz9Bcto/pBcVQGyGMT/v/tA/pBcVQGyGMT/v/tA/pBcVQGyGMT/v/tA/2FUlQGb1Jz8jucQ/2FUlQGb1Jz8jucQ/2FUlQGb1Jz8jucQ/ZGMZQGyGMT/QRbs/ZGMZQGyGMT/QRbs/ZGMZQGyGMT/QRbs/W6QSQPO5JL+7Ds8/W6QSQPO5JL+7Ds8/W6QSQPO5JL+7Ds8/5LEGQOkoG79nm8U/5LEGQOkoG79nm8U/5LEGQOkoG79nm8U/G/AWQPO5JL+dVbk/G/AWQPO5JL+dVbk/G/AWQPO5JL+dVbk/pP0KQOkoG79I4q8/pP0KQOkoG79I4q8/pP0KQOkoG79I4q8/PSK3PwXbij/MHzo/PSK3PwXbij/MHzo/PSK3PwXbij/MHzo/E3+YP3F4mT8FKTU/E3+YP3F4mT8FKTU/E3+YP3F4mT8FKTU/EJe5PwXbij8N9/o+EJe5PwXbij8N9/o+EJe5PwXbij8N9/o+5/OaP3F4mT96CfE+5/OaP3F4mT96CfE+5/OaP3F4mT96CfE+JakxP2yF8L5F2Co/JakxP2yF8L5F2Co/JakxP2yF8L5F2Co/osXoPrQPtr5/4SU/osXoPrQPtr5/4SU/osXoPrQPtr5/4SU/y5I2P2yF8L76Z9w+y5I2P2yF8L76Z9w+y5I2P2yF8L76Z9w+7pjyPrQPtr5petI+7pjyPrQPtr5petI+7pjyPrQPtr5petI+zBgMQI6slj8dB0Y/zBgMQI6slj8dB0Y/zBgMQI6slj8dB0Y/yfcIQMHGsz+QA0U/yfcIQMHGsz+QA0U/yfcIQMHGsz+QA0U/1CsNQI6slj8r+xA/1CsNQI6slj8r+xA/1CsNQI6slj8r+xA/0woKQMHGsz+Z9w8/0woKQMHGsz+Z9w8/0woKQMHGsz+Z9w8/MSugP6Pudz+2lDI/MSugP6Pudz+2lDI/MSugP6Pudz+2lDI/L+mZP4YRmT8nkTE/L+mZP4YRmT8nkTE/L+mZP4YRmT8nkTE/Q1GiP6Pudz+EEfs+Q1GiP6Pudz+EEfs+Q1GiP6Pudz+EEfs+QA+cP4QRmT9kCvk+QA+cP4QRmT9kCvk+QA+cP4QRmT9kCvk+PbMJQFQ4sz862w8/PbMJQFQ4sz862w8/PbMJQFQ4sz862w8/deX7P7wLoT9UDAw/deX7P7wLoT9UDAw/deX7P7wLoT9UDAw/NaAIQFI4sz8v50Q/NaAIQFI4sz8v50Q/NaAIQFI4sz8v50Q/ZL/5P7wLoT9HGEE/ZL/5P7wLoT9HGEE/ZL/5P7wLoT9HGEE/gYEvQDbsIz9wGxw/gYEvQDbsIz9wGxw/gYEvQDbsIz9wGxw//sAjQAkm/z6JTBg//sAjQAkm/z6JTBg//sAjQAkm/z6JTBg/d24uQDbsIz9jJ1E/d24uQDbsIz9jJ1E/d24uQDbsIz9jJ1E/9a0iQAkm/z58WE0/9a0iQAkm/z58WE0/9a0iQAkm/z58WE0/VSUsQGb1Jz8eJ00/VSUsQGb1Jz8eJ00/VSUsQGb1Jz8eJ00/FVcfQGyGMT/PAEk/FVcfQGyGMT/PAEk/FVcfQGyGMT/PAEk/xxYtQGb1Jz+blR4/xxYtQGb1Jz+blR4/xxYtQGb1Jz+blR4/iEggQGyGMT9Lbxo/iEggQGyGMT9Lbxo/iEggQGyGMT9Lbxo/uLYcQPO5JL/uJkg/uLYcQPO5JL/uJkg/uLYcQPO5JL/uJkg/d+gPQOkoG7+dAEQ/d+gPQOkoG7+dAEQ/d+gPQOkoG7+dAEQ/K6gdQPO5JL9plRk/K6gdQPO5JL9plRk/K6gdQPO5JL9plRk/6dkQQOkoG78ZbxU/6dkQQOkoG78ZbxU/6dkQQOkoG78ZbxU/ZxC1PwXbij95yBg+ZxC1PwXbij95yBg+ZxC1PwXbij95yBg+kWOWP3F4mT8beCg+kWOWP3F4mT8beCg+kWOWP3F4mT8beCg+oh+zPwXbij9ZKrS9oh+zPwXbij9ZKrS9oh+zPwXbij9ZKrS9zXKUP3F4mT8jy5S9zXKUP3F4mT8jy5S9zXKUP3F4mT8jy5S98EktP2yF8L7LEEk+8EktP2yF8L7LEEk+8EktP2yF8L7LEEk+jeDfPrQPtr5twFg+jeDfPrQPtr5twFg+jeDfPrQPtr5twFg+aGgpP2yF8L6LMye9aGgpP2yF8L6LMye9aGgpP2yF8L6LMye9fR3YPrQPtr4l6tC8fR3YPrQPtr4l6tC8fR3YPrQPtr4l6tC87fsKQI6slj8R66897fsKQI6slj8R66897fsKQI6slj8R668979kHQMHGsz+RU7Y979kHQMHGsz+RU7Y979kHQMHGsz+RU7Y9pyIKQI6slj97+vi9pyIKQI6slj97+vi9pyIKQI6slj97+vi9qAAHQMHGsz8LkvK9qAAHQMHGsz8LkvK9qAAHQMHGsz8LkvK9k8udP6Pudz82aRU+k8udP6Pudz82aRU+k8udP6Pudz82aRU+l4eXP4YRmT9xnRg+l4eXP4YRmT9xnRg+l4eXP4YRmT9xnRg+BRmcP6Pudz8/Jny9BRmcP6Pudz8/Jny9BRmcP6Pudz8/Jny9CdWVP4QRmT9fVW+9CdWVP4QRmT9fVW+9CdWVP4QRmT9fVW+996gGQFQ4sz+b3vG996gGQFQ4sz+b3vG996gGQFQ4sz+b3vG9fcn1P7wLoT9Hzdm9fcn1P7wLoT9Hzdm9fcn1P7wLoT9Hzdm9P4IHQFI4sz/3Brc9P4IHQFI4sz/3Brc9P4IHQFI4sz/3Brc9Cnz3P7wLoT9FGM89Cnz3P7wLoT9FGM89Cnz3P7wLoT9FGM89KYMsQDbsIz+9pR++KYMsQDbsIz+9pR++KYMsQDbsIz+9pR++8b4gQAkm/z4TnRO+8b4gQAkm/z4TnRO+8b4gQAkm/z4TnRO+cFwtQDbsIz83NFM9cFwtQDbsIz83NFM9cFwtQDbsIz83NFM9N5ghQAkm/z5oq4E9N5ghQAkm/z5oq4E9N5ghQAkm/z5oq4E9f/QqQGb1Jz/a8Sg9f/QqQGb1Jz/a8Sg9f/QqQGb1Jz/a8Sg9NSIeQGyGMT9XZV09NSIeQGyGMT9XZV09NSIeQGyGMT9XZV09wjUqQGb1Jz9iRBC+wjUqQGb1Jz9iRBC+wjUqQGb1Jz9iRBC+d2MdQGyGMT+HJwO+d2MdQGyGMT+HJwO+d2MdQGyGMT+HJwO+BIEbQPO5JL88J2g9BIEbQPO5JL88J2g9BIEbQPO5JL88J2g9uK4OQOkoG79hTY49uK4OQOkoG79hTY49uK4OQOkoG79hTY49RsIaQPO5JL8NdwC+RsIaQPO5JL8NdwC+RsIaQPO5JL8NdwC++u8NQOkoG79ftOa9+u8NQOkoG79ftOa9+u8NQOkoG79ftOa9ofCqPwXbij9txb++ofCqPwXbij9txb++ofCqPwXbij9txb++kVKNP3F4mT854Z6+kVKNP3F4mT854Z6+kVKNP3F4mT854Z6+U82iPwXbij8ughq/U82iPwXbij8ughq/U82iPwXbij8ughq/Qy+FP3F4mT8WEAq/Qy+FP3F4mT8WEAq/Qy+FP3F4mT8WEAq/RY0fP2yF8L44DzW+RY0fP2yF8L44DzW+RY0fP2yF8L44DzW+SqLIPrQPtr6bjea9SqLIPrQPtr6bjea9SqLIPrQPtr6bjea9rUYPP2yF8L6Rxs++rUYPP2yF8L6Rxs++rUYPP2yF8L6Rxs++FhWoPrQPtr5e4q6+FhWoPrQPtr5e4q6+FhWoPrQPtr5e4q6+JQ4EQI6slj8Ykxe/JQ4EQI6slj8Ykxe/JQ4EQI6slj8Ykxe/zQcBQMHGsz8lNxS/zQcBQMHGsz8lNxS/zQcBQMHGsz8lNxS/9H4AQI6slj/32kq/9H4AQI6slj/32kq/9H4AQI6slj/32kq/OfH6P8HGsz8Hf0e/OfH6P8HGsz8Hf0e/OfH6P8HGsz8Hf0e/xRSUP6Pudz8rS66+xRSUP6Pudz8rS66+xRSUP6Pudz8rS66+GAiOP4YRmT9Kk6e+GAiOP4YRmT9Kk6e+GAiOP4YRmT9Kk6e+Y/aMP6Pudz92bQq/Y/aMP6Pudz92bQq/Y/aMP6Pudz92bQq/temGP4QRmT+GEQe/temGP4QRmT+GEQe/temGP4QRmT+GEQe/4kf6P1Q4sz/+IEe/4kf6P1Q4sz/+IEe/4kf6P1Q4sz/+IEe/K4/jP7wLoT8kgzq/K4/jP7wLoT8kgzq/K4/jP7wLoT8kgzq/I7MAQFI4sz8e2RO/I7MAQFI4sz8e2RO/I7MAQFI4sz8e2RO/ja3qP7wLoT9EOwe/ja3qP7wLoT9EOwe/ja3qP7wLoT9EOwe/BLAhQDbsIz9St2+/BLAhQDbsIz9St2+/BLAhQDbsIz9St2+/qFMWQAkm/z54GWO/qFMWQAkm/z54GWO/qFMWQAkm/z54GWO/NT8lQDbsIz9xbzy/NT8lQDbsIz9xbzy/NT8lQDbsIz9xbzy/2uIZQAkm/z6Y0S+/2uIZQAkm/z6Y0S+/2uIZQAkm/z6Y0S+/rMEiQGb1Jz/WCj2/rMEiQGb1Jz/WCj2/rMEiQGb1Jz/WCj2/j2AWQGyGMT9nSy+/j2AWQGyGMT9nSy+/j2AWQGyGMT9nSy+/w6EfQGb1Jz98D2q/w6EfQGb1Jz98D2q/w6EfQGb1Jz98D2q/pUATQGyGMT8OUFy/pUATQGyGMT8OUFy/pUATQGyGMT8OUFy/lNYTQPO5JL+UeSy/lNYTQPO5JL+UeSy/lNYTQPO5JL+UeSy/dXUHQOkoG78iuh6/dXUHQOkoG78iuh6/dXUHQOkoG78iuh6/qrYQQPO5JL85flm/qrYQQPO5JL85flm/qrYQQPO5JL85flm/i1UEQOkoG7/Ivku/i1UEQOkoG7/Ivku/i1UEQOkoG7/Ivku/AAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAPwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAPwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AACAPwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAAAAAAIC/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIC/AACAvwAAAAAAAACAAAAAAAAAAAAAAIA/AAAAAAAAgD8AAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAAAAAAIA/AAAAANqZfT5oBni/MFKtMUyhfD+3miU+wkJ+P5YW7Dyx5ea96yRGshOCcb9N0qm+AAAAANqZfT5oBni/wkJ+P5YW7Dyx5ea9AAAAAOWZfb5nBng/AAAAAAH2bj+Eq7c+Yil7P6lJRL3E+D8+AAAAAAhSf79zIJW9AAAAAOWZfb5nBng/Yil7P6lJRL3E+D8+wUJ+v5gW7Dyz5ea9AAAAANqZfT5oBni/MFKtMUyhfD+3miU+wUJ+v5gW7Dyz5ea96yRGshOCcb9N0qm+AAAAANqZfT5oBni/Yil7v59JRL3B+D8+AAAAAOWZfb5nBng/AAAAAAH2bj+Eq7c+Yil7v59JRL3B+D8+AAAAAAhSf79zIJW9AAAAAOWZfb5nBng///9/vwAAAAAAAACAAAAAAJuRUL8wcRS/AAAAAC9xFL+akVA///9/vwAAAAAAAACAAAAAAC9xFL+akVA/AAAAAJqRUD8xcRQ///9/vwAAAAAAAACAAAAAAJuRUL8wcRS/AAAAADJxFD+akVC///9/vwAAAAAAAACAAAAAADJxFD+akVC/AAAAAJqRUD8xcRQ/AAAAAJuRUL8wcRS/AAAAAC9xFL+akVA/AACAPwAAAABJAh8zAAAAAC9xFL+akVA/AAAAAJqRUD8xcRQ/AACAPwAAAABJAh8zAAAAAJuRUL8wcRS/AAAAADJxFD+akVC/AACAPwAAAABJAh8zAAAAADJxFD+akVC/AAAAAJqRUD8xcRQ/AACAPwAAAABJAh8zwUJ+v5gW7Dyz5ea9Yil7v59JRL3B+D8+6yRGshOCcb9N0qm+AAAAAAhSf79zIJW9AAAAAAH2bj+Eq7c+MFKtMUyhfD+3miU+Yil7P6lJRL3E+D8+wkJ+P5YW7Dyx5ea9wUJ+v5gW7Dyz5ea9Yil7v59JRL3B+D8+AAAAAAH2bj+Eq7c+MFKtMUyhfD+3miU+6yRGshOCcb9N0qm+AAAAAAhSf79zIJW9Yil7P6lJRL3E+D8+wkJ+P5YW7Dyx5ea9zI54v7hzer0f+2w+Xojas7iBd7/syYK+0Rx1PmD5fb63T3A/zI54v7hzer0f+2w+U1C7tLiBdz/wyYI+0Rx1PmD5fb63T3A/zI54v7hzer0f+2w+6Bx1vjL5fT64T3C/Xojas7iBd7/syYK+zI54v7hzer0f+2w+6Bx1vjL5fT64T3C/U1C7tLiBdz/wyYI+Xojas7iBd7/syYK+0Rx1PmD5fb63T3A/y454Pyx0ej0S+2y+U1C7tLiBdz/wyYI+0Rx1PmD5fb63T3A/y454Pyx0ej0S+2y+6Bx1vjL5fT64T3C/Xojas7iBd7/syYK+y454Pyx0ej0S+2y+6Bx1vjL5fT64T3C/U1C7tLiBdz/wyYI+y454Pyx0ej0S+2y+AACAvwAAAAAAAACAAAAAAJfxZr+Q6tw+AAAAAI7q3D6X8WY/AACAvwAAAAAAAACAAAAAAI7q3D6X8WY/AAAAAJfxZj+Q6ty+AACAvwAAAAAAAACAAAAAAJfxZr+Q6tw+AAAAAI7q3L6X8Wa/AACAvwAAAAAAAACAAAAAAI7q3L6X8Wa/AAAAAJfxZj+Q6ty+AAAAAJfxZr+Q6tw+AAAAAI7q3D6X8WY/AACAPwAAAAAAAACAAAAAAI7q3D6X8WY/AAAAAJfxZj+Q6ty+AACAPwAAAAAAAACAAAAAAJfxZr+Q6tw+AAAAAI7q3L6X8Wa/AACAPwAAAAAAAACAAAAAAI7q3L6X8Wa/AAAAAJfxZj+Q6ty+AACAPwAAAAAAAACAAACAvwAAAAC2lcU0AAAAAJ7xZr916tw+AAAAAJ/q3D6W8WY/AACAvwAAAAC2lcU0AAAAAJ/q3D6W8WY/AAAAAJ7xZj956ty+AACAvwAAAAC2lcU0AAAAAJ7xZr916tw+AAAAAJzq3L6V8Wa/AACAvwAAAAC2lcU0AAAAAJzq3L6V8Wa/AAAAAJ7xZj956ty+AAAAAJ7xZr916tw+AAAAAJ/q3D6W8WY/AACAPwAAAAAAAACAAAAAAJ/q3D6W8WY/AAAAAJ7xZj956ty+AACAPwAAAAAAAACAAAAAAJ7xZr916tw+AAAAAJzq3L6V8Wa/AACAPwAAAAAAAACAAAAAAJzq3L6V8Wa/AAAAAJ7xZj956ty+AACAPwAAAAAAAACA0hx1vmH5fb63T3A/a8D5M7iBd7/tyYK+zI54P7hzer0f+2w+0hx1vmH5fb63T3A/U1C7NLiBdz/vyYI+zI54P7hzer0f+2w+a8D5M7iBd7/tyYK+6Bx1PjT5fT65T3C/zI54P7hzer0f+2w+U1C7NLiBdz/vyYI+6Bx1PjT5fT65T3C/zI54P7hzer0f+2w+zI54vy50ej0T+2y+0hx1vmH5fb63T3A/a8D5M7iBd7/tyYK+zI54vy50ej0T+2y+0hx1vmH5fb63T3A/U1C7NLiBdz/vyYI+zI54vy50ej0T+2y+a8D5M7iBd7/tyYK+6Bx1PjT5fT65T3C/zI54vy50ej0T+2y+U1C7NLiBdz/vyYI+6Bx1PjT5fT65T3C/AAAAAJfxZr+Q6tw+AAAAAI7q3D6X8WY/AACAPwAAAAAwkkyzAAAAAI7q3D6X8WY/AAAAAJfxZj+Q6ty+AACAPwAAAAAwkkyzAAAAAJfxZr+Q6tw+AAAAAI7q3L6X8Wa/AACAPwAAAAAwkkyzAAAAAI7q3L6X8Wa/AAAAAJfxZj+Q6ty+AACAPwAAAAAwkkyzAACAvwAAAAAwkkwyAAAAAJfxZr+Q6tw+AAAAAI7q3D6X8WY/AACAvwAAAAAwkkwyAAAAAI7q3D6X8WY/AAAAAJfxZj+Q6ty+AACAvwAAAAAwkkwyAAAAAJfxZr+Q6tw+AAAAAI7q3L6X8Wa/AACAvwAAAAAwkkwyAAAAAI7q3L6X8Wa/AAAAAJfxZj+Q6ty+AAAAAJ7xZr916tw+AAAAAJ/q3D6W8WY/AACAPwAAAAC2lcU0AAAAAJ/q3D6W8WY/AAAAAJ7xZj956ty+AACAPwAAAAC2lcU0AAAAAJ7xZr916tw+AAAAAJzq3L6V8Wa/AACAPwAAAAC2lcU0AAAAAJzq3L6V8Wa/AAAAAJ7xZj956ty+AACAPwAAAAC2lcU0AACAvwAAAAC2lcWzAAAAAJ7xZr916tw+AAAAAJ/q3D6W8WY/AACAvwAAAAC2lcWzAAAAAJ/q3D6W8WY/AAAAAJ7xZj956ty+AACAvwAAAAC2lcWzAAAAAJ7xZr916tw+AAAAAJzq3L6V8Wa/AACAvwAAAAC2lcWzAAAAAJzq3L6V8Wa/AAAAAJ7xZj956ty+4f1Wv/na275wEKo+8nHMvl8yZz+ruCE+JU+8PgAAAAB4Dm4/8nHMvl8yZz+ruCE+JU+8PgAAAAB4Dm4/4/1WP/3a2z5sEKq+4f1Wv/na275wEKo+8nHMvl8yZz+ruCE+N0+8vnTILrR2Dm6/8nHMvl8yZz+ruCE+N0+8vnTILrR2Dm6/4/1WP/3a2z5sEKq+4f1Wv/na275wEKo+JU+8PgAAAAB4Dm4/CXLMPlcyZ7/LuCG+JU+8PgAAAAB4Dm4/CXLMPlcyZ7/LuCG+4/1WP/3a2z5sEKq+4f1Wv/na275wEKo+N0+8vnTILrR2Dm6/CXLMPlcyZ7/LuCG+N0+8vnTILrR2Dm6/CXLMPlcyZ7/LuCG+4/1WP/3a2z5sEKq+9rNov5nxVz4ME7g+6S9OvjTteb99GaM9Jk+8Pn4p1rR4Dm4/9rNov5nxVz4ME7g+wi9OPjPteT/GGaO9Jk+8Pn4p1rR4Dm4/9rNov5nxVz4ME7g+KE+8vlvGDrV5Dm6/6S9OvjTteb99GaM99rNov5nxVz4ME7g+KE+8vlvGDrV5Dm6/wi9OPjPteT/GGaO96S9OvjTteb99GaM9Jk+8Pn4p1rR4Dm4/+LNoP3HxV74RE7i+wi9OPjPteT/GGaO9Jk+8Pn4p1rR4Dm4/+LNoP3HxV74RE7i+KE+8vlvGDrV5Dm6/6S9OvjTteb99GaM9+LNoP3HxV74RE7i+KE+8vlvGDrV5Dm6/wi9OPjPteT/GGaO9+LNoP3HxV74RE7i+7LU7v9pxHT/qe5Q+KE+8vlfGjjR5Dm6/NlIRPznESj+Z52W+KE+8vlfGjjR5Dm6/NlIRPznESj+Z52W+67U7P9txHb/me5S+7LU7v9pxHT/qe5Q+K0+8PlrGDrR3Dm4/NlIRPznESj+Z52W+K0+8PlrGDrR3Dm4/NlIRPznESj+Z52W+67U7P9txHb/me5S+7LU7v9pxHT/qe5Q+QVIRvyjESr8Z6GU+KE+8vlfGjjR5Dm6/QVIRvyjESr8Z6GU+KE+8vlfGjjR5Dm6/67U7P9txHb/me5S+7LU7v9pxHT/qe5Q+QVIRvyjESr8Z6GU+K0+8PlrGDrR3Dm4/QVIRvyjESr8Z6GU+K0+8PlrGDrR3Dm4/67U7P9txHb/me5S+OAlqv+BmO74BIbk+SEQuviutez+D2Yk9J0+8Phcc7TN4Dm4/SEQuviutez+D2Yk9J0+8Phcc7TN4Dm4/NwlqPwNnOz76ILm+OAlqv+BmO74BIbk+Mk+8vg0c7TN3Dm6/SEQuviutez+D2Yk9Mk+8vg0c7TN3Dm6/SEQuviutez+D2Yk9NwlqPwNnOz76ILm+OAlqv+BmO74BIbk+TUQuPiute7+o2Ym9J0+8Phcc7TN4Dm4/TUQuPiute7+o2Ym9J0+8Phcc7TN4Dm4/NwlqPwNnOz76ILm+OAlqv+BmO74BIbk+Mk+8vg0c7TN3Dm6/TUQuPiute7+o2Ym9Mk+8vg0c7TN3Dm6/TUQuPiute7+o2Ym9NwlqPwNnOz76ILm+FXFmv/za274FWZU9HiPbvl4yZz/gBQ49xV6lPZDTi7T/KX8/HiPbvl4yZz/gBQ49xV6lPZDTi7T/KX8/E3FmP/3a2z7/WJW9FXFmv/za274FWZU9HiPbvl4yZz/gBQ49Dl+lvZDTC7P/KX+/HiPbvl4yZz/gBQ49Dl+lvZDTC7P/KX+/E3FmP/3a2z7/WJW9FXFmv/za274FWZU9xV6lPZDTi7T/KX8/OyPbPlcyZ7+SBQ69xV6lPZDTi7T/KX8/OyPbPlcyZ7+SBQ69E3FmP/3a2z7/WJW9FXFmv/za274FWZU9Dl+lvZDTC7P/KX+/OyPbPlcyZ7+SBQ69Dl+lvZDTC7P/KX+/OyPbPlcyZ7+SBQ69E3FmP/3a2z7/WJW9/mx5v6HxVz6qp6E9DwFdvjTteb9nO488yF6lPYY8E7X/KX8//mx5v6HxVz6qp6E9yF6lPYY8E7X/KX8/DAFdPjPteT/1PI+8/mx5v6HxVz6qp6E9DwFdvjTteb9nO488216lvVfGjjMAKn+//mx5v6HxVz6qp6E9216lvVfGjjMAKn+/DAFdPjPteT/1PI+8DwFdvjTteb9nO488yF6lPYY8E7X/KX8/AW15P27xV74Fp6G9yF6lPYY8E7X/KX8/DAFdPjPteT/1PI+8AW15P27xV74Fp6G9DwFdvjTteb9nO488216lvVfGjjMAKn+/AW15P27xV74Fp6G9216lvVfGjjMAKn+/DAFdPjPteT/1PI+8AW15P27xV74Fp6G9ODNJv9txHT/rZYI9zl6lvU3GDjQAKn+/scMbPzTESj+W5Um9zl6lvU3GDjQAKn+/scMbPzTESj+W5Um9OzNJP9pxHb/8ZIK9ODNJv9txHT/rZYI99F6lPWDGjrQAKn8/scMbPzTESj+W5Um99F6lPWDGjrQAKn8/scMbPzTESj+W5Um9OzNJP9pxHb/8ZIK9ODNJv9txHT/rZYI9vMMbvyjESr+B50k9zl6lvU3GDjQAKn+/vMMbvyjESr+B50k9zl6lvU3GDjQAKn+/OzNJP9pxHb/8ZIK9ODNJv9txHT/rZYI9vMMbvyjESr+B50k99F6lPWDGjrQAKn8/vMMbvyjESr+B50k99F6lPWDGjrQAKn8/OzNJP9pxHb/8ZIK9yNp6v+NmO74klKI9Ico6vi2tez/IHnI8/16lPQAAAAAAKn8/Ico6vi2tez/IHnI8/16lPQAAAAAAKn8/x9p6PwdnOz6hk6K9yNp6v+NmO74klKI9Ico6vi2tez/IHnI8+16lvQsc7TL+KX+/Ico6vi2tez/IHnI8+16lvQsc7TL+KX+/x9p6PwdnOz6hk6K9yNp6v+NmO74klKI9/16lPQAAAAAAKn8/Zso6Piqte7/lHHK8/16lPQAAAAAAKn8/Zso6Piqte7/lHHK8x9p6PwdnOz6hk6K9yNp6v+NmO74klKI9+16lvQsc7TL+KX+/Zso6Piqte7/lHHK8+16lvQsc7TL+KX+/Zso6Piqte7/lHHK8x9p6PwdnOz6hk6K9zblmv/za277z92u9QGjbvl8yZz8oZOC8S6SCvXDILrOIen8/QGjbvl8yZz8oZOC8S6SCvXDILrOIen8/zrlmP//a2z5X92s9zblmv/za277z92u9QGjbvl8yZz8oZOC8J6SCPZLTi7OHen+/QGjbvl8yZz8oZOC8J6SCPZLTi7OHen+/zrlmP//a2z5X92s9zblmv/za277z92u9S6SCvXDILrOIen8/Z2jbPlcyZ79eZOA8S6SCvXDILrOIen8/Z2jbPlcyZ79eZOA8zrlmP//a2z5X92s9zblmv/za277z92u9J6SCPZLTi7OHen+/Z2jbPlcyZ79eZOA8J6SCPZLTi7OHen+/Z2jbPlcyZ79eZOA8zrlmP//a2z5X92s9uLt5v5jxVz5KZ3+9zUZdvjPteb/RTGK8Z6SCvaOp5LSGen8/uLt5v5jxVz5KZ3+9Z6SCvaOp5LSGen8/zEZdPjPteT+NS2I8uLt5v5jxVz5KZ3+9zUZdvjPteb/RTGK8VaSCPRqfoLKGen+/uLt5v5jxVz5KZ3+9VaSCPRqfoLKGen+/zEZdPjPteT+NS2I8zUZdvjPteb/RTGK8Z6SCvaOp5LSGen8/uLt5P3PxV77gaX89Z6SCvaOp5LSGen8/zEZdPjPteT+NS2I8uLt5P3PxV77gaX89zUZdvjPteb/RTGK8VaSCPRqfoLKGen+/uLt5P3PxV77gaX89VaSCPRqfoLKGen+/zEZdPjPteT+NS2I8uLt5P3PxV77gaX89t3JJv9pxHT9FB069ZaSCPR6fIDSGen+/2fQbPzPESj+vgB89ZaSCPR6fIDSGen+/2fQbPzPESj+vgB89t3JJP9xxHb8KBk49t3JJv9pxHT9FB069PKSCvW/av7SIen8/2fQbPzPESj+vgB89PKSCvW/av7SIen8/2fQbPzPESj+vgB89t3JJP9xxHb8KBk49t3JJv9pxHT9FB0694PQbvyzESr+zgB+9ZaSCPR6fIDSGen+/4PQbvyzESr+zgB+9ZaSCPR6fIDSGen+/t3JJP9xxHb8KBk49t3JJv9pxHT9FB0694PQbvyzESr+zgB+9PKSCvW/av7SIen8/4PQbvyzESr+zgB+9PKSCvW/av7SIen8/t3JJP9xxHb8KBk498yl7v+tmO76hb4C9HQU7vi2tez/NRD+8SqSCvT8DI7OHen8/HQU7vi2tez/NRD+8SqSCvT8DI7OHen8/8yl7P/9mOz6fb4A98yl7v+tmO76hb4C9HQU7vi2tez/NRD+8JaSCPYIxFDOGen+/HQU7vi2tez/NRD+8JaSCPYIxFDOGen+/8yl7P/9mOz6fb4A98yl7v+tmO76hb4C9SqSCvT8DI7OHen8/RAU7Piqte7+HRT88SqSCvT8DI7OHen8/RAU7Piqte7+HRT888yl7P/9mOz6fb4A98yl7v+tmO76hb4C9JaSCPYIxFDOGen+/RAU7Piqte7+HRT88JaSCPYIxFDOGen+/RAU7Piqte7+HRT888yl7P/9mOz6fb4A9NMVev/ja275CZXe+oNfTvlsyZz9tQuu98/eIvpDTi7Ntq3Y/oNfTvlsyZz9tQuu98/eIvpDTi7Ntq3Y/MsVeP//a2z5QZXc+NMVev/ja275CZXe+oNfTvlsyZz9tQuu95/eIPli9UbNwq3a/oNfTvlsyZz9tQuu95/eIPli9UbNwq3a/MsVeP//a2z5QZXc+NMVev/ja275CZXe+8/eIvpDTi7Ntq3Y/s9fTPlYyZ79kQus98/eIvpDTi7Ntq3Y/s9fTPlYyZ79kQus9MsVeP//a2z5QZXc+NMVev/ja275CZXe+5/eIPli9UbNwq3a/s9fTPlYyZ79kQus95/eIPli9UbNwq3a/s9fTPlYyZ79kQus9MsVeP//a2z5QZXc+UR9xv7XxVz5r44W+8veIvnop1rRsq3Y/paVVvjPteb+YQ229UR9xv7XxVz5r44W+8veIvnop1rRsq3Y/paVVPjTteT/yQm09UR9xv7XxVz5r44W+paVVvjPteb+YQ2297/eIPlfGjrNtq3a/UR9xv7XxVz5r44W+paVVPjTteT/yQm097/eIPlfGjrNtq3a/8veIvnop1rRsq3Y/paVVvjPteb+YQ229Vx9xP2rxV75o44U+8veIvnop1rRsq3Y/paVVPjTteT/yQm09Vx9xP2rxV75o44U+paVVvjPteb+YQ2297/eIPlfGjrNtq3a/Vx9xP2rxV75o44U+paVVPjTteT/yQm097/eIPlfGjrNtq3a/Vx9xP2rxV75o44U+ioBCv9pxHT/bAFi++feIPoIp1jRsq3a/N5QWPzDESj/LOSc++feIPoIp1jRsq3a/N5QWPzDESj/LOSc+i4BCP9xxHb+4AFg+ioBCv9pxHT/bAFi+7feIvoIp1rRuq3Y/N5QWPzDESj/LOSc+7feIvoIp1rRuq3Y/N5QWPzDESj/LOSc+i4BCP9xxHb+4AFg+ioBCv9pxHT/bAFi+QZQWvyvESr+oOSe++feIPoIp1jRsq3a/QZQWvyvESr+oOSe++feIPoIp1jRsq3a/i4BCP9xxHb+4AFg+ioBCv9pxHT/bAFi+QZQWvyvESr+oOSe+7feIvoIp1rRuq3Y/QZQWvyvESr+oOSe+7feIvoIp1rRuq3Y/i4BCP9xxHb+4AFg+74Byv+ZmO77Bp4a+8/eIvhkc7bNtq3Y/T5I0vi2tez9HiEi98/eIvhkc7bNtq3Y/T5I0vi2tez9HiEi974ByP/xmOz6/p4Y+74Byv+ZmO77Bp4a+T5I0vi2tez9HiEi94/eIPg0cbbNuq3a/T5I0vi2tez9HiEi94/eIPg0cbbNuq3a/74ByP/xmOz6/p4Y+74Byv+ZmO77Bp4a+8/eIvhkc7bNtq3Y/epI0Piqte7+giEg98/eIvhkc7bNtq3Y/epI0Piqte7+giEg974ByP/xmOz6/p4Y+74Byv+ZmO77Bp4a+epI0Piqte7+giEg94/eIPg0cbbNuq3a/epI0Piqte7+giEg94/eIPg0cbbNuq3a/74ByP/xmOz6/p4Y+JE+8vgAAAAB4Dm4/8nHMPl8yZz+ruCE+4f1WP/ra275wEKo+4/1Wv/3a2z5sEKq+JE+8vgAAAAB4Dm4/8nHMPl8yZz+ruCE+N0+8PpHTC7R2Dm6/8nHMPl8yZz+ruCE+4f1WP/ra275wEKo+4/1Wv/3a2z5sEKq+N0+8PpHTC7R2Dm6/8nHMPl8yZz+ruCE+C3LMvlcyZ7/LuCG+JE+8vgAAAAB4Dm4/4f1WP/ra275wEKo+4/1Wv/3a2z5sEKq+C3LMvlcyZ7/LuCG+JE+8vgAAAAB4Dm4/C3LMvlcyZ7/LuCG+N0+8PpHTC7R2Dm6/4f1WP/ra275wEKo+4/1Wv/3a2z5sEKq+C3LMvlcyZ7/LuCG+N0+8PpHTC7R2Dm6/I0+8vlTGDrV4Dm4/6S9OPjLteb99GaM99rNoP5vxVz4JE7g+I0+8vlTGDrV4Dm4/xS9OvjTteT/FGaO99rNoP5vxVz4JE7g+6S9OPjLteb99GaM9JU+8PlnGDrV4Dm6/9rNoP5vxVz4JE7g+xS9OvjTteT/FGaO9JU+8PlnGDrV4Dm6/9rNoP5vxVz4JE7g+9rNov23xV74UE7i+I0+8vlTGDrV4Dm4/6S9OPjLteb99GaM99rNov23xV74UE7i+I0+8vlTGDrV4Dm4/xS9OvjTteT/FGaO99rNov23xV74UE7i+6S9OPjLteb99GaM9JU+8PlnGDrV4Dm6/9rNov23xV74UE7i+xS9OvjTteT/FGaO9JU+8PlnGDrV4Dm6/NVIRvzvESj+R52W+Jk+8PlbGjjR6Dm6/67U7P9pxHT/pe5Q+67U7v9txHb/me5S+NVIRvzvESj+R52W+Jk+8PlbGjjR6Dm6/NVIRvzvESj+R52W+K0+8vlrGjrR3Dm4/67U7P9pxHT/pe5Q+67U7v9txHb/me5S+NVIRvzvESj+R52W+K0+8vlrGjrR3Dm4/Jk+8PlbGjjR6Dm6/RFIRPyXESr8c6GU+67U7P9pxHT/pe5Q+67U7v9txHb/me5S+Jk+8PlbGjjR6Dm6/RFIRPyXESr8c6GU+K0+8vlrGjrR3Dm4/RFIRPyXESr8c6GU+67U7P9pxHT/pe5Q+67U7v9txHb/me5S+K0+8vlrGjrR3Dm4/RFIRPyXESr8c6GU+J0+8vhcc7TN4Dm4/TEQuPiutez+C2Yk9OAlqP+VmO74BIbk+OAlqvwFnOz76ILm+J0+8vhcc7TN4Dm4/TEQuPiutez+C2Yk9TEQuPiutez+C2Yk9LU+8Pggc7TN3Dm6/OAlqP+VmO74BIbk+OAlqvwFnOz76ILm+TEQuPiutez+C2Yk9LU+8Pggc7TN3Dm6/J0+8vhcc7TN4Dm4/TUQuviute7+o2Ym9OAlqP+VmO74BIbk+OAlqvwFnOz76ILm+J0+8vhcc7TN4Dm4/TUQuviute7+o2Ym9TUQuviute7+o2Ym9LU+8Pggc7TN3Dm6/OAlqP+VmO74BIbk+OAlqvwFnOz76ILm+TUQuviute7+o2Ym9LU+8Pggc7TN3Dm6/xV6lvZDTi7T/KX8/GiPbPl0yZz/gBQ49FXFmP/ra274FWZU9E3Fmv/3a2z7/WJW9xV6lvZDTi7T/KX8/GiPbPl0yZz/gBQ49Dl+lPZDTi7P/KX+/GiPbPl0yZz/gBQ49FXFmP/ra274FWZU9E3Fmv/3a2z7/WJW9Dl+lPZDTi7P/KX+/GiPbPl0yZz/gBQ49PCPbvlcyZ7+SBQ69xV6lvZDTi7T/KX8/FXFmP/ra274FWZU9E3Fmv/3a2z7/WJW9PCPbvlcyZ7+SBQ69xV6lvZDTi7T/KX8/PCPbvlcyZ7+SBQ69Dl+lPZDTi7P/KX+/FXFmP/ra274FWZU9E3Fmv/3a2z7/WJW9PCPbvlcyZ7+SBQ69Dl+lPZDTi7P/KX+/xl6lvVPGDrX/KX8/EgFdPjPteb9nO488/Wx5P6PxVz6rp6E9CAFdvjPteT/0PI+8xl6lvVPGDrX/KX8//Wx5P6PxVz6rp6E93V6lPVfGDjQAKn+/EgFdPjPteb9nO488/Wx5P6PxVz6rp6E9CAFdvjPteT/0PI+83V6lPVfGDjQAKn+//Wx5P6PxVz6rp6E9Am15v27xV77rpqG9xl6lvVPGDrX/KX8/EgFdPjPteb9nO488Am15v27xV77rpqG9CAFdvjPteT/0PI+8xl6lvVPGDrX/KX8/Am15v27xV77rpqG93V6lPVfGDjQAKn+/EgFdPjPteb9nO488Am15v27xV77rpqG9CAFdvjPteT/0PI+83V6lPVfGDjQAKn+/scMbvzPESj985Um9zl6lPU3GDjQAKn+/ODNJP9txHT/qZYI9OjNJv9pxHb/8ZIK9scMbvzPESj985Um9zl6lPU3GDjQAKn+/scMbvzPESj985Um99l6lvWHGjrQAKn8/ODNJP9txHT/qZYI9OjNJv9pxHb/8ZIK9scMbvzPESj985Um99l6lvWHGjrQAKn8/zl6lPU3GDjQAKn+/u8MbPyrESr+B50k9ODNJP9txHT/qZYI9OjNJv9pxHb/8ZIK9zl6lPU3GDjQAKn+/u8MbPyrESr+B50k99l6lvWHGjrQAKn8/u8MbPyrESr+B50k9ODNJP9txHT/qZYI9OjNJv9pxHb/8ZIK99l6lvWHGjrQAKn8/u8MbPyrESr+B50k9BF+lvQAAAAAAKn8/GMo6Pi2tez/FHnI8yNp6P+RmO74klKI9x9p6vwVnOz6hk6K9BF+lvQAAAAAAKn8/GMo6Pi2tez/FHnI8+l6lPQocbTP/KX+/GMo6Pi2tez/FHnI8yNp6P+RmO74klKI9x9p6vwVnOz6hk6K9+l6lPQocbTP/KX+/GMo6Pi2tez/FHnI8aso6viqte7/lHHK8BF+lvQAAAAAAKn8/yNp6P+RmO74klKI9x9p6vwVnOz6hk6K9aso6viqte7/lHHK8BF+lvQAAAAAAKn8/aso6viqte7/lHHK8+l6lPQocbTP/KX+/yNp6P+RmO74klKI9x9p6vwVnOz6hk6K9aso6viqte7/lHHK8+l6lPQocbTP/KX+/SaSCPYvTC7OGen8/QGjbPl8yZz8oZOC8zblmP/za277z92u9zrlmv//a2z5X92s9SaSCPYvTC7OGen8/QGjbPl8yZz8oZOC8KKSCvZPTi7OIen+/QGjbPl8yZz8oZOC8zblmP/za277z92u9zrlmv//a2z5X92s9KKSCvZPTi7OIen+/QGjbPl8yZz8oZOC8Z2jbvlYyZ79eZOA8SaSCPYvTC7OGen8/zblmP/za277z92u9zrlmv//a2z5X92s9Z2jbvlYyZ79eZOA8SaSCPYvTC7OGen8/Z2jbvlYyZ79eZOA8KKSCvZPTi7OIen+/zblmP/za277z92u9zrlmv//a2z5X92s9Z2jbvlYyZ79eZOA8KKSCvZPTi7OIen+/Z6SCPUgC6LSGen8/zUZdPjPteb/RTGK8ubt5P5bxVz5KZ3+9zkZdvjPteT+NS2I8Z6SCPUgC6LSGen8/ubt5P5bxVz5KZ3+9VqSCvVDGDrOGen+/zUZdPjPteb/RTGK8ubt5P5bxVz5KZ3+9zkZdvjPteT+NS2I8VqSCvVDGDrOGen+/ubt5P5bxVz5KZ3+9uLt5v3HxV76aaX89Z6SCPUgC6LSGen8/zUZdPjPteb/RTGK8uLt5v3HxV76aaX89zkZdvjPteT+NS2I8Z6SCPUgC6LSGen8/uLt5v3HxV76aaX89VqSCvVDGDrOGen+/zUZdPjPteb/RTGK8uLt5v3HxV76aaX89zkZdvjPteT+NS2I8VqSCvVDGDrOGen+/1/QbvzXESj+egB89ZKSCveh3MjSHen+/uHJJP9txHT9IB069t3JJv9xxHb8KBk491/QbvzXESj+egB89ZKSCveh3MjSHen+/1/QbvzXESj+egB89OaSCPZ5QxLSHen8/uHJJP9txHT9IB069t3JJv9xxHb8KBk491/QbvzXESj+egB89OaSCPZ5QxLSHen8/ZKSCveh3MjSHen+/4vQbPyzESr+0gB+9uHJJP9txHT9IB069t3JJv9xxHb8KBk49ZKSCveh3MjSHen+/4vQbPyzESr+0gB+9OaSCPZ5QxLSHen8/4vQbPyzESr+0gB+9uHJJP9txHT9IB069t3JJv9xxHb8KBk49OaSCPZ5QxLSHen8/4vQbPyzESr+0gB+9SqSCPT8DI7OHen8/HwU7Piytez/LRD+88yl7P+xmO76hb4C98il7v/9mOz6fb4A9SqSCPT8DI7OHen8/HwU7Piytez/LRD+8IaSCvX8xFDOHen+/HwU7Piytez/LRD+88yl7P+xmO76hb4C98il7v/9mOz6fb4A9IaSCvX8xFDOHen+/HwU7Piytez/LRD+8SAU7viqte7+HRT88SqSCPT8DI7OHen8/8yl7P+xmO76hb4C98il7v/9mOz6fb4A9SAU7viqte7+HRT88SqSCPT8DI7OHen8/SAU7viqte7+HRT88IaSCvX8xFDOHen+/8yl7P+xmO76hb4C98il7v/9mOz6fb4A9SAU7viqte7+HRT88IaSCvX8xFDOHen+/8veIPo/Ti7Ntq3Y/oNfTPlwyZz9tQuu9NMVeP/ra275DZXe+MsVev//a2z5QZXc+8veIPo/Ti7Ntq3Y/oNfTPlwyZz9tQuu95/eIvpDTi7Nvq3a/oNfTPlwyZz9tQuu9NMVeP/ra275DZXe+MsVev//a2z5QZXc+5/eIvpDTi7Nvq3a/oNfTPlwyZz9tQuu9s9fTvlYyZ79iQus98veIPo/Ti7Ntq3Y/NMVeP/ra275DZXe+MsVev//a2z5QZXc+s9fTvlYyZ79iQus98veIPo/Ti7Ntq3Y/s9fTvlYyZ79iQus95/eIvpDTi7Nvq3a/NMVeP/ra275DZXe+MsVev//a2z5QZXc+s9fTvlYyZ79iQus95/eIvpDTi7Nvq3a/paVVPjPteb+YQ2298PeIPngp1rRtq3Y/UR9xP7XxVz5r44W+pKVVvjTteT/xQm098PeIPngp1rRtq3Y/UR9xP7XxVz5r44W+7veIvgAAAABtq3a/paVVPjPteb+YQ229UR9xP7XxVz5r44W+7veIvgAAAABtq3a/pKVVvjTteT/xQm09UR9xP7XxVz5r44W+Vx9xv2nxV75l44U+paVVPjPteb+YQ2298PeIPngp1rRtq3Y/Vx9xv2nxV75l44U+pKVVvjTteT/xQm098PeIPngp1rRtq3Y/Vx9xv2nxV75l44U+7veIvgAAAABtq3a/paVVPjPteb+YQ229Vx9xv2nxV75l44U+7veIvgAAAABtq3a/pKVVvjTteT/xQm09N5QWvzHESj/JOSc+9veIvn4p1jRrq3a/i4BCP9hxHT/ZAFi+ioBCv9txHb+1AFg+N5QWvzHESj/JOSc+9veIvn4p1jRrq3a/N5QWvzHESj/JOSc+7feIPoEp1rRuq3Y/i4BCP9hxHT/ZAFi+ioBCv9txHb+1AFg+N5QWvzHESj/JOSc+7feIPoEp1rRuq3Y/9veIvn4p1jRrq3a/QJQWPyvESr+nOSe+i4BCP9hxHT/ZAFi+ioBCv9txHb+1AFg+9veIvn4p1jRrq3a/QJQWPyvESr+nOSe+7feIPoEp1rRuq3Y/QJQWPyvESr+nOSe+i4BCP9hxHT/ZAFi+ioBCv9txHb+1AFg+7feIPoEp1rRuq3Y/QJQWPyvESr+nOSe+T5I0Piytez9HiEi98/eIPhcc7bNtq3Y/74ByP+ZmO77Ap4a+74Byv/1mOz6/p4Y+T5I0Piytez9HiEi98/eIPhcc7bNtq3Y/4veIvgocbbNuq3a/T5I0Piytez9HiEi974ByP+ZmO77Ap4a+74Byv/1mOz6/p4Y+4veIvgocbbNuq3a/T5I0Piytez9HiEi9gJI0viqte7+fiEg98/eIPhcc7bNtq3Y/74ByP+ZmO77Ap4a+74Byv/1mOz6/p4Y+gJI0viqte7+fiEg98/eIPhcc7bNtq3Y/4veIvgocbbNuq3a/gJI0viqte7+fiEg974ByP+ZmO77Ap4a+74Byv/1mOz6/p4Y+4veIvgocbbNuq3a/gJI0viqte7+fiEg9Uf3fPULt2z5SNAg+HvgXP74BAD1MAog+UDQIPh74Fz97/j8+Qu3bPlH93z1MAog+ev4/Plzwpz5QNAg+Qu3bPr4BAD1C7ds+UDQIPkLt2z4k/4c+XPCnPlH93z1C7ds+mgJwPh74Fz9R/d89XPCnPpoCcD4e+Bc/NR+gPh74Fz/KAQA9HvgXP3v+Pz5c8Kc+mgJwPkLt2z56/j8+Qu3bPpoCcD5C7ds+NR+gPkLt2z6+AQA9Qu3bPiT/hz5C7ds+ogUQP/j3fz7Ti0w/MBqBPvADST94v7Y9G3kSP6oGgT5tACQ/+Pd/Prz+XD94v7Y9R/tPP378pz5b50o/GnbUPvyaST8wGoE+kx0UPxp21D4W/WE/fvynPswdWz8wGoE+0VRFP3i/tj2iBRA/xLUXPvD1MT8wGoE+BloxP3i/tj39Di0/qgaBPm0AJD/EtRc+xb1EPzAagT5H+08/kCnYPmqaMz8adtQ++DozPzAagT6Hais/GnbUPhb9YT+QKdg+HBCgPaABAD21MvA9lPJvPscXYD548Ac+Svr/PKABAD3j/i8+ePAHPrUy8D2U8m8+HBCgPXjwBz6yMvA9ePAHPuP+Lz7wKD89Svr/PHjwBz7yAAA+8Cg/PbIy8D188Ac+Svr/PJTybz7HF2A+8Cg/PRwQoD2gAQA94/4vPvAoPz2/BFA+lPJvPvgL+z2gAQA9Svr/PHjwBz7j/i8+ePAHPhwQoD148Ac+8gAAPnjwBz6/BFA+ePAHPvIAAD548Ac+d4IvP4SbLj53gi8/hJsuPneCLz/AqKo+d4IvP8Coqj5M/04/iOKqPkz/Tj+I4qo+YyxHP4SbLj5jLEc/hJsuPmEsRz98my4+YSxHP3ybLj53gi8/iOKqPneCLz+I4qo+ogUQP8Coqj6iBRA/wKiqPkvWXj+Emy4+S9ZeP4SbLj5tAnI/8My/PWkAbD+gx/48ZgZmP6DH/jxvAHg/8My/PWkAbD/Ax/48ZgZmPwCX/jttAnI/wMf+PG0Ccj8Al/47aQBsP/DMvz1vAHg/wMf+PGkAbD8Al/47aQBsP/DMvz1tAnI/4Mf+PGkAbD+gx/48bwB4P+DH/jxmBmY/oMf+PGkAbD8Al/47dAJ+P+DH/jxtAnI/oMf+PG0Ccj/wzL89bwB4P/DMvz1rAGw/oMf+PGYGZj/wzL89dAJ+P/DMvz0vBXI/PNMPPi8Fcj8g9Rc+qAFmP9j9Lz4vBXI/wDzQPagBZj880w8+LwVyPyg68D2oAGw/PNMPPi8Fcj/Y/S8+LwVyP9j9Lz6oAGw/wDzQPS8Fcj880w8+0xh4Pyg68D3TGHg/IPUXPqgAbD/Y/S8+qABsP8A80D2oAGw/PNMPPi8Fcj9A0w8+qABsPzzTDz7TGHg/2P0vPqgAbD/Y/S8+qAFmP8A80D2oAGw/PNMPPtMYeD9A0w8+qAFmPzzTDz6l/20/sPpnPqX/bT8g+lc+9QBmP8j6Tz6l/20/yPpPPvUAZj/o/Tc+pf9tPwD1Pz5NAGo/rPpnPqX/bT+w+mc+pf9tP8j6Tz5NAGo/yPpPPqX/bT/o/Tc+/f5xPwD1Pz79/nE/IPpXPk0Aaj/I+k8+TQBqP8j6Tz5NAGo/5P03PqX/bT/I+k8+TQBqP7D6Zz79/nE/sPpnPk0Aaj/I+k8+9QBmP8j6Tz5NAGo/6P03Pv3+cT/I+k8+9QBmP7D6Zz5mBmY/oMf+PGkAbD+gx/48bQJyP/DMvz1mBmY/AJf+O2kAbD/Ax/48bwB4P/DMvz1pAGw/8My/PW0Ccj8Al/47bQJyP8DH/jxpAGw/8My/PWkAbD8Al/47bwB4P8DH/jxvAHg/4Mf+PGkAbD+gx/48bQJyP+DH/jx0An4/4Mf+PGkAbD8Al/47ZgZmP6DH/jxvAHg/8My/PW0Ccj/wzL89bQJyP6DH/jx0An4/8My/PWYGZj/wzL89awBsP6DH/jwvBXI/IPUXPqgBZj/Y/S8+LwVyPzzTDz6oAWY/PNMPPi8Fcj8oOvA9LwVyP8A80D0vBXI/2P0vPi8Fcj/Y/S8+qABsPzzTDz4vBXI/PNMPPtMYeD8oOvA9qABsP8A80D2oAGw/wDzQPdMYeD8g9Rc+qABsP9j9Lz6oAGw/PNMPPqgAbD880w8+LwVyP0DTDz6oAWY/wDzQPdMYeD/Y/S8+qABsP9j9Lz6oAWY/PNMPPqgAbD880w8+0xh4P0DTDz6l/20/IPpXPvUAZj/I+k8+pf9tP7D6Zz71AGY/6P03PqX/bT8A9T8+pf9tP8j6Tz6l/20/sPpnPqX/bT/I+k8+TQBqP6z6Zz6l/20/6P03Pv3+cT8A9T8+TQBqP8j6Tz5NAGo/yPpPPv3+cT8g+lc+TQBqP8j6Tz5NAGo/sPpnPk0Aaj/k/Tc+pf9tP8j6Tz71AGY/yPpPPv3+cT+w+mc+TQBqP8j6Tz71AGY/sPpnPk0Aaj/o/Tc+/f5xP8j6Tz7wAh4/G/1rP3r2KT+JBGY//QQMP9gSRD969ik/VAZgP2kFEj/YEkQ/rQoYP9gSRD8z+yM/Gv1rPzP7Iz+JBGY/aQUSPxv9az8z+yM/VAZgP60KGD8a/Ws/8AIeP9gSRD/wAh4/1xJEP/wEDD8b/Ws/fPYpP4oEZj9pBRI/G/1rP3z2KT8b/Ws/rgoYPxv9az8z+yM/1xJEP2kFEj/XEkQ/M/sjP4oEZj+tChg/2BJEPzP7Iz8a/Ws/8AIePxv9az8K+0s/LP9rP6MCRj8sAFI/FQEuPywAUj8K+0s/uxFmPzwSQD8s/2s/fw40P8D2UT+jAkY/LP9rP38OND/A9Ws/PBJAPywAUj+jAkY/uxFmPx4HOj8s/2s/Hgc6Pyz/az+jAkY/LP9rPxUBLj8s/2s/CvtLP0oEYD88EkA/LQBSP38OND/A9Ws/CvtLP7sRZj+ADjQ/wPZRPzwSQD8s/2s/owJGP0oEYD8eBzo/LQBSPx4HOj8sAFI/owJGP7oRZj+MEMw+5QJMP9Hysz7mBGY/2gDkPuYEZj/W/b8+5gRmP9oA5D6iC2A/2gDkPuUCTD8Z/dc+5QJMP4wQzD7mBGY/NCDwPuYEZj/W/b8+5gRmPzQg8D6iC2A/G/3XPuUCTD+MEMw+5gRmPzIg8D6iC2A/0fKzPuUCTD8yIPA++f1ZP9X9vz7lAkw/2gDkPuYEZj8Z/dc+5gRmP9oA5D6iC2A/jBDMPuUCTD/aAOQ++f1ZP9b9vz7lAkw/Gf3XPuYEZj/bDWg/Ce9DP40Abj+zAGY/WBFWP6b0az+NAG4/C/JfPz8KUD+m9Gs/cihcPwnvQz8nA2I/Ce9DP1oRVj+m9Gs/2w1oP7IAZj9zaFw/pvRrP9sNaD8L8l8/JwNiPwnvQz/bDWg/pvRrP40Abj+zAGY/WBFWPwnvQz+NAG4/pvRrPz0KUD8J70M/c2hcP6b0az8nQ2I/pvRrP1gRVj8J70M/2w1oP7MAZj9zKFw/Ce9DP9sNaD+m9Gs/J0NiP6b0az8z+yM/1xJEP3z2KT+KBGY/agUSP9cSRD989ik/VAZgP60KGD/YEkQ/rgoYP9gSRD/wAh4/2BJEPzP7Iz+KBGY//QQMPxv9az8z+yM/VAZgP2kFEj8a/Ws/8AIeP9gSRD8z+yM/G/1rP2kFEj8b/Ws/fPYpP4oEZj+tChg/G/1rP3z2KT8b/Ws/rQoYPxv9az/wAh4/G/1rP/wEDD/XEkQ/M/sjP4oEZj9pBRI/1xJEPzP7Iz8b/Ws/8AIePxv9az8K+0s/LP9rPzwSQD8s/2s/fw40P8D1az8K+0s/uxFmPxYBLj8s/2s/PBJAPyz/az+jAkY/LP9rP6MCRj8s/2s/Hgc6Py0AUj+jAkY/uxFmP38OND/A9lE/Hgc6Pyz/az88EkA/LABSP38OND/B9lE/owJGP7sRZj8VAS4/LQBSPzwSQD8sAFI/owJGP0oEYD+jAkY/LABSPx4HOj8s/2s/CvtLP7sRZj9/DjQ/wPVrPx4HOj8sAFI/CvtLP0oEYD8Z/dc+5gRmP9b9vz7lAkw/NCDwPqILYD/R8rM+5QJMPzIg8D7mBGY/2gDkPuUCTD+MEMw+5gRmP4wQzD7mBGY/2gDkPqILYD/W/b8+5gRmP9oA5D7mBGY/Gf3XPuUCTD8Z/dc+5QJMPzIg8D6iC2A/1f2/PuYEZj8yIPA++P1ZP9Hysz7mBGY/2gDkPuYEZj+MEMw+5QJMP9oA5D6hC2A/jBDMPuUCTD/aAOQ++P1ZP9b9vz7lAkw/Gf3XPuYEZj/bDWg/Cu9DP48Abj+yAGY/WBFWPwnvQz+PAG4/CvJfP3IoXD8K70M/cyhcPwrvQz8nA2I/Cu9DP9sNaD+zAGY/PwpQP6b0az/bDWg/C/JfP1gRVj+m9Gs/JwNiPwrvQz/bDWg/pvRrP1gRVj+m9Gs/jwBuP7QAZj9yaFw/pvRrP48Abj+m9Gs/c2hcP6b0az8nQ2I/pvRrPz0KUD8J70M/2w1oP7QAZj9YEVY/Ce9DP9sNaD+m9Gs/J0NiP6b0az/wAh4/G/1rP3r2KT+KBGY//AQMP9cSRD969ik/VAZgP2kFEj/XEkQ/rQoYP9gSRD8x+yM/G/1rPzP7Iz+KBGY/rQoYP9gSRD8x+yM/VAZgP2kFEj/YEkQ/8AIeP9gSRD/wAh4/1xJEP/0EDD8b/Ws/MfsjPxr9az9pBRI/G/1rPzH7Iz+KBGY/rQoYPxv9az8x+yM/2BJEP60KGD8b/Ws/evYpPxv9az9pBRI/G/1rP3r2KT+KBGY/8AIePxv9az+jAkY/uxFmP6MCRj8sAFI/FgEuPy0AUj+jAkY/LP9rP38OND/A9lE/Hgc6Py0AUj8K+0s/uxFmPzwSQD8sAFI/Hgc6PywAUj8K+0s/LP9rP38OND/A9lE/PBJAPywAUj+jAkY/LP9rPxUBLj8s/2s/CvtLP0oEYD9/DjQ/wPVrPx4HOj8s/2s/CvtLP7sRZj88EkA/LP9rPx4HOj8s/2s/owJGP0oEYD+ADjQ/wPVrPzwSQD8s/2s/owJGP7oRZj8Z/dc+5gRmP9b9vz7mBGY/MiDwPqILYD+MEMw+5gRmPzIg8D7mBGY/Gf3XPuYEZj+MEMw+5gRmP9Hysz7lAkw/2gDkPqILYD/W/b8+5QJMP9oA5D7mBGY/2gDkPuYEZj8Z/dc+5QJMP9oA5D74/Vk/1v2/PuUCTD/aAOQ+oQtgP4wQzD7lAkw/Gf3XPuUCTD+MEMw+5QJMPzIg8D74/Vk/0fKzPuYEZj8yIPA+ogtgP9b9vz7mBGY/2gDkPuUCTD8nA2I/Ce9DP40Abj+yAGY/WBFWP6b0az+NAG4/CvJfPz8KUD+m9Gs/JwNiPwrvQz9zKFw/Ce9DP9sNaD+zAGY/WBFWP6b0az/bDWg/CvJfP3NoXD+m9Gs/2w1oPwrvQz8nQ2I/pvRrP1gRVj8J70M/jQBuP7MAZj89ClA/Ce9DP40Abj+m9Gs/J0NiP6b0az9zaFw/pvRrP1gRVj8K70M/2w1oP7QAZj9zKFw/Cu9DP9sNaD+m9Gs/2w1oP6b0az8z+yM/1xJEP3z2KT+KBGY/rQoYPxv9az989ik/VAZgP2kFEj8a/Ws/rgoYP9gSRD/wAh4/1xJEPzP7Iz+JBGY/aQUSP9gSRD8z+yM/VAZgP/0EDD/YEkQ/8AIeP9gSRD8z+yM/G/1rP60KGD/XEkQ/M/sjPxr9az9pBRI/1xJEPzP7Iz+KBGY/rQoYPxv9az/wAh4/Gv1rP2kFEj8b/Ws/fPYpPxv9az/8BAw/G/1rP3z2KT+KBGY/8AIePxv9az8K+0s/uxFmP38OND/A9Ws/owJGPysAUj8K+0s/SgRgPxYBLj8s/2s/Hgc6PywAUj+jAkY/uxFmPzwSQD8rAFI/Hgc6PywAUj+jAkY/SgRgPzwSQD8rAFI/fw40P8D2UT9/DjQ/wPZRP6MCRj8s/2s/owJGPyz/az8VAS4/LQBSPx4HOj8s/2s/owJGP7sRZj88EkA/LP9rPx4HOj8s/2s/CvtLPyz/az88EkA/LP9rP4AOND/A9Ws/CvtLP7sRZj8b/dc+5gRmP9b9vz7lAkw/MiDwPvn9WT/R8rM+5QJMPzIg8D6iC2A/2gDkPuUCTD+MEMw+5gRmP4wQzD7mBGY/2gDkPvj9WT/W/b8+5gRmP9oA5D6iC2A/G/3XPuUCTD8b/dc+5QJMPzIg8D7mBGY/1f2/PuYEZj8yIPA+ogtgP9Hysz7mBGY/2gDkPuYEZj+MEMw+5QJMP9oA5D7mBGY/jBDMPuUCTD/aAOQ+ogtgP9b9vz7lAkw/G/3XPuYEZj/aDWg/Ce9DP1gRVj8J70M/2w1oPwryXz9yKFw/Ce9DP9sNaD+yAGY/cihcPwrvQz8nA2I/Ce9DP40Abj8K8l8/PwpQP6b0az+NAG4/tABmP1gRVj+m9Gs/JwNiPwrvQz/bDWg/pvRrP1gRVj+m9Gs/jQBuP7QAZj9xaFw/pvRrP40Abj+m9Gs/cmhcP6b0az8nQ2I/pvRrP9sNaD+0AGY/PQpQPwrvQz/bDWg/pvRrP1gRVj8K70M/J0NiP6b0az/9BAw/2BJEP3r2KT+JBGY/8AIePxv9az+tChg/2BJEP2kFEj/YEkQ/evYpP1QGYD9pBRI/G/1rPzP7Iz+JBGY/M/sjPxr9az/wAh4/2BJEP60KGD8a/Ws/M/sjP1QGYD989ik/igRmP/wEDD8b/Ws/8AIeP9cSRD+uChg/G/1rP3z2KT8b/Ws/aQUSPxv9az8z+yM/igRmP2kFEj/XEkQ/M/sjP9cSRD/wAh4/G/1rPzP7Iz8a/Ws/rQoYP9gSRD8VAS4/LABSP6MCRj8sAFI/CvtLPyz/az9/DjQ/wPZRPzwSQD8s/2s/CvtLP7sRZj88EkA/LABSP38OND/A9Ws/owJGPyz/az8eBzo/LP9rPx4HOj8s/2s/owJGP7sRZj8K+0s/SgRgPxUBLj8s/2s/owJGPyz/az8K+0s/uxFmP38OND/A9Ws/PBJAPy0AUj+jAkY/SgRgPzwSQD8s/2s/gA40P8D2UT+jAkY/uhFmPx4HOj8sAFI/Hgc6Py0AUj/aAOQ+5gRmP9Hysz7mBGY/jBDMPuUCTD/aAOQ+5QJMP9oA5D6iC2A/1v2/PuYEZj80IPA+5gRmP4wQzD7mBGY/Gf3XPuUCTD8b/dc+5QJMPzQg8D6iC2A/1v2/PuYEZj/R8rM+5QJMPzIg8D6iC2A/jBDMPuYEZj/aAOQ+5gRmP9X9vz7lAkw/MiDwPvn9WT+MEMw+5QJMP9oA5D6iC2A/Gf3XPuYEZj8Z/dc+5gRmP9b9vz7lAkw/2gDkPvn9WT9YEVY/pvRrP40Abj+zAGY/2w1oPwnvQz9yKFw/Ce9DPz8KUD+m9Gs/jQBuPwvyXz/bDWg/sgBmP1oRVj+m9Gs/JwNiPwnvQz8nA2I/Ce9DP9sNaD8L8l8/c2hcP6b0az9YEVY/Ce9DP40Abj+zAGY/2w1oP6b0az9zaFw/pvRrPz0KUD8J70M/jQBuP6b0az/bDWg/swBmP1gRVj8J70M/J0NiP6b0az8nQ2I/pvRrP9sNaD+m9Gs/cyhcPwnvQz9qBRI/1xJEP3z2KT+KBGY/M/sjP9cSRD+uChg/2BJEP60KGD/YEkQ/fPYpP1QGYD/9BAw/G/1rPzP7Iz+KBGY/8AIeP9gSRD/wAh4/2BJEP2kFEj8a/Ws/M/sjP1QGYD989ik/igRmP2kFEj8b/Ws/M/sjPxv9az+tChg/G/1rP3z2KT8b/Ws/rQoYPxv9az8z+yM/igRmP/wEDD/XEkQ/8AIePxv9az/wAh4/G/1rPzP7Iz8b/Ws/aQUSP9cSRD9/DjQ/wPVrPzwSQD8s/2s/CvtLPyz/az88EkA/LP9rPxYBLj8s/2s/CvtLP7sRZj8eBzo/LQBSP6MCRj8s/2s/owJGPyz/az8eBzo/LP9rP38OND/A9lE/owJGP7sRZj+jAkY/uxFmP38OND/B9lE/PBJAPywAUj+jAkY/SgRgPzwSQD8sAFI/FQEuPy0AUj8K+0s/uxFmPx4HOj8s/2s/owJGPywAUj8K+0s/SgRgPx4HOj8sAFI/fw40P8D1az80IPA+ogtgP9b9vz7lAkw/Gf3XPuYEZj/aAOQ+5QJMPzIg8D7mBGY/0fKzPuUCTD/aAOQ+ogtgP4wQzD7mBGY/jBDMPuYEZj8Z/dc+5QJMP9oA5D7mBGY/1v2/PuYEZj/V/b8+5gRmPzIg8D6iC2A/Gf3XPuUCTD/aAOQ+5gRmP9Hysz7mBGY/MiDwPvj9WT+MEMw+5QJMP9oA5D6hC2A/jBDMPuUCTD8Z/dc+5gRmP9b9vz7lAkw/2gDkPvj9WT9YEVY/Ce9DP48Abj+yAGY/2w1oPwrvQz9zKFw/Cu9DP3IoXD8K70M/jwBuPwryXz8/ClA/pvRrP9sNaD+zAGY/JwNiPwrvQz8nA2I/Cu9DP1gRVj+m9Gs/2w1oPwvyXz+PAG4/tABmP1gRVj+m9Gs/2w1oP6b0az9zaFw/pvRrP48Abj+m9Gs/cmhcP6b0az/bDWg/tABmPz0KUD8J70M/J0NiP6b0az8nQ2I/pvRrP9sNaD+m9Gs/WBFWPwnvQz/8BAw/1xJEP3r2KT+KBGY/8AIePxv9az+tChg/2BJEP2kFEj/XEkQ/evYpP1QGYD+tChg/2BJEPzP7Iz+KBGY/MfsjPxv9az/wAh4/2BJEP2kFEj/YEkQ/MfsjP1QGYD8x+yM/Gv1rP/0EDD8b/Ws/8AIeP9cSRD+tChg/G/1rPzH7Iz+KBGY/aQUSPxv9az969ik/G/1rP60KGD8b/Ws/MfsjP9gSRD/wAh4/G/1rP3r2KT+KBGY/aQUSPxv9az8WAS4/LQBSP6MCRj8sAFI/owJGP7sRZj8eBzo/LQBSP38OND/A9lE/owJGPyz/az8eBzo/LABSPzwSQD8sAFI/CvtLP7sRZj88EkA/LABSP38OND/A9lE/CvtLPyz/az8K+0s/SgRgPxUBLj8s/2s/owJGPyz/az8K+0s/uxFmPx4HOj8s/2s/fw40P8D1az+jAkY/SgRgPx4HOj8s/2s/PBJAPyz/az+jAkY/uhFmPzwSQD8s/2s/gA40P8D1az8yIPA+ogtgP9b9vz7mBGY/Gf3XPuYEZj8Z/dc+5gRmPzIg8D7mBGY/jBDMPuYEZj/aAOQ+ogtgP9Hysz7lAkw/jBDMPuYEZj/aAOQ+5gRmP9oA5D7mBGY/1v2/PuUCTD/W/b8+5QJMP9oA5D74/Vk/Gf3XPuUCTD8Z/dc+5QJMP4wQzD7lAkw/2gDkPqELYD/R8rM+5gRmPzIg8D74/Vk/jBDMPuUCTD/aAOQ+5QJMP9b9vz7mBGY/MiDwPqILYD9YEVY/pvRrP40Abj+yAGY/JwNiPwnvQz8nA2I/Cu9DPz8KUD+m9Gs/jQBuPwryXz9YEVY/pvRrP9sNaD+zAGY/cyhcPwnvQz/bDWg/Cu9DP3NoXD+m9Gs/2w1oPwryXz+NAG4/swBmP1gRVj8J70M/J0NiP6b0az8nQ2I/pvRrP40Abj+m9Gs/PQpQPwnvQz/bDWg/tABmP1gRVj8K70M/c2hcP6b0az/bDWg/pvRrP9sNaD+m9Gs/cyhcPwrvQz+tChg/G/1rP3z2KT+KBGY/M/sjP9cSRD+uChg/2BJEP2kFEj8a/Ws/fPYpP1QGYD9pBRI/2BJEPzP7Iz+JBGY/8AIeP9cSRD/wAh4/2BJEP/0EDD/YEkQ/M/sjP1QGYD8z+yM/Gv1rP60KGD/XEkQ/M/sjPxv9az+tChg/G/1rPzP7Iz+KBGY/aQUSP9cSRD989ik/G/1rP2kFEj8b/Ws/8AIePxr9az/wAh4/G/1rP3z2KT+KBGY//AQMPxv9az+jAkY/KwBSP38OND/A9Ws/CvtLP7sRZj8eBzo/LABSPxYBLj8s/2s/CvtLP0oEYD8eBzo/LABSPzwSQD8rAFI/owJGP7sRZj9/DjQ/wPZRPzwSQD8rAFI/owJGP0oEYD+jAkY/LP9rP6MCRj8s/2s/fw40P8D2UT+jAkY/uxFmPx4HOj8s/2s/FQEuPy0AUj8K+0s/LP9rPx4HOj8s/2s/PBJAPyz/az8K+0s/uxFmP4AOND/A9Ws/PBJAPyz/az8yIPA++f1ZP9b9vz7lAkw/G/3XPuYEZj/aAOQ+5QJMPzIg8D6iC2A/0fKzPuUCTD/aAOQ++P1ZP4wQzD7mBGY/jBDMPuYEZj8b/dc+5QJMP9oA5D6iC2A/1v2/PuYEZj/V/b8+5gRmPzIg8D7mBGY/G/3XPuUCTD/aAOQ+5gRmP9Hysz7mBGY/MiDwPqILYD+MEMw+5QJMP9oA5D7mBGY/jBDMPuUCTD8b/dc+5gRmP9b9vz7lAkw/2gDkPqILYD/bDWg/CvJfP1gRVj8J70M/2g1oPwnvQz9yKFw/Cu9DP9sNaD+yAGY/cihcPwnvQz8/ClA/pvRrP40Abj8K8l8/JwNiPwnvQz8nA2I/Cu9DP1gRVj+m9Gs/jQBuP7QAZj+NAG4/tABmP1gRVj+m9Gs/2w1oP6b0az9yaFw/pvRrP40Abj+m9Gs/cWhcP6b0az89ClA/Cu9DP9sNaD+0AGY/J0NiP6b0az8nQ2I/pvRrP1gRVj8K70M/2w1oP6b0az8BAA4AFAABABQABwAKAAYAEwAKABMAFwAVABIADAAVAAwADwAQAAMACQAQAAkAFgAFAAIACAAFAAgACwARAA0AAAARAAAABABMAFIALABMACwAHwAiAB4AKwAiACsALwBIAFAAJABIACQAJwBLAFUAIQBLACEALgBWAE4AIABWACAAIwApACUAGAApABgAHAA3AEIAPAA3ADwAMQA9AD8ANAA9ADQAMgBGADsANQBGADUAQAAwADMAOQAwADkANgBEAEcAQQBEAEEAPgA4ADoARQA4AEUAQwAdABoATwAdAE8AVwAoABsAVAAoAFQASgAtACoAUQAtAFEASQAZACYAUwAZAFMATQBYAFsAYQBYAGEAXgBfAGIAbQBfAG0AagBsAG8AaQBsAGkAZgBlAGgAXQBlAF0AWgBgAGsAZABgAGQAWQBuAGMAXABuAFwAZwBwAHMAeQBwAHkAdgB4AHoAhQB4AIUAgwCEAIcAgQCEAIEAfgB9AH8AdAB9AHQAcgB3AIIAfAB3AHwAcQCGAHsAdQCGAHUAgACIAIsAkQCIAJEAjgCQAJIAnQCQAJ0AmwCcAJ8AmQCcAJkAlgCVAJcAjACVAIwAigCPAJoAlACPAJQAiQCeAJMAjQCeAI0AmACiAKgAqwCiAKsApQCnALQAtwCnALcAqgCyAKwArwCyAK8AtQCtAKAAowCtAKMAsACmAKEArgCmAK4AswC2ALEApAC2AKQAqQC6AMAAwwC6AMMAvQC/AMwAzgC/AM4AwQDKAMQAxwDKAMcAzQDGALkAuwDGALsAyAC+ALgAxQC+AMUAywDPAMkAvADPALwAwgDSANgA2wDSANsA1QDXAOQA5gDXAOYA2QDiANwA3wDiAN8A5QDeANEA0wDeANMA4ADWANAA3QDWAN0A4wDnAOEA1ADnANQA2gDpAOsA8QDpAPEA7wDwAPIA/QDwAP0A+wD8AP4A+AD8APgA9gD1APcA7AD1AOwA6gDuAPoA9ADuAPQA6AD/APMA7QD/AO0A+QAAAQMBCQEAAQkBBgEHAQoBFQEHARUBEgEUARcBEQEUAREBDgENARABBQENAQUBAgEIARMBDAEIAQwBAQEWAQsBBAEWAQQBDwEpAR0BIwEpASMBLwEoASYBGQEoARkBGwEtASsBJQEtASUBJwEhAR8BLAEhASwBLgEYASQBKgEYASoBHgEcARoBIAEcASABIgExATMBOgExAToBOAE3ATkBRQE3AUUBQwFEAUYBPwFEAT8BPQE+AUABNAE+ATQBMgE2AUIBPAE2ATwBMAFHATsBNQFHATUBQQFJAUsBUQFJAVEBTwFQAVIBXQFQAV0BWwFcAV4BWAFcAVgBVgFVAVcBTAFVAUwBSgFOAVoBVAFOAVQBSAFfAVMBTQFfAU0BWQFgAWMBaQFgAWkBZgFoAWoBdQFoAXUBcwF0AXcBcQF0AXEBbgFtAW8BZAFtAWQBYgFnAXIBbAFnAWwBYQF2AWsBZQF2AWUBcAGJAX0BgwGJAYMBjwGIAYYBeQGIAXkBewGNAYsBhQGNAYUBhwGBAX8BjAGBAYwBjgF4AYQBigF4AYoBfgF8AXoBgAF8AYABggGRAZMBmQGRAZkBlwGYAZoBpQGYAaUBowGkAaYBoAGkAaABngGdAZ8BlAGdAZQBkgGWAaIBnAGWAZwBkAGnAZsBlQGnAZUBoQGpAasBsQGpAbEBrwGwAbIBvQGwAb0BuwG8Ab4BuAG8AbgBtgG1AbcBrAG1AawBqgGuAboBtAGuAbQBqAG/AbMBrQG/Aa0BuQHAAcMByQHAAckBxgHIAcoB1QHIAdUB0wHUAdcB0QHUAdEBzgHNAc8BxAHNAcQBwgHHAdIBzAHHAcwBwQHWAcsBxQHWAcUB0AHpAd0B4wHpAeMB7wHoAeYB2QHoAdkB2wHtAesB5QHtAeUB5wHhAd8B7AHhAewB7gHYAeQB6gHYAeoB3gHcAdoB4AHcAeAB4gHxAfMB+QHxAfkB9wH4AfoBBQL4AQUCAwIEAgYCAAIEAgAC/gH9Af8B9AH9AfQB8gH2AQIC/AH2AfwB8AEHAvsB9QEHAvUBAQIJAgsCEQIJAhECDwIQAhICHQIQAh0CGwIcAh4CGAIcAhgCFgIVAhcCDAIVAgwCCgIOAhoCFAIOAhQCCAIfAhMCDQIfAg0CGQIgAiMCKQIgAikCJgIoAisCNgIoAjYCMwI0AjcCMQI0AjECLgIsAi8CJAIsAiQCIQInAjICLQInAi0CIgI1AioCJQI1AiUCMAJJAj0CQwJJAkMCTwJIAkYCOQJIAjkCOwJNAksCRQJNAkUCRwJBAj8CTAJBAkwCTgI4AkQCSgI4AkoCPgI8AjoCQAI8AkACQgJSAlQCWQJSAlkCVwJYAloCZgJYAmYCZAJjAmUCYAJjAmACXgJdAl8CUwJdAlMCUQJWAmICXAJWAlwCUAJnAlsCVQJnAlUCYQJpAm8CcwJpAnMCbQJuAnsCfwJuAn8CcgJ6AnQCeAJ6AngCfgJ1AmgCbAJ1AmwCeQJwAmoCdgJwAnYCfAJ9AncCawJ9AmsCcQKCAogCiwKCAosChQKHApQClwKHApcCigKSAowCjwKSAo8ClQKNAoACgwKNAoMCkAKGAoECjgKGAo4CkwKWApEChAKWAoQCiQKnAq0CoQKnAqECmwKoAp0CmQKoApkCpAKvAqkCpQKvAqUCqwKjAq4CqgKjAqoCnwKaAqACrAKaAqwCpgKcAqICngKcAp4CmAKxArYCugKxAroCtQK3AsMCxwK3AscCuwLCAr0CwQLCAsECxgK8ArACtAK8ArQCwAK4ArICvgK4Ar4CxALFAr8CswLFArMCuQLJAs8C0wLJAtMCzQLOAtsC3wLOAt8C0gLaAtQC2ALaAtgC3gLVAsgCzALVAswC2QLQAsoC1gLQAtYC3ALdAtcCywLdAssC0QLiAugC6wLiAusC5QLmAvMC9wLmAvcC6gLyAuwC7wLyAu8C9QLtAuAC5ALtAuQC8QLnAuEC7gLnAu4C9AL2AvAC4wL2AuMC6QIHAw0DAQMHAwED+wIIA/0C+QIIA/kCBAMPAwkDBQMPAwUDCwMDAw4DCgMDAwoD/wL6AgADDAP6AgwDBgP8AgID/gL8Av4C+AIRAxcDGwMRAxsDFQMWAyMDJwMWAycDGgMiAxwDIAMiAyADJgMdAxADFAMdAxQDIQMYAxIDHgMYAx4DJAMlAx8DEwMlAxMDGQMpAy8DMwMpAzMDLQMuAzsDPwMuAz8DMgM6AzQDOAM6AzgDPgM1AygDLAM1AywDOQMwAyoDNgMwAzYDPAM9AzcDKwM9AysDMQNCA0gDSwNCA0sDRQNGA1MDVwNGA1cDSgNSA0wDTwNSA08DVQNNA0ADRANNA0QDUQNHA0EDTgNHA04DVANWA1ADQwNWA0MDSQNnA20DYQNnA2EDWwNoA10DWQNoA1kDZANvA2kDZQNvA2UDawNjA24DagNjA2oDXwNaA2ADbANaA2wDZgNcA2IDXgNcA14DWANxA3cDewNxA3sDdQN2A4MDhwN2A4cDegOCA3wDgAOCA4ADhgN9A3ADdAN9A3QDgQN4A3IDfgN4A34DhAOFA38DcwOFA3MDeQOJA48DkwOJA5MDjQOOA5sDnwOOA58DkgOaA5QDmAOaA5gDngOVA4gDjAOVA4wDmQOQA4oDlgOQA5YDnAOdA5cDiwOdA4sDkQOiA6gDqwOiA6sDpQOmA7MDtgOmA7YDqQOyA6wDrwOyA68DtQOuA6EDpAOuA6QDsQOnA6ADrQOnA60DtAO3A7ADowO3A6MDqgPHA80DwQPHA8EDuwPIA70DuQPIA7kDxAPPA8kDxQPPA8UDywPDA84DygPDA8oDvwO6A8ADzAO6A8wDxgO8A8IDvgO8A74DuAPQA9cD2wPQA9sD1APWA+ID5gPWA+YD2gPjA9wD4APjA+AD5wPdA9ED1QPdA9UD4QPYA9ID3gPYA94D5APlA98D0wPlA9MD2QM="}]} diff --git a/data/games/garage/mods/gltf/models/gltf_spider_animated.gltf b/data/games/garage/mods/gltf/models/gltf_spider_animated.gltf new file mode 100644 index 0000000..79221b0 --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_spider_animated.gltf @@ -0,0 +1 @@ +{"asset":{"generator":"Khronos glTF Blender I/O v1.7.33","version":"2.0"},"scene":0,"scenes":[{"name":"Scene","nodes":[58]}],"nodes":[{"name":"Pincer.L","rotation":[0.03853772580623627,0.09671717882156372,0.5138389468193054,0.8515457510948181],"translation":[-2.2351741790771484e-08,0.2836739718914032,-2.2351741790771484e-08]},{"children":[0],"name":"JawBase.L","rotation":[-0.23922589421272278,-9.208349638356594e-08,-0.38811206817626953,0.8900224566459656],"scale":[1,1,0.9999999403953552],"translation":[8.097286041675034e-08,0.7702280879020691,-1.169656727029178e-07]},{"name":"Pincer.R","rotation":[0.038537755608558655,-0.09671713411808014,-0.5138388872146606,0.8515458106994629],"scale":[0.9999997615814209,0.9999999403953552,1],"translation":[2.9802322387695312e-08,0.2836737036705017,-2.9802322387695312e-08]},{"children":[2],"name":"JawBase.R","rotation":[-0.2392251342535019,1.9714243535418063e-06,0.3881126046180725,0.8900225758552551],"translation":[1.3833086898173974e-09,0.7702280282974243,-6.620245329713725e-08]},{"children":[1,3],"name":"Head","rotation":[0.4052415192127228,-3.4197712478652165e-13,-8.695541282577324e-07,0.9142096638679504],"translation":[-2.0781445141115906e-16,0.6883190274238586,-1.4901161193847656e-08]},{"children":[4],"name":"NeckBase","rotation":[-0.778048574924469,7.488795716881214e-08,1.7622618315726868e-06,0.6282041072845459],"translation":[-3.399441372928941e-14,0.3915250301361084,-2.3283064365386963e-09]},{"name":"Body.002","rotation":[0.17414046823978424,0,-4.151832513343834e-07,0.9847208261489868],"translation":[5.897654597759178e-14,1.0079095363616943,-1.2134763416327132e-08]},{"children":[6],"name":"Body.001","rotation":[0.6673352122306824,-7.632472941426077e-14,-1.5910509318928234e-06,0.7447575330734253],"scale":[1,0.9999999403953552,0.9999999403953552],"translation":[-3.962037268363458e-15,0.3915250301361084,-3.1428597502269895e-09]},{"name":"Leg4Fore.L","rotation":[-0.021953541785478592,0.030033688992261887,-0.4378480017185211,0.8982790112495422],"scale":[1,0.9999998211860657,1.0000001192092896],"translation":[1.9202238377147296e-07,0.8228543996810913,-1.749940707895803e-07]},{"children":[8],"name":"Leg4Lower.L","rotation":[-0.11090508848428726,0.11991499364376068,-0.48737218976020813,0.8577813506126404],"scale":[0.9999995231628418,0.9999997615814209,1.000000238418579],"translation":[1.9631791303709178e-07,0.8208085298538208,-4.769351491518137e-08]},{"children":[9],"name":"Leg4Mid.L","rotation":[-0.21032677590847015,0.09273893386125565,-0.42330121994018555,0.8763437271118164],"scale":[1,0.9999996423721313,0.999999463558197],"translation":[-1.720833893159579e-07,1.5146127939224243,1.4611718768264836e-07]},{"children":[10],"name":"Leg4Upper.L","rotation":[0.581340491771698,-0.03387186676263809,0.4926694631576538,0.6466628909111023],"scale":[1.0000003576278687,1.000000238418579,1.0000003576278687],"translation":[-2.6137989550534257e-09,0.8996680974960327,-2.8558396536482178e-08]},{"children":[11],"name":"Leg4Base.L","rotation":[0.4988132119178772,0.67340087890625,0.0026363276410847902,0.5456278324127197],"scale":[0.9999998807907104,0.9999998807907104,0.9999999403953552],"translation":[6.932457941033476e-10,0.3915250301361084,-7.783789612858527e-09]},{"name":"Leg3Fore.L","rotation":[-0.040254246443510056,0.0051941643469035625,-0.3734953701496124,0.9267436861991882],"scale":[1.0000001192092896,1,1.0000003576278687],"translation":[-7.186849302343035e-07,0.761729896068573,1.4940267689667053e-08]},{"children":[13],"name":"Leg3Lower.L","rotation":[-0.02293548174202442,0.03108014352619648,-0.5376279950141907,0.8422969579696655],"scale":[1,0.9999998807907104,1],"translation":[2.6879865799855907e-07,0.890315592288971,-2.3254589365251377e-08]},{"children":[14],"name":"Leg3Mid.L","rotation":[-0.10393687337636948,0.026799378916621208,-0.47722530364990234,0.8722012042999268],"scale":[1,1.0000001192092896,1],"translation":[-4.5783519908582093e-07,1.5058820247650146,6.428529530921878e-08]},{"children":[15],"name":"Leg3Upper.L","rotation":[0.22388437390327454,0.00046301534166559577,0.7424523234367371,0.6313795447349548],"scale":[0.9999996423721313,0.9999999403953552,0.9999995231628418],"translation":[8.173065424443848e-08,0.8363674879074097,-3.891337030381692e-09]},{"children":[16],"name":"Leg3Base.L","rotation":[0.48101410269737244,0.8565962910652161,-0.006458853371441364,0.18661867082118988],"scale":[0.9999999403953552,0.9999998807907104,0.9999999403953552],"translation":[1.1383551878907383e-08,0.3915250301361084,2.5693926986036786e-09]},{"name":"Leg2Fore.L","rotation":[0.04987334460020065,-0.01207074522972107,-0.4028705060482025,0.9138174653053284],"scale":[0.999999463558197,1.0000004768371582,1.0000001192092896],"translation":[2.9161077463868423e-07,0.7777483463287354,1.7455030842938868e-07]},{"children":[18],"name":"Leg2Lower.L","rotation":[0.08352424204349518,-0.04269447177648544,-0.518085777759552,0.8501694202423096],"scale":[1.0000001192092896,1.0000004768371582,1.0000004768371582],"translation":[-1.5067358560827415e-07,0.9397417306900024,-4.163759115272114e-08]},{"children":[19],"name":"Leg2Mid.L","rotation":[0.14706559479236603,-0.028868243098258972,-0.47296836972236633,0.868239164352417],"scale":[1.0000004768371582,0.9999999403953552,0.9999999403953552],"translation":[-2.2217867012841452e-07,1.5058820247650146,-6.989571943449846e-08]},{"children":[20],"name":"Leg2Upper.L","rotation":[-0.42424774169921875,-0.0005238422891125083,0.6472405791282654,0.6333192586898804],"scale":[1.000000238418579,1.0000003576278687,1.0000005960464478],"translation":[9.311328597050306e-08,0.881853461265564,-1.8038990745594674e-08]},{"children":[21],"name":"Leg2Base.L","rotation":[-0.4972459375858307,-0.7882749438285828,0.006057440303266048,0.362398236989975],"scale":[0.9999997615814209,0.9999998807907104,0.9999999403953552],"translation":[7.375939858889069e-10,0.3915250301361084,4.028271050060539e-09]},{"name":"Leg1Fore.L","rotation":[-0.01934647001326084,-0.04218549281358719,-0.4403696358203888,0.8966162800788879],"scale":[1,1,0.9999997615814209],"translation":[2.0805721590022586e-07,0.815664529800415,4.0515438115562574e-08]},{"children":[23],"name":"Leg1Lower.L","rotation":[0.15678077936172485,-0.1661715805530548,-0.47995010018348694,0.8470270037651062],"scale":[0.999999463558197,1,0.9999999403953552],"translation":[3.670676562705921e-08,0.8788074851036072,8.29251618483795e-08]},{"children":[24],"name":"Leg1Mid.L","rotation":[0.26206591725349426,-0.11672191321849823,-0.4046621024608612,0.8683006763458252],"scale":[1.0000001192092896,0.9999999403953552,0.9999995231628418],"translation":[3.601947184961318e-08,1.5125981569290161,-1.6144279868512967e-07]},{"children":[25],"name":"Leg1Upper.L","rotation":[-0.62815922498703,0.04343283176422119,0.39305803179740906,0.6701006889343262],"translation":[-1.0171092412747385e-07,1.043814778327942,1.114601104745816e-07]},{"children":[26],"name":"Leg1Base.L","rotation":[-0.536352813243866,-0.596045732498169,-0.006935927551239729,0.5975006818771362],"scale":[0.9999998211860657,0.9999998211860657,1],"translation":[7.451212979958655e-09,0.3915250301361084,-5.977072614626877e-09]},{"name":"Leg4Fore.R","rotation":[-0.0219536405056715,-0.030033595860004425,0.43784812092781067,0.8982789516448975],"scale":[1.000000238418579,0.9999998807907104,1.0000001192092896],"translation":[4.575199454848189e-07,0.82285475730896,1.3987688873839943e-07]},{"children":[28],"name":"Leg4Lower.R","rotation":[-0.11090517044067383,-0.11991491913795471,0.48737218976020813,0.8577813506126404],"scale":[1.0000001192092896,0.9999999403953552,1.0000001192092896],"translation":[5.0247152216797986e-08,0.8208085894584656,1.2523592829438712e-07]},{"children":[29],"name":"Leg4Mid.R","rotation":[-0.21032673120498657,-0.09273889660835266,0.42330119013786316,0.876343846321106],"scale":[0.9999998211860657,0.9999995231628418,1.0000001192092896],"translation":[-1.2884336797469587e-07,1.514613151550293,6.563716681284859e-08]},{"children":[30],"name":"Leg4Upper.R","rotation":[0.5813404321670532,0.03387187048792839,-0.4926694333553314,0.6466629505157471],"scale":[1,1.000000238418579,0.9999997019767761],"translation":[-3.940737158814045e-08,0.8996680974960327,1.9567494291550247e-09]},{"children":[31],"name":"Leg4Base.R","rotation":[0.4988132119178772,-0.6733996272087097,-0.0026374668814241886,0.5456294417381287],"scale":[1,1.0000001192092896,1],"translation":[-1.1682686817948706e-08,0.3915250301361084,-1.3812247345867945e-08]},{"name":"Leg3Fore.R","rotation":[-0.04025428742170334,-0.005194155499339104,0.3734953999519348,0.9267436861991882],"scale":[0.9999998211860657,1.0000001192092896,1.0000001192092896],"translation":[-7.285660217348777e-07,0.7617300748825073,-4.0205627271916455e-08]},{"children":[33],"name":"Leg3Lower.R","rotation":[-0.02293553575873375,-0.03108006715774536,0.5376282930374146,0.8422967791557312],"scale":[1.0000001192092896,0.9999996423721313,0.9999999403953552],"translation":[7.143101754536474e-08,0.8903149366378784,6.888667769544554e-08]},{"children":[34],"name":"Leg3Mid.R","rotation":[-0.10393673926591873,-0.026799339801073074,0.47722548246383667,0.872201144695282],"scale":[1.0000003576278687,0.9999998807907104,0.9999998807907104],"translation":[1.4287303429227904e-07,1.5058823823928833,9.578651827268914e-08]},{"children":[35],"name":"Leg3Upper.R","rotation":[0.2238844484090805,-0.00046323961578309536,-0.7424524426460266,0.6313793659210205],"scale":[1.0000001192092896,1.0000005960464478,0.9999997615814209],"translation":[-2.9145089897042453e-08,0.8363675475120544,-1.3412945421009681e-08]},{"children":[36],"name":"Leg3Base.R","rotation":[0.48101410269737244,-0.8565958738327026,0.006457682233303785,0.18662074208259583],"scale":[0.9999999403953552,1.0000001192092896,1],"translation":[1.187698939197901e-09,0.3915250301361084,1.396204218906405e-08]},{"name":"Leg2Fore.R","rotation":[0.04987342655658722,0.012070796452462673,0.40287071466445923,0.9138173460960388],"scale":[0.9999997615814209,0.9999998807907104,0.9999997019767761],"translation":[4.900767294202524e-07,0.7777489423751831,1.3496240569565998e-07]},{"children":[38],"name":"Leg2Lower.R","rotation":[0.08352430164813995,0.04269447922706604,0.518085777759552,0.8501694202423096],"scale":[1.000000238418579,1.0000003576278687,0.9999999403953552],"translation":[1.2208448652017978e-07,0.9397414326667786,-3.409446946989192e-08]},{"children":[39],"name":"Leg2Mid.R","rotation":[0.1470656394958496,0.028868237510323524,0.4729681611061096,0.8682392835617065],"scale":[1.0000001192092896,1.0000003576278687,1.0000001192092896],"translation":[4.8437236443987786e-08,1.5058820247650146,-2.5024842642551448e-08]},{"children":[40],"name":"Leg2Upper.R","rotation":[-0.4242475926876068,0.0005238187150098383,-0.6472404599189758,0.6333194971084595],"scale":[0.9999997019767761,1,0.9999998211860657],"translation":[3.550610472302651e-09,0.8818532824516296,4.425183419698442e-08]},{"children":[41],"name":"Leg2Base.R","rotation":[-0.4972459375858307,0.7882757782936096,-0.006056289654225111,0.36239632964134216],"scale":[0.9999998211860657,1,0.9999999403953552],"translation":[-7.2600920830723226e-09,0.3915250301361084,-5.773719280455225e-09]},{"name":"Leg1Fore.R","rotation":[-0.015208502300083637,0.04422945901751518,0.4362727701663971,0.8985980749130249],"scale":[1.000000238418579,0.9999995827674866,0.9999997615814209],"translation":[-6.20622927272052e-07,0.8156638741493225,-1.6136721114889951e-07]},{"children":[43],"name":"Leg1Lower.R","rotation":[0.15885458886623383,0.17276015877723694,0.4745163321495056,0.848382830619812],"scale":[1.000000238418579,1.0000001192092896,1.0000004768371582],"translation":[-2.3015780925561558e-07,0.8788077235221863,2.258973452740065e-08]},{"children":[44],"name":"Leg1Mid.R","rotation":[0.2600231170654297,0.12465617805719376,0.4028773903846741,0.8686419725418091],"scale":[1,0.9999997019767761,0.9999999403953552],"translation":[-2.3629894485566183e-08,1.512597680091858,-5.442473494099431e-08]},{"children":[45],"name":"Leg1Upper.R","rotation":[-0.6237055063247681,-0.03962605446577072,-0.3963613212108612,0.6725466251373291],"scale":[1,1,0.9999995827674866],"translation":[4.151442212219081e-08,1.0438144207000732,6.221015524943141e-08]},{"children":[46],"name":"Leg1Base.R","rotation":[-0.5363527536392212,0.5960471630096436,0.0069372160360217094,0.5974993705749512],"scale":[1,1.0000001192092896,1.0000001192092896],"translation":[7.877114072130098e-09,0.3915250301361084,-5.523408841412447e-09]},{"children":[5,7,12,17,22,27,32,37,42,47],"name":"Body","rotation":[-0.9999927282333374,-4.546671483751652e-09,1.1920842553081457e-06,0.003814017167314887],"translation":[-2.1589291564903364e-17,0.5146726369857788,0.22900062799453735]},{"name":"Leg4IK.L","rotation":[-2.6692541510442425e-08,-2.6692541510442425e-08,-0.7071068286895752,0.7071068286895752],"translation":[2.2291481494903564,-0.5599625110626221,-0.7613579630851746]},{"name":"Leg3IK.L","rotation":[-2.6692541510442425e-08,-2.6692541510442425e-08,-0.7071068286895752,0.7071068286895752],"translation":[2.3687760829925537,-0.5599625110626221,-0.033313095569610596]},{"name":"Leg2IK.L","rotation":[-2.6692541510442425e-08,-2.6692541510442425e-08,-0.7071068286895752,0.7071068286895752],"translation":[2.3687760829925537,-0.5599625110626221,0.6964529752731323]},{"name":"Leg1IK.L","rotation":[-2.6692541510442425e-08,-2.6692541510442425e-08,-0.7071068286895752,0.7071068286895752],"translation":[2.2556710243225098,-0.5599625110626221,1.4977319240570068]},{"name":"Leg4IK.R","rotation":[-2.6692541510442425e-08,2.6692541510442425e-08,0.7071068286895752,0.7071068286895752],"translation":[-2.2291481494903564,-0.5599625110626221,-0.7613579630851746]},{"name":"Leg3IK.R","rotation":[-2.6692541510442425e-08,2.6692541510442425e-08,0.7071068286895752,0.7071068286895752],"translation":[-2.3687760829925537,-0.5599625110626221,-0.033313095569610596]},{"name":"Leg2IK.R","rotation":[-2.6692541510442425e-08,2.6692541510442425e-08,0.7071068286895752,0.7071068286895752],"translation":[-2.3687760829925537,-0.5599625110626221,0.6964529752731323]},{"name":"Leg1IK.R","rotation":[-2.6692541510442425e-08,2.6692541510442425e-08,0.7071068286895752,0.7071068286895752],"translation":[-2.2556710243225098,-0.5599625110626221,1.5977319478988647]},{"mesh":0,"name":"Spider","skin":0},{"children":[57,48,49,50,51,52,53,54,55,56],"name":"Armature"}],"animations":[{"channels":[{"sampler":0,"target":{"node":48,"path":"translation"}},{"sampler":1,"target":{"node":48,"path":"rotation"}},{"sampler":2,"target":{"node":48,"path":"scale"}},{"sampler":3,"target":{"node":4,"path":"translation"}},{"sampler":4,"target":{"node":4,"path":"rotation"}},{"sampler":5,"target":{"node":4,"path":"scale"}},{"sampler":6,"target":{"node":0,"path":"translation"}},{"sampler":7,"target":{"node":0,"path":"rotation"}},{"sampler":8,"target":{"node":0,"path":"scale"}},{"sampler":9,"target":{"node":2,"path":"translation"}},{"sampler":10,"target":{"node":2,"path":"rotation"}},{"sampler":11,"target":{"node":2,"path":"scale"}},{"sampler":12,"target":{"node":6,"path":"translation"}},{"sampler":13,"target":{"node":6,"path":"rotation"}},{"sampler":14,"target":{"node":6,"path":"scale"}},{"sampler":15,"target":{"node":11,"path":"rotation"}},{"sampler":16,"target":{"node":10,"path":"rotation"}},{"sampler":17,"target":{"node":9,"path":"rotation"}},{"sampler":18,"target":{"node":8,"path":"rotation"}},{"sampler":19,"target":{"node":16,"path":"rotation"}},{"sampler":20,"target":{"node":15,"path":"rotation"}},{"sampler":21,"target":{"node":14,"path":"rotation"}},{"sampler":22,"target":{"node":13,"path":"rotation"}},{"sampler":23,"target":{"node":21,"path":"rotation"}},{"sampler":24,"target":{"node":20,"path":"rotation"}},{"sampler":25,"target":{"node":19,"path":"rotation"}},{"sampler":26,"target":{"node":18,"path":"rotation"}},{"sampler":27,"target":{"node":26,"path":"rotation"}},{"sampler":28,"target":{"node":25,"path":"rotation"}},{"sampler":29,"target":{"node":24,"path":"rotation"}},{"sampler":30,"target":{"node":23,"path":"translation"}},{"sampler":31,"target":{"node":23,"path":"rotation"}},{"sampler":32,"target":{"node":23,"path":"scale"}},{"sampler":33,"target":{"node":31,"path":"rotation"}},{"sampler":34,"target":{"node":30,"path":"rotation"}},{"sampler":35,"target":{"node":29,"path":"rotation"}},{"sampler":36,"target":{"node":28,"path":"rotation"}},{"sampler":37,"target":{"node":36,"path":"rotation"}},{"sampler":38,"target":{"node":35,"path":"rotation"}},{"sampler":39,"target":{"node":34,"path":"rotation"}},{"sampler":40,"target":{"node":33,"path":"rotation"}},{"sampler":41,"target":{"node":41,"path":"rotation"}},{"sampler":42,"target":{"node":40,"path":"rotation"}},{"sampler":43,"target":{"node":39,"path":"rotation"}},{"sampler":44,"target":{"node":38,"path":"rotation"}},{"sampler":45,"target":{"node":46,"path":"rotation"}},{"sampler":46,"target":{"node":45,"path":"rotation"}},{"sampler":47,"target":{"node":44,"path":"rotation"}},{"sampler":48,"target":{"node":43,"path":"rotation"}},{"sampler":49,"target":{"node":49,"path":"translation"}},{"sampler":50,"target":{"node":49,"path":"rotation"}},{"sampler":51,"target":{"node":49,"path":"scale"}},{"sampler":52,"target":{"node":50,"path":"translation"}},{"sampler":53,"target":{"node":50,"path":"rotation"}},{"sampler":54,"target":{"node":50,"path":"scale"}},{"sampler":55,"target":{"node":51,"path":"translation"}},{"sampler":56,"target":{"node":51,"path":"rotation"}},{"sampler":57,"target":{"node":51,"path":"scale"}},{"sampler":58,"target":{"node":52,"path":"translation"}},{"sampler":59,"target":{"node":52,"path":"rotation"}},{"sampler":60,"target":{"node":52,"path":"scale"}},{"sampler":61,"target":{"node":53,"path":"translation"}},{"sampler":62,"target":{"node":53,"path":"rotation"}},{"sampler":63,"target":{"node":53,"path":"scale"}},{"sampler":64,"target":{"node":54,"path":"translation"}},{"sampler":65,"target":{"node":54,"path":"rotation"}},{"sampler":66,"target":{"node":54,"path":"scale"}},{"sampler":67,"target":{"node":55,"path":"translation"}},{"sampler":68,"target":{"node":55,"path":"rotation"}},{"sampler":69,"target":{"node":55,"path":"scale"}},{"sampler":70,"target":{"node":56,"path":"translation"}},{"sampler":71,"target":{"node":56,"path":"rotation"}},{"sampler":72,"target":{"node":56,"path":"scale"}}],"name":"ArmatureAction","samplers":[{"input":7,"interpolation":"LINEAR","output":8},{"input":7,"interpolation":"LINEAR","output":9},{"input":10,"interpolation":"LINEAR","output":11},{"input":10,"interpolation":"LINEAR","output":12},{"input":7,"interpolation":"LINEAR","output":13},{"input":10,"interpolation":"LINEAR","output":14},{"input":10,"interpolation":"LINEAR","output":15},{"input":7,"interpolation":"LINEAR","output":16},{"input":10,"interpolation":"LINEAR","output":17},{"input":10,"interpolation":"LINEAR","output":18},{"input":7,"interpolation":"LINEAR","output":19},{"input":10,"interpolation":"LINEAR","output":20},{"input":10,"interpolation":"LINEAR","output":21},{"input":7,"interpolation":"LINEAR","output":22},{"input":10,"interpolation":"LINEAR","output":23},{"input":7,"interpolation":"LINEAR","output":24},{"input":7,"interpolation":"LINEAR","output":25},{"input":7,"interpolation":"LINEAR","output":26},{"input":7,"interpolation":"LINEAR","output":27},{"input":7,"interpolation":"LINEAR","output":28},{"input":7,"interpolation":"LINEAR","output":29},{"input":7,"interpolation":"LINEAR","output":30},{"input":7,"interpolation":"LINEAR","output":31},{"input":7,"interpolation":"LINEAR","output":32},{"input":7,"interpolation":"LINEAR","output":33},{"input":7,"interpolation":"LINEAR","output":34},{"input":7,"interpolation":"LINEAR","output":35},{"input":7,"interpolation":"LINEAR","output":36},{"input":7,"interpolation":"LINEAR","output":37},{"input":7,"interpolation":"LINEAR","output":38},{"input":10,"interpolation":"LINEAR","output":39},{"input":7,"interpolation":"LINEAR","output":40},{"input":10,"interpolation":"LINEAR","output":41},{"input":7,"interpolation":"LINEAR","output":42},{"input":7,"interpolation":"LINEAR","output":43},{"input":7,"interpolation":"LINEAR","output":44},{"input":7,"interpolation":"LINEAR","output":45},{"input":7,"interpolation":"LINEAR","output":46},{"input":7,"interpolation":"LINEAR","output":47},{"input":7,"interpolation":"LINEAR","output":48},{"input":7,"interpolation":"LINEAR","output":49},{"input":7,"interpolation":"LINEAR","output":50},{"input":7,"interpolation":"LINEAR","output":51},{"input":7,"interpolation":"LINEAR","output":52},{"input":7,"interpolation":"LINEAR","output":53},{"input":7,"interpolation":"LINEAR","output":54},{"input":7,"interpolation":"LINEAR","output":55},{"input":7,"interpolation":"LINEAR","output":56},{"input":7,"interpolation":"LINEAR","output":57},{"input":7,"interpolation":"LINEAR","output":58},{"input":10,"interpolation":"LINEAR","output":59},{"input":7,"interpolation":"LINEAR","output":60},{"input":7,"interpolation":"LINEAR","output":61},{"input":10,"interpolation":"LINEAR","output":62},{"input":7,"interpolation":"LINEAR","output":63},{"input":7,"interpolation":"LINEAR","output":64},{"input":10,"interpolation":"LINEAR","output":65},{"input":7,"interpolation":"LINEAR","output":66},{"input":7,"interpolation":"LINEAR","output":67},{"input":10,"interpolation":"LINEAR","output":68},{"input":7,"interpolation":"LINEAR","output":69},{"input":7,"interpolation":"LINEAR","output":70},{"input":10,"interpolation":"LINEAR","output":71},{"input":7,"interpolation":"LINEAR","output":72},{"input":7,"interpolation":"LINEAR","output":73},{"input":10,"interpolation":"LINEAR","output":74},{"input":7,"interpolation":"LINEAR","output":75},{"input":7,"interpolation":"LINEAR","output":76},{"input":10,"interpolation":"LINEAR","output":77},{"input":7,"interpolation":"LINEAR","output":78},{"input":7,"interpolation":"LINEAR","output":79},{"input":10,"interpolation":"LINEAR","output":80},{"input":7,"interpolation":"LINEAR","output":81}]}],"materials":[{"doubleSided":true,"name":"Material.001","pbrMetallicRoughness":{}}],"meshes":[{"name":"Cube","primitives":[{"attributes":{"POSITION":0,"NORMAL":1,"TEXCOORD_0":2,"JOINTS_0":3,"WEIGHTS_0":4},"indices":5,"material":0}]}],"skins":[{"inverseBindMatrices":6,"joints":[48,5,4,1,0,3,2,7,6,12,11,10,9,8,17,16,15,14,13,22,21,20,19,18,27,26,25,24,23,32,31,30,29,28,37,36,35,34,33,42,41,40,39,38,47,46,45,44,43,49,50,51,52,53,54,55,56],"name":"Armature"}],"accessors":[{"bufferView":0,"componentType":5126,"count":1000,"max":[2.742279291152954,1.4045029878616333,2.0192716121673584],"min":[-2.742279291152954,-0.6434623599052429,-3.534085512161255],"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":1000,"type":"VEC3"},{"bufferView":2,"componentType":5126,"count":1000,"type":"VEC2"},{"bufferView":3,"componentType":5121,"count":1000,"type":"VEC4"},{"bufferView":4,"componentType":5126,"count":1000,"type":"VEC4"},{"bufferView":5,"componentType":5123,"count":1500,"type":"SCALAR"},{"bufferView":6,"componentType":5126,"count":57,"type":"MAT4"},{"bufferView":7,"componentType":5126,"count":120,"max":[5],"min":[0.041666666666666664],"type":"SCALAR"},{"bufferView":8,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":9,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":10,"componentType":5126,"count":2,"max":[5],"min":[0.041666666666666664],"type":"SCALAR"},{"bufferView":11,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":12,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":13,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":14,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":15,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":16,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":17,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":18,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":19,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":20,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":21,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":22,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":23,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":24,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":25,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":26,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":27,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":28,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":29,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":30,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":31,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":32,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":33,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":34,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":35,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":36,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":37,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":38,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":39,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":40,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":41,"componentType":5126,"count":2,"type":"VEC3"},{"bufferView":42,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":43,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":44,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":45,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":46,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":47,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":48,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":49,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":50,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":51,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":52,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":53,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":54,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":55,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":56,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":57,"componentType":5126,"count":120,"type":"VEC4"},{"bufferView":58,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":59,"componentType":5126,"count":2,"type":"VEC4"},{"bufferView":60,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":61,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":62,"componentType":5126,"count":2,"type":"VEC4"},{"bufferView":63,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":64,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":65,"componentType":5126,"count":2,"type":"VEC4"},{"bufferView":66,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":67,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":68,"componentType":5126,"count":2,"type":"VEC4"},{"bufferView":69,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":70,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":71,"componentType":5126,"count":2,"type":"VEC4"},{"bufferView":72,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":73,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":74,"componentType":5126,"count":2,"type":"VEC4"},{"bufferView":75,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":76,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":77,"componentType":5126,"count":2,"type":"VEC4"},{"bufferView":78,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":79,"componentType":5126,"count":120,"type":"VEC3"},{"bufferView":80,"componentType":5126,"count":2,"type":"VEC4"},{"bufferView":81,"componentType":5126,"count":120,"type":"VEC3"}],"bufferViews":[{"buffer":0,"byteLength":12000,"byteOffset":0},{"buffer":0,"byteLength":12000,"byteOffset":12000},{"buffer":0,"byteLength":8000,"byteOffset":24000},{"buffer":0,"byteLength":4000,"byteOffset":32000},{"buffer":0,"byteLength":16000,"byteOffset":36000},{"buffer":0,"byteLength":3000,"byteOffset":52000},{"buffer":0,"byteLength":3648,"byteOffset":55000},{"buffer":0,"byteLength":480,"byteOffset":58648},{"buffer":0,"byteLength":1440,"byteOffset":59128},{"buffer":0,"byteLength":1920,"byteOffset":60568},{"buffer":0,"byteLength":8,"byteOffset":62488},{"buffer":0,"byteLength":24,"byteOffset":62496},{"buffer":0,"byteLength":24,"byteOffset":62520},{"buffer":0,"byteLength":1920,"byteOffset":62544},{"buffer":0,"byteLength":24,"byteOffset":64464},{"buffer":0,"byteLength":24,"byteOffset":64488},{"buffer":0,"byteLength":1920,"byteOffset":64512},{"buffer":0,"byteLength":24,"byteOffset":66432},{"buffer":0,"byteLength":24,"byteOffset":66456},{"buffer":0,"byteLength":1920,"byteOffset":66480},{"buffer":0,"byteLength":24,"byteOffset":68400},{"buffer":0,"byteLength":24,"byteOffset":68424},{"buffer":0,"byteLength":1920,"byteOffset":68448},{"buffer":0,"byteLength":24,"byteOffset":70368},{"buffer":0,"byteLength":1920,"byteOffset":70392},{"buffer":0,"byteLength":1920,"byteOffset":72312},{"buffer":0,"byteLength":1920,"byteOffset":74232},{"buffer":0,"byteLength":1920,"byteOffset":76152},{"buffer":0,"byteLength":1920,"byteOffset":78072},{"buffer":0,"byteLength":1920,"byteOffset":79992},{"buffer":0,"byteLength":1920,"byteOffset":81912},{"buffer":0,"byteLength":1920,"byteOffset":83832},{"buffer":0,"byteLength":1920,"byteOffset":85752},{"buffer":0,"byteLength":1920,"byteOffset":87672},{"buffer":0,"byteLength":1920,"byteOffset":89592},{"buffer":0,"byteLength":1920,"byteOffset":91512},{"buffer":0,"byteLength":1920,"byteOffset":93432},{"buffer":0,"byteLength":1920,"byteOffset":95352},{"buffer":0,"byteLength":1920,"byteOffset":97272},{"buffer":0,"byteLength":24,"byteOffset":99192},{"buffer":0,"byteLength":1920,"byteOffset":99216},{"buffer":0,"byteLength":24,"byteOffset":101136},{"buffer":0,"byteLength":1920,"byteOffset":101160},{"buffer":0,"byteLength":1920,"byteOffset":103080},{"buffer":0,"byteLength":1920,"byteOffset":105000},{"buffer":0,"byteLength":1920,"byteOffset":106920},{"buffer":0,"byteLength":1920,"byteOffset":108840},{"buffer":0,"byteLength":1920,"byteOffset":110760},{"buffer":0,"byteLength":1920,"byteOffset":112680},{"buffer":0,"byteLength":1920,"byteOffset":114600},{"buffer":0,"byteLength":1920,"byteOffset":116520},{"buffer":0,"byteLength":1920,"byteOffset":118440},{"buffer":0,"byteLength":1920,"byteOffset":120360},{"buffer":0,"byteLength":1920,"byteOffset":122280},{"buffer":0,"byteLength":1920,"byteOffset":124200},{"buffer":0,"byteLength":1920,"byteOffset":126120},{"buffer":0,"byteLength":1920,"byteOffset":128040},{"buffer":0,"byteLength":1920,"byteOffset":129960},{"buffer":0,"byteLength":1440,"byteOffset":131880},{"buffer":0,"byteLength":32,"byteOffset":133320},{"buffer":0,"byteLength":1440,"byteOffset":133352},{"buffer":0,"byteLength":1440,"byteOffset":134792},{"buffer":0,"byteLength":32,"byteOffset":136232},{"buffer":0,"byteLength":1440,"byteOffset":136264},{"buffer":0,"byteLength":1440,"byteOffset":137704},{"buffer":0,"byteLength":32,"byteOffset":139144},{"buffer":0,"byteLength":1440,"byteOffset":139176},{"buffer":0,"byteLength":1440,"byteOffset":140616},{"buffer":0,"byteLength":32,"byteOffset":142056},{"buffer":0,"byteLength":1440,"byteOffset":142088},{"buffer":0,"byteLength":1440,"byteOffset":143528},{"buffer":0,"byteLength":32,"byteOffset":144968},{"buffer":0,"byteLength":1440,"byteOffset":145000},{"buffer":0,"byteLength":1440,"byteOffset":146440},{"buffer":0,"byteLength":32,"byteOffset":147880},{"buffer":0,"byteLength":1440,"byteOffset":147912},{"buffer":0,"byteLength":1440,"byteOffset":149352},{"buffer":0,"byteLength":32,"byteOffset":150792},{"buffer":0,"byteLength":1440,"byteOffset":150824},{"buffer":0,"byteLength":1440,"byteOffset":152264},{"buffer":0,"byteLength":32,"byteOffset":153704},{"buffer":0,"byteLength":1440,"byteOffset":153736}],"buffers":[{"byteLength":155176,"uri":"data:application/octet-stream;base64,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BgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALQAAAC0AAAAtAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALgAAAC4AAAAuAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAALwAAAC8AAAAvAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKQAAACkAAAApAAAAKQAAACkAAAApAAAAKQAAACkAAAApAAAAKQAAACkAAAApAAAAKQAAACkAAAApAAAAKQAAACkAAAApAAAAKQAAACkAAAApAAAAKQAAACkAAAApAAAAKgAAACoAAAAqAAAAKgAAACoAAAAqAAAAKgAAACoAAAAqAAAAKgAAACoAAAAqAAAAKgAAACoAAAAqAAAAKgAAACoAAAAqAAAAKgAAACoAAAAqAAAAKgAAACoAAAAqAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAKwAAACsAAAArAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAIwAAACMAAAAjAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJAAAACQAAAAkAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHgAAAB4AAAAeAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAHwAAAB8AAAAfAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIAAAACAAAAAgAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAIQAAACEAAAAhAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGQAAABkAAAAZAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGwAAABsAAAAbAAAAGwAAABsAAAAbAAAAGwAAABsAAAAbAAAAGwAAABsAAAAbAAAAGwAAABsAAAAbAAAAGwAAABsAAAAbAAAAGwAAABsAAAAbAAAAGwAAABsAAAAbAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAHAAAABwAAAAcAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFAAAABQAAAAUAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFQAAABUAAAAVAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFgAAABYAAAAWAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAAFwAAABcAAAAXAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAACwAAAAsAAAALAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAADQAAAA0AAAANAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAEADgAUAAEAFAAHAAoABgATAAoAEwAXABUAEgAMABUADAAPABAAAwAJABAACQAWAAUAAgAIAAUACAALABEADQAAABEAAAAEAEwAUgAsAEwALAAfACIAHgArACIAKwAvAEgAUAAkAEgAJAAnAEsAVQAhAEsAIQAuAFYATgAgAFYAIAAjACkAJQAYACkAGAAcADcAQgA8ADcAPAAxAD0APwA0AD0ANAAyAEYAOwA1AEYANQBAADAAMwA5ADAAOQA2AEQARwBBAEQAQQA+ADgAOgBFADgARQBDAB0AGgBPAB0ATwBXACgAGwBUACgAVABKAC0AKgBRAC0AUQBJABkAJgBTABkAUwBNAFgAWwBhAFgAYQBeAF8AYgBtAF8AbQBqAGwAbwBpAGwAaQBmAGUAaABdAGUAXQBaAGAAawBkAGAAZABZAG4AYwBcAG4AXABnAHAAcwB5AHAAeQB2AHgAegCFAHgAhQCDAIQAhwCBAIQAgQB+AH0AfwB0AH0AdAByAHcAggB8AHcAfABxAIYAewB1AIYAdQCAAIgAiwCRAIgAkQCOAJAAkgCdAJAAnQCbAJwAnwCZAJwAmQCWAJUAlwCMAJUAjACKAI8AmgCUAI8AlACJAJ4AkwCNAJ4AjQCYAKIAqACrAKIAqwClAKcAtAC3AKcAtwCqALIArACvALIArwC1AK0AoACjAK0AowCwAKYAoQCuAKYArgCzALYAsQCkALYApACpALoAwADDALoAwwC9AL8AzADOAL8AzgDBAMoAxADHAMoAxwDNAMYAuQC7AMYAuwDIAL4AuADFAL4AxQDLAM8AyQC8AM8AvADCANIA2ADbANIA2wDVANcA5ADmANcA5gDZAOIA3ADfAOIA3wDlAN4A0QDTAN4A0wDgANYA0ADdANYA3QDjAOcA4QDUAOcA1ADaAOkA6wDxAOkA8QDvAPAA8gD9APAA/QD7APwA/gD4APwA+AD2APUA9wDsAPUA7ADqAO4A+gD0AO4A9ADoAP8A8wDtAP8A7QD5AAABAwEJAQABCQEGAQcBCgEVAQcBFQESARQBFwERARQBEQEOAQ0BEAEFAQ0BBQECAQgBEwEMAQgBDAEBARYBCwEEARYBBAEPASkBHQEjASkBIwEvASgBJgEZASgBGQEbAS0BKwElAS0BJQEnASEBHwEsASEBLAEuARgBJAEqARgBKgEeARwBGgEgARwBIAEiATEBMwE6ATEBOgE4ATcBOQFFATcBRQFDAUQBRgE/AUQBPwE9AT4BQAE0AT4BNAEyATYBQgE8ATYBPAEwAUcBOwE1AUcBNQFBAUkBSwFRAUkBUQFPAVABUgFdAVABXQFbAVwBXgFYAVwBWAFWAVUBVwFMAVUBTAFKAU4BWgFUAU4BVAFIAV8BUwFNAV8BTQFZAWABYwFpAWABaQFmAWgBagF1AWgBdQFzAXQBdwFxAXQBcQFuAW0BbwFkAW0BZAFiAWcBcgFsAWcBbAFhAXYBawFlAXYBZQFwAYkBfQGDAYkBgwGPAYgBhgF5AYgBeQF7AY0BiwGFAY0BhQGHAYEBfwGMAYEBjAGOAXgBhAGKAXgBigF+AXwBegGAAXwBgAGCAZEBkwGZAZEBmQGXAZgBmgGlAZgBpQGjAaQBpgGgAaQBoAGeAZ0BnwGUAZ0BlAGSAZYBogGcAZYBnAGQAacBmwGVAacBlQGhAakBqwGxAakBsQGvAbABsgG9AbABvQG7AbwBvgG4AbwBuAG2AbUBtwGsAbUBrAGqAa4BugG0Aa4BtAGoAb8BswGtAb8BrQG5AcABwwHJAcAByQHGAcgBygHVAcgB1QHTAdQB1wHRAdQB0QHOAc0BzwHEAc0BxAHCAccB0gHMAccBzAHBAdYBywHFAdYBxQHQAekB3QHjAekB4wHvAegB5gHZAegB2QHbAe0B6wHlAe0B5QHnAeEB3wHsAeEB7AHuAdgB5AHqAdgB6gHeAdwB2gHgAdwB4AHiAfEB8wH5AfEB+QH3AfgB+gEFAvgBBQIDAgQCBgIAAgQCAAL+Af0B/wH0Af0B9AHyAfYBAgL8AfYB/AHwAQcC+wH1AQcC9QEBAgkCCwIRAgkCEQIPAhACEgIdAhACHQIbAhwCHgIYAhwCGAIWAhUCFwIMAhUCDAIKAg4CGgIUAg4CFAIIAh8CEwINAh8CDQIZAiACIwIpAiACKQImAigCKwI2AigCNgIzAjQCNwIxAjQCMQIuAiwCLwIkAiwCJAIhAicCMgItAicCLQIiAjUCKgIlAjUCJQIwAkkCPQJDAkkCQwJPAkgCRgI5AkgCOQI7Ak0CSwJFAk0CRQJHAkECPwJMAkECTAJOAjgCRAJKAjgCSgI+AjwCOgJAAjwCQAJCAlICVAJZAlICWQJXAlgCWgJmAlgCZgJkAmMCZQJgAmMCYAJeAl0CXwJTAl0CUwJRAlYCYgJcAlYCXAJQAmcCWwJVAmcCVQJhAmkCbwJzAmkCcwJtAm4CewJ/Am4CfwJyAnoCdAJ4AnoCeAJ+AnUCaAJsAnUCbAJ5AnACagJ2AnACdgJ8An0CdwJrAn0CawJxAoICiAKLAoICiwKFAocClAKXAocClwKKApICjAKPApICjwKVAo0CgAKDAo0CgwKQAoYCgQKOAoYCjgKTApYCkQKEApYChAKJAqcCrQKhAqcCoQKbAqgCnQKZAqgCmQKkAq8CqQKlAq8CpQKrAqMCrgKqAqMCqgKfApoCoAKsApoCrAKmApwCogKeApwCngKYArECtgK6ArECugK1ArcCwwLHArcCxwK7AsICvQLBAsICwQLGArwCsAK0ArwCtALAArgCsgK+ArgCvgLEAsUCvwKzAsUCswK5AskCzwLTAskC0wLNAs4C2wLfAs4C3wLSAtoC1ALYAtoC2ALeAtUCyALMAtUCzALZAtACygLWAtAC1gLcAt0C1wLLAt0CywLRAuIC6ALrAuIC6wLlAuYC8wL3AuYC9wLqAvIC7ALvAvIC7wL1Au0C4ALkAu0C5ALxAucC4QLuAucC7gL0AvYC8ALjAvYC4wLpAgcDDQMBAwcDAQP7AggD/QL5AggD+QIEAw8DCQMFAw8DBQMLAwMDDgMKAwMDCgP/AvoCAAMMA/oCDAMGA/wCAgP+AvwC/gL4AhEDFwMbAxEDGwMVAxYDIwMnAxYDJwMaAyIDHAMgAyIDIAMmAx0DEAMUAx0DFAMhAxgDEgMeAxgDHgMkAyUDHwMTAyUDEwMZAykDLwMzAykDMwMtAy4DOwM/Ay4DPwMyAzoDNAM4AzoDOAM+AzUDKAMsAzUDLAM5AzADKgM2AzADNgM8Az0DNwMrAz0DKwMxA0IDSANLA0IDSwNFA0YDUwNXA0YDVwNKA1IDTANPA1IDTwNVA00DQANEA00DRANRA0cDQQNOA0cDTgNUA1YDUANDA1YDQwNJA2cDbQNhA2cDYQNbA2gDXQNZA2gDWQNkA28DaQNlA28DZQNrA2MDbgNqA2MDagNfA1oDYANsA1oDbANmA1wDYgNeA1wDXgNYA3EDdwN7A3EDewN1A3YDgwOHA3YDhwN6A4IDfAOAA4IDgAOGA30DcAN0A30DdAOBA3gDcgN+A3gDfgOEA4UDfwNzA4UDcwN5A4kDjwOTA4kDkwONA44DmwOfA44DnwOSA5oDlAOYA5oDmAOeA5UDiAOMA5UDjAOZA5ADigOWA5ADlgOcA50DlwOLA50DiwORA6IDqAOrA6IDqwOlA6YDswO2A6YDtgOpA7IDrAOvA7IDrwO1A64DoQOkA64DpAOxA6cDoAOtA6cDrQO0A7cDsAOjA7cDowOqA8cDzQPBA8cDwQO7A8gDvQO5A8gDuQPEA88DyQPFA88DxQPLA8MDzgPKA8MD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TmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+cw9Rrv9jabWlCWo/0XvPPt5waq/JcWm1pQlqP9F7zz54BNKqTmtptaUJaj/Re88+jT7qr0Z4abWlCWo/0XvPPhnLKDCae2m1pwlqP9F7zz7t5U+vDU5ptaUJaj/Se88+goncLxOCabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4MKI+vempptaUJaj/Re88+WtPpL1ZeabWlCWo/0XvPPgDKKDCYe2m1pQlqP9F7zz5ssc+vzDBptaUJaj/Re88+NwGPsPxnabWlCWo/0XvPPuaqzi7ueWm1pQlqP9F7zz5TyIEve2hptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1pQlqP9F7zz4ZhMCqTmtptaUJaj/Re88+GYTAqk5rabWlCWo/0XvPPhmEwKpOa2m1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4G1iP+fAELztE0K9GXDnvvwEZD/Ubm27I9lMvcau3r5aKWY/BMwvuVYXVL21b9a+XhZoPyUpjjptxVa98bnSvvXsaD+J6Z652tVTvVoT1L5EoWg/nweCu5kqTL01Zde+DeRnP8KSFrxBaEG9XIfbvjjyZj9jLXm8ASo1vSVf376GCmY/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/eHyevLDKLL0feOG+pYhlP3h8nrywyiy9H3jhvqWIZT94fJ68sMosvR944b6liGU/fRmbvAekLb0AjOC+bMJlP2ROkryp1y+9SxjevoVaZj/IVIa8Gdcyvf2L2r7UMmc/zpJyvNAdNr0XVta+0i1oP13HWbzWQjm9ePDRvm0taT9Ir0S8M/07vd3jzb4ME2o/FLM0vFQhPr37xMq+N8BqP2DQK7zTXz+9SjDJvpwWaz+PoyK8iLNAvd5Oyr5r2Go/nfUQvDs+Q72B+M2+7gpqP/l78Lvg/ka9nPTRvpklaT8LXL27jU5LvQiK077sxmg/aiaHu9RrUL2HxNG+gilpPxcwI7v/CVa9XUTNvqMkaj8tNmS633pbvS0+yb74/mo/V0U+OoIFYL36X8q+cLxqP5jSBDqSW169UzHUvpuQaD/7lRm7t/ZUvfex4r4BJ2U/A6fYu2buSL1aJO6+zERiP+YWNLzQJD696Hrzvo3eYD8FFGm8m+s2vdKA9L5pmmA/sNN3vBjtNL2WpPW+ZktgP/UiXbzFMDi9WxP5vq9XXz9sxCW8QDI/vb+h/b6pC14/NuKuu1uvSb2nrAC/wfJcP8egsjmhUVe9VtIAv//QXD9lXdA7xbVnvZrp/L7tG14/gelHPMzMeb0rrPO+wpVgP6vRjjx0f4W9vAjpvptKYz8cd648nhCMvcuC4L7yV2U/f6m6PCucjr01Kt2+AR9mP3+pujwrnI69NSrdvgEfZj9/qbo8K5yOvTUq3b4BH2Y/AACAPwAAgD/8/38/AQCAPwIAgD8CAIA/udIUPy29Cj0qP/y+s4slP1zTFD9txAo9gz78vl2LJT991xQ/VPQKPQE5/L6ViSU/gOIUP/RzCz1RKfy+PIUlP8zTFT+bgRY9vLf5vu+OJT8IuhY/vKQgPatk9r4X8yU/N9oXP9NWKz2/WfG+drsmP8ghGT81+zQ9UgPtvtQTJz+aiho/dPU8PVNP6L50ZSc/VyMbP67oPz1+DOa+npwnPzGIGz9lfkE9vHrkvrHGJz/pHBw/82xEPQDS4r4+ySc/7zMcPwvYRT0XMeO+9ZEnP+1lHD/3UEY99lvivt2qJz/8lxw/ZrJGPcCD4b6FxCc/Rd4cPyq8ST0Z1eG+xGMnPz1MHT+Ak0s9jbDgvsNcJz8yJB0/3txJPU6D4L6akyc/qwccPyHIPT29Pd++kxYpP0DZGD/Sqhw9+oHbvsdLLT8KuQ0/b/GCPIa3375tcTU/CrUAPx/8e7uAs+y+pPs6PwM89T44ekK7yzn5vhsCOz9unvg+rZ+Aus3y/L6voDg/IEz7PjwtJLl46P2+RmM3P232/j6kiVw6jZ3+vhbfNT+NcQI/FpAnO94//75eiDM/PRsGP+OHxjva9f+++owwP8j5CT8vWjM84yMAv+ZoLT/VnA0/KtiIPEH+/76phyo/WaAQP15HvDwCMf++3DwoPw7jEj9uG+o8DPX9vsmuJj+/UBQ/P+oEPVnE/L5I0iU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT9+zRM/gGT+PJeX/L7KXCY/rmwRPxGCyzwkAP2+DFwoP0DXDj9ZEZo8rfn8vvqdKj/Alw0/9YuEPJnW/L7muCs/5ZcPP1tmqTwtfQC/VXYoP7T+Ez94pwA90N8Ev935ID8bkhg/GlA0PQP0CL+L4xg/3LQbP6YFXD1xkQq/o/0TP/mVHD9YbWg9w38Iv67oFD860Bs/6KxePXAFBL+IvBk/5WMaP5UATD0yq/6+1yEfPxiaGT+kvUE9CUn6vuipIT/s4xg/Qcc5PUHC+r7BMCI/C0kXPzJIJz1PlPu+mXMjP4ScFT/SzBM9Zhr8vp3bJD+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/udIUPy29Cj0qP/y+s4slP7nSFD8tvQo9Kj/8vrOLJT+50hQ/Lb0KPSo//L6ziyU/QhwVP/LvDT1b7/y+ZAMlP7t9FT/ZNBI9fob9vjltJD8wKhU/bgwOPQZ5+76KhSU/aIcTP1Ic9jzvJvW+dl8pP5/ZED/fsrs8/EzsvtTQLj8mQA4/5aWMPH3u5b6sEDM/qxsMP8XTXjz7TOO+ppg1PyQkCj/b6S08uQ7ivoZ+Nz+oqQg/2T0IPFrR4b7WrTg/VNsHP+194zt1QeK+kiQ5PwOlBz/AQtQ7uPnivksUOT/95gc/C5LgO1Cx474sqzg/d8YIPwrpBzw6kuS+I783P1owCj+qsi48KrjlvkNRNj+x8As/OJJgPJIZ577zhTQ/P9UNPzhfjDzUp+i+IYQyPx2tDz/SuKg87U3qvqF3MD/SRxE/uNPBPB3u6760ky4/dHISP/WF0zyNX+2+OhYtP23pEj/aatk8dmbuvtJULD/xmhI/Zl7TPP2c7r6lhiw/6L4RP7YkxjxmFO6+inMtP4piED8X37g8v47tvhTHLj8HeQ4/5qGyPIW27b40SzA/DPoLPzXmtzzI9O6+XtwxP5EeCT8LrM08URnyvkn/Mj+bcAY/4w/3PEcN+L7l8DI/uvIDPyEMEj1/QP6+s40yP2TeAT8O0Sk9RHICvzaZMT+sgwA/Ha07PZ3+BL/vnjA/ewgAP61jQj0H9gW/CzYwP3sIAD+tY0I9B/YFvws2MD97CAA/rWNCPQf2Bb8LNjA/3l9Xvu/tvb3vutg+EFhgP59gV74V5r29NrvYPg5YYD9eZle+CK+9vY292D7fV2A/TXZXvnQZvb1ExNg+RVdgPzN1Wb60KK29NsjZPvwsYD9SyFu+y1abvXcE2z7g718/edpevv1ag70eotw+JZdfPwI+Yb7Q4lm9h6LdPphhXz9LhGO+ofIqvcZ23j7NMF8/j4JkvjvtFb0c094+pRhfP2krZb4c4ge9OA7fPgsIXz9Y2mW+wJDsvK0o3z40AF8/LrdlvruG7Lz9+94+pw1fP3wLZr4mcN68ZxffPv4EXz+GX2a+CVjQvEQy3z5D/F4/gERmvqkxybyF5d4+1BJfP7G1Zr4RcLC8aOXePskQXz+2xGa+S460vA8S3z7UA18/Ei9nvkVS0byxQuA+NqpePwJbaL5mYA+9YTXjPmLBXT9w3WO+p0SuvW5f5D5i21w/tR9Tvo06Gb6iPdo+uDReP4E9RL7fMTq+WBnPPnYkYD+omkK+DP85vlzezT5jhmA/CRBDvhpgN76TLM4+k5BgP2guRL4G+zK+GfXOPpmLYD8RREa+0BUrvgVy0D6ueGA/WDpJvpTnH76MKdI+8GtgP1hsTL51lxK+/u/TPlhkYD/3nU++E1YEvqqP1T6pYGA/1aZSvojq7L3739Y+O19gP58ZVb6dANW9P97XPiBdYD9awla+XzvEva6A2D7dWWA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/92Va+e33IvRjb2D6MM2A/h6lVvolv373zDNk+2OJfPzFjVL4J9fW9vR/ZPjSTXz+DxFO+PQYAvlId2T7eb18/vBBSvpaM+r2IJdc+FhxgP0H+Tb7CH+y9E2DSPqS3YT+lpUm+ou3XvebYzD7aimM/VRxIvlF/wb3woMk+kqhkP4SBS76rW6y9k1vLPjdaZD+4ZFG+l+6avTQe0D6xI2M/BppWvklMj71zx9Q+K99hPyzIWL4cHIu9887WPjdNYT9dkFi+XiCTvZQk1z7DJ2E/sRVYvqKspL3A1dc+E9RgP4GZV75SE7a9EXfYPgV/YD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/3l9Xvu/tvb3vutg+EFhgP95fV77v7b2977rYPhBYYD/eX1e+7+29ve+62D4QWGA/ClRavmpJvL0bmNs+Qn1fP189Yr5YGbi9MUfjPnEeXT+4Lm6+emWyvVTw7j5KTVk/N8J8vg6XrL1MT/0+oTdUP41Thb5eEKm9vpoFP8TeTj+lv4i+jH+rvRcZCT9v+Us/+F6IvjuQtL1y2Qg/DhVMP3mvhr6AYcC9SFkHP+wwTT8iboS+J93LvRRNBT85uE4/0DqCvqR71L3ERwM/ojhQP7CVgL5oPdm9QMABPwtbUT+p1H++HcvZvRccAT9U2FE/6OB/vv6+1b26EQE/au5RP+EegL7aTM69JB8BP+L8UT+xeoC+nKbEvX9NAT9e91E/mQyBvpv6ub3dqQE/6s5RP9Tjgb5Ueq+98UgCP0NvUT9PGYO+U1+mvcZLAz/WulA/4NOEvqfwn71L5QQ/7oRPP1xLh77Njp29r1oHPw6NTT/uyIq+akievTnsCj/Sjko/gY6PvvX+n710yQ8/+ENGP229lb78j6K9LP4VP7NnQD+1Hp2+zTCmvd4yHT97/Tg/iC6lvv80q72W1SQ/N1AwPypKrb4t3LG97UwsP77fJj9k0LS+YT+6vXX+Mj8QbB0/svC6vuPgwr3IYzg/mQQVP3GVv77wZsu9M1s8P01ADj8Hc8K+YcbRvZzGPj+D1wk/M2/DvoQx1L1Kmz8/RkYIPzNvw76EMdS9Sps/P0ZGCD8zb8O+hDHUvUqbPz9GRgg/OSLjvfyV9b3aiPk+j5dbP6gf471Wj/W94on5PmyXWz+CDeO95GD1vdWQ+T6Nlls/BNzivdzi9L1vo/k+Q5RbP0hS3b35nee90En7PgBsWz8o09a97+jYvVm7/D7YV1s/2MDNvc0xxb0bJf4+lFxbP6I+xb2/krK96jn/PkprWz/9Kry9CQafvb/x/z7KkVs/V/m3vfhRlr2EDAA/Eq1bP1Mmtb1kf5C9NhIAP8PCWz8Oq7G9XhWJvYkfAD9c2Vs/F76xvVD4iL30LQA/ANFbP+dPsL2qCYa98SoAP5feWz/p4K69DRqDvXcmAD/c7Fs/K06uvZVkgb1OQAA/rONbP17bq71XOHi960EAP572Wz9wMKy9ujJ6vfszAD90+1s/enuuvff4g72ulv8+CSFcP8detL3bLJa9YeP8PtamXD+DG9a9zNTtvcxm8T75L14/ieP4vfmwLr69ddo+fDthP94IAr5kDEu+pd7LPjz2Yj89wAK+PMVKvs6XzT4MkGI/FNACvndjSL6Xvs8+tTNiPzywAr66bkS+qunSPpawYT9KLAK+KGU9vr8k2D522GA/l/oAvuxRM76f3N4+OsNfP/zK/b1yfye+5//lPtaZXj/fBfi9Pfkavq6l7D5lhl0/7zDxvVDdDr7uLPI+/qdcP4Bg6r2amAS+nTr2PpgMXD+MK+W9z+z6vZqw+D5GtFs/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz9cuua9lZT+vdRC+D74u1s/Bx3uvYYdCb5XFvU+ziFcP6mz9L1F3BK+KGzxPl6jXD8lafe9/UQXvgaa7z6c5lw/SOf2vcyCFL6+2vE+kmlcPylb9L1qhw2+IZH2PrZvWz+K5+69oiAEvkIc+z5gm1o/UInnvfQg9L3iTv4+AyxaP7vd3706VuK9Afr/PuEbWj+zkti9zfjUvZP//z57bVo/qLXSvTzyzL2nv/4+cgBbP9ZB0L3STsq9e9z9PoZVWz9wWdO9kSPRvYta/T6gVVs/VfzZvScT4L37A/w+TmNbP+hY4L2w4+69gGD6PjKDWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/OSLjvfyV9b3aiPk+j5dbPzki4738lfW92oj5Po+XWz85IuO9/JX1vdqI+T6Pl1s/V7fmvZJZ873g8/0+dE1aPwNO77272e29IEQEP5QWVz9OlPm9jBbnvfuKCj8CCFM/AkkBvseI4b0e2w8/jF5PP5UQBL6d59+9w6wSP2xNTT8n+AS+ttzjvQWZEj/DQE0/t/kEvhSy7L2upBA/wHpOP0/UBL63hPe9LQ0OP4oUUD8WfgS+Q+QAviFUCz+9u1E/QPoDvjmyBL4lAgk/FiFTP89zA756xQa+Hn0HP9cLVD9DLwO+D/cGvp0gBz+FR1Q/he8CvpsXBb4Hygc/ufBTP0FrAr7QsQG+Fu8IP8NaUz+SzwG+8Y/6vdJ5Cj/CiVI/PE0BvrW08L20Vgw/WYBRP3YbAb761ua913UOPyQ/UD8heAG+ewvevQfKED9GxU4/qKQCvrqG171aRRM/kxJNP5TdBL4os9S9WdMVP4krSz+h8ge+mQHVvcV0GD/hEUk/BFoLvqgA173uBRs/sOpGP3i1Dr4+Cdu9OTMdPzf7RD/asRG+S3bhve63Hj8ggkM/vA8Uvi+b6r1oXx8/+LFCP/22Fb6miva9nyIfP3WUQj9f8Ra+ARUCvpFFHj+J8kI/SQYYvoi+CL5WUR0/s2FDP6PBGL7fwg6+HFQcP8/eQz8SVBm+SPwSvhK0Gz8WJUQ/BJAZvv2KFL4Nfhs/OzpEPwSQGb79ihS+DX4bPzs6RD8EkBm+/YoUvg1+Gz87OkQ/CNizvAEJ9ryhLeA+nPVlP3PHs7xMAPa8ey7gPm31ZT/9UrO8SMP1vNgz4D5F9GU/bBayvMgd9bzmQeA+QfFlPzoRkLzDtOO8LC3hPjDCZT+UhVO8AWDQvKep4T50rWU/idXXu6ZTtrwJtuE+crRlP8CeMLr9d52858XhPra2ZT8qL7U7yimDvJFz4T70zWU/3DsIPOjebrybGOE+buRlPzXMJjz9Hl+8gMvgPgX3ZT/TOk08UPFKvFyV4D54A2Y/IlZNPLKUSrzB0eA+u/RlPzi7XDx5mEK8TZ7gPtcAZj89JGw8EJY6vKNn4D6jDWY/kiV0PCHONbyQw+A+6vZlPwSxhzwLSCe8mJXgPuwAZj/6XoU8hg8qvLdi4D6MDWY/UZlqPPFIPbyd8d4+cWhmP/ifFjzfdG+8AZjaPg90Zz9M+Im8XlDsvNz5zj5r/mk/s95IvXQmP73BGr0+TURtP9jWg7136GS9VaazPnW6bj+7kIS9arVkvR9xtj5eMW4/mouCvRyTYb3kvbg+RsdtP73Tfb1/Vly9Dum7Pvc0bT/hVHC9IwdTvcgAwT5RRWw/Eu5bveidRb2dh8c+/AhrPzjHQr218zW9OmnOPn+uaT9b7ya9VWQlvRO11D4WZmg/7NEKvSJmFb2TyNk+5VVnP5Y75Lxb5Qe9nGHdPtaQZj/5H8G8Cw39vNd63z6CHGY/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT92QMq8AvoAvbPg3j6NPmY/z2z6vL38Db3amts+DPRmP3J6FL3l6Bq9fMvXPnHDZz+5xR69TcUgvVXl1T40KWg/sOYZvdwLHb0hoNk+zVBnPz9hDL2wlhO9ebjhPittZT8yEvC888gGvUPd6T5ldGM/KhrAvLc18rzu7u4+bzViP3lokbzxntq8D0rvPhIsYj86plS8J33JvBQA7D4zEmM/fW0fvLFtv7xDauc+VURkPzPPC7yoJry8KQjlPnDfZD9X3y68oljFvMF15D6TAGU/9CZ7vMpc2bzT9OI+OldlPy4No7y3H+28zh7hPifAZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/CNizvAEJ9ryhLeA+nPVlPwjYs7wBCfa8oS3gPpz1ZT8I2LO8AQn2vKEt4D6c9WU/AKa0vAsR9LypweM+hBRlP8gxtrz0Zu+8ytXrPu4HYz9F8ba8lTjqvFzG8z7o7WA/0E+2vGE757xyQvc+3fpfP+JQtrxY3ui865j0Pja1YD//cby8KrjvvEKb7z5ICWI/GazLvI7r+rx0l+s+cBBjPwAw37weAwS909jnPlf+Yz+FwfG8SwUKveZx5D5y0WQ/Qjj/vF9PDr050uE+oHFlP6YdA71dhRC9J1LgPmLMZT9ZWgO9qJYQvTlP4D7szGU/Onj/vA0rDr1p2eE+4G9lP/bw8byayQm9ClfkPj/YZD+vceC8LCAEvXaN5z4aEWQ/flLNvDa1+7y3Qus+zyVjPyQGu7xlU++8XjvvPhEjYj/BKay8KZrkvM4w8z7uGWE/Wo6jvC9D3bydvfY+myVgP901pLwIcdu8OUX5PoRyXz/FGay8VqPevBhN+j5zJl8/sUi2vLn85LwS9/g+ZoJfPyBcwbwMEe+8D/3zPqLbYD8Ve8y8aCv9vBX16j6tOWM/N7zXvNWPB72CYN4+sVZmP/6847ykMxK90krPPhrLaT+yufC8AzwdveYhwD7392w/qeP9vFFnJ70EqbI+ioxvP2hdBb3GCjC9iuGoPkZHcT+SKQq99/g1vRjJoj7AS3I/Ev4LvVIjOL3Xp6A+/KNyPxL+C71SIzi916egPvyjcj8S/gu9UiM4vdenoD78o3I/9kFlPiPP8rldET6/FaIhPw1FZT7Bn++5SxE+v+WhIT9RWmU+RMDZuU4QPr8soSE/ypNlPq3Gnrk3DT6/tJ8hPxdhaz6NCSQ7PEo9v5H+IT8/rnE+JXyuOwkgPL/fwyI/ei96PuA9DDxwSjq/wA4kP7hOgT4iBDc84tY4v7jeJD/k5YU+O19ZPENIN78driU/+fWHPtIzZjzhgja/RRsmP+tXiT7Kl208Wfg1v71pJj9KHos+pP53PCh1Nb+omSY/JyeLPnGbejyrpjW/k2EmP+LZiz65T308/1s1v0qNJj9ejYw+Y7l/PAUQNb/tuSY/mPeMPvQZgzwyTDW/ZGEmPyE7jj6UIoY8IfQ0v9F7Jj9i/o0+3VKEPHTSNL+zrSY/2VCMPrgFbzwo4DO/ww8oP/iThz5PoSg8KBUxv6P5Kz+aXGA+HeO2u31vLr8axjI/xQsgPqn3s7wJGy+/jlI2P8F6+T03N7W8TxEzvxEvND+4lgA+3Su3vCSDNb8ljDE/ZD4FPkPkuLyqcja/Rl4wP7oaDD4Ob7q8ZW03v2cDLz/2nBc+zHm6vBbEOL93/iw/hAImPndRr7z4Zzq/fmYqP7qFNT52yJe8CvY7v020Jz9fmUQ+2yRuvJUmPb8xUCU/MrFRPtxuH7zE3z2/z30jP/n4Wz4ZXKa75iI+vytaIj8oxWI+EUHhujYePr/0yiE/9kFlPiPP8rldET6/FaIhP3mVbT4urNw7NN9LvzL5Dj+tJW8+tdfpO3tmSb8uRhI/A2ByPhO4+TsncUO/8NMZPztudT5gyO87Osg8vxGlIT8tzXY+D9DgO4uIOb+9PCU/i311PjHY0jvp9Tm/O+EkPybacT44tKc7yxA7v2T3Iz8eU2w+MIo4O7aKPL9TxyI/9kFlPiPP8rldET6/FaIhP38RXT6Neo+7zFk/v5nTID9N+VQ+FUADvPE0QL+ZeiA//KdOPghNLLw0pUC/uHUgP04ZTD5BQzu87cVAv72BID93ylE+fTsTvBLDQr+uoR0/kbBdPt65RLvt0ka/lG8XP73HaD7Cwmw7MWlKvxWHET95lW0+LqzcOzTfS78y+Q4/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/9kFlPiPP8rldET6/FaIhP/ZBZT4jz/K5XRE+vxWiIT/2QWU+I8/yuV0RPr8VoiE/MuZkPirSObpNsT2/3xoiP1bmYz5ASbW6kKo8v6diIz/fVWI+h6YduyYfO78lSSU/eEZgPsUIcrszLzm/AqAnP53SXT71eai7dvw2v244Kj9xJVs+SdzYu32sNL8P4iw/739YPhGKAryRaTK/7WovP+o7Vj4m4RO84WIwv5KfMT9XzFQ+peMdvFHMLr+OSjM/tLZUPnMiHrzE4S2/pi80P1rXVT42GRi85nstv798ND8Tg1c+5LwQvIpALb9WljQ/U5BZPlAbCbwpIC2/Zo40P6PXWz6kfwK83Qwtvwl1ND9FN14+u9/8u7b8LL8uVjQ/nIhgPrcs/LuP6Cy/lTs0Px3ZYj5qdQK8nqksv1pJND9Sk2U+BH0MvEtCLL92dDQ/DgBpPo03HLys6Su/7oE0P8ZIbT7a6C+8qN4rv+4xND/T/XE+3rVGvI8ELL/qpzM/jxV3PpQTXbytkiy/Za4yP1NnfD5FpG68z7UtvyIaMT9x+IA+U/B1vEW0L7/UnS4/2ziDPmPserzdizG/IVEsP3IVhT4uH3y84FQzv7sYKj8XZYY+tsV3vEQONb9DACg/t3OHPnqzb7z/yTa/zOYlP2stiD6NW2q8iAQ4v8ljJD8pmog+/4VmvG/NOL94ayM//76IPqYLZbwnFTm/pBIjP/++iD6mC2W8JxU5v6QSIz//vog+pgtlvCcVOb+kEiM/zNzUvTmK27zlVvQ+k0hfP6Td1L1+adu86Vb0PpdIXz/g49S9IoTavINX9D6NSF8/BPXUvToV2LyHWfQ+VkhfPyn71r2FBJa8Zun0PrYmXz/cQ9m9CY8ZvGul9T54814/ETrcveKhJjuwjfY+xqpeP92j3r01QV48dM72PoiIXj9Q4uC9NazMPIfN9j4pb14//czhvWU39jz2x/Y+dmJeP3xq4r3V7wg9+cD2PtBZXj+SIuO90DcaPUKG9j7bW14/vBTjvUY9Gj38V/Y+32heP4Fl471oIyE97FH2Pl5kXj9ttuO9EggoPSJL9j7bX14/YMbjvU2HKz0T6/U+gXdePzFL5L2pmzc97q71Pll8Xj+AQOS9XJk1PW7m9T7Wbl4/bwDkvWWNJz1wZfc+ohBeP3Wz4716nAE9lUL7Pg0VXT8UPN69NbyavG6TAD/ckFs/Pe/PvQYNs71lBfw+BS9cPyCswr0Q5Pu9L0DyPlj+XT/Tn8C9xI77vcaM8D46fV4/ttrAvdTC9b0Wi/A+ypZeP9eswb1KBuy9GejwPvCkXj95PsO9MY3avWiw8T6IsF4/ZQ/GvSD/wb08gPI+EsleP/Ysyb3Z6qS9PjXzPkPqXj+LaMy9HA+GvdW78z6EDF8//qnPvYK9UL3NEfQ+cyhfP9FX0r0RHB69nj70PsQ7Xz/iLdS9WNj1vMxR9D63RV8/zNzUvTmK27zlVvQ+k0hfP13Yyb3kn+W8aA3jPl/yYz/iRs29FdbCvGPC5j53/2I/3D/UvVTobLx9q+4+A+VgP4R/2r1IS6u7NCX2PrDNXj+MIt29jWKNumxe+T5Z3l0/DoLcvf96RLu98/g+ff5dP+PG2r3Hugi8Btf3PqFSXj/VJ9i9yx2HvPs79j5Qx14/zNzUvTmK27zlVvQ+k0hfP4Qy0b3CCB29/l7yPl7DXz8yu829KlhJvaaV8D4HKGA/FSLLvesEar37Re8+kWtgP80byr0PwHa9RsPuPmuEYD+YCsq93gxjvW9B7T6T/2A/7NTJvWVvNr3Afuk+9CNiP7DDyb34PQi9RS3lPpteYz9d2Mm95J/lvGgN4z5f8mM/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/zNzUvTmK27zlVvQ+k0hfP8zc1L05itu85Vb0PpNIXz/M3NS9OYrbvOVW9D6TSF8/ljXVvYOT3Lyp8fQ+lhxfP2Mr1r0rkN+84Z72PtOhXj8rnte9TYfkvK0p+T6B5V0/Y2/ZvTx367zsXvw+D/RcPy6F271ICvS81AcAPwzZWz+IzN297Wf9vKEJAj/Nnlo/eDrgvdYRA72TJAQ/I05ZP6jL4r1aIga9i0wGPxzuVz+6geW9z7EGvdR4CD9VhFY/hGzovSNzA73epAo//RNVP5t+671wF/q8294MPyWTUz9dve69b5jqvFZBDz987VE/hjbyvTJc2bzR1hE/shhQP4v89b2dese8Sa8UP04FTj9HJvq9Qiu2vMjhFz+anEs/2sX+vVO/prwLiBs/lsJIP5D1Ab4I6pe8xqwfPzBjRT9P2gS+gXWHvJVrJD9wV0E/6xMIvj4Ha7zl1Sk/a3g8P8WNC754KUS8iNgvPw65Nj9KLg++ZV8cvD4nNj+GQzA/eOQSvlCX6ruxkjw/5S8pPz2XFr4wNaG7FeFCPxOtIT9XHBq+X9A3u83kSD+37Bk/H2odviBskLqMVk4/6FMSPxduIL6QVVI5JTRTP3H/Cj/1FiO+XrSJOntKVz80YAQ/Kjclvjsz3jqHd1o/lcn9PpfEJr7lDhE7ssNcP1Fx9T6zuSe+GX0lO5opXj8lLfA+vw0ovvNVLDtxo14/UFnuPr8NKL7zVSw7caNeP1BZ7j6/DSi+81UsO3GjXj9QWe4+TuO7vKSb/rwCogk/xaBXP9HUu7w0gf68MaIJP7KgVz8Sb7u8b8j9vE+jCT9GoFc/fFq6vDbT+7w1pgk/O59XP0GnnLySMse8pMYJPy+eVz+CuXa8JjmNvE+1CT8Yulc/Z6odvGYWALz9WQk/qQJYPzFLmLtuGIQ66eoIPzhOWD9apPk5CcQmPBxECD9OtFg/i0w1O3kUaTwr5Ac/auxYP39/jDt8rIo87ZwHP08VWT8ZR8o7fb+mPD5LBz+QQlk/EQnKO9wepzyWWgc/7zhZP5bC4juoOrI8NzEHPxtQWT81avs7Kli9PG4GBz/tZ1k/wKQDPJuwwzzWDgc/FWFZPxgCGTzQmNc8Ts4GP4uDWT/dmxU8Te7TPG7KBj/+hlk/sq77O0twujzapwY/LaNZP1TPdzvci208mwgGP/MSWj+QBpS8n0HcvOhaBD8z+Vo/m8Y6vSCsqL22KPw+Nn5dP4OSbL0sZ+W9LtryPoMMXz/o5W29eQrlvYfS9D6Wgl4/GwlrvUb8372HsvY+khVeP8G0Zb35jde971T5PgmAXT8daVu9oZbIvSWL/T43kFw/uMdLvTRTs72eXwE/7GRbP65xN71ak5q9tv0DPzkyWj+XQCC9bKeAvVI9Bj/8J1k/eHkIvWrtT71z5wc/umNYP9ol5rwifCa9IvMIPyHrVz9pfse8rO8JvSx6CT8HsVc/TuO7vKSb/rwCogk/xaBXPwJRw7zkv/a8xaoMP9epVT/lhrS8Y8XcvLeYDD8UwFU/6YuSvLRnpby3Agw/ajVWP8rXXrxeZWC8EtQKP+UHVz/sqj68USkxvHIYCj9ChVc/kn9MvF7MSbwnHAo/vIBXP2kZc7zBQ4e81hsKP7l5Vz9h85a8jMm7vBz9CT/rflc/TuO7vKSb/rwCogk/xaBXP6mJ5LwfEyW9t/YIP1zqVz8exQS9xuxIvZ4SCD+EUVg/GfMRvf2yY73/Pwc/gbJYP4H1Fr2qOG69H+QGPwLdWD9kuw+9y+9cvYEbCD9lMVg/roL8vKYcNr23Ygo/T+1WP+zZ1byNCA696hYMP+b6VT8CUcO85L/2vMWqDD/XqVU/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/TuO7vKSb/rwCogk/xaBXP07ju7ykm/68AqIJP8WgVz9O47u8pJv+vAKiCT/FoFc/25u8vGXM/7xapAk/wZ5XPxa2vrxylAG9Rq8JP1GWVz+LKMK8z0gEvR3FCT/zhVc/3OHGvAjyB71G5wk/vmxXP2ywzLwLXQy9zhkKPypIVz9rNtO8NiERvd5lCj+PElc/zOnZvKeXFb0I2wo/QMJWP5Ye4Lzo3Bi9h48LPzhJVj9BF+W8YNsZvX+fDD8YlVU/xyPovBZUF72mKg4/3I9UP87K6byd8xG9ZyEQP40/Uz9rL+u8cnILvZ9UEj/+vlE/bansvKU4BL0KuBQ/ghNQP9Sg7rxoifm8VD0XP2tETj+CifG8h1/rvNHTGT+QW0w/hdH1vHBo37wQahw/iWRKP2XJ+ryQ19S88+weP5xuSD9HYP+8w17KvJs7IT/zlUY/sbwBvQifwLyKNyM/avZEPwdaA717ILi8hs0kPy2kQz8TlAS9YOmwvAz5JT8sp0I/rnQFvc5Dq7yIsiY/FglCP+7/Bb2Xgqe8df8mP1fHQT/Z7gW9HEGmvCngJj+b4kE/GpkFvdLLp7zlWCY/nVZCP4QQBb3Ba6y8+00lPzQ5Qz95cwS93d+yvB8vJD+qKUQ/u/UDvVlPuLxwUyM/y99EP6pVA73fvLy8j40iP66CRT816wK9kJ+/vOMOIj8+6kU/QMcCvRuiwLyR4yE/hw1GP0DHAr0bosC8keMhP4cNRj9AxwK9G6LAvJHjIT+HDUY/ruEkvaczqrvKOr8+Ez9tP5nYJL0DFaq7Iju/Pgg/bT/MmCS9iT+pu/k8vz7YPm0/VesjvZH8prt5Qb8+bj5tP7RXEb1YHlW7PS+/PsFObT8APPm8sUShutaYvj4YeW0/RNLBvFLRvjqKQb0+lcptP8G8jrwdoII7wgm8Pu4Qbj8l5jO8m+bYO4Rtuj5jZ24/9AgFvPrR/juihbk+7ZVuP9GMy7spFAw8ddy4PkS3bj890Xq72UEcPH0uuD4X2W4/etB6u82PHDzkY7g+xs5uP880PLu07yI8xgO4PkThbj8dP/u6rFEpPOOgtz4r9G4/uxW8ut0mLTxF2Lc+aOluP+r1fDnFsjg8bla3PuABbz/acRy4jno2PJY4tz60B28/HSYBu9sSJzylWbY+4TJvP3BY57uix/w7UICzPpe8bz8m7Ay9ubKNu0nyrT7/m3A/xYyQvYHhqLwOTKM+LeZxP5xetr1s2vK8hHqdPvxmcj98Y7e9M0jyvD1ToD6B7HE/tvS0vfTo67xBXKI+f55xP/iPsL3mWOG80RClPp04cT/Pbqi9K7/OvE9PqT6Ql3A/XVWcvZtptLykla4+7MtvP0WVjb0dNJa8vuyzPsj4bj8DA3u9V/NtvNiBuD44QW4/mytbvdA1M7yf2bs+h7xtP7aQP73tmwK8oeu9PgZtbT+MKyy9yNTCuyDwvj6iSG0/ruEkvaczqrvKOr8+Ez9tP7uMLL0yPpq7g0zNPoZEaj9P+yG9oSd5u2mHyz4Xr2o/BcsKvc0M+7qiwsY+R8NrP56o57yE2hi5PdXAPvgJbT+T/tK8yUglOr3GvT5xrG0/A+PbvO1TUTnMAr4+cJ5tP9Kk9LwWcoO6Ro2+PqB8bT89Jw29Alk6u5ETvz7xVm0/ruEkvaczqrvKOr8+Ez9tPz5GP7148wC8Zry+PndDbT8GzFe9Bv0qvJqpvT7UY20/uLZpvey1SrwKgLw+i4xtP8WmcL2NQ1e8Q/a7PjegbT/P9Wa9DCNCvLg6vz7sA20/GmRQvUs2E7y3usU+xsRrPz8eOL2Poca7fjDLPs2waj+7jCy9Mj6au4NMzT6GRGo/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/ruEkvaczqrvKOr8+Ez9tP67hJL2nM6q7yjq/PhM/bT+u4SS9pzOqu8o6vz4TP20/tRglvYCUq7tR/74+4kptP428Jb2mb6+7G2S+PpJpbT9W1ya9lpi1u0CEvT58lW0/Qm8ovS3ivbvxd7w+mMltPzB0Kr2zzse7ZFu7PjkAbj/qtCy9U17Su1ZTuj5CMm4/6tsuvez327sUj7k+2VZuP7VyML0faeK7zEi5Pj9jbj/H6jC98v3iu1HEuT7aSm4/WqAvvfWD2rugR7s+GABuP3DxLL31rcq7V6C9PkCLbT/wtim9yNK3uwtPwD6nA20/NiAmva3porvQLMM+TnBsP6RjIr2CH427bQXGPnrbaz+OvR69M81vu92RyD4rVGs/mXAbvX5XSrsFe8o+s+1qPwgRGL2DISi7u4HLPj23aj/k7BO9ZjQGu2wqyz7gzGo/bPMOvYN3zLp39Mg+pklrPxYuCb07Y5W6bKfEPj41bD+2yAK92H9NurqSvj4Jd20/yu33vJIuA7rZ6bY++/puP7wU6rzaQqC5fRmuPlyicD/KLt28eQWEuSzlpD7xQnI/wbHRvIuyq7mynJs+Pc1zPxp+yLyWWAq6+bCSPh8wdT8p8cC8Kz9Uuopnij40ZXY/Pta6vL8wibpXvYM+w093PyOytrzEa6O6wxt+Pjftdz9WLbS8G4S0ujJUeD5MS3g/c1CzvDl3urpWV3Y+H2t4P3NQs7w5d7q6Vld2Ph9reD9zULO8OXe6ulZXdj4fa3g//TbZvuFQCTqNsSW/OCEiP6Y12b4R5Qo69LElv0IhIj8HLNm+CZYWOki0Jb8YIiI/uxHZvnvhNjo1uiW/1yQiP3kR1r7NBJU7kPAlvxPrIj8YjNK+1NETPFfiJb/7GiQ/c5fNvuMzczy0lSW/yPAlP6T2yL6MQp48o5Ylv4FRJz8+68O+ERm/PEaaJb+mwig/npXBvsoRzTzqjCW/sXcpPyIAwL4IIdY8Wn4lv0D2KT+MG76+dp7fPJuSJb+CZyo/ODq+voIi3jwTvyW/LDQqP8xpvb4GceI8T7Mlv0V4Kj+7l7y+tKvmPIemJb9zvSo/TWy8vm3i5Tzy9yW/lXoqPzUXu74xq+s8ygkmvxTFKj+uMLu+FB/sPPPbJb966io/tt+7vt5s7zwnlCS/X/UrP8Wjvb4XGfo8xdwgvyLzLj/er86+l/+1PK6rF7+MYTI/brPpvlfhujuctQ6/f4UxP+SA+76uZk67MWINv2duLD+u6Pu+TJT9u3UOEL+BCyo/3776viVnGrxKfxG/nD0pPyG1+L666zS8QEUTv09zKD9kEvW+Fi5TvD/9Fb8oXyc/AH/wvu+VY7z7ZRm/Ce4lP1Je677oElq83uwcv3Z3JD/FFua+zSc4vOsZIL94RyM/2zPhvo2o/7tZoCK/hX8iP6sh3b63B3y7gV4kv7omIj8JStq+Y2k5uoFdJb+qGiI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/Wztq+mMeGugLSJL/UeyI/wULevqJehLsIqyK/l3kjPxC34b6jcc67rzIgv7e4JD9FT+O+dBjmu/r4Hr9/WyU/54/jvnHlJrwxACK/3UoiP02X476i/IS8dZoov69gGz9OeOK+HvqlvOc4L783RRQ/3KPfvuNNm7ytFTO/mLIQPw/y2r4tlTu8Vb8yv6DxEj98TdW+YfKhuiqPL7+Gxhg/20nQvofZ9zs5tyu/sb4eP44Xzr5+1Tg8utMpv6p0IT8a+c++pyEePMVVKb9cYCE/IOfTvlGHwTuhDyi/JHEhP2mY175rUQ07jYAmvzPXIT/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI//TbZvuFQCTqNsSW/OCEiP/022b7hUAk6jbElvzghIj/9Ntm+4VAJOo2xJb84ISI/963YvpC9yDpGRiW/K7wiP9w9175aboo7LBokvwtjJD+tItW+J/0EPJxFIr+Z3CY/rpbSvn9sUDz24B+/5u4pP//Wz77uxI885Q0dv8BZLT/SJs2+ule1PIf7Gb9h1jA/S9HKvut81Txf5Ra/IBs0P64dyb4qnOw8cxYUv1bdNj+Wesi+k4r6PDHDEb/m4Dg/KNrIvo+U/zxLMRC/iP85P5nzyb4cvv48bzEPvyR5Oj94iMu+uWT8PHRfDr+lrDo/MXLNvh16+Dzn5w2/24I6P7Fdz75wNfI8APcNvzvxOT9h4dC+vuHmPILZDr8N2jg/1Y3Rvmbu0zwd2hC/8B03P3WG0r4cHK88Aa0UvwnIMz+0ktS+oAJ2PAnCGb8x4S4/b8TWvqzeDzxzmB6/M9gpP5Rt2L4fwoU7eTYiv8rdJT9qZNm+Uu+QOnGNJL+AOiM/ae3ZvuFAW7r3QSa/oU8hP7w12r5FIx67BuYnv0GBHz+eF9q+OPFdu9JIKb+bEh4/FvbYviFLD7uWRim/03gePwDU1b40J9g6bf0mv7LsIT9jANC+phzPO3QQI789tic/X8XIvgO/+jsMfSC/CVUsPwKTwr5mo5A7Fi8hv7l2LT83ob6+W5Zzua9uI7+jdCw/Cv68vu6KObuJ4SS/8oUrPwr+vL7uijm7ieEkv/KFKz8K/ry+7oo5u4nhJL/yhSs/YZgWPiF97DzlKPI+7UReP/OXFj77new8tSjyPvZEXj80lRY+QYPtPO8n8j4NRV4/840WPiXx7zwzJvI+LkVeP5/5FT6Vcxg9Wk7yPpksXj9HaBU+wek7Pa6T8j6gBF4/iaAUPt+Daj381/I++s1dPxeVEz5Xtoo9SoLyPg+/XT/dbxI+IbWgPQPh8T7Yu10/yPMRPiFfqj3KkPE+9rldP/KdET4kxrA9RljxPtS4XT9SEhE+YtG4PfHj8D7ww10/mfUQPpLnuD2nufA+T9BdP7fHED4UE7w9QpvwPsLPXT8hmRA+cTy/PTh88D5Cz10/L0cQPnz9wD10GPA+iOddP2XVDz5WlsY9x7bvPsvyXT9CBRA+VZXFPSDw7z7y5F0/nEwRPuWKvj2bfvE+FYRdPyB/FD6GVqs9Ypz1Pqd+XD+Zfxw+MawJPe9q/j4JhFo/xnAgPmITF71uBf4+9GpaPzGyHz5dM5i9Dm72PvP+Wz/LQB8+XN2WvUhp9D6wl1w/YQ4fPqkxkL1dHPQ+FcFcP0rTHj75PIW9wg30Pk/jXD9fbB4+XJVjvVcf9D6MDl0/fF4dPm+kLb3NG/Q+fkxdP0gYHD5GNd28tefzPryRXT8ioBo+PVYzvNiM8z490l0/0iIZPiBiijuLG/M+rwVePx7YFz4Ztoo8c6byPrkpXj+07xY+DQvSPD5M8j48Pl4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj/JdRc+BcnAPBv88j5sDF4/kVMZProcQDylw/Q+bopdPwojGz43JBu5G3z2PjcBXT+I8Bs+iRK2uww+9z7QwFw/LF8aPqNNILuGZfQ+xJ1dP895Fj59tr47qJPtPt+fXz/hlhE+m36PPNnX5T72y2E/EbUNPu3C+jxtIOE+TQtjPwHQDD7JQzA9YS3iPoCvYj8xJg4+Qd1ZPeB/5j5qZmE/2PcPPnZDdT2hx+o+HRxgP83TED6hEX89g6XsPniKXz8ewhE+xRtqPaSJ7T42W18/lsMTPtJnOz3edO8+9u5eP4a4FT4c/gs9SVPxPs17Xj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/YZgWPiF97DzlKPI+7UReP2GYFj4hfew85SjyPu1EXj9hmBY+IX3sPOUo8j7tRF4/Qt8WPmu48jyP0/I+rBFePx2tFz4mTAE9B7X0Ph2AXT+9+Bg+684LPaCf9z6Vm1w/oLcaPsKuFj2gZvs+uG5bP8fdHD5t8x89t+D/PmMDWj+DYB8+AAAmPTl2Aj9oYVg/4zoiPtyVJz0SOwU/W4xWP1GRJT4KzCM9mUMIPz98VD/UMik+SisaPZyLCz9YMVI/jd0sPp5sDT2x6w4/XcJPPy+IMD7Dlv08A1YSP9Y1TT8DLjQ+6nzcPHjCFT/6j0o/sZI3PiAqvDzJ/Bg/pvlHP/pFOj5wcKI8u5wbP9nNRT8+6Ts+xF+WPPo3HT8NcUQ/EBM8Pitqnzy9XB0/Uk9EPyf7OD5bKbQ8blkaPwPaRj93mzI+lerEPIEzFD/F0Es/HGorPoeR0Dw4QQ0/Mg5RP6UqJT7mRNg8jjEHP3tTVT9CoSA+qb3ePJvOAj86QFg/kGcePtE15zxutQA/hJlZP7vdHj5bBfU8WFEBP9IzWT837CE+ADQEPR+PBD8iE1c/S70nPuXnDz11kgo/1e9SP8IZMj62Thw93osUP0xzSz+oPkI+AWEpPa3dIj/RJz8/naxVPnarOD3RBzM/gqIuP9wAZz4b00k9F/dAP+1/HT+PbHI+81lZPTQJSj/wbRA/bKV2PlQAYT3xPk0/F1ILP2yldj5UAGE98T5NPxdSCz9spXY+VABhPfE+TT8XUgs/yQ6rPWfgLj1FoQQ/tKRZPyQSqz187S49EKEEP7+kWT9qKas9CEkvPXifBD8npVk/VmirPYFBMD39mgQ/U6ZZP7XAsT3aako9dvUDP8jfWT8SW7g9pihnPQUMAz8OOlo/z4LAPcqahj12lgE/I9FaP9Cdxz0POZg98SYAP75hWz/zZ849JlSqPUb5/D6GClw/HzzRPb1Gsj1aV/s+Ul5cP5QK0z2Skbc9DjT6PuSYXD+wUNU9YTu+PZjW+D5X3Fw/J2zVPS1Jvj0V8/g+t9NcP6FC1j2O7sA9bVf4PhjzXD+5FNc9s5PDPVq59z70El0/27LXPSkExT2Aofc+HhJdP3kv2T3itck9f6D2PixDXT8319g9TuHIPemv9j4+Q10/v1zWPSQawz3yDfc+WkddP5gXzz1surM9xJD3PpByXT+hSKg9VXlFPcul/T42CV0/0xZXPcZW+bsVI/4+fdJdPzxUFz2P9R+9inX7PqaSXj+8QRo9WVUgvapm/T49A14/n8QgPXEZFr0QwP4+36JdP+AXKz38yAS9oT8APxwlXT+4JT09u63LvB+NAT8bZFw/ZuBVPTJhaLycAgM/IIBbP2m5cj0NxvK65EAEP2eqWj+3Eog9Y0A0PKgHBT9yClo/tLKVPVxFvTxWRQU/ILFZP+jgoD3U/wc90BkFP+2VWT+QV6g9lFkkPYzJBD/TnFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT9Zr6Y916IdPXfvBD++j1k/ZsGcPaso7zyMZAU/131ZP0OEkj24p6I8I40FPyWTWT91zI09ZnZ/PC+GBT++qVk/pz+RPQMHkTydQAY/HCtZP9q7mT29WcA8lXwHP9tFWD96gaQ90XkDPbgOCD+nt1c/pV6vPdK9LT39nAc/Ir9XP8/XuD2gIlg93k0GP6dKWD+bp789Ebp7PWZYBD8BQVk/SCPDPeHXiT1eSQI/ZFVaP8IFxD3KO449z0sBP4XdWj80iMA9nbWFPcf3AT+DmVo/Bke4PZPSZT3tQAM/7RtaPxlTrz00FUA9tEMEP4zBWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/yQ6rPWfgLj1FoQQ/tKRZP8kOqz1n4C49RaEEP7SkWT/JDqs9Z+AuPUWhBD+0pFk/FLCrPZOYMT0DiwQ/E65ZP+FUrT3Yjjg9AVcEP7bCWT8wjq89+eFBPfIVBD/62lk/Ae2xPRO/Sz1J2AM/oe9ZPxIYtD3fhlQ9RLQDP+f1WT9P2rU96d5aPQfJAz863Vk/ICe3PTivXT3qPgQ/iY5ZP1AbuD2k0ls9TUIFP7PuWD9/5rg9hyZVPTL9Bj8r4Fc/oAq6PZfZSz0LZAk/AWBWP3xguz0L6UA9TCkMP3KYVD93Xbw9Em80PXTlDj/ay1I/xze9PRIuKD2faRE/qBhRP0BNvj33TB49y6ITPx6MTz+XEsA9fk0ZPZCCFT/EME4/4P3CPQjlGz0w9xY/lhNNP/NTxT3hfCE9m5sXP9qMTD8G58Q9KWIkPUrkFj+QE00/ytTBPU3pJT2KsxQ/97VOP75bvT2cIic9TqoRP/LrUD82pbk9abcoPeUJDz9+xlI/zf24PehcKz3lKA4/ql5TP8hrvT1n6i89/i4QPwXrUT8WYcY9Vbo2PW29FD9oj04/iSjSPVMaQD1IwBo/NeBJP0gf3j12p0w9lK4gP/nuRD9gPOc9qeFdPYLGJD/ER0E/+r7rPWw2dT0+8CU/HxZAP7OF7D12Cog9HNAkP7/lQD/Gj+w9LDKTPQA5Iz/2HUI/8kjsPXwUmD3vaSI/rb1CP/JI7D18FJg972kiP629Qj/ySOw9fBSYPe9pIj+tvUI/D0hMPaPERTwQRc4+8O9pP9tQTD2d1EU8w0TOPvjvaT/djUw9N0VGPB5Czj5S8Gk/9TJNPdl2Rzx7Os4+YPFpPysDXj3ismc8kuLMPrEraj8o5289dJmFPOXqyj5ChWo/0mmDPVM0nTx+ysc+qRRrP9DmjT1bNLM8bPXEPiqRaz8VXZg92+jJPMC5wT7bHWw/SNWcPUvi0zyTH8A+uGNsP9TDnz2Mi9o8TgG/PlOUbD9HhaM9DfXiPLS/vT7AyGw/cKqjPTIH4zzM8b0+Sr5sP1cYpT1VYOY8d1i9PjbYbD+vg6Y9WbrpPLm8vD5/8mw/5YOnPb6P6zzf0Lw+NetsP10eqj00iPE89ui7Pl4QbT8fjKk9WnjwPE7fuz4wFG0/LoilPTAb6TyBjbs+jjFtP9+Bmj01utU8DjG6PmuYbT+oHEk9kh5jPO8dvD5tvG0/ws04PM1tXLuijrs+lC9uP4fOFbycCFu8RBe7PrBCbj/k5Qy832JcvEYXvj7Iqm0/L0Pau+mOT7wOxr8++VVtP++5ZrvVsjm879bBPrvsbD9ligM7d6QSvKnkxD5hTWw/sg4gPHePtrvPZMg+Po9rP1hNmTxJF+C6BZHLPsrYaj9dhOQ8EZAWO3/EzT5+Tmo/dScVPQ4bxjsyyc4+VABqP9/YMT2g/BU8M9zOPmLmaT87L0U9lNQ4PE1+zj4Q6mk/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT/+g0A9558wPK56zj4m72k/5CMmPcnxATyzes4+RQVqP48zCz3jx6U7PdjNPvA7aj+unP08LUx1OzRZzT5BX2o/nZQHPXdRjzsGRdA+87RpP2W8HT0A68c7eifWPvpQaD/NJDs97ZYOPKcH2z4AFmc/Bs9ZPa+ZQjy4Wtw+EqhmP/kCdD1bgnc8fzvZPvtHZz8gPoM9dgaSPAI00z75lGg/rj2IPVsMoTw96Mw+cu5pPw+0iT2qk6Y8lfLJPo+Oaj/NaYQ94PObPPLyyj49ZWo/bNJwPV+rhDzJvMw+Ih9qPwDkVz0641o8Re7NPnP3aT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/D0hMPaPERTwQRc4+8O9pPw9ITD2jxEU8EEXOPvDvaT8PSEw9o8RFPBBFzj7w72k/DLRNPe8rSTzwzM0+9AhqP75OUT225FE8mZDMPpRKaj+++1U97JldPIPFyj5gqWo/zaRaPQ4Majz1n8g+ThprPzdkXj3JPXU81V/GPi+Qaz+fmmA9XYV9PKdVxD7Q+ms/N+9gPYzDgDxU4MI+ikdsP78IXz07qX88bFnCPj1lbD/2TFs9j953PBMXwz4wQmw/20pXPSHlbDxRIcU+HdprP44JUz0f6V88M9jHPmNMaz/itk09u/dQPNVbyj5LyGo/nkVIPQknQjxYdcw+RVlqP4BURD1mJTY8Tm7OPnHuaT9YxUM9PRUwPEqv0D4Vb2k/Yp1IPepmMzxPpNM+K8BoP7XbUD0s6zk8WFTYPhukZz8QbFc9NlI8PJlR3T6Eb2Y/gBJaPdvpPDwHft8+k+ZlPzZiWT2kcD08PJvePi8eZj/XKVg9wMs+PM3N3D5MjmY/6MZZPRnDQTx1wtw+V49mP99FYT0TVEc8BMjgPpeOZT9SBG49LSZQPIQS6D70rmM/5Cx9PT4jXTxKze8+yJphP911hD1AYXA89HnyPsbUYD+xi4U9zIqGPJky6j4s/2I/j3yBPR+9mTx1P9Y+LuVnP4iZdz1hT648Z4u+Pl4LbT/IWW895729PLVJrD6IiHA/pgttPZIxxDy61qU+8KpxP6YLbT2SMcQ8utalPvCqcT+mC209kjHEPLrWpT7wqnE/Kqsfv9ZOIr3g78q+BCwsP6eqH7/cRyK9vfDKvkIsLD/Iph+/mRQivf31yr5+Liw/Apwfv3qHIb2IA8u+ADUsP1AyHr/l4hC91r7LvktZLT8CbRy/Ikr8vA0XzL6U5y4//d0Zv0+hzLxFPMy+hy0xPweZF79bgai8T+rMvkv3Mj9MHxW/p++IvPDGzb660DQ/z/YTvyYUd7zYDs6+s7E1P90rE7+dwmW8ljbOvmpMNj8yRxK/AJRTvOqkzr5Y5jY/LWYSvzVdVrwp6s6+w7k2P2j8Eb+9JU68XvfOvisLNz+IkRG/mhFGvCUDz75wXTc/d5kRv/OER7w3kc++3S43P5X5EL9mcjy8FuTPvsyWNz+79RC/tJg7vB+Uz76BsDc/stUQv7yCNbw6WM2+fWo4P4JTEL86/SK8QdnGvvmVOj/g6RS/oMKavIO+s74Gxzs/j/wdvytlI70g0Zy+gUQ5P2FmJr/kLFu9EYKVvqEVMz/Vxye/zlxvvbXzmr4mhTA/s80nv7P3dL1CNZ6+l74vP7qFJ7/x/Xi9y1OivtQMLz8D6ya/enZ7vXqiqL7bHi4/8hYmv/yveL0ZYLC+6wEtP9AUJb+zEW69Byi4vkkALD/XwiO/nh9fvZsYv76ucis/bWUiv1DgSr3XdMS+c1QrP5oWIb9pvja98B3IvgGYKz/VEiC/Qe0nvco6yr6b+ys/Kqsfv9ZOIr3g78q+BCwsP99JKL/CgWy9BB7ivvSbGz99ECa/lktUvfDu3r68PR8/Jsggv5PwH71ed9e+0UQnP4T5Gr9lkdu87nXPvm8/Lz+6Khi/XOSvvPCsy75t1DI/6SMZv8Dxv7x+lMu+EQIyP3t1G79pfuq8rzfLvooKMD8WPR6/3t8SvZRsyr7GsC0/EM8gv7rmMb3xPsm+sosrP5vSIr+JpEu9RhrIvj3cKT+dRiS/6kNevUs+x74xnig/by0lv9OUab07wca+0NEnP9B9Jb8IcW29vp3GvqeHJz88Gia/YudvvdqUy75xaCU/gz4nv0Zicb1fodW+zwUhP7AMKL+jp269qXrevnEoHT/fSSi/woFsvQQe4r70mxs/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/Kqsfv9ZOIr3g78q+BCwsPyqrH7/WTiK94O/KvgQsLD8qqx+/1k4iveDvyr4ELCw/XVwfvyM+IL0p0sm+ososP5WDHr/Zoxq95LzGvr95Lj9KOh2/OUYSvQUGwr7s+TA/rpkbvwjDB70a/ru+Qww0P46/Gb+RLve8hf+0vuRuNz/w0Be/TXbcvIV5rb5p3Do/9v0Vv3J+wLww9aW+Qgs+P6p4FL/lh6W8WxufvoC1QD98VRO/fD+PvJC5mb5xrkI/pb4SvxgLgbxPppa++btDPxeNEr9vO3K8PoWVvrEZRD/2chK/DGhlvOhUlb5gN0Q/RGMSv0djW7z7C5a+4iBEP9g1Er/rFFS8H6OXvvf0Qz9X1RG/aLVPvG8bmr7SwUM/hy0Rv00LULy4jp2+uY5DP1lHEL8321i89e2hvuBTQz9YPA+/XwVvvPwyp76M+kI/lRcOv5DCi7zrq62+E2NCP8XDDL+Qlqe8fPO0voGrQT+lTgu/jWDKvDLkvL5Cy0A/q8gJv7Se8ryvS8W+cbw/PwJECL9WLQ+9igbOvmd2Pj+uywa/goglvVLq1r7g+Tw/yyAFvz/iOL0kTd6+AvM7P2E0A7+6LUi96s/jvjGXOz9qSwG/7WRUvej3575Ilzs/T3n/vg6+Xr2DaOu+Noo7P5Am/b7+rma9HgHuvoh4Oz8gsfu+H45svSgo8L4yPzs//jD7vgGMbr1t5PC+OCs7P/4w+74BjG69beTwvjgrOz/+MPu+AYxuvW3k8L44Kzs/wSGFPsNL/z3yRc4+UF9ePzchhT5gU/89cUXOPl9fXj+6HYU+ZIj/PVNCzj6rX14/dxSFPgIMAD4yOs4+W2BeP4lMhD7oegc+1aXNPg9aXj/pf4M+a38PPjYUzT6NSV4/g2KCPi/qGT4nO8w+CTZeP0sIgT6lbSM+4/bKPiRGXj+NJn8+MxMtPrxayT7XZF4/2s59PldJMT7encg+BHNeP/LkfD6+ETQ+4h3IPrh8Xj/Kins+epA3Phlcxz4Jk14/n1p7PpabNz6TPMc+65xeP7zhej77+jg+U/vGPtmhXj+0Z3o+Mlk6PqG5xj7apl4/LMp5PiseOz5eWsY+0bxeP0LBeD58ij0+w8fFPijPXj84HHk+/xk9PlD+xT6qwl4/4JJ7PicEOj5xe8c+22peP90FgT4JkDE+7n7LPpB5XT/iK4s+K1gDPtXA1z4WCls/j0CTPglAdT0xjt8+6a5ZP60nlD71Iao8DWbdPt6NWj/qHJM+V7iwPH432z4QRls/Zo2SPiG8zTxsb9o+pIlbP0LYkT7q+/w8fJ7ZPkrPWz+dkpA+Hd4nPWN02D7cMlw/OsaOPj1XYD0N4NY+iK5cP8OljD4ggpA9kgLVPksuXT+wdYo+yVuxPXoW0z7dnF0/KWqIPj2nzz3NRNE+HvNdPwi4hj7KdOg9XrzPPi4vXj+tj4U+9ij5Pf6rzj77Ul4/wSGFPsNL/z3yRc4+UF9eP8NPdz4oowI+VTbAPge9Yj8cAXo+rD4HPuG4wj4L2WE/HYB/PgUyET5qssc+zftfPy4dgj6B4Bo+VfLLPjhGXj8eCYM+sDEfPkunzT7QjV0/sGqDPpFlGz5Q6s0+8ppdP6NMhD5LvRE+g3jOPjnBXT8sUYU+09QEPsL6zj6N/V0/fi2GPtEL7z3fL88+9UheP7Cwhj5u+dg9BwDPPsSaXj9R6oY+/erIPQiYzj5u5l4/4veGPjotvz3qMc4+Qh5fPw/2hj466bs9gQTOPh00Xz+dUYU+TH7HPd/0yz4KxF8/2IWBPs7q4D0xRMc+3f9gP3QMez7OCPo9h2/CPoY0Yj/DT3c+KKMCPlU2wD4HvWI/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/wSGFPsNL/z3yRc4+UF9eP8EhhT7DS/898kXOPlBfXj/BIYU+w0v/PfJFzj5QX14/P7SFPnje/T3fFc8+hh9eP9FGhz4g3fk9qlHRPn1uXT9soYk+4p3zPSuq1D7TYFw/lY2MPpp36z2e0tg+2wlbPxPZjz5z2eE94YTdPk57WT/vV5M+/1bXPQGF4j7MxFc/m+SWPtmkzD13quc+w/FVP5Bamj42kMI91djsPiYMVD9PpJ0+LjO6PaDL8T7HJ1I/D66gPqWntD2vZfY+u09QP1yYoz7AzLE9JNn6PjZyTj8RmqY+vtCwPRp8/z5IbUw/+L6pPl3BsT0NNQI/RjNKP1oQrT4s77Q9UMgEP4DDRz91lLA+R5q6Pcp5Bz8tFkU/tlC0PqERwz0DSQo/xyNCP8FcuD5Bes099EANP1fbPj8B07w+HafYPQNtED/RKTs/xbTBPq+l5D16vhM/6A43P7O7xj7UY/E9SAkXP6K3Mj8Hwcs+75f+PZk7Gj83Oy4/PqLQPuH0BT7MRh0/DLIpP0FN1T7ikAw+qx8gPyAwJT/mwNk+9TETPnG4Ij9TxyA/g8fdPhEXGT42HiU/II8cP3V74T7S7B0+y2MnP4J4GD/mr+Q+XtwhPilnKT8qwBQ/lirnPkMnJT43/Co/rLkRP4bw6D6gqCc+EyIsP8Z4Dz8zCOo+S4cpPm/ILD8zGg4/RWfqPvMuKj4mAS0/SqENP0Vn6j7zLio+JgEtP0qhDT9FZ+o+8y4qPiYBLT9KoQ0/waoiPgvoMD7P8/I+ni9ZP7yrIj4x6zA+e/LyPsgvWT9jsiI+QAExPvTo8j4DMVk/TcQiPho9MT7SzvI+bTRZP9JyJD6KhDc+WMLvPl2lWT9HBSY+x1w+Ph0T7D7JNVo/wbInPrRYRz7QyuY+KApbPxH7KD4Tj08+V8vhPmLNWz/sAio+DcpXPq5Y3D5Ko1w/iFYqPlZqWz5sz9k+HwddP4SCKj7G0l0+1hTYPhtLXT98uyo+btdgPvf31T71ml0/ucoqPgXcYD7tDtY+Y5RdPyTXKj7iDmI+2ynVPnm3XT8q4So+X0FjPupC1D7J2l0/RQMrPn7kYz62+9M+tN9dP48bKz6DAWY+UnfSPg0YXj+ICSs+paNlPqyh0j70FF4/xIAqPqUVYz6mvdM+CwJeP8uyKD7yQlw+iVDWPgboXT9IuB4+QOE2Po0U5z6+Rlw/GN8JPj4t/D0mj/c+CCpbP3WS+j0x8LY9bdD9PuvrWj8Qqvw9k1S2Pfaw/z5WWFo/xNH/PUXBuz0zJAA/0QpaPzJOAj5JAcU9AWEAP6GvWT9USwY+zMnVPQGJAD/AMVk/yZwLPhm/7D0ZZQA/8bFYP8R/ET66gAM+KIL/PrxbWD/eDhc+0+4QPloo/T5bRlg/S+cbPiBPHT6A/Pk+DHFYP+2UHz6zeic+GqX2PlvBWD/X3iE+xF0uPu8A9D6SDlk/waoiPgvoMD7P8/I+ni9ZP1uNJT4f4jA+7+b3PqulVz/4oSY+0TY1Pk629T4o/1c//nEoPmaOPj4fCPA+NQBZPy5nKT6VvEc+kD/pPqdIWj8Kiik+++NLPg/U5T5q8Vo/1ewoPiaaSD7Srec+wKxaP7UZJz7VT0A+MBHsPsENWj/vIiQ+/1s1PoY78T7XXVk/KYsgPtYoKj4LvPU+wtZYPz01HT5m4iA+Cdb4PrmMWD+tmho+sBwaPpK7+j6BbVg/zvQYPtP6FT54u/s+bGRYPwpkGD5ZlhQ+Ewr8Pk1jWD/gzRo+zegYPhUR/D6fFVg/qLEfPmuQIj57O/s+BKpXP0LmIz4iYiw+4TP5PjyUVz9bjSU+H+IwPu/m9z6rpVc/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/waoiPgvoMD7P8/I+ni9ZP8GqIj4L6DA+z/PyPp4vWT/BqiI+C+gwPs/z8j6eL1k/2oQiPjBpMD68KvM+eShZPzoaIj4bBS8+5MXzPvgTWT/KayE+FNssPn2r9D5D91g/3HogPqgKKj4+vvU+YNhYP0pVHz5CuiY+9+j2Pju6WD/1Gx4+zRojPocn+D62mVg/3wAdPptuHz61ivk+TGxYP9U+HD4lCxw+sT77Pm4eWD/LMxw+qSwZPhyP/T6gklc/aT0dPq8rFz7aZgA/4qZWP+ZAHz7kCRY+f2oCPwVkVT/L2yE+CpwVPsaXBD/K8FM/QfskPlz/FT6X3gY/j1RSP4+eKD5RQhc+PDMJPzCUUD+DuSw+64kZPsqDCz+cuE4/ED0xPrwDHT71vA0/OcxMPxLsNT4BaSE+rtYPP5HaSj+nfTo+XlAmPoTMET878Eg/feI+PrewKz4zkhM/gxhHP3sPQz55gzE+VSoVP+RTRT/W6kY+CLs3PhWOFj9Hq0M/AF9KPpE7Pj74txc/mydCP/JfTT4x20Q+fp0YP3jWQD8kBVA+81lLPsssGT/ryj8/5xhSPrl9UT6KYhk/qRE/PzxnUz4qEFc+gx4ZPxTOPj/ZMlQ+yfVbPu+YGD+n0T4/St1UPjwUYD6AJRg/SNU+P7pfVT6FOWM+1ssXPxHYPj/1nlU+QV1lPq+OFz9M2z4/kLdVPrEZZj4EeRc/mdw+P5C3VT6xGWY+BHkXP5ncPj+Qt1U+sRlmPgR5Fz+Z3D4/Ei15vPEpNT0lX98+hgpmP30NebzbLTU9Ll7fPsEKZj/pMHi8JEk1Pd9W3z6BDGY/tNp1vBuTNT2KQt8+XhFmP4ymN7yLSj09y5fcPjSzZj+HrOm7PKVFPV022T7ee2c/yAv3uh+OUD2lS9Q+RZdoPwhEODuzhlo9vuDPPtKMaT/nyfM7QmVkPWUOyz6XkGo/9sMaPOG7aD0kycg+FghrPw9lMDzWnGs99zrHPuxYaz8fcUs81T1vPXRsxT5EtWs/aMVLPO9Ibz0/m8U+Z6trP3RfVjy1t3A9dcvEPtDUaz/H6mA8DiZyPaT5wz5l/ms/HdtmPIv0cj0E7MM+CQBsP+R+eTxIgXU9BKPCPjxAbD9oGnY8Xgp1Pa2swj7zPmw/mU1ePGHNcT0f4sI+vzhsPyNWHTwQJGk9gvPCPiBBbD/vCky8UQQ7PbsFzD4BfGo/k1pBvRJZ5TwMgtU+K0FoP3dai72KAYg8dbzaPjPEZj+Esou9s3SHPMMy3j5j72U/KVWIvT4ijzz2ot8+/5xlP/GUgr3tFZw8iyjhPgNJZT8qL3C9FoSzPMEQ4z4342Q/6ihTvb760jzx1+Q+uIdkP9CsMb0oIfY80czlPvddZD88gw+90LwMPat35T4tgWQ/FdTfvAWfHD2xAeQ+AeZkP9UXrLyebyk9HPXhPvdpZT+PVIm8FQQyPR8i4D6922U/Ei15vPEpNT0lX98+hgpmPyyOeLys/TQ9vK3tPt9tYj+rq0u8kag6PY0C6j4gYGM/o8jau/qCRj0YMeE+U5FlPy2IprrPxFE9V3DXPvrcZz/2K446WMVWPfG50j727Gg/eL9Zuoe4Uj0PdtQ+vYtoP/AyvLt0fEg9H4/YPjyhZz+8EEu8kOA6PbNW3T5shmY/SXyevJ/KLD0jeOE+pohlPyNmzrxZ7iA9nlnkPjLRZD8ut/G8DSAYPXgs5j6DWWQ/d7EDvXCtEj0qMOc+dxVkP7xbB71B0xA9HIXnPvP+Yz+Mvfe85YQWPUw46T7PkmM/9xLFvM/6Ij2FAew+gd5iP4LMkrw/YC89LnXtPsB9Yj8sjni8rP00Pbyt7T7fbWI/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/Ei15vPEpNT0lX98+hgpmPxItebzxKTU9JV/fPoYKZj8SLXm88Sk1PSVf3z6GCmY/zId9vNGhND0vF98+GhxmP97jhLxBIzM98FTePmNLZj8wg468z8owPTEr3T5kk2Y/VyabvL+zLT1qp9s+TfBmP3cSqrxVBCo9HN7ZPp1cZz+MMrq8xvUlPXTz1z5Zz2c/BfnJvKfjIT0QG9Y+XjxoPyx617zCVh49XZ7UPimTaD/pSuG86qgbPQL/0z4At2g/FFblvIxrGj1fuNQ+iYxoP/2147x+oBo9m33WPqEkaD8qt928HPgbPbeF2D5arGc/zfHSvCahHj09kto+zDFnP6tdw7zlqCI9FYTcPh+8Zj8Si668+0IoPeYp3j4GV2Y/XPyTvFSxLz2wT98+Dg9mPxzXaryaoDg9dLvfPknyZT98eSq8s49CPTUv3z60D2Y/tizQuz5ZTT0dkN0+Cm1mP+WkELtL7Fg9zCDbPpL4Zj898AE7hCRlPQkC2D6lqGc/DVzJO0bAcT3LVdQ+k3NoP7usJjypTH49oUDQPspPaT8J9mM8ofuEPVDoyz66NGo/676NPAREij3HAMc+KDJrP0BLpTzkvY49aErBPtFTbD8v97g8unCSPX+Suz5ebW0/8H3JPBZ8lT3/6rY+a0puPxQc1jxkxZc9QXSzPj3qbj/eNd48CVCZPbCfsT7wO28/oALhPCXVmT0B/rA+5ldvP6AC4Twl1Zk9Af6wPuZXbz+gAuE8JdWZPQH+sD7mV28/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQDbNI75b6EK/XaoOQDjNY77tIje/XaoOQAJNuL5nPR2/XaoOQGez/r7iVwO/XaoOQLRZD7/sJO++XaoOQLRZD7+HMPq+XaoOQLRZD7/Ckwy/XaoOQLRZD78TZCS/XaoOQLRZD79b6EK/XaoOQLRZD783p2W/XaoOQLRZD7+aYoO/XaoOQLRZD78wx4+/XaoOQLVZD79gp5S/XaoOQGaz/r5gp4y/XaoOQAFNuL6NG3a/XaoOQDbNY75a6FK/XaoOQDbNI75b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/XaoOQLRZD79b6EK/MeoOQLRZD7/9y0O/lZ4PQLRZD79LT0a/4LYQQLRZD7/kNkq/biISQLRZD79mR0+/ltATQLRZD79vRVW/srAVQLRZD7+e9Vu/HLIXQLRZD7+QHGO/LMQZQLRZD7/kfmq/PNYbQLRZD7844XG/ptcdQLRZD78rCHm/wrcfQLRZD79auH+/62UhQLRZD78y24K/eNEiQLRZD79yY4W/w+kjQLRZD78+V4e/Jp4kQLRZD7/mmIi/+90kQLVZD7+2Com/yJIjQLVZD7+2Com/zO4fQLVZD7+2Com/dk4aQLVZD7+2Com/Mg4TQLVZD7+2Com/cIoKQLVZD7+2Com/mx8BQLVZD7+2Com/Q1TuP7VZD7+1Com/4gzaP7VZD7+1Com/8SHGP7VZD7+1Com/SEyzP7VZD7+1Com/wkSiP7VZD7+1Com/OsSTP7VZD7+1Com/joOIP7VZD7+1Com/mDuBP7VZD7+1Com/Ykp9P7VZD7+1Com/Ykp9P7VZD7+1Com/Ykp9P7VZD7+1Com/hUnlsoVJ5bL0BDW/9AQ1P4VJ5bKFSeWy9AQ1v/QENT8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/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AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAP5IMgT+SDIE/AACAP5QDhD+UA4Q/AACAP/SeiD/0nog/AACAP6OYjj+jmI4/AACAP5KqlT+SqpU/AACAP7GOnT+xjp0/AACAP/D+pT/w/qU/AACAPz61rj8+ta4/AACAP4xrtz+Ma7c/AACAP8zbvz/M278/AACAP+q/xz/qv8c/AACAP9rRzj/a0c4/AACAP4rL1D+Ky9Q/AACAP+pm2T/qZtk/AACAP+ld3D/pXdw/AACAP3xq3T98at0/AACAP8BZ2z98at0/AACAP+iJ1T98at0/AACAP4SOzD98at0/AACAPyH7wD98at0/AACAP05jsz98at0/AACAP5hapD98at0/AACAP4x0lD98at0/AACAP7pEhD98at0/AACAP1+9aD98at0/AACAP/KrSj98at0/AACAP018Lz98at0/AACAP4ZVGD98at0/AACAP7xeBj98at0/AACAPyB+9T58at0/AACAPy077T58at0/AACAPy077T58at0/AACAPy077T58at0/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utbk/6lwQQLRZD797gqw/6lwQQLRZD79IT58/6lwQQLRZD79IT5k/6lwQQGaz/r6utZ0/6lwQQABNuL5IT6k/6lwQQDjNY76utbk/6lwQQDXNI757gsw/6lwQQDfNY75IT98/6lwQQAFNuL6tte8/6lwQQGez/r5HT/s/6lwQQLRZD7+utf8/6lwQQLNZD79HT/s/6lwQQLRZD7+ste8/6lwQQLRZD79GT98/6lwQQLRZD796gsw/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/6lwQQLRZD7+utb8/x1UQQLRZD78EhME/0yMQQLRZD7/oRsY/PJwPQLRZD78pAs0/MpQOQLRZD7+ZudQ/4+AMQLRZD78Jcdw/fVcKQLRZD79KLOM/MM0GQLRZD78t7+c/KhcCQLRZD7+Dvek/uef0P7RZD790D+c/YGTeP7RZD7+//t8/DoDDP7RZD7+cAdY/ghanP7RZD79Djso/ggOMP7RZD7/qGr8/mEVqP7VZD7/IHbU/TKBKP7VZD78SDa4/pM4+P7RZD78DX6s/lpVQP7RZD78DX6s/8AZ9P7RZD78DX6s/wGabP7RZD78DX6s/CEq4P7RZD78DX6s/toLOP7RZD78DX6s/LmbXP7RZD78DX6s/VszRP7RZD78DX6s/osnCP7RZD78DX6s/UQ6tP7RZD78DX6s/okqTP7RZD78EX6s/qF1wP7RZD78EX6s/StY8P7RZD78EX6s/qF8RP7RZD78EX6s/hLTmPrRZD78EX6s/IE3QPrRZD78EX6s/IE3QPrRZD78EX6s/IE3QPrRZD78EX6s/hUnlsoVJ5bL0BDW/9AQ1P4VJ5bKFSeWy9AQ1v/QENT8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ViaAP1YmgD8AAIA/V5eAP1eXgD8AAIA/AlCBPwJQgT8AAIA/VU2CP1VNgj8AAIA/T4yDP0+Mgz8AAIA/7wmFP+8JhT8AAIA/NMOGPzTDhj8AAIA/G7WIPxu1iD8AAIA/pdyKP6Xcij8AAIA/zzaNP882jT8AAIA/mcCPP5nAjz8AAIA/AHeSPwB3kj8AAIA/A1eVPwNXlT8AAIA/o12YP6NdmD8AAIA/3IebP9yHmz8AAIA/rtKeP67Snj8AAIA/FjuiPxY7oj8AAIA/Fr6lPxa+pT8AAIA/qlipP6pYqT8AAIA/0QetP9EHrT8AAIA/i8iwP4vIsD8AAIA/1Ze0P9WXtD8AAIA/rnK4P65yuD8AAIA/F1a8PxdWvD8AAIA/Cz/APws/wD8AAIA/iyrEP4sqxD8AAIA/lhXIP5YVyD8AAIA/Kv3LPyr9yz8AAIA/Rd7PP0Xezz8AAIA/57XTP+e10z8AAIA/DYHXPw2B1z8AAIA/tzzbP7c82z8AAIA/4+XeP+Pl3j8AAIA/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tFkPvxnErL4gwuK9tFkPvxnErL6ACWC9tFkPvxnErL5AFw69tFkPvxnErL5AFw69tFkPvxnErL5AFw69tFkPvxnErL6FSeWyhUnlMvQENT/0BDU/hUnlsoVJ5TL0BDU/9AQ1PwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD9vNoA/bzaAPwAAgD851oA/OdaAPwAAgD8Z2oE/GdqBPwAAgD/KPIM/yjyDPwAAgD8I+YQ/CPmEPwAAgD+QCYc/kAmHPwAAgD8caYk/HGmJPwAAgD9nEow/ZxKMPwAAgD8tAI8/LQCPPwAAgD8pLZI/KS2SPwAAgD8XlJU/F5SVPwAAgD+zL5k/sy+ZPwAAgD+3+pw/t/qcPwAAgD/g76A/4O+gPwAAgD/oCaU/6AmlPwAAgD+MQ6k/jEOpPwAAgD+Gl60/hpetPwAAgD+TALI/kwCyPwAAgD9tebY/bXm2PwAAgD/R/Lo/0fy6PwAAgD95hb8/eYW/PwAAgD8hDsQ/IQ7EPwAAgD+Ekcg/hJHIPwAAgD9eCs0/XgrNPwAAgD9qc9E/anPRPwAAgD9mx9U/ZsfVPwAAgD8KAdo/CgHaPwAAgD8QG94/EBvePwAAgD86EOI/OhDiPwAAgD8/2+U/P9vlPwAAgD/Zduk/2XbpPwAAgD/I3ew/yN3sPwAAgD/FCvA/xQrwPwAAgD+L+PI/i/jyPwAAgD/VofU/1aH1PwAAgD9hAfg/YQH4PwAAgD/pEfo/6RH6PwAAgD8mzvs/Js77PwAAgD/YMP0/2DD9PwAAgD+4NP4/uDT+PwAAgD+D1P4/g9T+PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD/xCv8/8Qr/PwAAgD+Wsfo/8Qr/PwAAgD/YxO4/8Qr/PwAAgD+y89w/8Qr/PwAAgD8c7cY/8Qr/PwAAgD8OYK4/8Qr/PwAAgD+F+5Q/8Qr/PwAAgD/v3Hg/8Qr/PwAAgD/Az0w/8Qr/PwAAgD9wLSk/8Qr/PwAAgD/2UxE/8Qr/PwAAgD9CoQg/8Qr/PwAAgD9CoQg/8Qr/PwAAgD9CoQg/8Qr/PweaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8A2zSO+UHMIvQeaF8A4zWO+FTNePAeaF8ACTbi+kvnuPQeaF8Bns/6+XhZhPgeaF8C0WQ+/MIuIPgeaF8C0WQ+/kkl6PgeaF8C0WQ+/+K86PgeaF8C0WQ+/jPmyPQeaF8C0WQ+/UHMIvQeaF8C0WQ+/brYtvgeaF8C0WQ+/aA6ZvgeaF8CzWQ+/znTKvgeaF8C0WQ+/N9vdvgeaF8Bms/6+Ntu9vgeaF8AATbi+oeluvgeaF8A2zWO+qznEvQeaF8A2zSO+UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvQeaF8C0WQ+/UHMIvSVLF8C0WQ+/gVX5vDFiFsC0WQ+/Xbu2vLDkFMC0WQ+/HHwevCvYEsC0WQ+/MPLbOypCEMC0WQ+/mM7VPDMoDcC0WQ+/HolDPc+PCcC0WQ+/ZiiRPYZ+BcC0WQ+/tBXCPd35AMC0WQ+/AAPzPb0O+L+0WQ+/bDMRPiBZ7b+0WQ+/4lsnPvTd4b+0WQ+/JDY7Pkmo1b+0WQ+/dv1LPizDyL+0WQ+/Hu1YPq85u7+0WQ+/ZEBhPt8Wrb+0WQ+/iDJkPpRsnr+0WQ+/iDJkPs9nj7+0WQ+/iDJkPlk8gL+0WQ+/iDJkPvI7Yr+0WQ+/iDJkPvCARL+0WQ+/iDJkPkCvJ7+0WQ+/iDJkPnYuDL+0WQ+/iDJkPjjM5L60WQ+/iDJkPpB7tb60WQ+/iDJkPig6i760WQ+/iDJkPvCtTb60WQ+/iDJkPpBCEr60WQ+/iDJkPuCgy720WQ+/iDJkPmDrk720WQ+/iDJkPqChgL20WQ+/iDJkPqChgL20WQ+/iDJkPqChgL20WQ+/iDJkPoVJ5bKFSeUy9AQ1P/QENT+FSeWyhUnlMvQENT/0BDU/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAP5IMgT+SDIE/AACAP5QDhD+UA4Q/AACAP/SeiD/0nog/AACAP6OYjj+jmI4/AACAP5KqlT+SqpU/AACAP7GOnT+xjp0/AACAP/D+pT/w/qU/AACAPz61rj8+ta4/AACAP4xrtz+Ma7c/AACAP8zbvz/M278/AACAP+q/xz/qv8c/AACAP9rRzj/a0c4/AACAP4rL1D+Ky9Q/AACAP+pm2T/qZtk/AACAP+ld3D/pXdw/AACAP3xq3T98at0/AACAP8BZ2z98at0/AACAP+iJ1T98at0/AACAP4SOzD98at0/AACAPyH7wD98at0/AACAP05jsz98at0/AACAP5hapD98at0/AACAP4x0lD98at0/AACAP7pEhD98at0/AACAP1+9aD98at0/AACAP/KrSj98at0/AACAP018Lz98at0/AACAP4ZVGD98at0/AACAP7xeBj98at0/AACAPyB+9T58at0/AACAPy077T58at0/AACAPy077T58at0/AACAPy077T58at0/B5oXwLRZD7++SjI/B5oXwLRZD7++SjI/B5oXwLRZD7++SjI/B5oXwLRZD7++SjI/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AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ViaAP1YmgD8AAIA/V5eAP1eXgD8AAIA/AlCBPwJQgT8AAIA/VU2CP1VNgj8AAIA/T4yDP0+Mgz8AAIA/7wmFP+8JhT8AAIA/NMOGPzTDhj8AAIA/G7WIPxu1iD8AAIA/pdyKP6Xcij8AAIA/zzaNP882jT8AAIA/mcCPP5nAjz8AAIA/AHeSPwB3kj8AAIA/A1eVPwNXlT8AAIA/o12YP6NdmD8AAIA/3IebP9yHmz8AAIA/rtKeP67Snj8AAIA/FjuiPxY7oj8AAIA/Fr6lPxa+pT8AAIA/qlipP6pYqT8AAIA/0QetP9EHrT8AAIA/i8iwP4vIsD8AAIA/1Ze0P9WXtD8AAIA/rnK4P65yuD8AAIA/F1a8PxdWvD8AAIA/Cz/APws/wD8AAIA/iyrEP4sqxD8AAIA/lhXIP5YVyD8AAIA/Kv3LPyr9yz8AAIA/Rd7PP0Xezz8AAIA/57XTP+e10z8AAIA/DYHXPw2B1z8AAIA/tzzbP7c82z8AAIA/4+XeP+Pl3j8AAIA/kXniP5F54j8AAIA/vvTlP7705T8AAIA/aFTpP2hU6T8AAIA/lJXsP5SV7D8AAIA/OLXvPzi17z8AAIA/VrDyP1aw8j8AAIA/7oP1P+6D9T8AAIA//yz4P/8s+D8AAIA/hqj6P4ao+j8AAIA/gvP8P4Lz/D8AAIA/8Qr/P/EK/z8AAIA/+nUAQPp1AEAAAIA/E0oBQBNKAUAAAIA/pAACQKQAAkAAAIA/jJgCQIyYAkAAAIA/qBADQKgQA0AAAIA/2GcDQNhnA0AAAIA//ZwDQP2cA0AAAIA/9a4DQPWuA0AAAIA/9a4DQPWuA0AAAIA/9a4DQPWuA0AAAIA/9a4DQPWuA0AAAIA/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AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD+SDIE/kgyBPwAAgD+UA4Q/lAOEPwAAgD/0nog/9J6IPwAAgD+jmI4/o5iOPwAAgD+SqpU/kqqVPwAAgD+xjp0/sY6dPwAAgD/w/qU/8P6lPwAAgD8+ta4/PrWuPwAAgD+Ma7c/jGu3PwAAgD/M278/zNu/PwAAgD/qv8c/6r/HPwAAgD/a0c4/2tHOPwAAgD+Ky9Q/isvUPwAAgD/qZtk/6mbZPwAAgD/pXdw/6V3cPwAAgD98at0/fGrdPwAAgD/AWds/fGrdPwAAgD/oidU/fGrdPwAAgD+Ejsw/fGrdPwAAgD8h+8A/fGrdPwAAgD9OY7M/fGrdPwAAgD+YWqQ/fGrdPwAAgD+MdJQ/fGrdPwAAgD+6RIQ/fGrdPwAAgD9fvWg/fGrdPwAAgD/yq0o/fGrdPwAAgD9NfC8/fGrdPwAAgD+GVRg/fGrdPwAAgD+8XgY/fGrdPwAAgD8gfvU+fGrdPwAAgD8tO+0+fGrdPwAAgD8tO+0+fGrdPwAAgD8tO+0+fGrdPw=="}]} diff --git a/data/games/garage/mods/gltf/models/gltf_triangle_with_vertex_stride.gltf b/data/games/garage/mods/gltf/models/gltf_triangle_with_vertex_stride.gltf new file mode 100644 index 0000000..feddfbb --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_triangle_with_vertex_stride.gltf @@ -0,0 +1 @@ +{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":1},"indices":0}]}],"buffers":[{"uri":"data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAA=","byteLength":80}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":6,"target":34963},{"buffer":0,"byteOffset":8,"byteLength":72,"byteStride":24,"target":34962}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5123,"count":3,"type":"SCALAR","max":[2],"min":[0]},{"bufferView":1,"byteOffset":0,"componentType":5126,"count":3,"type":"VEC3","max":[1,1,0],"min":[0,0,0]}],"asset":{"version":"2.0"}} diff --git a/data/games/garage/mods/gltf/models/gltf_triangle_without_indices.gltf b/data/games/garage/mods/gltf/models/gltf_triangle_without_indices.gltf new file mode 100644 index 0000000..e91cc0e --- /dev/null +++ b/data/games/garage/mods/gltf/models/gltf_triangle_without_indices.gltf @@ -0,0 +1 @@ +{"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"mesh":0}],"meshes":[{"primitives":[{"attributes":{"POSITION":0}}]}],"buffers":[{"uri":"data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA","byteLength":36}],"bufferViews":[{"buffer":0,"byteOffset":0,"byteLength":36,"target":34962}],"accessors":[{"bufferView":0,"byteOffset":0,"componentType":5126,"count":3,"type":"VEC3","max":[1,1,0],"min":[0,0,0]}],"asset":{"version":"2.0"}} diff --git a/data/games/garage/mods/gltf/textures/gltf_cube.png b/data/games/garage/mods/gltf/textures/gltf_cube.png new file mode 100644 index 0000000000000000000000000000000000000000..1d019108550471be78c1efa02d4367a5aaacdc92 GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxc>kD|E9eB^b_}10Yw@- zT^vI+&hMRgm-B!EPs?MDz6TnTOJ_@LQFZ=u)N}1I`3qqhB2w{o=bEjB7#buN_JkT= zklJ;8HkW(z-bQ}jZ8vMquQFZKQ}e`}$+SSlVV20tH7!q0W{TZ3P_wxBxO0)kBPKcB zF#pE(4z9h&cK@~bm2E%&{ZU)l=bvI9miBHu&l=+9n`|96og3&D22WQ%mvv4FO#sL{ BPoDq) literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/gltf/textures/gltf_frog.png b/data/games/garage/mods/gltf/textures/gltf_frog.png new file mode 100644 index 0000000000000000000000000000000000000000..552ae36493c59c6107de9eb9c08b85cf494d3647 GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvi2$DvS0D`p(auuIo^pl3@)r** zx_@QWpC9+F^;c*BB^XPB{DK)Ap4~_Ta+Z0zIEF|_-aUA+uqi>H^`iAA)g?_HjC?@{ zj{W`jy*_R^t3pE7>UrIx=4=#B{D``d7B}@YEIM2ItZx z*QMOrdNy~*B)&;M7Pqfs_j>8Tuikej{qR=KR}%X?qh{`}?U|hNz{{a{{?cuXs%EB7 z-B&WO-uQeqJJq*WdS$6@&$mZzi4UVfYQC+ry|tl(VN2s7um6qnCOWNuCjLFyc#?Pi RV-=9cJYD@<);T3K0RXN~Zvg-R literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/gltf/textures/gltf_snow_man.png b/data/games/garage/mods/gltf/textures/gltf_snow_man.png new file mode 100644 index 0000000000000000000000000000000000000000..7f2784358b94af2238337bc6a1555c32c06f9c80 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDB3?!H8JlO)I_yc@GT!AzY1Sgi{RrLJ-|3BuI z$}}LKu_VYZn8D%MjWi%9$J50z#G?1@g@e2e3Oub3*Et+w+0f|Y@aet%Wc9!^s~5)Y zx$%1XzC*^p(<>Q_8F+1fGx*F_*5a_@s<{yO`N)DPK`K|SZOcD!CZ=Hi>5HpcmN2|X z;k9~o)lFniy^Eslft!zXSM}YSuF%?e`lIZ5wHa=yVzLW>_A+?7`njxgN@xNA7I;nX literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/gltf/textures/gltf_spider.png b/data/games/garage/mods/gltf/textures/gltf_spider.png new file mode 100644 index 0000000000000000000000000000000000000000..1e3d3ae8cbb31c80219081ed7ebdc1bb1ad78373 GIT binary patch literal 10957 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 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/initial_message/init.lua b/data/games/garage/mods/initial_message/init.lua new file mode 100644 index 0000000..255dca0 --- /dev/null +++ b/data/games/garage/mods/initial_message/init.lua @@ -0,0 +1,9 @@ +core.register_on_joinplayer(function(player) + local cb = function(player) + if not player or not player:is_player() then + return + end + core.chat_send_player(player:get_player_name(), "This is the \"Development Test\" [devtest], meant only for testing and development.") + end + core.after(2.0, cb, player) +end) diff --git a/data/games/garage/mods/initial_message/mod.conf b/data/games/garage/mods/initial_message/mod.conf new file mode 100644 index 0000000..32aa2ac --- /dev/null +++ b/data/games/garage/mods/initial_message/mod.conf @@ -0,0 +1,2 @@ +name = initial_message +description = Show message to joining players explaining what this testing game is about diff --git a/data/games/garage/mods/last_mod/init.lua b/data/games/garage/mods/last_mod/init.lua new file mode 100644 index 0000000..3909a39 --- /dev/null +++ b/data/games/garage/mods/last_mod/init.lua @@ -0,0 +1 @@ +-- Nothing to do here, loading order is tested in C++ unittests. diff --git a/data/games/garage/mods/last_mod/mod.conf b/data/games/garage/mods/last_mod/mod.conf new file mode 100644 index 0000000..734bf4c --- /dev/null +++ b/data/games/garage/mods/last_mod/mod.conf @@ -0,0 +1,5 @@ +name = last_mod +description = Mod which should be loaded as last mod. +# Test dependencies +optional_depends = unittests +depends = first_mod diff --git a/data/games/garage/mods/lighting/init.lua b/data/games/garage/mods/lighting/init.lua new file mode 100644 index 0000000..1251ef1 --- /dev/null +++ b/data/games/garage/mods/lighting/init.lua @@ -0,0 +1,156 @@ +local lighting_sections = { + {n = "shadows", d = "Shadows", + entries = { + { n = "intensity", d = "Shadow Intensity", min = 0, max = 1 } + } + }, + { + n = "exposure", d = "Exposure", + entries = { + {n = "luminance_min", d = "Minimum Luminance", min = -10, max = 10}, + {n = "luminance_max", d = "Maximum Luminance", min = -10, max = 10}, + {n = "exposure_correction", d = "Exposure Correction", min = -10, max = 10}, + {n = "speed_dark_bright", d = "Bright light adaptation speed", min = -10, max = 10, type="log2"}, + {n = "speed_bright_dark", d = "Dark scene adaptation speed", min = -10, max = 10, type="log2"}, + {n = "center_weight_power", d = "Power factor for center-weighting", min = 0.1, max = 10}, + } + }, + { + n = "bloom", d = "Bloom", + entries = { + {n = "intensity", d = "Intensity", min = 0, max = 1}, + {n = "strength_factor", d = "Strength Factor", min = 0.1, max = 10}, + {n = "radius", d = "Radius", min = 0.1, max = 8}, + }, + }, + { + n = "volumetric_light", d = "Volumetric Lighting", + entries = { + {n = "strength", d = "Strength", min = 0, max = 1}, + }, + }, +} + +local function dump_lighting(lighting) + local result = "{\n" + local section_count = 0 + for _,section in ipairs(lighting_sections) do + section_count = section_count + 1 + + local parameters = section.entries or {} + local state = lighting[section.n] or {} + + result = result.." "..section.n.." = {\n" + + local count = 0 + for _,v in ipairs(parameters) do + count = count + 1 + result = result.." "..v.n.." = "..(math.floor(state[v.n] * 1000)/1000) + if count < #parameters then + result = result.."," + end + result = result.."\n" + end + + result = result.." }" + + if section_count < #lighting_sections then + result = result.."," + end + result = result.."\n" + end + result = result .."}" + return result +end + +core.register_chatcommand("set_lighting", { + params = "", + description = "Tune lighting parameters", + func = function(player_name, param) + local player = core.get_player_by_name(player_name); + if not player then return end + + local lighting = player:get_lighting() + local exposure = lighting.exposure or {} + + local content = {} + local line = 1 + for _,section in ipairs(lighting_sections) do + local parameters = section.entries or {} + local state = lighting[section.n] or {} + + table.insert(content, "label[1,"..line..";"..section.d.."]") + line = line + 1 + + for _,v in ipairs(parameters) do + table.insert(content, "label[2,"..line..";"..v.d.."]") + table.insert(content, "scrollbaroptions[min=0;max=1000;smallstep=10;largestep=100;thumbsize=10]") + local value = state[v.n] + if v.type == "log2" then + value = math.log(value or 1) / math.log(2) + end + local sb_scale = math.floor(1000 * (math.max(v.min, value or 0) - v.min) / (v.max - v.min)) + table.insert(content, "scrollbar[2,"..(line+0.7)..";12,1;horizontal;"..section.n.."."..v.n..";"..sb_scale.."]") + line = line + 2.7 + end + + line = line + 1 + end + + local form = { + "formspec_version[2]", + "size[15,", line, "]", + "position[0.99,0.15]", + "anchor[1,0]", + "padding[0.05,0.1]", + "no_prepend[]", + } + table.insert_all(form, content) + + core.show_formspec(player_name, "lighting", table.concat(form)) + local debug_value = dump_lighting(lighting) + local debug_ui = player:hud_add({type="text", position={x=0.1, y=0.3}, scale={x=1,y=1}, alignment = {x=1, y=1}, text=debug_value, number=0xFFFFFF}) + player:get_meta():set_int("lighting_hud", debug_ui) + end +}) + +core.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "lighting" then return end + + if not player then return end + + local hud_id = player:get_meta():get_int("lighting_hud") + + if fields.quit then + player:hud_remove(hud_id) + player:get_meta():set_int("lighting_hud", -1) + return + end + + local lighting = player:get_lighting() + for _,section in ipairs(lighting_sections) do + local parameters = section.entries or {} + + local state = (lighting[section.n] or {}) + lighting[section.n] = state + + for _,v in ipairs(parameters) do + + if fields[section.n.."."..v.n] then + local event = core.explode_scrollbar_event(fields[section.n.."."..v.n]) + if event.type == "CHG" then + local value = v.min + (v.max - v.min) * (event.value / 1000); + if v.type == "log2" then + value = math.pow(2, value); + end + state[v.n] = value; + end + end + end + end + + local debug_value = dump_lighting(lighting) + player:hud_change(hud_id, "text", debug_value) + + player:set_lighting(lighting) +end) \ No newline at end of file diff --git a/data/games/garage/mods/lighting/mod.conf b/data/games/garage/mods/lighting/mod.conf new file mode 100644 index 0000000..83bbbef --- /dev/null +++ b/data/games/garage/mods/lighting/mod.conf @@ -0,0 +1,2 @@ +name = lighting +description = UI to control and debug lighting parameters diff --git a/data/games/garage/mods/log/init.lua b/data/games/garage/mods/log/init.lua new file mode 100644 index 0000000..64673f2 --- /dev/null +++ b/data/games/garage/mods/log/init.lua @@ -0,0 +1,16 @@ +local modname = core.get_current_modname() +local prefix = "["..modname.."] " + +-- Startup info +core.log("action", prefix.."modname="..dump(modname)) +core.log("action", prefix.."modpath="..dump(core.get_modpath(modname))) +core.log("action", prefix.."worldpath="..dump(core.get_worldpath())) + +-- Callback info +core.register_on_mods_loaded(function() + core.log("action", prefix.."Callback: on_mods_loaded()") +end) + +core.register_on_chatcommand(function(name, command, params) + core.log("action", prefix.."Caught command '"..command.."', issued by '"..name.."'. Parameters: '"..params.."'") +end) diff --git a/data/games/garage/mods/log/mod.conf b/data/games/garage/mods/log/mod.conf new file mode 100644 index 0000000..d2f37b9 --- /dev/null +++ b/data/games/garage/mods/log/mod.conf @@ -0,0 +1,2 @@ +name = log +description = Log DevTest-related actions diff --git a/data/games/garage/mods/mapgen/init.lua b/data/games/garage/mods/mapgen/init.lua new file mode 100644 index 0000000..d843902 --- /dev/null +++ b/data/games/garage/mods/mapgen/init.lua @@ -0,0 +1,104 @@ +-- +-- Aliases for map generator outputs +-- + +-- ESSENTIAL node aliases +-- Basic nodes +core.register_alias("mapgen_stone", "basenodes:stone") +core.register_alias("mapgen_water_source", "basenodes:water_source") +core.register_alias("mapgen_river_water_source", "basenodes:river_water_source") + +-- Additional essential aliases for v6 +core.register_alias("mapgen_lava_source", "basenodes:lava_source") +core.register_alias("mapgen_dirt", "basenodes:dirt") +core.register_alias("mapgen_dirt_with_grass", "basenodes:dirt_with_grass") +core.register_alias("mapgen_sand", "basenodes:sand") +core.register_alias("mapgen_tree", "basenodes:tree") +core.register_alias("mapgen_leaves", "basenodes:leaves") +core.register_alias("mapgen_apple", "basenodes:apple") + +-- Essential alias for dungeons +core.register_alias("mapgen_cobble", "basenodes:cobble") + +-- Optional aliases for v6 (they all have fallback values in the engine) +if core.settings:get_bool("devtest_v6_mapgen_aliases", false) then + core.register_alias("mapgen_gravel", "basenodes:gravel") + core.register_alias("mapgen_desert_stone", "basenodes:desert_stone") + core.register_alias("mapgen_desert_sand", "basenodes:desert_sand") + core.register_alias("mapgen_dirt_with_snow", "basenodes:dirt_with_snow") + core.register_alias("mapgen_snowblock", "basenodes:snowblock") + core.register_alias("mapgen_snow", "basenodes:snow") + core.register_alias("mapgen_ice", "basenodes:ice") + core.register_alias("mapgen_junglegrass", "basenodes:junglegrass") + core.register_alias("mapgen_jungletree", "basenodes:jungletree") + core.register_alias("mapgen_jungleleaves", "basenodes:jungleleaves") + core.register_alias("mapgen_pine_tree", "basenodes:pine_tree") + core.register_alias("mapgen_pine_needles", "basenodes:pine_needles") +end +-- Optional alias for mossycobble (should fall back to cobble) +if core.settings:get_bool("devtest_dungeon_mossycobble", false) then + core.register_alias("mapgen_mossycobble", "basenodes:mossycobble") +end +-- Optional aliases for dungeon stairs (should fall back to full nodes) +if core.settings:get_bool("devtest_dungeon_stairs", false) then + core.register_alias("mapgen_stair_cobble", "stairs:stair_cobble") + if core.settings:get_bool("devtest_v6_mapgen_aliases", false) then + core.register_alias("mapgen_stair_desert_stone", "stairs:stair_desert_stone") + end +end + +-- +-- Register biomes for biome API +-- + +core.clear_registered_biomes() +core.clear_registered_decorations() + +if core.settings:get_bool("devtest_register_biomes", true) then + core.register_biome({ + name = "mapgen:grassland", + node_top = "basenodes:dirt_with_grass", + depth_top = 1, + node_filler = "basenodes:dirt", + depth_filler = 1, + node_riverbed = "basenodes:sand", + depth_riverbed = 2, + node_dungeon = "basenodes:cobble", + node_dungeon_alt = "basenodes:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 4, + heat_point = 50, + humidity_point = 50, + }) + + core.register_biome({ + name = "mapgen:grassland_ocean", + node_top = "basenodes:sand", + depth_top = 1, + node_filler = "basenodes:sand", + depth_filler = 3, + node_riverbed = "basenodes:sand", + depth_riverbed = 2, + node_cave_liquid = "basenodes:water_source", + node_dungeon = "basenodes:cobble", + node_dungeon_alt = "basenodes:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 3, + y_min = -255, + heat_point = 50, + humidity_point = 50, + }) + + core.register_biome({ + name = "mapgen:grassland_under", + node_cave_liquid = {"basenodes:water_source", "basenodes:lava_source"}, + node_dungeon = "basenodes:cobble", + node_dungeon_alt = "basenodes:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 50, + humidity_point = 50, + }) +end diff --git a/data/games/garage/mods/mapgen/mod.conf b/data/games/garage/mods/mapgen/mod.conf new file mode 100644 index 0000000..15750cc --- /dev/null +++ b/data/games/garage/mods/mapgen/mod.conf @@ -0,0 +1,3 @@ +name = mapgen +description = Minimal map generator +depends = basenodes diff --git a/data/games/garage/mods/modchannels/init.lua b/data/games/garage/mods/modchannels/init.lua new file mode 100644 index 0000000..2003841 --- /dev/null +++ b/data/games/garage/mods/modchannels/init.lua @@ -0,0 +1,14 @@ +-- +-- Mod channels experimental handlers +-- +local mod_channel = core.mod_channel_join("experimental_preview") + +core.register_on_modchannel_message(function(channel, sender, message) + core.log("action", "[modchannels] Server received message `" .. message + .. "` on channel `" .. channel .. "` from sender `" .. sender .. "`") + + if mod_channel:is_writeable() then + mod_channel:send_all("experimental answers to preview") + mod_channel:leave() + end +end) diff --git a/data/games/garage/mods/modchannels/mod.conf b/data/games/garage/mods/modchannels/mod.conf new file mode 100644 index 0000000..7c13aad --- /dev/null +++ b/data/games/garage/mods/modchannels/mod.conf @@ -0,0 +1,2 @@ +name = modchannels +description = Add experimental mod channel handlers diff --git a/data/games/garage/mods/soundstuff/bigfoot.lua b/data/games/garage/mods/soundstuff/bigfoot.lua new file mode 100644 index 0000000..afa2b6e --- /dev/null +++ b/data/games/garage/mods/soundstuff/bigfoot.lua @@ -0,0 +1,48 @@ + +local walk_speed = 2 +local walk_distance = 10 + +core.register_entity("soundstuff:bigfoot", { + initial_properties = { + physical = false, + collisionbox = {-1, -1, -1, 1, 1, 1}, + selectionbox = {-1, -1, -1, 1, 1, 1}, + visual = "upright_sprite", + visual_size = {x = 2, y = 2, z = 2}, + textures = {"soundstuff_bigfoot.png", "soundstuff_bigfoot.png^[transformFX"}, + makes_footstep_sound = true, + static_save = false, + }, + + on_activate = function(self, _staticdata, _dtime_s) + self.min_x = self.object:get_pos().x - walk_distance * 0.5 + self.max_x = self.min_x + walk_distance + self.vel = vector.new(walk_speed, 0, 0) + end, + + on_step = function(self, _dtime, _moveresult) + local pos = self.object:get_pos() + if pos.x < self.min_x then + self.vel = vector.new(walk_speed, 0, 0) + elseif pos.x > self.max_x then + self.vel = vector.new(-walk_speed, 0, 0) + end + self.object:set_velocity(self.vel) + end, +}) + +core.register_chatcommand("spawn_bigfoot", { + params = "", + description = "Spawn a big foot object that makes footstep sounds", + func = function(name, _param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local pos = player:get_pos() + pos.y = pos.y + player:get_properties().collisionbox[2] + pos.y = pos.y - (-1) -- bigfoot collisionbox goes 1 down + core.add_entity(pos, "soundstuff:bigfoot") + return true + end, +}) diff --git a/data/games/garage/mods/soundstuff/init.lua b/data/games/garage/mods/soundstuff/init.lua new file mode 100644 index 0000000..6c0049a --- /dev/null +++ b/data/games/garage/mods/soundstuff/init.lua @@ -0,0 +1,6 @@ + +local path = core.get_modpath("soundstuff") .. "/" +dofile(path .. "sound_event_items.lua") +dofile(path .. "jukebox.lua") +dofile(path .. "bigfoot.lua") +dofile(path .. "racecar.lua") diff --git a/data/games/garage/mods/soundstuff/jukebox.lua b/data/games/garage/mods/soundstuff/jukebox.lua new file mode 100644 index 0000000..6c70fe3 --- /dev/null +++ b/data/games/garage/mods/soundstuff/jukebox.lua @@ -0,0 +1,331 @@ +local F = core.formspec_escape + +-- hashed node pos -> sound handle +local played_sounds = {} + +-- all of these can be set via the formspec +local meta_keys = { + -- SimpleSoundSpec + "sss.name", + "sss.gain", + "sss.pitch", + "sss.fade", + -- sound parameters + "sparam.gain", + "sparam.pitch", + "sparam.fade", + "sparam.start_time", + "sparam.loop", + "sparam.pos", + "sparam.object", + "sparam.to_player", + "sparam.exclude_player", + "sparam.max_hear_distance", + -- fade + "fade.step", + "fade.gain", + -- other + "ephemeral", +} + +local function get_all_metadata(meta) + return { + sss = { + name = meta:get_string("sss.name"), + gain = meta:get_string("sss.gain"), + pitch = meta:get_string("sss.pitch"), + fade = meta:get_string("sss.fade"), + }, + sparam = { + gain = meta:get_string("sparam.gain"), + pitch = meta:get_string("sparam.pitch"), + fade = meta:get_string("sparam.fade"), + start_time = meta:get_string("sparam.start_time"), + loop = meta:get_string("sparam.loop"), + pos = meta:get_string("sparam.pos"), + object = meta:get_string("sparam.object"), + to_player = meta:get_string("sparam.to_player"), + exclude_player = meta:get_string("sparam.exclude_player"), + max_hear_distance = meta:get_string("sparam.max_hear_distance"), + }, + fade = { + gain = meta:get_string("fade.gain"), + step = meta:get_string("fade.step"), + }, + ephemeral = meta:get_string("ephemeral"), + } +end + +local function log_msg(msg) + core.log("action", msg) + core.chat_send_all(msg) +end + +local function try_call(f, ...) + local function log_on_err(success, errmsg, ...) + if not success then + log_msg("[soundstuff:jukebox] Call failed: "..errmsg) + else + return errmsg, ... + end + end + + return log_on_err(pcall(f, ...)) +end + +local function show_formspec(pos, player) + local meta = core.get_meta(pos) + + local md = get_all_metadata(meta) + + local pos_hash = core.hash_node_position(pos) + local sound_handle = played_sounds[pos_hash] + + local fs = {} + local function fs_add(str) + table.insert(fs, str) + end + + fs_add([[ + formspec_version[6] + size[14,12] + ]]) + + -- SimpleSoundSpec + fs_add(string.format([[ + container[0.5,0.5] + box[-0.1,-0.1;4.2,3.2;#EBEBEB20] + style[*;font=mono,bold] + label[0,0.25;SimpleSoundSpec] + style[*;font=mono] + field[0.00,1.00;4,0.75;sss.name;name;%s] + field[0.00,2.25;1,0.75;sss.gain;gain;%s] + field[1.25,2.25;1,0.75;sss.pitch;pitch;%s] + field[2.50,2.25;1,0.75;sss.fade;fade;%s] + container_end[] + field_close_on_enter[sss.name;false] + field_close_on_enter[sss.gain;false] + field_close_on_enter[sss.pitch;false] + field_close_on_enter[sss.fade;false] + ]], F(md.sss.name), F(md.sss.gain), F(md.sss.pitch), F(md.sss.fade))) + + -- sound parameter table + fs_add(string.format([[ + container[5.5,0.5] + box[-0.1,-0.1;4.2,10.7;#EBEBEB20] + style[*;font=mono,bold] + label[0,0.25;sound parameter table] + style[*;font=mono] + field[0.00,1;1,0.75;sparam.gain;gain;%s] + field[1.25,1;1,0.75;sparam.pitch;pitch;%s] + field[2.50,1;1,0.75;sparam.fade;fade;%s] + field[0,2.25;4,0.75;sparam.start_time;start_time;%s] + field[0,3.50;4,0.75;sparam.loop;loop;%s] + field[0,4.75;4,0.75;sparam.pos;pos;%s] + field[0,6.00;4,0.75;sparam.object;object;%s] + field[0,7.25;4,0.75;sparam.to_player;to_player;%s] + field[0,8.50;4,0.75;sparam.exclude_player;exclude_player;%s] + field[0,9.75;4,0.75;sparam.max_hear_distance;max_hear_distance;%s] + container_end[] + field_close_on_enter[sparam.gain;false] + field_close_on_enter[sparam.pitch;false] + field_close_on_enter[sparam.fade;false] + field_close_on_enter[sparam.start_time;false] + field_close_on_enter[sparam.loop;false] + field_close_on_enter[sparam.pos;false] + field_close_on_enter[sparam.object;false] + field_close_on_enter[sparam.to_player;false] + field_close_on_enter[sparam.exclude_player;false] + field_close_on_enter[sparam.max_hear_distance;false] + tooltip[sparam.object;Get a name with the Branding Iron.] + ]], F(md.sparam.gain), F(md.sparam.pitch), F(md.sparam.fade), + F(md.sparam.start_time), F(md.sparam.loop), F(md.sparam.pos), + F(md.sparam.object), F(md.sparam.to_player), F(md.sparam.exclude_player), + F(md.sparam.max_hear_distance))) + + -- fade + fs_add(string.format([[ + container[10.75,3] + box[-0.1,-0.1;3.2,3.2;#EBEBEB20] + style[*;font=mono,bold] + label[0,0.25;fade] + style[*;font=mono] + field[0.00,1;1,0.75;fade.step;step;%s] + field[1.25,1;1,0.75;fade.gain;gain;%s] + ]], F(md.fade.step), F(md.fade.gain))) + if not sound_handle then + fs_add([[ + box[0,2;3,0.75;#363636FF] + label[0.25,2.375;no sound] + ]]) + else + fs_add([[ + button[0,2;3,0.75;btn_fade;Fade] + ]]) + end + fs_add([[ + container_end[] + field_close_on_enter[fade.step;false] + field_close_on_enter[fade.gain;false] + ]]) + + -- ephemeral + fs_add(string.format([[ + checkbox[0.5,5;ephemeral;ephemeral;%s] + ]], md.ephemeral)) + + -- play/stop and release buttons + if not sound_handle then + fs_add([[ + container[10.75,0.5] + button[0,0;3,0.75;btn_play;Play] + container_end[] + ]]) + else + fs_add([[ + container[10.75,0.5] + button[0,0;3,0.75;btn_stop;Stop] + button[0,1;3,0.75;btn_release;Release] + container_end[] + ]]) + end + + -- save and quit button + fs_add([[ + button_exit[10.75,11;3,0.75;btn_save_quit;Save & Quit] + ]]) + + core.show_formspec(player:get_player_name(), "soundstuff:jukebox@"..pos:to_string(), + table.concat(fs)) +end + +core.register_node("soundstuff:jukebox", { + description = "Jukebox\nAllows to play arbitrary sounds.", + tiles = {"soundstuff_jukebox.png"}, + groups = {dig_immediate = 2}, + + on_construct = function(pos) + local meta = core.get_meta(pos) + -- SimpleSoundSpec + meta:set_string("sss.name", "") + meta:set_string("sss.gain", "") + meta:set_string("sss.pitch", "") + meta:set_string("sss.fade", "") + -- sound parameters + meta:set_string("sparam.gain", "") + meta:set_string("sparam.pitch", "") + meta:set_string("sparam.fade", "") + meta:set_string("sparam.start_time", "") + meta:set_string("sparam.loop", "") + meta:set_string("sparam.pos", pos:to_string()) + meta:set_string("sparam.object", "") + meta:set_string("sparam.to_player", "") + meta:set_string("sparam.exclude_player", "") + meta:set_string("sparam.max_hear_distance", "") + -- fade + meta:set_string("fade.gain", "") + meta:set_string("fade.step", "") + -- other + meta:set_string("ephemeral", "") + + meta:mark_as_private(meta_keys) + end, + + on_rightclick = function(pos, _node, clicker, _itemstack, _pointed_thing) + show_formspec(pos, clicker) + end, +}) + +core.register_on_player_receive_fields(function(player, formname, fields) + if formname:sub(1, 19) ~= "soundstuff:jukebox@" then + return false + end + + local pos = vector.from_string(formname, 20) + if not pos or pos ~= pos:round() then + core.log("error", "[soundstuff:jukebox] Invalid formname.") + return true + end + + local meta = core.get_meta(pos) + + for _, k in ipairs(meta_keys) do + if fields[k] then + meta:set_string(k, fields[k]) + end + end + meta:mark_as_private(meta_keys) + + local pos_hash = core.hash_node_position(pos) + local sound_handle = played_sounds[pos_hash] + + if not sound_handle then + if fields.btn_play then + local md = get_all_metadata(meta) + + local sss = { + name = md.sss.name, + gain = tonumber(md.sss.gain), + pitch = tonumber(md.sss.pitch), + fade = tonumber(md.sss.fade), + } + local sparam = { + gain = tonumber(md.sparam.gain), + pitch = tonumber(md.sparam.pitch), + fade = tonumber(md.sparam.fade), + start_time = tonumber(md.sparam.start_time), + loop = core.is_yes(md.sparam.loop), + pos = vector.from_string(md.sparam.pos), + object = testtools.get_branded_object(md.sparam.object), + to_player = md.sparam.to_player, + exclude_player = md.sparam.exclude_player, + max_hear_distance = tonumber(md.sparam.max_hear_distance), + } + local ephemeral = core.is_yes(md.ephemeral) + + log_msg(string.format( + "[soundstuff:jukebox] Playing sound: core.sound_play(%s, %s, %s)", + string.format("{name=\"%s\", gain=%s, pitch=%s, fade=%s}", + sss.name, sss.gain, sss.pitch, sss.fade), + string.format("{gain=%s, pitch=%s, fade=%s, start_time=%s, loop=%s, pos=%s, " + .."object=%s, to_player=\"%s\", exclude_player=\"%s\", max_hear_distance=%s}", + sparam.gain, sparam.pitch, sparam.fade, sparam.start_time, + sparam.loop, sparam.pos, sparam.object and "", + sparam.to_player, sparam.exclude_player, + sparam.max_hear_distance), + tostring(ephemeral))) + + sound_handle = try_call(core.sound_play, sss, sparam, ephemeral) + + played_sounds[pos_hash] = sound_handle + show_formspec(pos, player) + end + + else + if fields.btn_stop then + log_msg("[soundstuff:jukebox] Stopping sound: core.sound_stop()") + + try_call(core.sound_stop, sound_handle) + + elseif fields.btn_release then + log_msg("[soundstuff:jukebox] Releasing handle.") + + played_sounds[pos_hash] = nil + show_formspec(pos, player) + + elseif fields.btn_fade then + local md = get_all_metadata(meta) + + local step = tonumber(md.fade.step) + local gain = tonumber(md.fade.gain) + + log_msg(string.format( + "[soundstuff:jukebox] Fading sound: core.sound_fade(, %s, %s)", + step, gain)) + + try_call(core.sound_fade, sound_handle, step, gain) + end + end + + return true +end) diff --git a/data/games/garage/mods/soundstuff/mod.conf b/data/games/garage/mods/soundstuff/mod.conf new file mode 100644 index 0000000..a6ed6d4 --- /dev/null +++ b/data/games/garage/mods/soundstuff/mod.conf @@ -0,0 +1,3 @@ +name = soundstuff +description = Example items and nodes for testing sound effects +depends = testtools diff --git a/data/games/garage/mods/soundstuff/racecar.lua b/data/games/garage/mods/soundstuff/racecar.lua new file mode 100644 index 0000000..9162792 --- /dev/null +++ b/data/games/garage/mods/soundstuff/racecar.lua @@ -0,0 +1,31 @@ + +local drive_speed = 20 +local drive_distance = 30 + +core.register_entity("soundstuff:racecar", { + initial_properties = { + physical = false, + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + visual = "upright_sprite", + visual_size = {x = 1, y = 1, z = 1}, + textures = {"soundstuff_racecar.png", "soundstuff_racecar.png^[transformFX"}, + static_save = false, + }, + + on_activate = function(self, _staticdata, _dtime_s) + self.min_x = self.object:get_pos().x - drive_distance * 0.5 + self.max_x = self.min_x + drive_distance + self.vel = vector.new(drive_speed, 0, 0) + end, + + on_step = function(self, _dtime, _moveresult) + local pos = self.object:get_pos() + if pos.x < self.min_x then + self.vel = vector.new(drive_speed, 0, 0) + elseif pos.x > self.max_x then + self.vel = vector.new(-drive_speed, 0, 0) + end + self.object:set_velocity(self.vel) + end, +}) diff --git a/data/games/garage/mods/soundstuff/sound_event_items.lua b/data/games/garage/mods/soundstuff/sound_event_items.lua new file mode 100644 index 0000000..9b2eb6b --- /dev/null +++ b/data/games/garage/mods/soundstuff/sound_event_items.lua @@ -0,0 +1,209 @@ +local simple_nodes = { + footstep = { "Footstep Sound Node", "soundstuff_node_footstep.png", "Plays sound when you step on it" }, + dig = { "Dig Sound Node", "soundstuff_node_dig.png", "Plays sound when you dig it" }, + dug = { "Dug Sound Node", "soundstuff_node_dug.png", "Plays sound when you've dug it" }, + place = { "Place Sound Node", "soundstuff_node_place.png", "Plays sound when you place it" }, + place_failed = { "Place Failed Sound Node", "soundstuff_node_place_failed.png", "Plays sound when you try to place it but failed" }, +} + +for k,v in pairs(simple_nodes) do + core.register_node("soundstuff:"..k, { + description = v[1].."\n"..v[3], + tiles = {"soundstuff_node_sound.png","soundstuff_node_sound.png",v[2]}, + groups = {dig_immediate=2}, + sounds = { + [k] = { name = "soundstuff_mono", gain = 1.0 }, + } + }) +end + +core.register_node("soundstuff:place_failed_attached", { + description = "Attached Place Failed Sound Node".."\n".. + "Attached to the floor; plays a sound when you try to place it but failed", + tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_place_failed.png"}, + groups = {dig_immediate=2, attached_node=1}, + drawtype = "nodebox", + paramtype = "light", + node_box = { type = "fixed", fixed = { + { -7/16, -7/16, -7/16, 7/16, 7/16, 7/16 }, + { -0.5, -0.5, -0.5, 0.5, -7/16, 0.5 }, + }}, + sounds = { + place_failed = { name = "soundstuff_mono", gain = 1.0 }, + }, +}) + +core.register_node("soundstuff:fall", { + description = "Fall Sound Node".."\n".. + "Falls and plays sound if node below is gone", + tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_fall.png"}, + groups = {dig_immediate=2, falling_node=1}, + sounds = { + fall = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + +core.register_node("soundstuff:fall_attached", { + description = "Attached Fall Sound Node".."\n".. + "Drops as item and plays sound if node below is gone", + tiles = {"soundstuff_node_sound.png", "soundstuff_node_sound.png", "soundstuff_node_fall.png"}, + groups = {dig_immediate=2, attached_node=1}, + drawtype = "nodebox", + paramtype = "light", + node_box = { type = "fixed", fixed = { + { -7/16, -7/16, -7/16, 7/16, 7/16, 7/16 }, + { -0.5, -0.5, -0.5, 0.5, -7/16, 0.5 }, + }}, + sounds = { + fall = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + +core.register_node("soundstuff:footstep_liquid", { + description = "Liquid Footstep Sound Node".."\n".. + "Plays sound when moving inside it; swimmable", + drawtype = "liquid", + tiles = { + "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190", + }, + special_tiles = { + {name = "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190", + backface_culling = false}, + {name = "soundstuff_node_sound.png^[colorize:#0000FF:127^[opacity:190", + backface_culling = true}, + }, + liquids_pointable = true, + liquidtype = "source", + liquid_alternative_flowing = "soundstuff:footstep_liquid", + liquid_alternative_source = "soundstuff:footstep_liquid", + liquid_renewable = false, + liquid_range = 0, + liquid_viscosity = 0, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + post_effect_color = {a = 64, r = 0, g = 0, b = 200}, + sounds = { + footstep = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + +core.register_node("soundstuff:footstep_climbable", { + description = "Climbable Footstep Sound Node".."\n".. + "Plays sound when moving inside it; can climb up and down here", + drawtype = "allfaces", + tiles = { + "soundstuff_node_climbable.png", + }, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + climbable = true, + is_ground_content = false, + groups = { dig_immediate = 2 }, + sounds = { + footstep = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + + + +core.register_craftitem("soundstuff:eat", { + description = "Eat Sound Item".."\n".. + "Makes a sound when 'eaten' (with punch key)", + inventory_image = "soundstuff_eat.png", + on_use = core.item_eat(0), + sound = { + eat = { name = "soundstuff_mono", gain = 1.0 }, + } +}) + +core.register_tool("soundstuff:breaks", { + description = "Break Sound Tool".."\n".. + "Digs cracky=3 and more".."\n".. + "Makes a sound when it breaks", + inventory_image = "soundstuff_node_dug.png", + sound = { + breaks = { name = "soundstuff_mono", gain = 1.0 }, + }, + tool_capabilities = { + max_drop_level=0, + groupcaps={ + cracky={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0}, + choppy={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0}, + snappy={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0}, + crumbly={times={[2]=2.00, [3]=1.20}, uses=1, maxlevel=0}, + }, + }, +}) + + +core.register_tool("soundstuff:punch_use", { + description = "Punch Use Sound Tool\n".. + "Digs cracky=3 and more\n".. + "Makes a sound when used on node or entity", + inventory_image = "soundstuff_node_dig.png", + sound = { + punch_use = { name = "soundstuff_mono", gain = 1.0 }, + }, + tool_capabilities = { + max_drop_level=0, + groupcaps={ + cracky={times={[2]=2.00, [3]=1.20}, uses=0, maxlevel=0}, + choppy={times={[2]=2.00, [3]=1.20}, uses=0, maxlevel=0}, + snappy={times={[2]=2.00, [3]=1.20}, uses=0, maxlevel=0}, + crumbly={times={[2]=2.00, [3]=1.20}, uses=0, maxlevel=0}, + }, + }, +}) + +core.register_tool("soundstuff:punch_use_air", { + description = "Punch Use (Air) Sound Tool\n".. + "Makes a sound when used pointing at nothing", + inventory_image = "soundstuff_node_dig.png", + sound = { + punch_use_air = { name = "soundstuff_mono", gain = 1.0 }, + }, +}) + +-- Plays sound repeatedly +core.register_node("soundstuff:positional", { + description = "Positional Sound Node".."\n".. + "Repeatedly plays a sound at the node location", + on_construct = function(pos) + local timer = core.get_node_timer(pos) + timer:start(0) + end, + on_timer = function(pos, elapsed) + local node = core.get_node(pos) + local dist = node.param2 + if dist == 0 then + dist = nil + end + core.sound_play("soundstuff_mono", { pos = pos, max_hear_distance = dist }) + local timer = core.get_node_timer(pos) + timer:start(0.7) + end, + on_rightclick = function(pos, node, clicker) + node.param2 = (node.param2 + 1) % 64 + core.set_node(pos, node) + if clicker and clicker:is_player() then + local dist = node.param2 + local diststr + if dist == 0 then + diststr = "" + else + diststr = tostring(dist) + end + core.chat_send_player(clicker:get_player_name(), "max_hear_distance = " .. diststr) + end + end, + + groups = { dig_immediate = 2 }, + tiles = { "soundstuff_node_sound.png" }, +}) + diff --git a/data/games/garage/mods/soundstuff/sounds/gitignored_sounds/custom_sounds_here.txt b/data/games/garage/mods/soundstuff/sounds/gitignored_sounds/custom_sounds_here.txt new file mode 100644 index 0000000..f07d44b --- /dev/null +++ b/data/games/garage/mods/soundstuff/sounds/gitignored_sounds/custom_sounds_here.txt @@ -0,0 +1,2 @@ +Put your own testing sounds here. The folder is gitignored. +Using a sound-pack is also possible. diff --git a/data/games/garage/mods/soundstuff/sounds/soundstuff_mono.ogg b/data/games/garage/mods/soundstuff/sounds/soundstuff_mono.ogg new file mode 100644 index 0000000000000000000000000000000000000000..43428d5664cbb98fe197b7b04330bf0abfd23abf GIT binary patch literal 4362 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 J%Q~loCIDGHG0p%0 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/soundstuff/textures/soundstuff_eat.png b/data/games/garage/mods/soundstuff/textures/soundstuff_eat.png new file mode 100644 index 0000000000000000000000000000000000000000..aed205422ec6f8a10055baeb2d7a83e99b3a6756 GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|7M?DSAr*|t5mN3_Ou?!yN~e-TpXA^SOo;uGX@Ltnj8@PDaCe=KY^iK!d1|H`xX}|CWgSmSLqiYWpo0~VDNPH Kb6Mw<&;$U~cp97l literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/soundstuff/textures/soundstuff_jukebox.png b/data/games/garage/mods/soundstuff/textures/soundstuff_jukebox.png new file mode 100644 index 0000000000000000000000000000000000000000..b8c17a669db76b28dd336c75e07a6bde822a6720 GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|u0Ze!wloI_U<-ohR2cURcd^*{+uyV17paQ5hSnT8=WGyWiq( h~DYuCG^|OMwP5c)I$ztaD0e0s!p6CRYFe literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/soundstuff/textures/soundstuff_node_dug.png b/data/games/garage/mods/soundstuff/textures/soundstuff_node_dug.png new file mode 100644 index 0000000000000000000000000000000000000000..bab5fbe516cf878f5bd81987458df8556cd85cd0 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|-kvUwAr*{MFEX+*D2lLLuzfi% zY5kV(Z@A+hE|qjP(7*C|f8_IzvD+P0na$YJgKswWHu|zMurVxiz7X3Ke#wgM5Bpu- f22BR82_+0X+h1}qocrMoG?u~B)z4*}Q$iB}Yyv5Q literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/soundstuff/textures/soundstuff_node_fall.png b/data/games/garage/mods/soundstuff/textures/soundstuff_node_fall.png new file mode 100644 index 0000000000000000000000000000000000000000..17b14f1e4aa456f652b0f55b50acc82f12c65577 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|+MX_sAr*|t5mN3_Ou?!yN?KVA x%x|RJOdl{*D81>#fouk5pTb>BRWAuJq}si+s7Z?|1De9% M>FVdQ&MBb@05g;ud;kCd literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/soundstuff/textures/soundstuff_node_place_failed.png b/data/games/garage/mods/soundstuff/textures/soundstuff_node_place_failed.png new file mode 100644 index 0000000000000000000000000000000000000000..780ba946d28da2347913ddd350da00a47d698946 GIT binary patch literal 143 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-u1n(>mX-iH41DYiHcbzA z09kgPE{-7;jL8hl7cX28;7}B^`^we);_FL?yq_@&g3(+e(Ndh_GGsPzX2q mt2bdrovel+TS(6ZZYBmRR*@G@JFAjGhI+dCxvX?{wo$!WzlT+uX3Wo)ZR~)367)-35?oSt;v;k-g NgQu&X%Q~loCIDhg9Gn0E literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/soundstuff/textures/soundstuff_racecar.png b/data/games/garage/mods/soundstuff/textures/soundstuff_racecar.png new file mode 100644 index 0000000000000000000000000000000000000000..8e8ff5ac7ff0512801c6ea2f589e57f7017cb0cb GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|u0R?H{xdMx{=TaVWHFWm z`2{mLJiCzwFVdQ&MBb@0I2#O3IG5A literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/stairs/init.lua b/data/games/garage/mods/stairs/init.lua new file mode 100644 index 0000000..267540e --- /dev/null +++ b/data/games/garage/mods/stairs/init.lua @@ -0,0 +1,66 @@ +stairs = {} + +-- Node will be called stairs:stair_ +function stairs.register_stair(subname, recipeitem, groups, images, description) + core.register_node(":stairs:stair_" .. subname, { + description = description.."\n".. + "param2 = facedir rotation (0..23)", + drawtype = "nodebox", + tiles = images, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = true, + groups = groups, + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + }) +end + +-- Node will be called stairs:slab_ +function stairs.register_slab(subname, recipeitem, groups, images, description) + core.register_node(":stairs:slab_" .. subname, { + description = description, + drawtype = "nodebox", + tiles = images, + paramtype = "light", + is_ground_content = true, + groups = groups, + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + }, + }) +end + +-- Nodes will be called stairs:{stair,slab}_ +function stairs.register_stair_and_slab(subname, recipeitem, groups, images, desc_stair, desc_slab) + stairs.register_stair(subname, recipeitem, groups, images, desc_stair) + stairs.register_slab(subname, recipeitem, groups, images, desc_slab) +end + +stairs.register_stair_and_slab("stone", "basenodes:stone", + {cracky=3}, + {"default_stone.png"}, + "Stone Stair", + "Stone Slab") + +stairs.register_stair_and_slab("desert_stone", "basenodes:desert_stone", + {cracky=3}, + {"default_desert_stone.png"}, + "Desert Stone Stair", + "Desert Stone Slab") + +stairs.register_stair_and_slab("cobble", "basenodes:cobble", + {cracky=3}, + {"default_cobble.png"}, + "Cobblestone Stair", + "Cobblestone Slab") diff --git a/data/games/garage/mods/stairs/mod.conf b/data/games/garage/mods/stairs/mod.conf new file mode 100644 index 0000000..724bff8 --- /dev/null +++ b/data/games/garage/mods/stairs/mod.conf @@ -0,0 +1,3 @@ +name = stairs +description = Adds stairs and slabs +depends = basenodes diff --git a/data/games/garage/mods/testabms/README.md b/data/games/garage/mods/testabms/README.md new file mode 100644 index 0000000..60fa6d6 --- /dev/null +++ b/data/games/garage/mods/testabms/README.md @@ -0,0 +1,6 @@ +# Test ABMs + +This mod contains a nodes and related ABM actions. +By placing these nodes, you can test basic ABM behaviours. + +There are separate tests for ABM `chance`, `interval`, `min_y`, `max_y`, `neighbor` and `without_neighbor` fields. diff --git a/data/games/garage/mods/testabms/after_node.lua b/data/games/garage/mods/testabms/after_node.lua new file mode 100644 index 0000000..fa2b3ab --- /dev/null +++ b/data/games/garage/mods/testabms/after_node.lua @@ -0,0 +1,12 @@ + +local S = core.get_translator("testnodes") + +-- After ABM node +core.register_node("testabms:after_abm", { + description = S("After ABM processed node."), + drawtype = "normal", + tiles = { "testabms_after_node.png" }, + + groups = { dig_immediate = 3 }, +}) + diff --git a/data/games/garage/mods/testabms/chances.lua b/data/games/garage/mods/testabms/chances.lua new file mode 100644 index 0000000..a84e752 --- /dev/null +++ b/data/games/garage/mods/testabms/chances.lua @@ -0,0 +1,56 @@ +-- test ABMs with different chances + +local S = core.get_translator("testnodes") + +-- ABM chance 5 node +core.register_node("testabms:chance_5", { + description = S("Node for test ABM chance_5"), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", "Waiting for ABM testabms:chance_5") + end, +}) + +core.register_abm({ + label = "testabms:chance_5", + nodenames = "testabms:chance_5", + interval = 10, + chance = 5, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", "ABM testabsm:chance_5 changed this node.") + end +}) + +-- ABM chance 20 node +core.register_node("testabms:chance_20", { + description = S("Node for test ABM chance_20"), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", "Waiting for ABM testabms:chance_20") + end, +}) + +core.register_abm({ + label = "testabms:chance_20", + nodenames = "testabms:chance_20", + interval = 10, + chance = 20, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", "ABM testabsm:chance_20 changed this node.") + end +}) + diff --git a/data/games/garage/mods/testabms/init.lua b/data/games/garage/mods/testabms/init.lua new file mode 100644 index 0000000..8bf4975 --- /dev/null +++ b/data/games/garage/mods/testabms/init.lua @@ -0,0 +1,7 @@ +local path = core.get_modpath(core.get_current_modname()) + +dofile(path.."/after_node.lua") +dofile(path.."/chances.lua") +dofile(path.."/intervals.lua") +dofile(path.."/min_max.lua") +dofile(path.."/neighbors.lua") diff --git a/data/games/garage/mods/testabms/intervals.lua b/data/games/garage/mods/testabms/intervals.lua new file mode 100644 index 0000000..9284065 --- /dev/null +++ b/data/games/garage/mods/testabms/intervals.lua @@ -0,0 +1,56 @@ +-- test ABMs with different interval + +local S = core.get_translator("testnodes") + +-- ABM inteval 1 node +core.register_node("testabms:interval_1", { + description = S("Node for test ABM interval_1"), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", "Waiting for ABM testabms:interval_1") + end, +}) + +core.register_abm({ + label = "testabms:interval_1", + nodenames = "testabms:interval_1", + interval = 1, + chance = 1, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", "ABM testabsm:interval_1 changed this node.") + end +}) + +-- ABM interval 60 node +core.register_node("testabms:interval_60", { + description = S("Node for test ABM interval_60"), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", "Waiting for ABM testabms:interval_60") + end, +}) + +core.register_abm({ + label = "testabms:interval_60", + nodenames = "testabms:interval_60", + interval = 60, + chance = 1, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", "ABM testabsm:interval_60 changed this node.") + end +}) + diff --git a/data/games/garage/mods/testabms/min_max.lua b/data/games/garage/mods/testabms/min_max.lua new file mode 100644 index 0000000..b5df4e4 --- /dev/null +++ b/data/games/garage/mods/testabms/min_max.lua @@ -0,0 +1,58 @@ +-- test ABMs with min_y and max_y + +local S = core.get_translator("testnodes") + +-- ABM min_y node +core.register_node("testabms:min_y", { + description = S("Node for test ABM min_y."), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", "Waiting for ABM testabms:min_y at y "..pos.y.." with min_y = 0") + end, +}) + +core.register_abm({ + label = "testabms:min_y", + nodenames = "testabms:min_y", + interval = 10, + chance = 1, + min_y = 0, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", "ABM testabsm:min_y changed this node.") + end +}) + +-- ABM max_y node +core.register_node("testabms:max_y", { + description = S("Node for test ABM max_y."), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", "Waiting for ABM testabms:max_y at y "..pos.y.." with max_y = 0") + end, +}) + +core.register_abm({ + label = "testabms:max_y", + nodenames = "testabms:max_y", + interval = 10, + chance = 1, + max_y = 0, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", "ABM testabsm:max_y changed this node.") + end +}) + diff --git a/data/games/garage/mods/testabms/mod.conf b/data/games/garage/mods/testabms/mod.conf new file mode 100644 index 0000000..ad74cd2 --- /dev/null +++ b/data/games/garage/mods/testabms/mod.conf @@ -0,0 +1,2 @@ +name = testabms +description = Contains some nodes for test ABMs. diff --git a/data/games/garage/mods/testabms/neighbors.lua b/data/games/garage/mods/testabms/neighbors.lua new file mode 100644 index 0000000..0ce21c2 --- /dev/null +++ b/data/games/garage/mods/testabms/neighbors.lua @@ -0,0 +1,99 @@ +-- test ABMs with neighbor and without_neighbor + +local S = core.get_translator("testnodes") + +-- ABM required neighbor +core.register_node("testabms:required_neighbor", { + description = S("Node for test ABM required_neighbor.") .. "\n" + .. S("Sensitive neighbor node is testnodes:normal."), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", + "Waiting for ABM testabms:required_neighbor " + .. "(normal drawtype testnode sensitive)") + end, +}) + +core.register_abm({ + label = "testabms:required_neighbor", + nodenames = "testabms:required_neighbor", + neighbors = {"testnodes:normal"}, + interval = 1, + chance = 1, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", + "ABM testabsm:required_neighbor changed this node.") + end +}) + +-- ABM missing neighbor node +core.register_node("testabms:missing_neighbor", { + description = S("Node for test ABM missing_neighbor.") .. "\n" + .. S("Sensitive neighbor node is testnodes:normal."), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", + "Waiting for ABM testabms:missing_neighbor" + .. " (normal drawtype testnode sensitive)") + end, +}) + +core.register_abm({ + label = "testabms:missing_neighbor", + nodenames = "testabms:missing_neighbor", + without_neighbors = {"testnodes:normal"}, + interval = 1, + chance = 1, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", + "ABM testabsm:missing_neighbor changed this node.") + end +}) + +-- ABM required and missing neighbor node +core.register_node("testabms:required_missing_neighbor", { + description = S("Node for test ABM required_missing_neighbor.") .. "\n" + .. S("Sensitive neighbor nodes are testnodes:normal and testnodes:glasslike."), + drawtype = "normal", + tiles = { "testabms_wait_node.png" }, + + groups = { dig_immediate = 3 }, + + on_construct = function (pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", + "Waiting for ABM testabms:required_missing_neighbor" + .. " (wint normal drawtype testnode and no glasslike" + .. " drawtype testnode sensitive)") + end, +}) + +core.register_abm({ + label = "testabms:required_missing_neighbor", + nodenames = "testabms:required_missing_neighbor", + neighbors = {"testnodes:normal"}, + without_neighbors = {"testnodes:glasslike"}, + interval = 1, + chance = 1, + action = function (pos) + core.swap_node(pos, {name="testabms:after_abm"}) + local meta = core.get_meta(pos) + meta:set_string("infotext", + "ABM testabsm:required_missing_neighbor changed this node.") + end +}) + diff --git a/data/games/garage/mods/testabms/textures/testabms_after_node.png b/data/games/garage/mods/testabms/textures/testabms_after_node.png new file mode 100644 index 0000000000000000000000000000000000000000..dab87594b998dde660a623a10cb6e8fe9a1a8b74 GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#VfSXm-H;@Q#K(^opENwkdiDLntV2h`_qQKreZkP3#AD~DpHR%m*I>YK zwjGT(@8;C;|3_=v}$Oz_?mj^GY`-UXGp4=yt@ Y%$;W#T>IM27-%blr>mdKI;Vst0G7r(4*&oF literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testabms/textures/testabms_wait_node.png b/data/games/garage/mods/testabms/textures/testabms_wait_node.png new file mode 100644 index 0000000000000000000000000000000000000000..a9bd9a36f78fdc973c949fb4b9ded1d444215edd GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vfj|2BG;e?M9j;d3T7>A%)9PS@tiKNgrtl`-%3-M7kz|#}Bta^XmL%oFUpD#X->OMTD=4o-qQx2oT_|ManSMX`=ZSV<~ e)wuhgoj>ufCtviv(>g$#89ZJ6T-G@yGywp@vqLce literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/armor.lua b/data/games/garage/mods/testentities/armor.lua new file mode 100644 index 0000000..95351ab --- /dev/null +++ b/data/games/garage/mods/testentities/armor.lua @@ -0,0 +1,61 @@ +-- Armorball: Test entity for testing armor groups +-- Rightclick to change armor group + +local phasearmor = { + [0]={icy=100}, + [1]={fiery=100}, + [2]={icy=100, fiery=100}, + [3]={fleshy=-100}, + [4]={fleshy=1}, + [5]={fleshy=10}, + [6]={fleshy=50}, + [7]={fleshy=100}, + [8]={fleshy=200}, + [9]={fleshy=1000}, + [10]={fleshy=32767}, + [11]={immortal=1}, + [12]={punch_operable=1}, +} +local max_phase = 12 + +core.register_entity("testentities:armorball", { + initial_properties = { + hp_max = 20, + physical = false, + collisionbox = {-0.4,-0.4,-0.4, 0.4,0.4,0.4}, + visual = "sprite", + visual_size = {x=1, y=1}, + textures = {"testentities_armorball.png"}, + spritediv = {x=1, y=max_phase+1}, + initial_sprite_basepos = {x=0, y=0}, + }, + + _phase = 7, + + on_activate = function(self, staticdata) + core.log("action", "[testentities] armorball.on_activate") + self.object:set_armor_groups(phasearmor[self._phase]) + self.object:set_sprite({x=0, y=self._phase}) + end, + + on_rightclick = function(self, clicker) + -- Change armor group and sprite + self._phase = self._phase + 1 + if self._phase >= max_phase + 1 then + self._phase = 0 + end + self.object:set_sprite({x=0, y=self._phase}) + self.object:set_armor_groups(phasearmor[self._phase]) + end, + + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + if not puncher then + return + end + local name = puncher:get_player_name() + if not name then + return + end + core.chat_send_player(name, "time_from_last_punch="..string.format("%.3f", time_from_last_punch).."; damage="..tostring(damage)) + end, +}) diff --git a/data/games/garage/mods/testentities/init.lua b/data/games/garage/mods/testentities/init.lua new file mode 100644 index 0000000..4ad8557 --- /dev/null +++ b/data/games/garage/mods/testentities/init.lua @@ -0,0 +1,5 @@ +dofile(core.get_modpath("testentities").."/visuals.lua") +dofile(core.get_modpath("testentities").."/observers.lua") +dofile(core.get_modpath("testentities").."/selectionbox.lua") +dofile(core.get_modpath("testentities").."/armor.lua") +dofile(core.get_modpath("testentities").."/pointable.lua") diff --git a/data/games/garage/mods/testentities/mod.conf b/data/games/garage/mods/testentities/mod.conf new file mode 100644 index 0000000..7a8cb5a --- /dev/null +++ b/data/games/garage/mods/testentities/mod.conf @@ -0,0 +1,2 @@ +name = testentities +description = Example entities for testing diff --git a/data/games/garage/mods/testentities/models/LICENSE.txt b/data/games/garage/mods/testentities/models/LICENSE.txt new file mode 100644 index 0000000..4317d68 --- /dev/null +++ b/data/games/garage/mods/testentities/models/LICENSE.txt @@ -0,0 +1,7 @@ +Original model by MirceaKitsune (CC BY-SA 3.0). +Various alterations and fixes by kilbith, sofar, xunto, Rogier-5, TeTpaAka, Desour, +stujones11, An0n3m0us (CC BY-SA 3.0): + testentities_sam.b3d + +Jordach (CC BY-SA 3.0): + testentities_sam.png diff --git a/data/games/garage/mods/testentities/models/testentities_sam.b3d b/data/games/garage/mods/testentities/models/testentities_sam.b3d new file mode 100644 index 0000000000000000000000000000000000000000..3e0827e40b5608d36019d0cfef98994d2fb9584c GIT binary patch literal 73433 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 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/models/testentities_sam.png b/data/games/garage/mods/testentities/models/testentities_sam.png new file mode 100644 index 0000000000000000000000000000000000000000..05021781e03fbb71cb309d5ac233c6c90f332fda GIT binary patch literal 2754 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 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/textures/testentities_cube1.png b/data/games/garage/mods/testentities/textures/testentities_cube1.png new file mode 100644 index 0000000000000000000000000000000000000000..c667e425f451aae2c5d859d1f32428bb4c361f5b GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|o}Mm_Ar*|tKh7VR;Ks$U^4#n^ zcNM3MAN*_zY)vj4hi-E4o)D_=DB(5P#&|R2keNWI#$|@>vo^4$Ty@E8Sgm%G&B!#s dc8UiJgUY{7d9@u?!9YV9JYD@<);T3K0RXmoCei=^ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/textures/testentities_cube2.png b/data/games/garage/mods/testentities/textures/testentities_cube2.png new file mode 100644 index 0000000000000000000000000000000000000000..481823420c1030ae7be3944b1ed0115b7ddb9198 GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|?w&4=Ar*|tKh7VR;Ks$Ua$U?b zCl#lRAN*_zY)vj4hi-E4o)D_=DB(5P#&|R2keNWI#-)Y=o{druZe^q~$7n7!3y||t bVPcpXyJ-2*J?6)NMlyK1`njxgN@xNAZIdR( literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/textures/testentities_cube3.png b/data/games/garage/mods/testentities/textures/testentities_cube3.png new file mode 100644 index 0000000000000000000000000000000000000000..03b5daa15f10cc7bbc998db2dc75f7c7cd40addf GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|&YmugAr*|tKh7VR;Ks$UGVks? zUlpf}AN*_zY)vj4hi-E4o)D_=DB(5P#&|R2keNWI#-)Y=o{druZn5p>ozgDU$-ofc Wuzj|l*+LJXaSWcWelF{r5}E+!G9@Jd literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/textures/testentities_cube4.png b/data/games/garage/mods/testentities/textures/testentities_cube4.png new file mode 100644 index 0000000000000000000000000000000000000000..639204896232e73ba5cb54c9a4a2ed4b632009a9 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|uAVNAAr*|tKh7VR;Ks$Ua$bp1 zheykW5Ar+?JS?38Et>_UCa8Xx@Iophhk4V=mRtp)z$J_i!)|3ZFkbrO(8so_U8s|R ZLB8&^_UCa8Xx@Iophhk4V=mRtp)z$J_iC4@{a++f>b=9Rm^W{L+3 ZgQD%tPs(eR@_+_1c)I$ztaD0e0su&ACPM%K literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/textures/testentities_cube6.png b/data/games/garage/mods/testentities/textures/testentities_cube6.png new file mode 100644 index 0000000000000000000000000000000000000000..5f81a64d91be219377841be129da41e48db7856a GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|uAVNAAr*|tKh7VR;Ks$UGVYtn zG>?`GALMx)cvw0GS~d$xO;G(X;e}L24)dm!Ex8IpflC-4N(h-;ILa1ea)9BgbEgXf ZLrCXGRoR`_<^c_4@O1TaS?83{1OQxYCh!0N literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/textures/testentities_dungeon_master.png b/data/games/garage/mods/testentities/textures/testentities_dungeon_master.png new file mode 100644 index 0000000000000000000000000000000000000000..1e31077464eaf2b7e39a24f21687e15b723fb5f1 GIT binary patch literal 2855 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 L^>bP0l+XkKkyj%p literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testentities/textures/testentities_upright_sprite2.png b/data/games/garage/mods/testentities/textures/testentities_upright_sprite2.png new file mode 100644 index 0000000000000000000000000000000000000000..a79a760e341eb96412b298df8fc072249bfda002 GIT binary patch literal 119 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|cAhSdAr*{U`y1I93^-VSKd#&L ze@ElB1AENowm+D|^ICY_Iu?aJe0(8^J2sRH3$0an=dAEjv|%HY!T;t>;$kh_PP!Z9 SM3{jlF?hQAxvX 5 then + self.bgcolor = { + r = math.random(0, 255), + g = math.random(0, 255), + b = math.random(0, 255), + a = math.random(0, 255), + } + end + end + + assert(self.color) + self.object:set_properties({ + nametag = tostring(math.random(1000, 10000)), + nametag_color = self.color, + nametag_bgcolor = self.bgcolor, + }) + end, + + get_staticdata = function(self) + return core.serialize({ color = self.color, bgcolor = self.bgcolor }) + end, +}) diff --git a/data/games/garage/mods/testfood/init.lua b/data/games/garage/mods/testfood/init.lua new file mode 100644 index 0000000..0a264a3 --- /dev/null +++ b/data/games/garage/mods/testfood/init.lua @@ -0,0 +1,35 @@ +local S = core.get_translator("testfood") + +core.register_craftitem("testfood:good1", { + description = S("Good Food (+1)").."\n".. + S("Punch: Eat"), + inventory_image = "testfood_good.png", + on_use = core.item_eat(1), +}) +core.register_craftitem("testfood:good5", { + description = S("Good Food (+5)").."\n".. + S("Punch: Eat"), + inventory_image = "testfood_good2.png", + on_use = core.item_eat(5), +}) + +core.register_craftitem("testfood:bad1", { + description = S("Bad Food (-1)").."\n".. + S("Punch: Eat"), + inventory_image = "testfood_bad.png", + on_use = core.item_eat(-1), +}) +core.register_craftitem("testfood:bad5", { + description = S("Bad Food (-5)").."\n".. + S("Punch: Eat"), + inventory_image = "testfood_bad2.png", + on_use = core.item_eat(-5), +}) + +core.register_craftitem("testfood:replace1", { + description = S("Replacing Food (+1)").."\n".. + S("Punch: Eat and replace with 'Good Food (+1)'"), + inventory_image = "testfood_replace.png", + on_use = core.item_eat(1, "testfood:good1"), +}) + diff --git a/data/games/garage/mods/testfood/mod.conf b/data/games/garage/mods/testfood/mod.conf new file mode 100644 index 0000000..7bff21b --- /dev/null +++ b/data/games/garage/mods/testfood/mod.conf @@ -0,0 +1,2 @@ +name = testfood +description = For testing food items diff --git a/data/games/garage/mods/testfood/textures/testfood_bad.png b/data/games/garage/mods/testfood/textures/testfood_bad.png new file mode 100644 index 0000000000000000000000000000000000000000..6e92514407228ec296e19cddee0c1ed1d3384b62 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`uAVNAAr*|t4b6cc*u~XuHT<{Y z`G3*SjCsrdhlUI{(?XaR|*ddEN^0$*sz9iy0HGj z^aF!HJmC}$G?T&8)z4*}Q$iB}^Die( literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testfood/textures/testfood_good2.png b/data/games/garage/mods/testfood/textures/testfood_good2.png new file mode 100644 index 0000000000000000000000000000000000000000..e43dda209b1361c4d465ced4d962d551181b87dd GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`5uPrNAr*|t3(S8oA5M{8P}KR* zzC-PDS_`8APk4j0a*o?^fyzT%9J?8UnGUK8u+0$KF=xeJ{;R41cFPzI%=E+^3=_o# rUb8kedVJ1UVxf3ZS2MY4Y824M&x?Hck4y^#+QH!I>gTe~DWM4fIj$@2 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testfood/textures/testfood_replace.png b/data/games/garage/mods/testfood/textures/testfood_replace.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef6876e5bbf794803a9282601a1836def754849 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`ex5FlAr*|t5;Gsz%PelRulP_e z67yMpwPL-4&;FG+o!SS~|M{*mZpZEf)hIr*f@dT^6ZjBwh h!bOagoEa6246|yNc^<#LY(LOs22WQ%mvv4FO#sNwDZu~$ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/LICENSE.txt b/data/games/garage/mods/testformspec/LICENSE.txt new file mode 100644 index 0000000..07696cc --- /dev/null +++ b/data/games/garage/mods/testformspec/LICENSE.txt @@ -0,0 +1,14 @@ +License of media files +---------------------- +Content imported from minetest_game. + + +BlockMen (CC BY-SA 3.0) + default_chest_front.png + default_chest_lock.png + default_chest_side.png + default_chest_top.png + +stujones11 (CC BY-SA 3.0) +An0n3m0us (CC BY-SA 3.0) + testformspec_character.b3d diff --git a/data/games/garage/mods/testformspec/callbacks.lua b/data/games/garage/mods/testformspec/callbacks.lua new file mode 100644 index 0000000..a4df232 --- /dev/null +++ b/data/games/garage/mods/testformspec/callbacks.lua @@ -0,0 +1,51 @@ +local callback_test = 0 + +local out = function(player, formname, fields, number) + local snum = "" + if number then + snum = " "..number + end + local msg = "Formspec callback"..snum..": player="..player:get_player_name()..", formname=\""..tostring(formname).."\", fields="..dump(fields) + core.chat_send_player(player:get_player_name(), msg) + core.log("action", msg) +end + +core.register_on_player_receive_fields(function(player, formname, fields) + if callback_test == 1 then + out(player, formname, fields) + elseif callback_test == 2 then + out(player, formname, fields, 1) + end +end) +core.register_on_player_receive_fields(function(player, formname, fields) + if callback_test == 2 then + out(player, formname, fields, 2) + return true -- Disable the first callback + end +end) +core.register_on_player_receive_fields(function(player, formname, fields) + if callback_test == 2 then + out(player, formname, fields, 3) + end +end) + +core.register_chatcommand("test_formspec_callbacks", { + params = "[ 0 | 1 | 2 ]", + description = "Test: Change formspec callbacks testing mode", + func = function(name, param) + local mode = tonumber(param) + if not mode then + callback_test = (callback_test + 1 % 3) + else + callback_test = mode + end + if callback_test == 1 then + core.chat_send_player(name, "Formspec callback test mode 1 enabled: Logging only") + elseif callback_test == 2 then + core.chat_send_player(name, "Formspec callback test mode 2 enabled: Three callbacks, disable pre-registered callbacks") + else + callback_test = 0 + core.chat_send_player(name, "Formspec callback test disabled!") + end + end +}) diff --git a/data/games/garage/mods/testformspec/dummy_items.lua b/data/games/garage/mods/testformspec/dummy_items.lua new file mode 100644 index 0000000..50fb989 --- /dev/null +++ b/data/games/garage/mods/testformspec/dummy_items.lua @@ -0,0 +1,14 @@ +-- This code adds dummy items that are supposed to be used in formspecs +-- for testing item_image formspec elements. + +core.register_node("testformspec:node", { + description = "Formspec Test Node", + tiles = { "testformspec_node.png" }, + groups = { dig_immediate = 3, dummy = 1 }, +}) + +core.register_craftitem("testformspec:item", { + description = "Formspec Test Item", + inventory_image = "testformspec_item.png", + groups = { dummy = 1 }, +}) diff --git a/data/games/garage/mods/testformspec/formspec.lua b/data/games/garage/mods/testformspec/formspec.lua new file mode 100644 index 0000000..29014f1 --- /dev/null +++ b/data/games/garage/mods/testformspec/formspec.lua @@ -0,0 +1,591 @@ +local color = core.colorize + +-- \208\176 is a cyrillic small a +local unsafe_url = core.formspec_escape("https://u:p@wikipedi\208\176.org:1233/heIIoll?a=b#c") + +local clip_fs = [[ + style_type[label,button,image_button,item_image_button, + tabheader,scrollbar,table,animated_image + ,field,textarea,checkbox,dropdown;noclip=%c] + + label[0,0;A clipping test] + button_url[0,1;3,0.8;clip_button;A clipping test;]] .. unsafe_url .. [[] + image_button[0,2;3,0.8;testformspec_button_image.png;clip_image_button;A clipping test] + item_image_button[0,3;3,0.8;testformspec:item;clip_item_image_button;A clipping test] + tabheader[0,4.7;3,0.63;clip_tabheader;Clip,Test,Text,Tabs;1;false;false] + field[0,5;3,0.8;clip_field;Title;] + textarea[0,6;3,1;clip_textarea;Title;] + checkbox[0,7.5;clip_checkbox;This is a test;true] + dropdown[0,8;3,0.8;clip_dropdown;Select An Item,One,Two,Three,Four,Five;1] + scrollbar[0,9;3,0.8;horizontal;clip_scrollbar;3] + tablecolumns[text;text] + table[0,10;3,1;clip_table;one,two,three,four;1] + animated_image[-0.5,11;4.5,1;clip_animated_image;testformspec_animation.png;4;100] +]] + +local tabheaders_fs = [[ + tabheader[0,0;10,0.63;tabs_opaque;Opaque,Without,Border;1;false;false] + tabheader[0,1;10,0.63;tabs_opaque_border;Opaque,With,Border;1;false;true] + tabheader[0,2;10,0.63;tabs_transparent;Transparent,Without,Border;1;true;false] + tabheader[0,3;10,0.63;tabs_transparent_border;Transparent,With,Border;1;true;true] + tabheader[0,4;tabs_default;Default,Tabs;1] + tabheader[0,6;10,0.5;tabs_size1;Height=0.5;1;false;false] + tabheader[2,6;10,0.75;tabs_size1;Height=0.75;1;false;false] + tabheader[4,6;10,1;tabs_size2;Height=1;1;false;false] + tabheader[6,6;10,1.25;tabs_size2;Height=1.25;1;false;false] + tabheader[8,6;10,1.5;tabs_size2;Height=1.5;1;false;false] +]] + +local inv_style_fs = [[ + style_type[list;noclip=true] + list[current_player;main;-0.75,0.75;2,2] + + real_coordinates[false] + list[current_player;main;1.5,0;3,2] + real_coordinates[true] + + real_coordinates[false] + style_type[list;size=1.1;spacing=0.1] + list[current_player;main;5,0;3,2] + real_coordinates[true] + + style_type[list;size=.001;spacing=0] + list[current_player;main;7,3.5;8,4] + + box[3,3.5;1,1;#000000] + box[5,3.5;1,1;#000000] + box[4,4.5;1,1;#000000] + box[3,5.5;1,1;#000000] + box[5,5.5;1,1;#000000] + style_type[list;spacing=.25,.125;size=.75,.875] + list[current_player;main;3,3.5;3,3] + + style_type[list;spacing=0;size=1.1] + list[current_player;main;.5,7;8,4] +]] + +-- Some textures from textures/base/pack and Devtest, with many different sizes +-- and aspect ratios. +local image_column = "image,0=logo.png,1=crack_anylength.png^[invert:rgb,2=checkbox_16.png," .. + "3=checkbox_32.png,4=checkbox_64.png,5=default_lava.png," .. + "6=progress_bar.png,7=progress_bar_bg.png" +local words = { + "esciunt", "repudiandae", "repellat", "voluptatem", "autem", "vitae", "et", + "minima", "quasi", "facere", "nihil", "ea", "nemo", "rem", "non", "eos", + "laudantium", "eveniet", "veritatis", +} + +local reseed = math.random(2^31-1) +math.randomseed(1337) + +local table_content = {} +for i = 1, 100 do + table.insert(table_content, words[math.random(#words)]) + table.insert(table_content, words[math.random(#words)]) + table.insert(table_content, words[math.random(#words)]) + table.insert(table_content, math.random(0, 7)) + table.insert(table_content, math.random(0, 7)) + table.insert(table_content, math.random(0, 7)) + table.insert(table_content, words[math.random(#words)]) +end + +math.randomseed(reseed) + +local table_fs = table.concat({ + "tablecolumns[text,align=left;text,align=right;text,align=center;", + image_column, ",align=left;", + image_column, ",align=right;", + image_column, ",align=center;text,align=right]", + "table[0,0;17,12;the_table;", table.concat(table_content, ","), ";1]" +}) + +local hypertext_basic = [[A hypertext element +Normal test +This is a normal text. + +style test + + . + + +Tag test +normal +mono +bold +italic +underlined +big +bigger +left +
center
+right +justify. Here comes a blind text: Lorem testum dolor sit amet consecutor celeron fiftifahivus e shadoninia e smalus jokus anrus relsocutoti rubenwardus. Erasputinus hara holisti dominus wusi. Grumarinsti erltusmuate ol fortitusti fla flo, blani burki e sfani fahif. Ultae ratii, e megus gigae don anonimus. Grinus dimondus krockus e nore. Endus finalus nowus comus endus o blindus tekstus. + +Custom tag test + + + + + +color=green +Action: color=green +Action: hovercolor=yellow +Action URL: open URL +size=24 +font=mono +color=green font=mono size=24 + +action test +action + +img test +Normal: + +width=48 height=48: + +float=left: + +float=right: + + +item test +Normal: + +width=48 height=48 + +angle=30,0,0: + +angle=0,30,0: + +angle=0,0,30: + +rotate=yes: + +rotate=100,0,0: + +rotate=0,100,0: + +rotate=0,0,100: + +rotate=50,75,100: + +angle=-30,-45,90 rotate=100,150,-50: +]] + +local hypertext_global = [[ + +This is a test of the global tag. The parameters are: +background=gray margin=20 valign=bottom halign=right color=pink hovercolor=purple size=12 font=mono +action]] + +local hypertext_fs = "hypertext[0,0;11,9;hypertext;"..core.formspec_escape(hypertext_basic).."]".. + "hypertext[0,9.5;11,2.5;hypertext;"..core.formspec_escape(hypertext_global).."]" + +local style_fs = [[ + style[one_btn1;bgcolor=red;textcolor=yellow;bgcolor_hovered=orange; + bgcolor_pressed=purple] + button_url_exit[0,0;2.5,0.8;one_btn1;Button;]] .. unsafe_url .. [[] + + style[one_btn2;border=false;textcolor=cyan] ]].. + "button[0,1.05;2.5,0.8;one_btn2;Text " .. color("#FF0", "Yellow") .. [[] + + style[one_btn3;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png; + bgimg_pressed=testformspec_pressed.png] + button[0,2.1;1,1;one_btn3;Border] + + style[one_btn4;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png; + bgimg_pressed=testformspec_pressed.png;border=false] + button[1.25,2.1;1,1;one_btn4;NoBor] + + style[one_btn5;bgimg=testformspec_button_image.png;bgimg_hovered=testformspec_hovered.png; + bgimg_pressed=testformspec_pressed.png;border=false;alpha=false] + button[0,3.35;1,1;one_btn5;Alph] + + style[one_btn6;border=true] + image_button[0,4.6;1,1;testformspec_button_image.png;one_btn6;Border] + + style[one_btn7;border=false] + image_button[1.25,4.6;1,1;testformspec_button_image.png;one_btn7;NoBor] + + style[one_btn8;border=false] + image_button[0,5.85;1,1;testformspec_button_image.png;one_btn8;Border;false;true;testformspec_pressed.png] + + style[one_btn9;border=true] + image_button[1.25,5.85;1,1;testformspec_button_image.png;one_btn9;NoBor;false;false;testformspec_pressed.png] + + style[one_btn10;alpha=false] + image_button[0,7.1;1,1;testformspec_button_image.png;one_btn10;NoAlpha] + + style[one_btn11;alpha=true] + image_button[1.25,7.1;1,1;testformspec_button_image.png;one_btn11;Alpha] + + style[one_btn12;border=true] + item_image_button[0,8.35;1,1;testformspec:item;one_btn12;Border] + + style[one_btn13;border=false] + item_image_button[1.25,8.35;1,1;testformspec:item;one_btn13;NoBor] + + style[one_btn14;border=false;bgimg=testformspec_bg.png;fgimg=testformspec_button_image.png] + style[one_btn14:hovered;bgimg=testformspec_bg_hovered.png;fgimg=testformspec_hovered.png;textcolor=yellow] + style[one_btn14:pressed;bgimg=testformspec_bg_pressed.png;fgimg=testformspec_pressed.png;textcolor=blue] + style[one_btn14:hovered+pressed;textcolor=purple] + style[one_btn14:focused;textcolor=red] + image_button[0,9.6;1,1;testformspec_button_image.png;one_btn14;Bg] + + style[one_btn15;border=false;bgcolor=#1cc;bgimg=testformspec_bg.png;bgimg_hovered=testformspec_bg_hovered.png;bgimg_pressed=testformspec_bg_pressed.png] + item_image_button[1.25,9.6;1,1;testformspec:item;one_btn15;Bg] + + style[one_btn16;border=false;bgimg=testformspec_bg_9slice.png;bgimg_middle=4,6;padding=5,7;fgimg=testformspec_bg.png;fgimg_middle=1] + style[one_btn16:hovered;bgimg=testformspec_bg_9slice_hovered.png;fgimg=testformspec_bg_hovered.png] + style[one_btn16:pressed;bgimg=testformspec_bg_9slice_pressed.png;fgimg=testformspec_bg_pressed.png] + style[one_btn16:focused;bgimg=testformspec_bg_9slice_focused.png;fgimg=testformspec_bg_focused.png] + image_button[2.5,9.6;2,1;;one_btn16;9-Slice Bg] + + + container[2.75,0] + + style[one_tb1;textcolor=Yellow] + tabheader[0,3;2.5,0.63;one_tb1;Yellow,Text,Tabs;1;false;false] + + style[one_f1;textcolor=yellow] + field[0,4.25;2.5,0.8;one_f1;Field One;Yellow Text] + + style[one_f2;border=false;textcolor=cyan] + field[0,5.75;2.5,0.8;one_f2;Field Two;Borderless Cyan Text] + + style[one_f3;textcolor=yellow] + textarea[0,7.025;2.5,0.8;one_f3;Label;]] .. + core.formspec_escape("Yellow Text\nLine two") .. [[ ] + + style[one_f4;border=false;textcolor=cyan] + textarea[0,8.324999999999999;2.5,0.8;one_f4;Label;]] .. + core.formspec_escape("Borderless Cyan Text\nLine two") .. [[ ] + + container_end[] +]] + +local scroll_fs = + "button[8.5,1;4,1;outside;Outside of container]".. + "box[1,1;8,6;#00aa]".. + "scroll_container[1,1;8,6;scrbar;vertical]".. + "button[0,1;1,1;lorem;Lorem]".. + "animated_image[0,1;4.5,1;clip_animated_image;testformspec_animation.png;4;100]" .. + "button[0,10;1,1;ipsum;Ipsum]".. + "pwdfield[2,2;1,1;lorem2;Lorem]".. + "list[current_player;main;4,4;1,5;]".. + "box[2,5;3,2;#ffff00]".. + "image[1,10;3,2;testformspec_item.png]".. + "image[3,1;testformspec_item.png]".. + "item_image[2,6;3,2;testformspec:node]".. + "label[2,15;bla Bli\nfoo bar]".. + "item_image_button[2,3;1,1;testformspec:node;itemimagebutton;ItemImageButton]".. + "tooltip[0,11;3,2;Buz;#f00;#000]".. + "box[0,11;3,2;#00ff00]".. + "hypertext[3,13;3,3;;" .. hypertext_basic .. "]" .. + "hypertext[3,17;3,3;;Hypertext with no scrollbar\\; the scroll container should scroll.]" .. + "textarea[3,21;3,1;textarea;;More scroll within scroll]" .. + "container[0,18]".. + "box[1,2;3,2;#0a0a]".. + "scroll_container[1,2;3,2;scrbar2;horizontal;0.06]".. + "button[0,0;6,1;butnest;Nest]".. + "label[10,0.5;nest]".. + "scroll_container_end[]".. + "scrollbar[1,0;3.5,0.3;horizontal;scrbar2;0]".. + "container_end[]".. + "dropdown[0,6;2;hmdrpdwn;apple,bulb;1]".. + "image_button[0,4;2,2;testformspec_button_image.png;imagebutton;bbbbtt;false;true;testformspec_pressed.png]".. + "box[1,22.5;4,1;#a00a]".. + "scroll_container_end[]".. + "scrollbaroptions[max=170]".. -- lowest seen pos is: 0.1*170+6=23 (factor*max+height) + "scrollbar[7.5,0;0.3,4;vertical;scrbar;0]".. + "scrollbar[8,0;0.3,4;vertical;scrbarhmmm;0]".. + "dropdown[0,6;2;hmdrpdwnnn;Outside,of,container;1]".. + "scroll_container[0,8;10,4;scrbar420;vertical;0.1;2]".. + "button[0.5,0.5;10,1;;Container with padding=2]".. + "list[current_player;main;0,5;8,4;]".. + "scroll_container_end[]".. + "scrollbar[10.1,8;0.5,4;vertical;scrbar420;0]".. + -- Buttons for scale comparison + "button[11,8;1,1;;0]".. + "button[11,9;1,1;;1]".. + "button[11,10;1,1;;2]".. + "button[11,11;1,1;;3]".. + "button[11,12;1,1;;4]" + +--style_type[label;textcolor=green] +--label[0,0;Green] +--style_type[label;textcolor=blue] +--label[0,1;Blue] +--style_type[label;textcolor=;border=true] +--label[1.2,0;Border] +--style_type[label;border=true;bgcolor=red] +--label[1.2,1;Background] +--style_type[label;border=;bgcolor=] +--label[0.75,2;Reset] + +local window = { + sizex = 12, + sizey = 13, + positionx = 0.5, + positiony = 0.5, + anchorx = 0.5, + anchory = 0.5, + paddingx = 0.05, + paddingy = 0.05 +} + +local pages = { + -- Real Coordinates + [[ + formspec_version[3] + size[12,13] + image_button[0,0;1,1;logo.png;rc_image_button_1x1;1x1] + image_button[1,0;2,2;logo.png;rc_image_button_2x2;2x2] + button[0,2;1,1;rc_button_1x1;1x1] + button[1,2;2,2;rc_button_2x2;2x2] + item_image[0,4;1,1;air] + item_image[1,4;2,2;air] + item_image_button[0,6;1,1;testformspec:node;rc_item_image_button_1x1;1x1] + item_image_button[1,6;2,2;testformspec:node;rc_item_image_button_2x2;2x2] + field[3,.5;3,.5;rc_field;Field;text] + pwdfield[6,.5;3,1;rc_pwdfield;Password Field] + field[3,1;3,1;;Read-Only Field;text] + textarea[3,2;3,.5;rc_textarea_small;Textarea;text] + textarea[6,2;3,2;rc_textarea_big;Textarea;text\nmore text] + textarea[3,3;3,1;;Read-Only Textarea;text\nmore text] + textlist[3,4;3,2;rc_textlist;Textlist,Perfect Coordinates;1;false] + tableoptions[highlight=#ABCDEF75;background=#00000055;border=false] + table[6,4;3,2;rc_table;Table,Cool Stuff,Foo,Bar;2] + dropdown[3,6;3,1;rc_dropdown_small;This,is,a,dropdown;1] + dropdown[6,6;3,2;rc_dropdown_big;I,am,a,bigger,dropdown;5] + image[0,8;3,2;ignore.png] + box[3,7;3,1;#00A3FF] + checkbox[3,8;rc_checkbox_1;Check me!;false] + checkbox[3,9;rc_checkbox_2;Uncheck me now!;true] + scrollbar[0,11.5;11.5,.5;horizontal;rc_scrollbar_horizontal;500] + scrollbar[11.5,0;.5,11.5;vertical;rc_scrollbar_vertical;0] + list[current_player;main;6,8;3,2;1] + button[9,0;2.5,1;rc_empty_button_1;] + button[9,1;2.5,1;rc_empty_button_2;] + button[9,2;2.5,1;rc_empty_button_3;] ]].. + "label[9,0.5;This is a label.\nLine\nLine\nLine\nEnd]".. + [[button[9,3;1,1;rc_empty_button_4;] + vertlabel[9,4;VERT] + label[10,3;HORIZ] + tabheader[8,0;6,0.65;rc_tabheader;Tab 1,Tab 2,Tab 3,Secrets;1;false;false] + ]], + -- Style + + "formspec_version[3]size[12,13]" .. + ("label[0.375,0.375;Styled - %s %s]"):format( + color("#F00", "red text"), + color("#77FF00CC", "green text")) .. + "label[6.375,0.375;Unstyled]" .. + "box[0,0.75;12,0.1;#999]" .. + "box[6,0.85;0.1,11.15;#999]" .. + "container[0.375,1.225]" .. + style_fs .. + "container_end[]container[6.375,1.225]" .. + style_fs:gsub("one_", "two_"):gsub("style%[[^%]]+%]", ""):gsub("style_type%[[^%]]+%]", "") .. + "container_end[]", + + -- Noclip + "formspec_version[3]size[12,13]" .. + "label[0.1,0.5;Clip]" .. + "container[-2.5,1]" .. clip_fs:gsub("%%c", "false") .. "container_end[]" .. + "label[11,0.5;Noclip]" .. + "container[11.5,1]" .. clip_fs:gsub("%%c", "true") .. "container_end[]", + + -- Table + "size[18,13]real_coordinates[true]" .. + "container[0.5,0.5]" .. table_fs.. "container_end[]", + + -- Hypertext + "size[12,13]real_coordinates[true]" .. + "container[0.5,0.5]" .. hypertext_fs .. "container_end[]", + + -- Tabheaders + "size[12,13]real_coordinates[true]" .. + "container[0.5,1.5]" .. tabheaders_fs .. "container_end[]", + + -- Inv + "size[12,13]real_coordinates[true]" .. inv_style_fs, + + -- Window + function() + return "formspec_version[3]" .. + string.format("size[%s,%s]position[%s,%s]anchor[%s,%s]padding[%s,%s]", + window.sizex, window.sizey, window.positionx, window.positiony, + window.anchorx, window.anchory, window.paddingx, window.paddingy) .. + string.format("field[0.5,0.5;2.5,0.5;sizex;X Size;%s]field[3.5,0.5;2.5,0.5;sizey;Y Size;%s]" .. + "field[0.5,1.5;2.5,0.5;positionx;X Position;%s]field[3.5,1.5;2.5,0.5;positiony;Y Position;%s]" .. + "field[0.5,2.5;2.5,0.5;anchorx;X Anchor;%s]field[3.5,2.5;2.5,0.5;anchory;Y Anchor;%s]" .. + "field[0.5,3.5;2.5,0.5;paddingx;X Padding;%s]field[3.5,3.5;2.5,0.5;paddingy;Y Padding;%s]" .. + "button[2,4.5;2.5,0.5;submit_window;Submit]", + window.sizex, window.sizey, window.positionx, window.positiony, + window.anchorx, window.anchory, window.paddingx, window.paddingy) .. + "field_close_on_enter[sizex;false]field_close_on_enter[sizey;false]" .. + "field_close_on_enter[positionx;false]field_close_on_enter[positiony;false]" .. + "field_close_on_enter[anchorx;false]field_close_on_enter[anchory;false]" .. + "field_close_on_enter[paddingx;false]field_close_on_enter[paddingy;false]" + end, + + -- Animation + [[ + formspec_version[6] + size[12,13] + animated_image[0.5,0.5;1,1;;testformspec_animation.png;4;100] + animated_image[0.5,1.75;1,1;;testformspec_animation.jpg;4;100] + animated_image[1.75,0.5;1,1;;testformspec_animation.png;100;100] + animated_image[3,0.5;1,1;ani_img_1;testformspec_animation.png;4;1000] + image[0.5,3;1,1;testformspec_bg.png;1] + animated_image[0.5,4.25;1,1;;[combine:16x48:0,0=testformspec_bg.png:0,16=testformspec_bg_hovered.png:0,32=testformspec_bg_pressed.png;3;250;1;1] + image[0.5,5.5;2,1;testformspec_9slice.png;16,0,-16,-16] + animated_image[2.75,5.5;1.5,0.5;;[combine:300x140:0,0=testformspec_9slice.png:0,70=(testformspec_9slice.png^[transformFX);2;500;1;16,0,-16,-16] + button[4.25,0.5;1,1;ani_btn_1;Current +Number] + animated_image[3,1.75;1,1;ani_img_2;testformspec_animation.png;4;1000;2] + button[4.25,1.75;1,1;ani_btn_2;Current +Number] + animated_image[3,3;1,1;;testformspec_animation.png;4;0] + animated_image[3,4.25;1,1;;testformspec_animation.png;4;0;3] + animated_image[5.5,0.5;5,2;;testformspec_animation.png;4;100] + animated_image[5.5,2.75;5,2;;testformspec_animation.jpg;4;100] + + ]], + + -- Model + [[ + formspec_version[3] + size[12,13] + style[m1;bgcolor=black] + style[m2;bgcolor=black] + label[5,1;all defaults] + label[5,5.1;angle = 0, 180 +continuous = false +mouse control = false +frame loop range = 0,30] + label[5,9.2;continuous = true +mouse control = true] + model[0.5,0.1;4,4;m1;testformspec_character.b3d;testformspec_character.png] + model[0.5,4.2;4,4;m2;testformspec_character.b3d;testformspec_character.png;0,180;false;false;0,30] + model[0.5,8.3;4,4;m3;testformspec_chest.obj;default_chest_top.png,default_chest_top.png,default_chest_side.png,default_chest_side.png,default_chest_front.png,default_chest_inside.png;30,1;true;true] + ]], + + -- Scroll containers + "formspec_version[7]size[12,13]" .. + scroll_fs, + + -- Sound + [[ + formspec_version[3] + size[12,13] + style[snd_btn;sound=soundstuff_mono] + style[snd_ibtn;sound=soundstuff_mono] + style[snd_drp;sound=soundstuff_mono] + style[snd_chk;sound=soundstuff_mono] + style[snd_tab;sound=soundstuff_mono] + button[0.5,0.5;2,1;snd_btn;Sound] + image_button[0.5,2;2,1;testformspec_item.png;snd_ibtn;Sound] + dropdown[0.5,4;4;snd_drp;Sound,Two,Three;] + checkbox[0.5,5.5.5;snd_chk;Sound;] + tabheader[0.5,7;8,0.65;snd_tab;Soundtab1,Soundtab2,Soundtab3;1;false;false] + ]], + + -- Background + [[ + formspec_version[3] + size[12,13] + box[0,0;12,13;#f0f1] + background[0,0;0,0;testformspec_bg.png;true] + box[3.9,2.9;6.2,4.2;#d00f] + scroll_container[4,3;6,4;scrbar;vertical] + background9[1,0.5;0,0;testformspec_bg_9slice.png;true;4,6] + label[0,0.2;Backgrounds are not be applied to scroll containers,] + label[0,0.5;but to the whole form.] + scroll_container_end[] + scrollbar[3.5,3;0.3,4;vertical;scrbar;0] + container[2,11] + box[-0.1,0.5;3.2,1;#fff5] + background[0,0;2,3;testformspec_bg.png;false] + background9[1,0;2,3;testformspec_bg_9slice.png;false;4,6] + container_end[] + ]], + + -- Unsized + [[ + formspec_version[3] + background9[0,0;0,0;testformspec_bg_9slice.png;true;4,6] + background[1,1;0,0;testformspec_bg.png;true] + ]], +} + +local page_id = 2 +local function show_test_formspec(pname) + local page = pages[page_id] + if type(page) == "function" then + page = page() + end + + local fs = page .. "tabheader[0,0;11,0.65;maintabs;Real Coord,Styles,Noclip,Table,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound,Background,Unsized;" .. page_id .. ";false;false]" + + core.show_formspec(pname, "testformspec:formspec", fs) +end + +core.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "testformspec:formspec" then + return false + end + + if fields.maintabs then + page_id = tonumber(fields.maintabs) + show_test_formspec(player:get_player_name()) + return true + end + + if fields.ani_img_1 and fields.ani_btn_1 then + core.chat_send_player(player:get_player_name(), "ani_img_1 = " .. tostring(fields.ani_img_1)) + return true + elseif fields.ani_img_2 and fields.ani_btn_2 then + core.chat_send_player(player:get_player_name(), "ani_img_2 = " .. tostring(fields.ani_img_2)) + return true + end + + if fields.hypertext then + core.chat_send_player(player:get_player_name(), "Hypertext action received: " .. tostring(fields.hypertext)) + return true + end + + for name, value in pairs(fields) do + if window[name] then + print(name, window[name]) + local num_val = tonumber(value) or 0 + + if name == "sizex" and num_val < 4 then + num_val = 6.5 + elseif name == "sizey" and num_val < 5 then + num_val = 5.5 + end + + window[name] = num_val + print(name, window[name]) + end + end + + if fields.submit_window then + show_test_formspec(player:get_player_name()) + end +end) + +core.register_chatcommand("test_formspec", { + params = "", + description = "Open the test formspec", + func = function(name) + if not core.get_player_by_name(name) then + return false, "You need to be online!" + end + + show_test_formspec(name) + return true + end, +}) diff --git a/data/games/garage/mods/testformspec/init.lua b/data/games/garage/mods/testformspec/init.lua new file mode 100644 index 0000000..ef1a841 --- /dev/null +++ b/data/games/garage/mods/testformspec/init.lua @@ -0,0 +1,3 @@ +dofile(core.get_modpath("testformspec").."/dummy_items.lua") +dofile(core.get_modpath("testformspec").."/formspec.lua") +dofile(core.get_modpath("testformspec").."/callbacks.lua") diff --git a/data/games/garage/mods/testformspec/mod.conf b/data/games/garage/mods/testformspec/mod.conf new file mode 100644 index 0000000..00eac30 --- /dev/null +++ b/data/games/garage/mods/testformspec/mod.conf @@ -0,0 +1,2 @@ +name = testformspec +description = Contains an example formspec to test all the features of formspecs diff --git a/data/games/garage/mods/testformspec/models/testformspec_character.b3d b/data/games/garage/mods/testformspec/models/testformspec_character.b3d new file mode 100644 index 0000000000000000000000000000000000000000..8edbaf6377891568c248cd73d2d691f97c775311 GIT binary patch literal 73433 zcmeEvcX$)W6Sgq6>AiPjz?kMH+gQ@sGQET89Zc`d^lH(2@7?qe0 zEnY?u(WzaB_W4UFV)5c$&;}0l&DgZ@d~E!{c{2YDsDbB99T<R=veAjVyU9JYmca9GoI1jHU^Ff{NQ4AkP{j|p|?E238Q-415{+NEs=ecyW zXQupE)PFF$zIr@~U!U1Wd)#?_ZTW26$H!5B=eYCw>T$o! z`B9C-b@9l&f0y|~+wgHFpV`Mb|9l+n;~aO|M?LOm-nj9+ReSz)+`fUu54EqM=*M+u z3c$Dp_5TFM_bb;|kH@m{%_LuY+|N7!{Bymg|HhI1=dtmDANhZL<~ZC#toFEt$;WZ0 zeNcDQ6Xh%8czwk_+&0LGW%5P+)Z>bNIPR41I_|u_wtR~@PACKewDdWXp{A2mb{Nm@gWZH+zW(vT6{Fr;4i|G~Md*B|u2e^Cy`!}*E9_@zCbf&RtDF+P0!c^r58|HtDx zkk7_d^40n|<>U1SLmY>c_6Hd>-ZEfqs-JpV{Z*aUH)t z#YfbSAIuN={j>P-@#j&#(>~5|t|RKl?91dk?WZ1B@|W}e@cMk5$=C7x^Rav!ch0YB z9Onh)2;-{jtH#;&nSDMU*Wvx)^AL?;MKheKk$6fQAdOXuVRQd_ypak>JSm*t@jw|=?Tp#N3%>1KT zU#{cKzN-C`FwX6-+W)zZTX23<`$zS767zo?ckW+Z$Cc}YZ&3bHkF$Bi{HBV(uH!m( zeMLUYPvl#C{*-Z)uf$j3^Qd18&;QQ#oylSM&&QqqqaN2`d~u1Nd>rl1{M#jdsK@dC zmHnM_{jvLo`^a2>Z2#ws4}3fpIDVP?JMD1`laKL5TfQ=m>swi$JT~Ap{Fr=EKlQkx zAC5cayN)}ruPvXAv-m>es`<;jzACs`twfxvx|TH{uTYW z?Gf?wEWWb&`Pe^Vg>mQna2;^m59f#7zxMnn*9ejl>6iH-6@}sqkOjiX7aVi zQNC;b27 z9aruT?W5RVJsv0AzxKGF#`@thGOy44TQ$FQ|2U5Kr})3hKWH4U?;Ll|FPD$w?D}ke zobusQ%!bZ!=l$Ur9w<;6|9BkbJMH5f=Q_p<@}2Xe9@pv6e$M+t{rEVOpE>@qd>nVq zuWB6if#IJ`$Kdi{8`4kZKd$4h_EV4h;q{sS zIj`?JZi(s8u37uvbF%B{@cU5wUK9`fC+y?l3(W_bH?&;T$Md|<@<7WCEg$vqydbm! z(DFkoM14Fj3atpV!qAFQAJ0odgRfuI((5gbKPJKMD39SaSKxnn7kLUR1bRB55p#@VP&%>bM7u6xq z^wh`mNN5qz!lBirKAsz)8K6Z$Gf^MUG4bH$OoE1!gnc}(53L@wSZEEPVIR*MLu&-B zA+#pc$MfdUnn7y{tp)Y*yfw5|&{{%kLw!7N2dyo%IB4yukLR7Bb%fRdT4(Cxc{gZX zp>=`Qo%(p*3tCTTJ)rfbKA!i5)(2WVw0_XAkLLrS4S?1k+92xV`A}#>pbdsLjQV&! z650r8!=a6$KAz*Z{$rqxhBlV^cs>EzcxdCGO{6}aPk}ZW+9YUGsgLI~piPH14O$}g z@q8Avnb0iIW<$e1p3j3e7upf`w`XiK3jfwr9bc)kkSN@y#f zt)@PnuYk-x` zY(UtMun}Qn!X|`G37Zi%Cu~93lCTwFYr-~!afEFN+Yz=W>_CXY4v$U>u%L&hU8vuc zup41_!X6AQ=AMMT2zwL8GgN{gp7y1FKf?Zm0|*Ba4k8>(ID~L0;V{DCgd+$?5{@Dq zO*n=yfp9G0I6@4TcuY`$1x-AiME%KxQwXOLP9vO7ID;^e&_Xzqa2DZg!a0O<3Fi^c zCtN_dkZ=*CBx_G*Q`Wp#15pE{jLb#Q1 z8{u}sB*GnpI|+9Y?k3zrxR-DrVT(px+v9E}7xZ&LysLVfhQrm)DtL^M%fT-P_N=op|Jo z4Q=7db(MP$xEZAj*mG-eU2SFq?z}$H_BcZudddgpW$a)Ub^xcL(b zISRYMEeG5VIm$YUxWPUBZ=yNqroW@88{DbDZTe*mM=>|Jje)!NM3AGn2G`ZT)qtB~ z4|SAqgIgB3SB{1`O1i;Cxu1hv+*`Q%uj{;_zUx5W(r$3k4$Z(0W!&JReS^WiW!>QN zc`N4zm-|C`H@Mu-D!9Q#|2+x*TTz4SI&ZixWLOuKG`Ozz1`5GSi?a9!nM{G9{w7gEfB`Xt8n z%@EhCyTL`BHbA}zbd&1~d8me)T%fTB_5WH!sDn4it>vcNQ=o5cH@Ikr*= zE&=-nX>hgXZ9L3dum;yvF3)cv8eCVoJimo%a9!o{{1&Fcb(PE4h29M=t~U$hH`ug% zo`J#>#76Bhf@$ABHiF(-1#5mx4Ld{c|419gIf;dc7*(9aD&U^uh9)I z#`Pu;*G+D4F<-2Qd?9IYUG2;BP_!Fdp5J2J;G*1Skl%1~_g`xh^&NRU$Pw!XcN%cd zIBGcRxxqaP+&2z?M}0TA6=B}IZj^B}(BQh-%mUo`frT6m-QfNJ+>5_^IU2daZ43VU zMZur!josi{fg3dIvb~80*L7XwgZ0*;a*DmF8{Ce-{p!|gdovBLs~uJX_lM%6?D!n+ zI>)ZuW58YRZ?w12;JWI2AGp2h=e4(VgZm1&eXF0awQ_^|4{%e~O|-RkgNt#!=9|2> zHg0fH|FwI^r^mU;_5EaQT3a`{Kx1FbqJ6Jk%5U~9JOn}^f6i0BUjvE-|LwC6K8xBz z#~p65uvKXtG`OzwhH{tpTbNNaCoH#j*WkL^EH7{i4NkH5(BQh-VLPnj z*kw2DJ>B5?0k`RuKkdET;I4tVW6NE@(c2B~dx(?Ut5tBsyTKg@+?fE(O#z)fx3(J{~sZa?52 z9^c6^$PF&at<$8VW3U@s)c5nlZ5>10;Qj*KW%d>h{2tJC&Aa+!XRz<{0Sz3(G`Oxl zc@wz)m!llR-Qe~Ge`x4m+cClo?%%+T+FQXf(hcr1@Za8t3phq;a9!`MEUb&=6aTi4 z*5JC{+eY9%nQ+TK#tp77tmD85Ry%%A`d{|#4%{nqR@%pEa9wrS4BS2S`q{_1!954u zV{tX?*od&Btq1H|9O8eG?V z<8gh78(hp62O(c9b%Tp}Cz9zb$uzi*k#A+!bzcQQzyZJQfhjK4k`*4wtb!Ns_~Y*tNMk{evK zVe!1{(|5SZ^(nh9ZKs>uqo;B$-lgWU_j~Yt38ldh9+qFdBjn$`Bh0&@lQ|dv!QJBl zcdrNBeI9T>@qoLZxcGiacE4|yI{J0mr^F4A&t=OkvujM+0pi~5d^TI|&QbZ(J|pg# zdZ)7GrtZr)dXTu|?qy`lje9%g=po|jblG!(ru*DYxxd~$SvQ%u|E2HH`5mKDi2Gl5 zcsFK8R4Q@*%f5fzJ`-gnt{d|fb=U*BUwEMJ5#s)r9fpG)juQ93=Iu4uH;uUN%v-vf za$(+%+T7F^<}J-mTsP(|%|To@<}K|Qaow1=wBv4acggGW$Zl{aK>RIPe6A@&gX@~# zw)_R(8x@@(op6IY^ZP_|dW)Z>lNwytTv+~6qPfDK{?Vu0;3l0&G@CvRi$3iJHwxrl zzvv%*MuY2mZ)ZT?p8{S=XEnI4`d$M&1kOs3zSQ8l%AE!F{j=f>(>V>Ut6Zh8)1CK# zdx5w&d@p3iJ}n*osW`)ak+{>07c;r8I^exkpOxUaMBF)NE@g6E<)Y1A1iW;7Mcg`n zf0fB~m5X!n^+o?j2G{?uTxFPrI%|!E>UyB~Qs-dr|4om({G`D{x-)Ng-H?m^a1H$7o`$|z`PqHqW;bu#e;*K6J#VgZac%lmnqhxP-0bE} zu_3&`4KLwNuLUo559otmf$A*yAw;K<`40r}uXKnn;X2>s_oDHfgx-WcguaBi2y+wW zA{*pIM3L**|L@N^*c z2N4b?96~sha2Vlm!V!cc2}co*CLBYUKsc6g9N~Dv34{{~ClO92oI*I2a2nxs!Wo2# zgcib?gtG`|6V4%=OE`~kKH&nwg@lU;7ZWZaTuQi%a5>=$h8FWm!c~N;3D*#=C0s|i zo^S)mn+dlNZYA7CxScSGa0lT|!d-;B3HK20CEQ2o`VubuGmpP`3d>C0bQbn8 z_>Y%z@(~vk0)A$9tq)Oq!ltBoh2}h(lW{Ep_?MIPu}r!6WktC*I^(}vr>4*UC1;wq z!rey|rqr4AJdA4zfWP951s>CZ>wFZxKzlXm4^!*p(e{c%{!PzIa*3NM z7x{DHi@8F*N=Yw79mNHp*M zdyW*_*UNF;zQ9(9xHNC6YHsLniRMY6DBFcxj?Rz2uoWk{iXAMO`l9@fz|DASm74Sq zag2YPW-CEll517#Pyx6^JBQ6yQj{yqaa-WpLGG#3A&#B#>9$fX`l@aA z61aUp-%oxHa;#4{YAa20xgFFt`|)RZQ5Wnm_);xL`r6TOntELy{o&W zv0bV=?#=kzR+e;doj3f<)7OdS@i1?O<&_=NM(nqhBe~ok)Np1#$ zhpjwuxu0<^eyMo$_e66~@UyYyiaLrIHri;i^m&*PUalByxqh=nY@;8(_WN8}rmYf7@uAALHsQTI={Jtj*7Q zmXbQm_{u)O(%Dv7k;~&l3fh&=M*zf!c!&>YGY;DaE{nGLlU%YHix1oul_Borg18fK zXtTXegDSQv#MO#t_kf!p;@J;}XW3U4&10)dT*W8FIN1&Kd0M)uY0AhB_L5(IlU_~K zA(`undVC7p{Sbf47pi72U*=$X0OMM?eTBGwAGoC*u3sp-`fu4caY9k@jx zUo>5#SD zCpAAr{nM$qar27JQMIzr7q5@{9%-#JK5w$gxaneLLv4kdr5#dEt}rI%cx^17I@M5z zbf7s-cIs&{?+3Zf!M+;@S2LBEc+e2!qOY3U6}Ww1-oE&|gQg|0KlRs;V{oA`%m z-LNlAU)GB;LSSTM*L8uPc?|2KDXfckahFZIdUi4D6)LwGi>X|X9@xXmCBRhL7hO@nO4Xi;B5 zhoZop0{N|8w=fCbjWouHas~UM+(ExvrKKZ6CGVm(BWxb=u(U$5l?NX$iH-n_| zU5^@L73yA|-|*gevx6PZM;(;>FVvK-m$Mq{DO}oXD7hPD;){UyU{5gO);`H^YBeco z(LrN<#^rHc$M!JDMcLJ1-o9(QL-HzENs9k!udxB?K>B9xcaXmk_AqlVZj@4YmXenE zY&SL}xmxzE411$|y;n*zI~0=6w^?UwL~?1~1e>LSPj0WeK#Dc_O2y7BF*eSEi#oId zU*Fwtnl$3hU#9e_vy4qdE)=9y?hEhjA?*8p4j&}l|Ko{iY~fKx<@uS%b!Wc7HPjRK zlk*Ax5A1&%4yr7b zsj}TP<4J(A1>^DtEr>hm%W_Nicg-`M4J%-5slmnj!&VXE+2OI@m@0JWZYq-V znV}VNX)f6F1zsPykAYja(*aYLSAnL7fhmU8#HG9`EPmO5Nll!-c=O6zR=#CkJ*aI+HZC0zLT0L2cEK3D62 z_ZHQopy@B)rMAX-&ZKn|z64PKT`#`)s8+i9op619y@AddKZEFD3gmi1Yyo9pIaJzYo0x! zpCi31=<5jl#$@YFTxE`vGUcMa z5fGyS->i_**A{XV*wWM%FL1G_h;!Z!LG0VuWuxT%qLkxebO&1>kqbR1HwI$r@_R|r z+b)$HFL(5^^<`Xc2R|kkp8@bQZy;6==)O-fT&U)#wR4cIpD34cQCH;NfE;kf_L+3F zd@aX?BBN~m1-Z(13S5srAh*=GmMpcd8SEHiA7>k&aLLz|e8IW>fGa0hrS+#n9o>3O zvJE616#K>rb_fP;yS|5|pHspdFZWNj4HD$)GM}YUXOw%epHLeR|e@8J@ zu>;rP9dO_DNtSjQLmWTXonTYG9+|@RM?4WRCnGVRsb_#s*#;Q5eX1`*Nz~!xMBLy9Fnfl_r9S2`O z9XC=cu^^8lPxV;aC`B&qCoRHr%U;+cE;-p&s(y;ht%R|?uPY`s_1#=#9@ma4#ZJjCPSvC8N^MleSirf(7 zaQ;2u)~UC`xbgIB+q=-f^hu1%^~Lu?oLqc%N7=69l|lU!wv3x8yXN??a|r(YZEgasOA2;A7ry$0%n_ALeW4SH71bm{yc zL!zMXBS9|C+ahJ&OqW8}8Z3;`2oAT~HYM3eLfE}lO(a#oupB-Gc z#Uy`u&oE2i#tVLi{##t}U(>;&?+vpV*Ft;n6#|#9iv{N{o7RmhY@9<}#U~4=s&(M& zt=Fq(rpoOr8|MmK?R6Y`^PTCNcA>_3q%Zk;rVcp27#~hTd?>XbkF>pdtZ}{~m%e|9 zWn6XKxdm}&t6wqc`tnvr`u%{OMHXZg&!jIqcQw*)41E8axsFi>jFUeqaZ+m9y`OQB zaBmr*YCEXnuVkD%%($5JRlaM>GOkN6zZzp)BG^H+FXoG1lzbswjhbLwN^)r~H1p8* zl3~(~uO}Iok=(5ETYJcFFH^##YoAUwE_acuzBkNo8IU(OoDP+Yy(bx02>L3ykjD~L zK9=Gf`3_weUUVcu}Rvq9PKNXue67}qknd=Fy@<+`Fha32)_ z`>3O93rT0TG&QahxPEM1a6azOhQR(T-$Y;O);A{OdO=@5;dvAHeb1DApJ|hSka2^+ z)v>t4<>G#_4D2V@bo$;jeRd_|M&c@S?2-#%pL!4WsmV<*o4S=NY*c>7;?Kt!EJopd zp={j${t5fvW#*$MYfhbUGu@jacLQ5*+$Z?H`ltBqrmF|PF>GpI-9 zU65-L?hT(?s>5@ODd#KWmPP@FBtdRG%NP9K@Oda2o`>H0E;YW+b0&&?@d$&;ddv9e zIqMBPXI-@3G!$)KB5J3g19qITS~+*-w_S=3Y`;^uU#K-Z?rsmbdpzLo^?#55o&!?5nc_#3i|h)N=9V8RWtXU=q?k z6S$T`+#eC~1z9-8|dd_fAw@Fll+FI3=SUq*g5E^%*QTxmd3%SIRd0a&;cA4yF8}ic_vpm*I5E%+cGyl zOkB$I0+-AEK1YB9XMP|X{ci+b~Q;R7##C4vs@2LEH;luPS$$HjYtp3@G>xig;03U{A!Zx$iP zx^go}F8?k*JGm!_tLz`JleG>fiL2#jt~#7z+)Q5w7yVf7hYugBy#MfF?`cu4UW@yd zxMxT%?RT`|ddfTEo+U2XjO}+s+04FGfwu2U;wtx+rF|Lq9OGuj66k$=Zwf_u2^R_3 z*^I~E3+zLD%{%u-=x^v}vGBJ9Zz=v>BreGnY^L&GX?;#holC@3{J|O5QSZ}iU06ae z{w5W$9QulJd3?|b_Qmz~qKqyD)>|~vE|Xl+AzW<-)jE#uR=-c^6_QKyCg{uK1IFK9 z%zZ+y5_i4w&WJE?s<;z9$j~qJYvR&x?!xaaO8nI&Lp+lvhV%=)MqJWYxHldrG5(IP z(L3}y<7V%_JpSHrLoScMH{H{hg`8W&RqTKTiJg9?vI7e_w~0&ZSm1K|^7wm)aWn5N zt9d&H^Oka#6&tn}+qG}XL((_9^`=mimvCp+f-1@b2K8<^VBk0%l(1(>7zh@%u}LP5>4J`#^#A`w zT*V@O3@ql#g#Lt82r*is9jg%r5LPD)WT=$r#?zYAhdE(KZ9>=uvLlEvm=K;q*a6v) z9S|wl0p7$8@N9NO5JnQ#C5$385E=>D4j0ZP*0-2hw1fMIp+0j2=*P0YQqmhw>r=l0 zVMB%%b0fmWgiQ#WGE_=@<7sp1w;*gu*ov?E2`3RwCY(Yzm2ev2bix^giG&uynS`?lXA{mLoJ%;5 za6aJzLi&=7l^e%@T1@}Ggm5Y0GQ#DAD+pH-t|DAbxQ1{o;X1YZ{;JbpSzF}&KSb3=ZcgG_?hgE1m+>J;%{{krIxKyQ{O#|CI>`0rT!UA#?&=4S z?bKm@-aFYYRf$Kxu_(6k`b+zLm6e(Zy;AU-Qof$@`#3)x7WDKeSTwmf2 z{$Nek75-O{JL$+7BUE^l2fSYqR%_QM!N$eoT<9zg`Y13f$bp z9X+IWitg{%Ob4zrRH8K5fE)TaZ}3}($%;?-XtTqYdZg$EIYQNPp~9sJDh0|1AA|WFd0_FGPHUvikw*YaAd)-d4yzmy}LWMvRR0@=h`h&s0 z*iF`g#0}8@lA^04a-l+?1eF5i9?2QOJAqq>xR!NZsk+fQ1-S(i3Q5y}yQBZL;LgA; zOxyUIG^?1WM(AyZpQFf(rt-2ywee#ZxU6MJ`lmm7r3fT<*rJ;43zhwJ34F zTUItzw>gI(H|kOi2`UB3X>b1u-U!@c#BHAIZMY>$cNp;7>FPq+38=?>fy#67pj>kHkFBDdyeVG>jdlvk9`nH&e)lEj^@ zA$J?e&2=$na#!G%azo!Ud3=*m-_pd*&JJ^J zy!8($k&N?Jj<{O>P=Nfw>zDG$=nv(Io1LGvIA1M!2XHG8x3q@;o+khOXMS+&=h2TI)E1)^XPsZITZH7x!=&AJQ;B zYcrK`7f=D0<%=m>W+r342qdmfBM(6ZT$YEPS!XeB4bBBr4rgwmzKn=+YXWAK-?-e} zl;3I*S4-bBr0+w@Z?!pB!wz%E4reL9)gi8yeV37a%Tay{BCgiFL4|iAzXcQ5o%{w) z$n2oyXRi4zl(_EXw=m*rtqa%urYG(+jr=x~*4rJ*Z{fu4ps|im(mMV?`7MIDTJhm5 z#RrMJv9dUf7pphtAbA&X8xc48-OUus8*$H7 zzt2ymHn2b2a4k6bSKu}#?l_$z#j;!6_pN_^*^~<0Jq?V>QIId15cgcY9Vxm-;(qe@ z+7we>*iSyr*@)%0roMu1l(3!-$8wnb;(M8<2v~7 znQZ(AxMx0B@>^@-#{c{8=ekGYbIbWw`Pp;JhEyfLwIQxw;az~iYpY*n#Jn60PK-@b) zzRB?C@oX-*+?RiboBt^iVJ>#T+xq6bx4t8BJ6>21+zd#$P8}va4>u3>k1#jA5@EjB$;W!LgO9#Dahrs!vFgf) zfi0Z#);CYMxyFYGbMq-a)<+Y4^gW1cpII+eS2%>p<^0~a_2xApk!G*$KGsTGeDpnu zJ7;5`R9#3hfm?fz-dwzIr1|_QAM3CTAAK+4F6j?{T=D3sFmD~k>CIJFMVb?z`&bV= z@zM7tZofjyQ+1XdjLUWC)L3tBB}bYI=JBtkH*JG0B{%`JY2 zG|#H;YrW_1tM5bHH+eq+Zl8l{n?3(C%v>>lU9*3EU#nlVuf8vF8=g%8?nq%S+T0B@ zd)2IK?$X8Anzy~Lz8`Vh3`(w=XImFjmufMOpKXEHRIS%*M zhjID66-o{>$F{3$t~bHgx^%R!egJVN2b@gR#m{409{bMk2{SkBQP-S2-Pij4L|^?t z;x;m#0=Y{CxdV2FnOF9%Yu=;FX^orWs~<$%7b>}Y4WZlyAUE{Am-Q*g9ZcL+&py`I z8}w}f`kwutmvs&3JA}BYJr7xR8RY~WDuErgf*tz*=w@xha+}R7 zr#Clz5oxx6;$>Z0#aBOqxMSylpZRTPTyBRS8tTo5Ga}7v7kOE)`uOTc68EBRCUBn! z++hiNv-g@vbKfCe)_hNW^rMJ-yj(xdk}uN1Anwy{wf_`sha!cX>>M zR9#Y#u!i>C0Dbk5=BbsvtR=Sj=*JMZYM&~gLleg3c9`HBZZ6;zY5wuw99G>FAAJIG zJ1$=VbJ0!U9*zt*H@g;L9)356_3utT`mw~__x)vvJBQg^aDD&j7jEvgC&FAPEr-=N z(nmjzxW8511o5n~z%8~k+&p($g!$;k9M+-vIa=7_qmk4t} zVh-!Aci#F5#Erk57r6O__?zQOxcR0r!u(=z4(qe$-uj8eJ>75%#Ii?1T;KQ%?yX9M zc|_+N)*ZLJ^^=IZW>#L{iuug~`C>rP2=k-nIjk`ky!Dfbo7fIoR^(N$@DZ~Y!!x?{F^V?KlU@n}blFRL|8RWJEx!*#5L%Gw4+b|n_`$2v)gTB*= zdq%?!o4^iD!45AWzwH7$%ph+6Z0tMy2XE^SVBbXI{-v5X9;0yHPQbkFd+%+%4fAFp z?i-aq@Rv%9fIrLwe=wEtu@(V;m`U9IDnH|PKtJmZezvNv5A(BG#Ldos-*oX|{yUqv zRaEPO>&w^0sA)cIUCbfwGL7}NAJ$tvSZ_IY_*jd>dYen!W4Ml2bPqw9+#jyeI-YaJ zhpppz#66!)e0cVQ4~q};i91deceuVh?v%;vYrO(-X900DRPl^+F`hMmcqRq?q@u2Vt#u9a#s-d!qboQ zTS3Tg^&r2=kl&VozAK4aXB_1DSS7!4`!=LJ-xTs&4A@~6ac%c-|DfbI&W(fpLk`Gq zx9)gZ^MHL<6E`Xp^IO-0YCq%qk{u_#tQBG2))05`4$N!6`Hjy7-=Do5!<2oi}@`c_LHk&KRLaUm$d@yCpQw;?{|Or-d@RX zTrS_Ip8Y2W+ox_K?&|#BU^DIgZ^@(?`Cx&8dMi@0-Awpl~$Z`q64xZZH?zRPnurQ?<9@+Y789KZ3` zg4Ep}aQAq?-Rl8&p9kDeJmBspuI}gKur9^D1`NSrkt>{=R{)=nKZPE9K7QBzBW|QV zfAq$?iSpDPUxj$@Fj)_9?%@v*8x*-bp5<$tD`wA$>2kZlXG8xfWwd_Ax&1%SR7?K6mI{NI$U4Qty4QaMm{i7u2ydjoi@M9@)2i6aA<<3Z1AG2ZR zIJxoZl+>0 z?~c4rz5C8+g$EFY`}6USxG)5VMPB~ZzEU`EhoQ&jO(mDl#SlfVxzKlWL+`&c>c8Mz z4Sj<_-`TmQnol+;76$t2k8rMr9cF?Z*3BGeUNF5^SeG_>{ZY=;EF)~9hUpmI2${Y$~T^_o50JR0WhctRb0IuO{s^-uZ8AHGri!8~Bp*3<@%5HyKfB&%qWR?IQ>l%IMdR+XddI#rLJp2(i z4A#Y_yHM;RFt1g&!=yjPx!J5Yps?Rtj&m;l13R2{fC{*B|2B?(CHNa(04r9bT00bvrcVr=uqQ z3F5AJb34p$_Ruioa^Jb_|57>wFKX7Ub1)=)ze#_RxOvUR^?qSUX*X{n=@tfa+Cfvannl`*T+X`%bjqjU<%4T zL);F}Z-vG87xleP`X#d+95-_KGJm*0+)ug= zO5r+i8%q>_XG8q;f%tooxCtkEq`KZ)F~xu71c<+XLj1i%+;-1zrIy}^HC~+hj#1Wy zT#@4MSHwM9s<_p4E*`*oYp068mx&8=Y;~REq7;9JDC^jIg}AR%;5)t0G0e}n9vFX* zL;S4*@fYHQ^(t{swr!iLoBJ2@Up^O;DE>Bs_zQ8z`ZaOSv~3&4xm<2-C7#K@K>W>F zI?8&@se_*Dz~v64`1_LL?{(s8`7aE?;f%jGpoen|_x6!o9)Bf@zc-0{RzqLc_&ibk*CtlO#TRkwC5%vB#ND*9S*%X?2{fIB8(Km57q)2rUwjeQVlIQX2lrQ& zupD7|!U}{H2`dr$G1TcQ6Z#WYA*@PRjWB?)I$j*T5bgu#R% zgrS5GRoDR$jve8I5rmP1bqS*g4TMHQ6QM*HO&CK6PZ8{hC9FqSpRfU8L&8RcjR~6& zHYIFE*qpEhVN1eRgslnN5XKRRKjV5(+Ot~CK6f*XA;gLoJ}}~p~XCxa30}&!UYU6qdC`UiD)@WUCR|({d6whZ5HXxh+;SGr$Hw zwm+y|_hJ2{bnk4qI|n~8{0rQ#`yQ)%;$pbXhqxa;?2Cm{2tiJLd*p9!d=1%0`51DXGN`i^0zIQz_kb!e=^!WG9CbKjjOh(YaPPuxrs~n z#&p094az^VsHCYsa7!NlCu(H(QT9B7T=B25e!dWE(gFA4GCxC?h8yj9iL2b3s6+Uv z5vD2d;zXoZV?%rIWA=Q+^v*#DMVkNgu_4b$w z0r&gu3k^TO|6aQQab4#P@2}Z0yD1!AVoB(_#UPtYI0_P1%f96vUNyCPn{N*u&v1Np#u!~&eajxn1@216nC(2EpUo`CBUEfiJ zxQZQg%nqFUa#RlK{9lQ3*!tUscFjc{*mF<>Q0Vg#C@;$ z8T1r=kzeJ?Mlf%m!n~CuuG(gtn?nB36#T&e z{!rdUF4~s23gl-c$j>Sem+Z^zz~`=s%72f8|5hX}`HrA3Ul&hkT~rdd;=J+oRtVNx zC0K8M#MN5I5wwo$(mJk8T)u|54N<6d%q*eCQ1E!JoLaHdFY0As(i4HK zM7f&rtQN(ysxDlV$J;B4llLJ`&W1Qyjkq*#Li~-R_?rXbZ(fMM0iwRpbIRp${Q<=F zV-VM?i`)=3w>ssE1CTF1K)whhF1MMQn}_mHk)Hx06NhhS6>+o5Ss(@u=YvU2=sCHT zAhq0?BzHOFx8{)FY7v*_LeRGf>6;Gv-UoeaXT#k_`RyyRLmlFh?+9|ckbU!jeT#v8 zK|z(i%1ixR=YMG49>TmWhj|MYxMFT`&2Ml~CYSCl+x!NDY8`~?jjs6(79-!9=0`gk~ap~Tmr}!lDTTpx$2l?#;#D_@Y@;J%4 zh?P`v=MLnzy2Pb*kr{uH>l)8sqolT(ps!h#-#&vlX&~-@#oxmae~qGCHWxgu*QdB1 zOL5&q-2ciKnBOGg(!6EHRCONW`7N5bihad6>6+hS1i8>r#fOva3rGVY7v>!BlcC<> zcn1U|mG5K-HXB(#pR@s?kmtLvdu-6P?Bb|L zTy-qLAG49a?MhB*HgNkazHfN3s;#5Gpo31BNb;R;Y8{5S2I9(NNGq;c|T+cKqJd7xqT+fyWK&=SDah333%3xZS$nzG*53d#*+$ zQw`TY)NnKwvbp=Ng;^w6NB)>lLZ?E~nG#2)KYogX0 zW_K&>Xe!Euo^uT~EU?>D7WR|vw=XcfAL`}6XKakArrd|bW*?{Ke*_bqyi8 zY;6TDbX59c5Bf6xm%oVX%x`QgGtcjic@K{&7WwiEFUD;T!%nUR(vouxoxFO3>5y7$ zPThH7xojPXtJp!Qh>Q9%okuM(J_mgpj|z&KI4srHQQ#^SarwRNd;ijy2HZb`S4Xv4 zQqtZ@;EL6_Vnzg-MgezC_}5Vt-gdNi7W7TdtS*SMHy-F_$`9Nnmvb2k{IJO0Mc`V5 zN{>%X^GqwicYd-581gLo)ZUf2ivPwj|K&0D$i8i+58%K3i!?HPy5hXOn;_TutcN;W z9dyLh1-NTg_BB*L_T1iGkn5MCp11GXeP!AW>#b^@M8lL3UXC6DSF9A$ufY@3cd(8# zsxCE1JqtT}3OZy6awALpWhxEaM@2UozFk+r(TljQ{)=(_f*`5@Xrb0Y3PD?TTx*)<4FX-U31KwlfTBW2T5L16UZ8yjTVjX>4xN1A> zTTxMZ3vvC}@23rQ#x`^GC9a~cUuGV{&kX;&suTy@ORp{&4zFwL=qJh*VqeaBH6{6f ziSnya*A3sa>Eh@w$X&p43)kad`yi<`a7!+@V^}e=r(=L97kbLNKszkD9U|of?%|~S z218oBW1zrwR>Z~6Jh%`lz4!y{aQA^B$M=04g9NTKuA|(M=R+hPkQ=h@zM;#Wc*kJk zDs~X(_{4)cQg`6~^S|4M@W(wILx`*7`6OmD^j~bbz73R~0r%MPuMJn-;wFbsS4oqdcT z*CMR9{1?`kq9K+Tu0|PN*~;&RqEV(KME`S{A4f^=?;^ZK9yB7^|zcDaihSWyh)Hy53j9 zZIcAKI(Rg3%5^lF23uZ>9CEOHUGK(8>5~PnSP{4Iy(zGjw#X$fl#84-dONF#>&#j3 zL6uzWAs7FPxo|3=lPgxl-E>!xdky4P1G&>guJByAjP!l@S^2uh8YQJqC$8dW;xnY4 z>>!gJW(aa)1^YfG`*r~P=G>iROBA@4&+*=H&aiz)^L7#Dtv1Y?Md0cLf9OR1P!#;3 zBKX5h;*!3C{|1wv4Fo@X1%5V5;KpbA4(h`FHwFB+9{BHUfh+n$KGnMT8P>%dL0=1t z5B&aI*V|k{uE-thvX18oaur`kx!8Dos0{I86~u@60ymc3n`_+JN^xfaaVeg$dE;~8 z8qXFAa>Y3LgyQ5nh?8cBlZyndUuN7veG5|jEe`Q_B*fpv#MO%H-VoQHLR_~&T>l*6 z`V!(QbNncj+W^ruUn~`LC>+MQcz^0V)D7~`GJ%_Yep@bZ6}c!AZM?g8sPrCk;iZfR zhH%K6D+I2X3)@A7NKtTag+6;=us}XuDR4&%&xI$a1W7A_TXgIL!*R&-s|4-_G0(rP zCHX*pYxv`R!xY#*tQNRpzSw^=P+AGx$uI92zE5c8SVLUJz8TDS&~CVodKFSlstNm@ zz~sAzL9pLhOI-4uOfK@}Z~UaIz>PeA+pre)QR@U9ME|Yws+=?v@@C7nHw|07YC6^n zT+w%`bt@@_L*8s$@tR>0?E5wd+}BJ8?!P~lEiC;6+%g3(8y@y3?AR!9#dUnVY946^ zio-+i(K6Mju6+8F|_x5&R4k-?D?1#N44Lcmq?VAN|tWcqT#hN#!e}Eft&t_;3 z`|2&kRcz+0;ETTVzS}pZO^}bPN2M5^Ed12IRp2@+;^O@+$~b2Vf*kv-!5%{ycn;Vm zaG?WpfDO5mLX%Bj05`b7I>S3SgueLM19-eC3A#gK<=d9RO`AqPCd6diE%55kVk;}GI;6jJ=Rgm>%{4eIW zU4WS1&}LU(?M=md;{39QPTCi}nk@fsNzdbfg=VrBaoy$a@j&ig54ih0;C|u(cRz9I zxm(z4zz`f3Iqw)Bf3(@B&~xqy*jT1NOi8#UB|lFzKVQAy-n_2Wbbz?zlbMxZ(Z=6@ z_$qq#&KYLEM}-|#t9>SYCUT+Y-0!4qY#P(?@)UD{pMo79c2ti(NL=;z1bl7A^jjDc zQfGpB_R%Ouj%@>?4{30@>{G^dF{L8MnFrS~I0hA;8Vwr;;oj8#@Z!nRm~)H9o4daV zbjrOQt?|Fr%O`_aUJXjtS~ayx7(6Eh{>bo2F&)9g2j z9FQQPWvN5Ly~WX91L38|7qe{zAEcVBBA4xVoO-|@%-jBZy3#mrhea-qW%~N#$BUzX z9SFZQ*KQU1x~0kb1#v0<3io#TaG97HWv0uG$9xz1$rgk4h`@!8O78IqgJWLDO_mo; zsTtPuR;2YPano=T-c~?;nuWlxP>;ai`o3yIJwf(9$`;M>aFS7 zaE~W1j5)k=f_&t+W?{RogGuP4#mQ1z)R8gY`CrJT#hbi zogoj=uMf?6-e`4b=zzHm+lGy|q&Y9(kN^8_4N3mYWIZNwHP;(ZSd2O@a-rv(x6xe+ z!*<9b-)o)If^&?44c8{cU$!sdK3uu)Z}!{}tB*eHXt>d|uswsg>fiOa?ET$-kXk;0 z7jbL1v^_kYM>;`VTF2maP8~ip=o?*db)xy)wX?R#{_~`h#8u|lB5f4I za^$g(d5|WZa?t_ha(%lNI}p9i7yeHK?MvDdZeEa16PLb=2X}Vr@D$|!402C_+ysz& zhPY%0y_&nCp`!13(03B(dsg6DgdA{)?9dPF@Br-arN|BC`l8N}WZ(T@-*3Ub=ZLH2 z>o5d|^EvB0^t56s%J=Wmhs|-Jnm%lfFNoaCy(e=22l02o4^WY|_8eOR#NUe|7q6Ka ztC!`t9KCY)4D+j>r`!7ld?sBYu3}${V6(8zO=BXiPBGtV^rv0Ft9tZT#3g@VT=a94 zzXjs&b%?(Uy4G;4hWLA#xb)i$^9Q~z&Qkns4e@s%#NR8#rFmmqu5;SAOJnBG9&i3C zu#V%)@*|?Jid^V9{b645!7#Ne}E!(9llGKBdw-~A{Tm2-+>PHF_g0Si!b8Ns-;xKZ8v1lU{(?rM=eVG z=#wy0?34eOmBh7}OQ7OliIRk+2um~6>BI4R*j1WJfq*1Ysm$UBW0r z1EG=7L?{tP6UGoSM}YHK*0-4J5!NScK-iF>PS=RAF<}$Jri9H1n-jJmY)ROPur*;D z!Z?N&b6di8gzX7CFx2Tf5_Tf&OxT5?#oU#!8)0|C9t?H5o`k&!dlSYJ_95&`*pIM3 z;Q+#cgo6kN6AmF9N;r&gIN=Dwk%XfNM-z@AOduRfIF4{U;RM2ogp&v-6HXzVN;r+7 z#XOyG24Nzhg`rM2lW-Q{Y{EH&a|!1W&L>_JIf*@Kd}a(1OkT}tB0?vxBHO!t;uX;qh! zxUvT&apmkv!Mc>hl|3klD|=89S9YglU`et=cBKeiO5$d#uS-eXZ0+Du5?9WyB%@17 zTsgaWb18|d=?__y#Ld>vTuS1~S|u;DD2Xe3P!d_JIfxAI#}T5s9Obt#Ffsc#k~ zaW(T>7A0{t?VCkOT+MmQq9m?c`7MO(pyg*-l*EsSB#LYJTx|GC~Jt&DQdr%Tr&MptRl*Dx_zu|Ko`h!+U z+(Mr#rR2LqNn9)?Zzir*N!%0ZK~fX=<<9F5pJXiI8%tcRlDG$~HKb|4%}7#8zT-0_ z>Yy%(%YNa5Z+p7h{H3$N-FKm2@>P&qpSW5jaVuXbBUON31oa(-lDM)~N!-nTg(M4b z<(fiCTv=Tbm+!;PFTA85f!o_JAbGE|B(AJg68H8mKbqRYH_{>h1}DF9mc*5{O5&F4 zaoKbjxR)jvlMPVj0H2M~4q7E~=lqe(-elYp(-kbxBITjUwGup(L)X zRTB5b?7XZb?wT)!lDM*FN!**`;Hwae+{>Dqzso?Ic~BBp_MjxL>_JIf*@Kd}vIiw`We-Z?${v)&l|3klD|=89SN5PJ zuIxccTzQH6C2?gBO5(~Ml*E-iD2Xe3P!d=6pd_yBK}lTMgOa$iJ0%10yE$BM9+bqD zJt&DQt4k;HSe->lTsgavj4mZ{Wp$}XUdksSB z#1-Ns-*aVA5;xoU>rxU|i0k+lgxInui7R_h5?A)1B(7We4Szeq_2xlIT-k$?xUvT& zab*um;>sSB#FafLi7R_h5?A)1B(Cg1NnF{3lDM)5C2?gBO5(~Ml*E-iD2Xe3P!d=6 zpd_yBK}lTMgOa$i2PJXc%5V5vAg(v9lDIGOoDQXuxG|TXtheIth3<0kH$`{3_`9RK zT>Nd)UG66yaQ728yOOy6=jJWtZ{ng3I*pRJ;Z*u_l2Q^^e}KzXmBi)y>grIEaTk;n z9ifzD)PKgg8YOYZDkX8vrJy7umMT5Sxf&&LsU)M>tdzvnAL3j<<#7IX>ss3Hb0DyL z(O9logC2{r1oSRK4*oI0;MtutBYLu8YQHj}CP?FKBbd)}obF(O2Tk-7-^J^%{ zh^1?-oSS_~-1YoTTy}3NxqL2WLa9fPD@Q9O8QGh-jH{t<9V+2_S}BRk-o#~G4Le{- z#`RDdI1x%RVrk%`Twe|Q1}P)hmwrtp;YNH&UL>et`N`o{bf-SSN5PJuIxccT-k$?xUvT&ab>NNqFI#0l|3kl zD|=89SN5PJuIxccT+Mld>4(Glw%>W^G5=-%&c@7qj@$mWY7ugwByQ%LxX4wP#N|GD zk4k?Y*v?9l>o1aAt&*ZesHF2~h`->!`b)%Bmn!8tV5w**Np3Dr@%Jm@YL&$OmP%0b z_bw`m&E1z@=~x^k{nCHeob7hlDItn{zmclno|eO z(zO_W-$MMo3Gw$jakcyxhTvc&aasJm0X>{It&+IIsMIdT-v?0Y{3da=O5%o63Exu` ze{T_2T@shuY%0ayi4=ct6IZJwZf&qHmVB?Ql*F~(A+FZExt21%OI)pzxa#-|C2_6y zh^ysiy!5hNDT!;nPuy($SFQ%}7fb3tAg;P3F82omm5Ppq_?r*n??d7O(BaH2%0D>Q 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 ZXpY6Y*b3|77Oab}F$*L6x^P}^{{uEY)gk}@ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/models/testformspec_chest.obj b/data/games/garage/mods/testformspec/models/testformspec_chest.obj new file mode 100644 index 0000000..72ba175 --- /dev/null +++ b/data/games/garage/mods/testformspec/models/testformspec_chest.obj @@ -0,0 +1,79 @@ +# Blender v2.78 (sub 0) OBJ File: 'chest-open.blend' +# www.blender.org +o Top_Cube.002_None_Top_Cube.002_None_bottom +v -0.500000 0.408471 0.720970 +v -0.500000 1.115578 0.013863 +v -0.500000 0.894607 -0.207108 +v -0.500000 0.187501 0.499999 +v 0.500000 1.115578 0.013863 +v 0.500000 0.408471 0.720970 +v 0.500000 0.187501 0.499999 +v 0.500000 0.894607 -0.207108 +v -0.500000 0.187500 -0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 0.187500 -0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +vt 0.0000 1.0000 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 1.0000 0.6875 +vt 0.0000 0.6875 +vt 1.0000 1.0000 +vt 0.0000 0.6875 +vt 1.0000 0.6875 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 0.0000 0.0000 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 0.0000 1.0000 +vt 0.0000 0.6875 +vt 0.0000 0.6875 +vt 0.0000 0.0000 +vt 1.0000 0.5000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.5000 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vn 0.0000 0.7071 0.7071 +vn -0.0000 -1.0000 -0.0000 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 -0.0000 +vn 0.0000 -0.7071 0.7071 +vn 0.0000 0.0000 1.0000 +vn -0.0000 0.7071 -0.7071 +vn -0.0000 0.0000 -1.0000 +vn -0.0000 -0.7071 -0.7071 +vn -0.0000 1.0000 -0.0000 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Top +s off +f 6/1/1 5/2/1 2/3/1 1/4/1 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Bottom +f 11/5/2 10/6/2 14/7/2 13/8/2 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Right-Left +f 1/9/3 2/10/3 3/11/3 4/12/3 +f 5/13/4 6/1/4 7/14/4 8/15/4 +f 4/12/3 9/16/3 10/17/3 11/18/3 +f 12/19/4 7/14/4 13/8/4 14/20/4 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Back +f 6/21/5 1/9/5 4/12/5 7/22/5 +f 7/22/6 4/12/6 11/18/6 13/23/6 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Front +f 2/10/7 5/24/7 8/25/7 3/11/7 +f 9/16/8 12/26/8 14/27/8 10/17/8 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Inside +f 4/28/9 3/29/9 8/30/9 7/31/9 +f 7/31/10 12/32/10 9/33/10 4/28/10 diff --git a/data/games/garage/mods/testformspec/textures/default_chest_front.png b/data/games/garage/mods/testformspec/textures/default_chest_front.png new file mode 100644 index 0000000000000000000000000000000000000000..f4132794d52be74ba00fc1a05fd403fac4ae7277 GIT binary patch literal 421 zcmV;W0b2fvP)i&K4LJ(h4fd|)}Lf=h&H zLXT)Oby_pmu656)Y`~XZu7*#Kb4!G4MT>1goOVBpWiV}2FKSRK-QC@|u%qC!dc~Y& zzLs61d_{+CM1p2Nz__cUqocE{p6j=Mc6N54fmoDxPm^{|mw8KwZcBJ!K5tn$lWaGU zYBh#mEPz=jWJ@J{RU=tkP^|y}0J2F$K~xwSZNWui!!Q5@z?Cd!Guz>$%=G_{wfA%e z*WN;vk})QQ^Dw*s2*+GX-?@VoV&4O(j+y0L)b(z6#|Hp~%T?|vrG%)s;vZGT7RJ8U z#VjTn08d=l*A4O8LORI+u!*?S_Wowm^QL|PkSL}3czbz1*uCfhoSi3%jH8!XCQkrD zoBe59D|pj90$3wagb+2UuA>0}i+V2Kwbn6Cv;e?#`SbNTmmlSx#8izWM; P00000NkvXXu0mjfwQRVu literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/default_chest_inside.png b/data/games/garage/mods/testformspec/textures/default_chest_inside.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2e883d2cc39f188109b6568949f06935a6ec90 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^0zj<5!2~3yyw0Buq*Og!978O6lQ&!sSKu^kFu0fy sa(G2s<28q(PjYAZ7fZEmWSbn`5knO{RcJoOVB!a5-&MFKSRK;In$zuXoa@aHD)h zf@VK%ST=rFCF{3-pn+J3ZcC(oM}}W4WJ@JsV)uan0065=L_t&-(`C+A5`!=dMbXH@ z-MB%3P}BSV*B6mr?&lfJ= zdsUum4#6X1C?EZJP^f8bSOa-|wF`=iC+qn|{rj V3gJ4$MZo|7002ovPDHLkV1iD9pBn%G literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/default_chest_top.png b/data/games/garage/mods/testformspec/textures/default_chest_top.png new file mode 100644 index 0000000000000000000000000000000000000000..1fbdbb94c966b39145bb0f06d30619afb5ba81f8 GIT binary patch literal 418 zcmV;T0bTxyP)nsh*fXFYILEX|{8#G7NJgI1=1NtAU-k#a-k;In$zuXoa@aJiCM zwU1VxfK#S~QIT*zdtp40Y&wEtIDB0)iDE8wS1oK%C}&9`>$iThkYbm5Q>TGSifA}x zPAvL-GKl~H0J}*T^13?f3z@BBeJ!TX$7^M7Dv;V5Xr&G90(|D|=Fb>@h zfFN=yBb)iwm}C#&LacSpY}TvQmm2^avRwQ|ob#T9z5_UlSeIf}MX9v90yq~+D|MT7 zPn1^xI%m?YrASJ-lNEqh*=LNUX_C0j`WryWInQk-nNJh52Qcm;62xsJ8QUHJ1ke6? z-W8!j^kMAf)4=R*X8+q)c0kn>r;gfe_Q+w!YS1S)Bpeg M07*qoM6N<$f@c=8ZU6uP literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_9slice.png b/data/games/garage/mods/testformspec/textures/testformspec_9slice.png new file mode 100644 index 0000000000000000000000000000000000000000..e36a8bee574b9f1eb5874904ea234622e9a7d32f GIT binary patch literal 513 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 Gvf+Ou20{4% literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_animation.png b/data/games/garage/mods/testformspec/textures/testformspec_animation.png new file mode 100644 index 0000000000000000000000000000000000000000..b972e5dbbb6e6bfa4af0f88c5fd0b334f318672c GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0zmA*#0(_!gymU*6lZ`>h${obivR!r19|LCauq;| zu_VYZn8D%MjWi&q+SA1`q=K=xmyzvofPl;YL-Q7J7R|DCy3l%0!P58QJq5?&Q|G*O zG@aP{pX{HR>#oC6&&52$k^c|ZU+(w8FW$YKlXvCWo>Oozp)WsLIcn0|rbC({Qm-GXhFf1U%K!QkoY K=d#Wzp$P!m%}>Pu literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_bg.png b/data/games/garage/mods/testformspec/textures/testformspec_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..cd1e50900354b48dfeadd44e74fb2926399e96b4 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|%APKcAr*|tGpzUaR!o^Kd!Auo phfCwXh0MznLk_QC<8ZZMVsJcTmus{sG#03w!PC{xWt~$(69C7B7{CAk literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_bg_9slice.png b/data/games/garage/mods/testformspec/textures/testformspec_bg_9slice.png new file mode 100644 index 0000000000000000000000000000000000000000..34433ac82a89114e0be99fd1f2a9bd1bfdfd0a2e GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4*Z=?j1DUzm@pGrQ1^S1s zuk85)VwDlZ#9wlUa#$l&N{JAj2?I42-+ sp^kCwZ{`;jR~UJ2{Aw>b*38Vn&=V_}>fGg}0ko9C)78&qol`;+08XYmU;qFB literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_bg_9slice_hovered.png b/data/games/garage/mods/testformspec/textures/testformspec_bg_9slice_hovered.png new file mode 100644 index 0000000000000000000000000000000000000000..01c2dc7776417e5de676f1af3579e143725b1de7 GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv{s5m4*QWpffy}y^{ACL#CncmG zZF}JfzhDN3XE)M-979hR$B+ufWCbRUMGS0gZmG#C2`UE;WISnNnc~Rg<- z$CIr$)PJvM6Ii@XZNAQ&DHHz9XH1dW$(D0}Tk;jwkivr*3Vht+4VzRt7>#(Pd;R%b am>Jr*nl%r6Tk;QRB7>)^pUXO@geCx|5h{ZK literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_bg_hovered.png b/data/games/garage/mods/testformspec/textures/testformspec_bg_hovered.png new file mode 100644 index 0000000000000000000000000000000000000000..3ebbb988c2b4e7c291db81f3f15744b14bce63e4 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|%APKcAr*|t5!(ukKCW1&HlNW+ puyc~oC3e5VE7}5i1-dF&7~D4I&8?a!Apum*;OXk;vd$@?2>_;P7vKN@ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_bg_pressed.png b/data/games/garage/mods/testformspec/textures/testformspec_bg_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..2fb5fc21ecd7d0ac75f0bb293d91269c4fdc33f0 GIT binary patch literal 91 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 ZGkh^&|C2f?B?f2^gQu&X%Q~loCIB4yG;06= literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_node.png b/data/games/garage/mods/testformspec/textures/testformspec_node.png new file mode 100644 index 0000000000000000000000000000000000000000..c107f28a31020c89606f4e8b7882bac829aed00e GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|7M?DSAr*|t7cN}bQ5V}>F^RDw z-S@RB+tsVn7``^-G!$?wdb6gcgI6U(BGIhp7Q;gU7Y=C;uZIjfSQ2M{&S*XgG=ss@ L)z4*}Q$iB}*NP+k literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testformspec/textures/testformspec_pressed.png b/data/games/garage/mods/testformspec/textures/testformspec_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..45c504f275aa726991eb2b327792aa2855187d37 GIT binary patch literal 165 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ii4<#Ar*|t761Ngx=Q%u{MrA_ zUf{o?;D2|s2mH5_+x{E%t9Bkz*s5Tw!FE8UMeg&XLkX2DTqAfJG!L~qW_1`hG&Vlm zzhsFD$K+H7C*>yJdS;DpOh+3#PBYwcRrXzO%0!~fKjbhR!6hQvczTZG*f#{unS N@O1TaS?83{1OQtbI&%O3 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testfullscreenfs/init.lua b/data/games/garage/mods/testfullscreenfs/init.lua new file mode 100644 index 0000000..1b84033 --- /dev/null +++ b/data/games/garage/mods/testfullscreenfs/init.lua @@ -0,0 +1,71 @@ +local function window_info_equal(a, b) + return + -- size + a.size.x == b.size.x and a.size.y == b.size.y and + -- real_gui_scaling, real_hud_scaling + a.real_gui_scaling == b.real_gui_scaling and + a.real_hud_scaling == b.real_hud_scaling and + -- max_formspec_size + a.max_formspec_size.x == b.max_formspec_size.x and + a.max_formspec_size.y == b.max_formspec_size.y and + -- touch_controls + a.touch_controls == b.touch_controls +end + +local last_window_info = {} + +local function show_fullscreen_fs(name, window) + print(dump(window)) + + local size = window.max_formspec_size + local touch_text = window.touch_controls and "Touch controls enabled" or + "Touch controls disabled" + local fs = { + "formspec_version[4]", + ("size[%f,%f]"):format(size.x, size.y), + "padding[0,0]", + "bgcolor[;true]", + ("button[%f,%f;1,1;%s;%s]"):format(0, 0, "tl", "TL"), + ("button[%f,%f;1,1;%s;%s]"):format(size.x - 1, 0, "tr", "TR"), + ("button[%f,%f;1,1;%s;%s]"):format(size.x - 1, size.y - 1, "br", "BR"), + ("button[%f,%f;1,1;%s;%s]"):format(0, size.y - 1, "bl", "BL"), + + ("label[%f,%f;%s]"):format(size.x / 2, size.y / 2, "Fullscreen"), + ("label[%f,%f;%s]"):format(size.x / 2, size.y / 2 + 1, touch_text), + } + + core.show_formspec(name, "testfullscreenfs:fs", table.concat(fs)) + core.chat_send_player(name, ("Calculated size of %f, %f"):format(size.x, size.y)) + last_window_info[name] = window +end + +core.register_chatcommand("testfullscreenfs", { + func = function(name) + local window = core.get_player_window_information(name) + if not window then + return false, "Unable to get window info" + end + + show_fullscreen_fs(name, window) + return true + end, +}) + +core.register_globalstep(function() + for name, last_window in pairs(last_window_info) do + local window = core.get_player_window_information(name) + if window and not window_info_equal(last_window, window) then + show_fullscreen_fs(name, window) + end + end +end) + +core.register_on_player_receive_fields(function(player, formname, fields) + if formname == "testfullscreenfs:fs" and fields.quit then + last_window_info[player:get_player_name()] = nil + end +end) + +core.register_on_leaveplayer(function(player) + last_window_info[player:get_player_name()] = nil +end) diff --git a/data/games/garage/mods/testfullscreenfs/mod.conf b/data/games/garage/mods/testfullscreenfs/mod.conf new file mode 100644 index 0000000..68e7a10 --- /dev/null +++ b/data/games/garage/mods/testfullscreenfs/mod.conf @@ -0,0 +1,2 @@ +name = testfullscreenfs +description = Test mod to use core.get_player_window_information() diff --git a/data/games/garage/mods/testhud/init.lua b/data/games/garage/mods/testhud/init.lua new file mode 100644 index 0000000..0512345 --- /dev/null +++ b/data/games/garage/mods/testhud/init.lua @@ -0,0 +1,393 @@ +local player_font_huds = {} + +local font_states = { + {0, "Normal font"}, + {1, "Bold font"}, + {2, "Italic font"}, + {3, "Bold and italic font"}, + {4, "Monospace font"}, + {5, "Bold and monospace font"}, + {7, "ZOMG all the font styles"}, + {7, "Colors test! " .. core.colorize("green", "Green") .. + core.colorize("red", "\nRed") .. " END"}, +} + + +local font_default_def = { + type = "text", + position = {x = 0.5, y = 0.5}, + scale = {x = 2, y = 2}, + alignment = { x = 0, y = 0 }, + number = 0xFFFFFF, +} + +local function add_font_hud(player, state) + local def = table.copy(font_default_def) + local statetbl = font_states[state] + def.offset = {x = 0, y = 32 * state} + def.style = statetbl[1] + def.text = statetbl[2] + return player:hud_add(def) +end + +local font_etime = 0 +local font_state = 0 + +core.register_globalstep(function(dtime) + font_etime = font_etime + dtime + if font_etime < 1 then + return + end + font_etime = 0 + for _, player in ipairs(core.get_connected_players()) do + local huds = player_font_huds[player:get_player_name()] + if huds then + for i, hud_id in ipairs(huds) do + local statetbl = font_states[(font_state + i) % #font_states + 1] + player:hud_change(hud_id, "style", statetbl[1]) + player:hud_change(hud_id, "text", statetbl[2]) + end + end + end + font_state = font_state + 1 +end) + +core.register_chatcommand("hudfonts", { + params = "[]", + description = "Show/Hide some text on the HUD with various font options", + func = function(name, param) + local player = core.get_player_by_name(name) + local param = tonumber(param) or 0 + param = math.min(math.max(param, 1), #font_states) + if player_font_huds[name] == nil then + player_font_huds[name] = {} + for i = 1, param do + table.insert(player_font_huds[name], add_font_hud(player, i)) + end + core.chat_send_player(name, ("%d text HUD element(s) added."):format(param)) + else + local huds = player_font_huds[name] + if huds then + for _, hud_id in ipairs(huds) do + player:hud_remove(hud_id) + end + core.chat_send_player(name, "All text HUD elements removed.") + end + player_font_huds[name] = nil + end + return true + end, +}) + +-- Testing waypoint capabilities + +local player_waypoints = {} +core.register_chatcommand("hudwaypoints", { + params = "[ add | add_change | remove ]", + description = "Create HUD waypoints at your position for testing (add: Add waypoints and change them after 0.5s (default). add_change: Add waypoints and change immediately. remove: Remove all waypoints)", + func = function(name, params) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + if params == "remove" then + if player_waypoints[name] then + for i=1, #player_waypoints[name] do + player:hud_remove(player_waypoints[name][i]) + end + player_waypoints[name] = {} + end + return true, "All waypoint HUD elements removed." + end + if not (params == "add_change" or params == "add" or params == "") then + -- Incorrect syntax + return false + end + local regular = player:hud_add { + type = "waypoint", + name = "regular waypoint", + text = "m", + number = 0xFFFFFF, + world_pos = vector.add(player:get_pos(), {x = 0, y = 1.5, z = 0}) + } + local reduced_precision = player:hud_add { + type = "waypoint", + name = "imprecise waypoint", + text = "m (0.1 steps, precision = 10)", + precision = 10, + number = 0xFFFFFF, + world_pos = vector.add(player:get_pos(), {x = 0, y = 1, z = 0}) + } + local hidden_distance = player:hud_add { + type = "waypoint", + name = "waypoint with hidden distance", + text = "this text is hidden as well (precision = 0)", + precision = 0, + number = 0xFFFFFF, + world_pos = vector.add(player:get_pos(), {x = 0, y = 0.5, z = 0}) + } + local function change(chplayer) + if not (chplayer and chplayer:is_player()) then + return + end + if regular then + chplayer:hud_change(regular, "world_pos", vector.add(player:get_pos(), {x = 0, y = 3, z = 0})) + chplayer:hud_change(regular, "number", 0xFF0000) + end + if reduced_precision then + chplayer:hud_change(reduced_precision, "precision", 2) + chplayer:hud_change(reduced_precision, "text", "m (0.5 steps, precision = 2)") + chplayer:hud_change(reduced_precision, "number", 0xFFFF00) + end + if hidden_distance then + chplayer:hud_change(hidden_distance, "number", 0x0000FF) + end + core.chat_send_player(chplayer:get_player_name(), "Waypoints changed.") + end + if params == "add_change" then + -- change immediate + change(player) + else + core.after(0.5, change, player) + end + local image_waypoint = player:hud_add { + type = "image_waypoint", + text = "testhud_waypoint.png", + world_pos = player:get_pos(), + -- 20% of screen width, 3x image height + scale = {x = -20, y = 3}, + offset = {x = 0, y = -32} + } + if not player_waypoints[name] then + player_waypoints[name] = {} + end + if regular then + table.insert(player_waypoints[name], regular) + end + if reduced_precision then + table.insert(player_waypoints[name], reduced_precision) + end + if hidden_distance then + table.insert(player_waypoints[name], hidden_distance) + end + if image_waypoint then + table.insert(player_waypoints[name], image_waypoint) + end + regular = regular or "error" + reduced_precision = reduced_precision or "error" + hidden_distance = hidden_distance or "error" + image_waypoint = image_waypoint or "error" + return true, "Waypoints added. IDs: regular: " .. regular .. ", reduced precision: " .. reduced_precision .. + ", hidden distance: " .. hidden_distance .. ", image waypoint: " .. image_waypoint + end +}) + +core.register_on_joinplayer(function(player) + player:set_properties({zoom_fov = 15}) +end) + +core.register_chatcommand("zoomfov", { + params = "[]", + description = "Set or display your zoom_fov", + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + if param == "" then + local fov = player:get_properties().zoom_fov + return true, "zoom_fov = "..tostring(fov) + end + local fov = tonumber(param) + if not fov then + return false, "Missing or incorrect zoom_fov parameter!" + end + player:set_properties({zoom_fov = fov}) + fov = player:get_properties().zoom_fov + return true, "zoom_fov = "..tostring(fov) + end, +}) + +-- Hotbars + +local hud_hotbar_defs = { + { + type = "hotbar", + position = {x=0.2, y=0.5}, + direction = 0, + alignment = {x=1, y=-1}, + }, + { + type = "hotbar", + position = {x=0.2, y=0.5}, + direction = 2, + alignment = {x=1, y=1}, + }, + { + type = "hotbar", + position = {x=0.7, y=0.5}, + direction = 0, + offset = {x=140, y=20}, + alignment = {x=-1, y=-1}, + }, + { + type = "hotbar", + position = {x=0.7, y=0.5}, + direction = 2, + offset = {x=140, y=20}, + alignment = {x=-1, y=1}, + }, +} + + +local player_hud_hotbars= {} +core.register_chatcommand("hudhotbars", { + description = "Shows some test Lua HUD elements of type hotbar. " .. + "(add: Adds elements (default). remove: Removes elements)", + params = "[ add | remove ]", + func = function(name, params) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + + local id_table = player_hud_hotbars[name] + if not id_table then + id_table = {} + player_hud_hotbars[name] = id_table + end + + if params == "remove" then + for _, id in ipairs(id_table) do + player:hud_remove(id) + end + return true, "Hotbars removed." + end + + -- params == "add" or default + for _, def in ipairs(hud_hotbar_defs) do + table.insert(id_table, player:hud_add(def)) + end + return true, #hud_hotbar_defs .." Hotbars added." + end +}) + +-- Inventories + +local hud_inventory_defs = { + { + type = "inventory", + position = {x=0.2, y=0.5}, + direction = 0, + text = "main", + number = 4, + item = 2, + }, + { + type = "inventory", + position = {x=0.2, y=0.5}, + direction = 2, + text = "main", + number = 4, + item = 2, + }, + { + type = "inventory", + position = {x=0.7, y=0.5}, + direction = 1, + text = "main", + number = 4, + item = 2, + }, + { + type = "inventory", + position = {x=0.7, y=0.5}, + direction = 3, + text = "main", + number = 4, + item = 2, + }, +} + +local player_hud_inventories= {} +core.register_chatcommand("hudinventories", { + description = "Shows some test Lua HUD elements of type inventory. (add: Adds elements (default). remove: Removes elements)", + params = "[ add | remove ]", + func = function(name, params) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + + local id_table = player_hud_inventories[name] + if not id_table then + id_table = {} + player_hud_inventories[name] = id_table + end + + if params == "remove" then + for _, id in ipairs(id_table) do + player:hud_remove(id) + end + return true, "HUD Inventories removed." + end + + -- params == "add" or default + for _, def in ipairs(hud_inventory_defs) do + table.insert(id_table, player:hud_add(def)) + end + return true, #hud_inventory_defs .." HUD Inventories added." + end +}) + + +core.register_on_leaveplayer(function(player) + local playername = player:get_player_name() + player_font_huds[playername] = nil + player_waypoints[playername] = nil + player_hud_hotbars[playername] = nil + player_hud_inventories[playername] = nil +end) + +core.register_chatcommand("hudprint", { + description = "Writes all used Lua HUD elements into chat.", + func = function(name, params) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + + local s = "HUD elements:" + for k, elem in pairs(player:hud_get_all()) do + local ename = dump(elem.name) + local etype = dump(elem.type) + local epos = "{x="..elem.position.x..", y="..elem.position.y.."}" + s = s.."\n["..k.."] type = "..etype.." | name = "..ename.." | pos = ".. epos + end + + return true, s + end +}) + +local hud_flags = {"hotbar", "healthbar", "crosshair", "wielditem", "breathbar", + "minimap", "minimap_radar", "basic_debug", "chat"} + +core.register_chatcommand("hudtoggleflag", { + description = "Toggles a hud flag.", + params = "[ ".. table.concat(hud_flags, " | ") .." ]", + func = function(name, params) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + + local flags = player:hud_get_flags() + if flags[params] == nil then + return false, "Unknown hud flag." + end + + flags[params] = not flags[params] + player:hud_set_flags(flags) + return true, "Flag \"".. params .."\" set to ".. tostring(flags[params]) .. "." + end +}) diff --git a/data/games/garage/mods/testhud/mod.conf b/data/games/garage/mods/testhud/mod.conf new file mode 100644 index 0000000..ed9f65c --- /dev/null +++ b/data/games/garage/mods/testhud/mod.conf @@ -0,0 +1,2 @@ +name = testhud +description = For testing HUD functionality diff --git a/data/games/garage/mods/testhud/textures/testhud_waypoint.png b/data/games/garage/mods/testhud/textures/testhud_waypoint.png new file mode 100644 index 0000000000000000000000000000000000000000..f9f1308130f65a32d8220d3ef8dfeec45b4d4074 GIT binary patch literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;TYyi9>z3%-K<2Df8t;IVil>WX zNCjguL({K%9zGuhk%%J#FIZg^+*SySR9ZTwG@fe6V!Y$eDZnnOvka)7!PC{xWt~$( F69DG%8f*Xn literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testitems/init.lua b/data/games/garage/mods/testitems/init.lua new file mode 100644 index 0000000..12da2ad --- /dev/null +++ b/data/games/garage/mods/testitems/init.lua @@ -0,0 +1,107 @@ +local S = core.get_translator("testitems") + +-- +-- Texture overlays for items +-- + +-- For the global overlay color test +local GLOBAL_COLOR_ARG = "orange" + +-- Punch handler to set random color with "color" argument in item metadata +local overlay_on_use = function(itemstack, user, pointed_thing) + local meta = itemstack:get_meta() + local color = math.random(0x0, 0xFFFFFF) + local colorstr = string.format("#%06x", color) + meta:set_string("color", colorstr) + core.log("action", "[testitems] Color of "..itemstack:get_name().." changed to "..colorstr) + return itemstack +end +-- Place handler to clear item metadata color +local overlay_on_place = function(itemstack, user, pointed_thing) + local meta = itemstack:get_meta() + meta:set_string("color", "") + return itemstack +end + +core.register_craftitem("testitems:overlay_meta", { + description = S("Texture Overlay Test Item, Meta Color") .. "\n" .. + S("Image must be a square with rainbow cross (inventory and wield)") .. "\n" .. + S("Item meta color must only change square color") .. "\n" .. + S("Punch: Set random color") .. "\n" .. + S("Place: Clear color"), + -- Base texture: A grayscale square (can be colorized) + inventory_image = "testitems_overlay_base.png", + wield_image = "testitems_overlay_base.png", + -- Overlay: A rainbow cross (NOT to be colorized!) + inventory_overlay = "testitems_overlay_overlay.png", + wield_overlay = "testitems_overlay_overlay.png", + + on_use = overlay_on_use, + on_place = overlay_on_place, + on_secondary_use = overlay_on_place, +}) + +core.register_craftitem("testitems:overlay_global", { + description = S("Texture Overlay Test Item, Global Color") .. "\n" .. + S("Image must be an orange square with rainbow cross (inventory and wield)"), + -- Base texture: A grayscale square (to be colorized) + inventory_image = "testitems_overlay_base.png", + wield_image = "testitems_overlay_base.png", + -- Overlay: A rainbow cross (NOT to be colorized!) + inventory_overlay = "testitems_overlay_overlay.png", + wield_overlay = "testitems_overlay_overlay.png", + color = GLOBAL_COLOR_ARG, +}) + +core.register_craftitem("testitems:image_meta", { + description = S("Image Override Meta Test Item"), + inventory_image = "default_apple.png", + wield_image = "basetools_icesword.png", + + on_use = function(itemstack, player) + local meta = itemstack:get_meta() + local state = meta:get_int("state") + state = (state + 1) % 5 + meta:set_int("state", state) + core.chat_send_player(player:get_player_name(), "State " .. state) + + if state == 0 then + meta:set_string("inventory_image", "") + meta:set_string("wield_image", "") + meta:set_string("inventory_overlay", "") + meta:set_string("wield_overlay", "") + meta:set_string("wield_scale", "") + elseif state == 1 then + meta:set_string("inventory_image", "default_tree.png") + meta:set_string("wield_image", "basetools_firesword.png") + elseif state == 2 then + meta:set_string("inventory_image", "default_apple.png^testitems_overridden.png") + meta:set_string("wield_image", "basetools_icesword.png^testitems_overridden.png") + elseif state == 3 then + meta:set_string("inventory_image", "default_tree.png") + meta:set_string("wield_image", "basetools_firesword.png") + meta:set_string("inventory_overlay", "default_apple.png") + meta:set_string("wield_overlay", "default_apple.png") + elseif state == 4 then + local scale = vector.new(0.5, 0.5, 0.5) + meta:set_string("wield_scale", scale:to_string()) + end + + return itemstack + end, +}) + +core.register_craftitem("testitems:telescope_stick", { + description = S("Telescope Stick (Increases range on use.)"), + inventory_image = "testitems_telescope_stick.png", + on_use = function(itemstack, player) + local meta = itemstack:get_meta() + local range = meta:get_float("range") + 1.2 + if range > 10 then + range = 0 + end + meta:set_float("range", range) + core.chat_send_player(player:get_player_name(), "Telescope Stick range set to "..range) + return itemstack + end, +}) diff --git a/data/games/garage/mods/testitems/mod.conf b/data/games/garage/mods/testitems/mod.conf new file mode 100644 index 0000000..f91febe --- /dev/null +++ b/data/games/garage/mods/testitems/mod.conf @@ -0,0 +1,2 @@ +name = testitems +description = Test mod to test misc. items that are neither tools nor nodes diff --git a/data/games/garage/mods/testitems/textures/testitems_overlay_base.png b/data/games/garage/mods/testitems/textures/testitems_overlay_base.png new file mode 100644 index 0000000000000000000000000000000000000000..f473623beceb882cf5e982fe4a99d049443cc625 GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|hMq2tAr*|t3haN>r4&r|C^0R_ z-q9|eaJ@i?{lM~v0&Egj9XvM(^;vjLV!PNdX9+LE+zQtD$-mA`1ZrmRboFyt=akR{ E01!DH@&Et; literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testitems/textures/testitems_overlay_overlay.png b/data/games/garage/mods/testitems/textures/testitems_overlay_overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..75a7d9fc3c58528ed454b68afd2f203618e4f7a1 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!Wq?nJE0F&G|Nj>~y;sIx#1%h^ zD}47=m z^W>+l<+;V{qGi7P6?1ZA$~mAg#pJARCC95@7n9{IS5_}swb)%RbK^$l?xS4gDL5$E%(Yj z>a=0QY5(sxoH)X^?|j5GO)|}3=^w*v-6hkHOB9qZQP>)G#?rB4O-@?I+Qtb}jN}zH zpYGj$O?GPa`>5}0bxQA_3NoL*vURJ*YD<6a9Z+TO~L6&a;L!0h<)dni+t8r TC3$v$+`!=J>gTe~DWM4f73x6F literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/README.md b/data/games/garage/mods/testnodes/README.md new file mode 100644 index 0000000..13ed972 --- /dev/null +++ b/data/games/garage/mods/testnodes/README.md @@ -0,0 +1,11 @@ +# Test Nodes + +This mod contains a bunch of basic nodes to test development stuff. +Most nodes are kept as minimal as possible in order to show off one particular feature of the engine, to make testing stuff easier. + +This mod includes tests for: + +* drawtypes +* paramtype2's +* node properties such as damage, drowning, falling, etc. +* other random stuff diff --git a/data/games/garage/mods/testnodes/commands.lua b/data/games/garage/mods/testnodes/commands.lua new file mode 100644 index 0000000..946df50 --- /dev/null +++ b/data/games/garage/mods/testnodes/commands.lua @@ -0,0 +1,139 @@ +-- Add chat command to place all the nodes in DevTest + +local function advance_pos(pos, start_pos, advance_z) + if advance_z then + pos.z = pos.z + 2 + pos.x = start_pos.x + else + pos.x = pos.x + 2 + end + if pos.x > 30900 or pos.x - start_pos.x > 46 then + pos.x = start_pos.x + pos.z = pos.z + 2 + end + if pos.z > 30900 then + -- We ran out of space! Aborting + aborted = true + return false + end + return pos +end + +local function place_nodes(param) + local nodes = param.nodes + local name = param.name + local pos = param.pos + local start_pos = param.start_pos + table.sort(nodes) + core.chat_send_player(name, "Placing nodes …") + local nodes_placed = 0 + local aborted = false + for n=1, #nodes do + local itemstring = nodes[n] + local def = core.registered_nodes[itemstring] + local p2_max = 0 + if param.param ~= "no_param2" then + -- Also test the param2 values of the nodes + -- ... but we only use permissible param2 values + if def.paramtype2 == "wallmounted" then + p2_max = 5 + elseif def.paramtype2 == "facedir" then + p2_max = 23 + elseif def.paramtype2 == "4dir" then + p2_max = 3 + elseif def.paramtype2 == "glasslikeliquidlevel" then + p2_max = 63 + elseif def.paramtype2 == "meshoptions" and def.drawtype == "plantlike" then + p2_max = 63 + elseif def.paramtype2 == "leveled" then + p2_max = 127 + elseif def.paramtype2 == "degrotate" and (def.drawtype == "plantlike" or def.drawtype == "mesh") then + p2_max = 239 + elseif def.paramtype2 == "colorfacedir" or + def.paramtype2 == "colorwallmounted" or + def.paramtype2 == "colordegrotate" or + def.paramtype2 == "color4dir" or + def.paramtype2 == "color" then + p2_max = 255 + end + end + for p2 = 0, p2_max do + -- Skip undefined param2 values + if not ((def.paramtype2 == "meshoptions" and p2 % 8 > 4) or + (def.paramtype2 == "colorwallmounted" and p2 % 8 > 5) or + ((def.paramtype2 == "colorfacedir" or def.paramtype2 == "colordegrotate") + and p2 % 32 > 23)) then + + core.set_node(pos, { name = itemstring, param2 = p2 }) + nodes_placed = nodes_placed + 1 + pos = advance_pos(pos, start_pos) + if not pos then + aborted = true + break + end + end + end + if aborted then + break + end + end + if aborted then + core.chat_send_player(name, "Not all nodes could be placed, please move further away from the world boundary. Nodes placed: "..nodes_placed) + end + core.chat_send_player(name, "Nodes placed: "..nodes_placed..".") +end + +local function after_emerge(blockpos, action, calls_remaining, param) + if calls_remaining == 0 then + place_nodes(param) + end +end + +core.register_chatcommand("test_place_nodes", { + params = "[ no_param2 ]", + description = "Test: Place all nodes (except dummy and callback nodes) and optionally their permissible param2 variants", + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local pos = vector.floor(player:get_pos()) + pos.x = math.ceil(pos.x + 3) + pos.z = math.ceil(pos.z + 3) + pos.y = math.ceil(pos.y + 1) + local start_pos = table.copy(pos) + if pos.x > 30800 then + return false, "Too close to world boundary (+X). Please move to X < 30800." + end + if pos.z > 30800 then + return false, "Too close to world boundary (+Z). Please move to Z < 30800." + end + + local aborted = false + local nodes = {} + local emerge_estimate = 0 + for itemstring, def in pairs(core.registered_nodes) do + if itemstring ~= "ignore" and + -- Skip callback test and dummy nodes + -- to avoid clutter and chat spam + core.get_item_group(itemstring, "callback_test") == 0 and + core.get_item_group(itemstring, "dummy") == 0 then + table.insert(nodes, itemstring) + if def.paramtype2 == 0 then + emerge_estimate = emerge_estimate + 1 + else + emerge_estimate = emerge_estimate + 255 + end + end + end + -- Emerge area to make sure that all nodes are being placed. + -- Note we will emerge much more than we need to (overestimation), + -- the estimation code could be improved performance-wise … + local length = 16 + math.ceil(emerge_estimate / 24) * 2 + core.emerge_area(start_pos, + { x = start_pos.x + 46, y = start_pos.y, z = start_pos.z + length }, + after_emerge, { nodes = nodes, name = name, pos = pos, start_pos = start_pos, param = param }) + return true, "Emerging area …" + end, +}) + diff --git a/data/games/garage/mods/testnodes/drawtypes.lua b/data/games/garage/mods/testnodes/drawtypes.lua new file mode 100644 index 0000000..95dae96 --- /dev/null +++ b/data/games/garage/mods/testnodes/drawtypes.lua @@ -0,0 +1,727 @@ +--[[ Drawtype Test: This file tests out and provides examples for +all drawtypes in Luanti. It is attempted to keep the node +definitions as simple and minimal as possible to keep +side-effects to a minimum. + +How to read the node definitions: +There are two parts which are separated by 2 newlines: +The first part contains the things that are more or less essential +for defining the drawtype (except description, which is +at the top for readability). +The second part (after the 2 newlines) contains stuff that are +unrelated to the drawtype, stuff that is mostly there to make +testing this node easier and more convenient. +]] + +local S = core.get_translator("testnodes") + +-- A regular cube +core.register_node("testnodes:normal", { + description = S("\"normal\" Drawtype Test Node").."\n".. + S("Opaque texture"), + drawtype = "normal", + tiles = { "testnodes_normal.png" }, + + groups = { dig_immediate = 3 }, +}) + +-- Standard glasslike node +core.register_node("testnodes:glasslike", { + description = S("\"glasslike\" Drawtype Test Node").."\n".. + S("Transparent node with hidden backfaces"), + drawtype = "glasslike", + paramtype = "light", + tiles = { "testnodes_glasslike.png" }, + + groups = { dig_immediate = 3 }, +}) + +-- Glasslike framed with the two textures (normal and "detail") +core.register_node("testnodes:glasslike_framed", { + description = S("\"glasslike_framed\" Drawtype Test Node").."\n".. + S("Transparent node with hidden backfaces").."\n".. + S("Frame connects to neighbors"), + drawtype = "glasslike_framed", + paramtype = "light", + tiles = { + "testnodes_glasslike_framed.png", + "testnodes_glasslike_detail.png", + }, + + + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +-- Like the one above, but without the "detail" texture (texture 2). +-- This node was added to see how the engine behaves when the "detail" texture +-- is missing. +core.register_node("testnodes:glasslike_framed_no_detail", { + description = S("\"glasslike_framed\" Drawtype without Detail Test Node").."\n".. + S("Transparent node with hidden backfaces").."\n".. + S("Frame connects to neighbors, but the 'detail' tile is not used"), + drawtype = "glasslike_framed", + paramtype = "light", + tiles = { "testnodes_glasslike_framed2.png" }, + + + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + + +core.register_node("testnodes:glasslike_framed_optional", { + description = S("\"glasslike_framed_optional\" Drawtype Test Node").."\n".. + S("Transparent node with hidden backfaces").."\n".. + S("Frame connects if 'connected_glass' setting is true"), + drawtype = "glasslike_framed_optional", + paramtype = "light", + tiles = { + "testnodes_glasslike_framed_optional.png", + "testnodes_glasslike_detail.png", + }, + + + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + + + +core.register_node("testnodes:allfaces", { + description = S("\"allfaces\" Drawtype Test Node").."\n".. + S("Transparent node with visible internal backfaces"), + drawtype = "allfaces", + paramtype = "light", + tiles = { "testnodes_allfaces.png" }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:allfaces_6", { + description = S("\"allfaces 6 Textures\" Drawtype Test Node").."\n".. + S("Transparent node with visible internal backfaces"), + drawtype = "allfaces", + paramtype = "light", + tiles = { + "testnodes_allfaces.png^[colorize:red", + "testnodes_allfaces.png^[colorize:orange", + "testnodes_allfaces.png^[colorize:yellow", + "testnodes_allfaces.png^[colorize:green", + "testnodes_allfaces.png^[colorize:blue", + "testnodes_allfaces.png^[colorize:purple" + }, + + groups = { dig_immediate = 3 }, +}) + +local allfaces_optional_tooltip = "".. + S("Rendering depends on 'leaves_style' setting:").."\n".. + S("* 'fancy': transparent with visible internal backfaces").."\n".. + S("* 'simple': transparent with hidden backfaces").."\n".. + S("* 'opaque': opaque") + +core.register_node("testnodes:allfaces_optional", { + description = S("\"allfaces_optional\" Drawtype Test Node").."\n".. + allfaces_optional_tooltip, + drawtype = "allfaces_optional", + paramtype = "light", + tiles = { "testnodes_allfaces_optional.png" }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:allfaces_optional_waving", { + description = S("Waving \"allfaces_optional\" Drawtype Test Node").."\n".. + allfaces_optional_tooltip.."\n".. + S("Waves if waving leaves are enabled by client"), + drawtype = "allfaces_optional", + paramtype = "light", + tiles = { "testnodes_allfaces_optional.png^[brighten" }, + waving = 2, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:firelike", { + description = S("\"firelike\" Drawtype Test Node").."\n".. + S("Changes shape based on neighbors"), + drawtype = "firelike", + paramtype = "light", + tiles = { "testnodes_firelike.png" }, + + + walkable = false, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:fencelike", { + description = S("\"fencelike\" Drawtype Test Node").."\n".. + S("Connects to neighbors"), + drawtype = "fencelike", + paramtype = "light", + tiles = { "testnodes_fencelike.png" }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:torchlike", { + description = S("Floor \"torchlike\" Drawtype Test Node").."\n".. + S("Always on floor"), + drawtype = "torchlike", + paramtype = "light", + tiles = { "testnodes_torchlike_floor.png^[colorize:#FF0000:64" }, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:torchlike_wallmounted", { + description = S("Wallmounted \"torchlike\" Drawtype Test Node").."\n".. + S("param2 = wallmounted rotation (0..7)"), + drawtype = "torchlike", + paramtype = "light", + paramtype2 = "wallmounted", + tiles = { + "testnodes_torchlike_floor.png", + "testnodes_torchlike_ceiling.png", + "testnodes_torchlike_wall.png", + }, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:torchlike_wallmounted_rot", { + description = S("Wallmounted Rotatable Torchlike Drawtype Test Node"), + drawtype = "torchlike", + paramtype = "light", + paramtype2 = "wallmounted", + wallmounted_rotate_vertical = true, + tiles = { + "testnodes_torchlike_floor.png^[colorize:#FFFF00:40", + "testnodes_torchlike_ceiling.png^[colorize:#FFFF00:40", + "testnodes_torchlike_wall.png^[colorize:#FFFF00:40", + }, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:signlike", { + description = S("Floor \"signlike\" Drawtype Test Node").."\n".. + S("Always on floor"), + drawtype = "signlike", + paramtype = "light", + tiles = { "testnodes_signlike.png^[colorize:#FF0000:64" }, + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:signlike_wallmounted", { + description = S("Wallmounted \"signlike\" Drawtype Test Node").."\n".. + S("param2 = wallmounted rotation (0..7)"), + drawtype = "signlike", + paramtype = "light", + paramtype2 = "wallmounted", + tiles = { "testnodes_signlike.png" }, + + + walkable = false, + groups = { dig_immediate = 3 }, + sunlight_propagates = true, +}) + +core.register_node("testnodes:signlike_rot", { + description = S("Wallmounted Rotatable Signlike Drawtype Test Node"), + drawtype = "signlike", + paramtype = "light", + paramtype2 = "wallmounted", + wallmounted_rotate_vertical = true, + tiles = { "testnodes_signlike.png^[colorize:#FFFF00:40" }, + + + walkable = false, + groups = { dig_immediate = 3 }, + sunlight_propagates = true, +}) + + + +core.register_node("testnodes:plantlike", { + description = S("\"plantlike\" Drawtype Test Node"), + drawtype = "plantlike", + paramtype = "light", + tiles = { "testnodes_plantlike.png" }, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:plantlike_waving", { + description = S("Waving \"plantlike\" Drawtype Test Node").."\n".. + S("Waves if waving plants are enabled by client"), + drawtype = "plantlike", + paramtype = "light", + tiles = { "testnodes_plantlike_waving.png" }, + waving = 1, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:plantlike_wallmounted", { + description = S("Wallmounted \"plantlike\" Drawtype Test Node").."\n".. + S("param2 = wallmounted rotation (0..7)"), + drawtype = "plantlike", + paramtype = "light", + paramtype2 = "wallmounted", + tiles = { "testnodes_plantlike_wallmounted.png" }, + leveled = 1, + + + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + + +-- param2 will rotate +local function rotate_on_rightclick(pos, node, clicker) + local def = core.registered_nodes[node.name] + local aux1 = clicker:get_player_control().aux1 + + local deg, deg_max + local color, color_mult = 0, 0 + if def.paramtype2 == "degrotate" then + deg = node.param2 + deg_max = 240 + elseif def.paramtype2 == "colordegrotate" then + -- MSB [3x color, 5x rotation] LSB + deg = node.param2 % 2^5 + deg_max = 24 + color_mult = 2^5 + color = math.floor(node.param2 / color_mult) + end + + deg = (deg + (aux1 and 10 or 1)) % deg_max + node.param2 = color * color_mult + deg + core.swap_node(pos, node) + core.chat_send_player(clicker:get_player_name(), + "Rotation is now " .. deg .. " / " .. deg_max) +end + +core.register_node("testnodes:plantlike_degrotate", { + description = S("Degrotate \"plantlike\" Drawtype Test Node").."\n".. + S("param2 = horizontal rotation (0..239)"), + drawtype = "plantlike", + paramtype = "light", + paramtype2 = "degrotate", + tiles = { "testnodes_plantlike_degrotate.png" }, + + on_rightclick = rotate_on_rightclick, + place_param2 = 7, + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:mesh_degrotate", { + description = S("Degrotate \"mesh\" Drawtype Test Node").."\n".. + S("param2 = horizontal rotation (0..239)"), + drawtype = "mesh", + paramtype = "light", + paramtype2 = "degrotate", + mesh = "testnodes_ocorner.obj", + tiles = { "testnodes_mesh_stripes7.png" }, + + on_rightclick = rotate_on_rightclick, + place_param2 = 10, -- 15° + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:mesh_colordegrotate", { + description = S("Colordegrotate \"mesh\" Drawtype Test Node").."\n".. + S("param2 = color + horizontal rotation (0..23, 32..55, ...)"), + drawtype = "mesh", + paramtype = "light", + paramtype2 = "colordegrotate", + palette = "testnodes_palette_facedir.png", + mesh = "testnodes_ocorner.obj", + tiles = { "testnodes_mesh_stripes8.png" }, + + on_rightclick = rotate_on_rightclick, + -- color index 1, 1 step (=15°) rotated + place_param2 = 1 * 2^5 + 1, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +-- param2 will change height +core.register_node("testnodes:plantlike_leveled", { + description = S("Leveled \"plantlike\" Drawtype Test Node").."\n".. + S("param2 = height (0..255)"), + drawtype = "plantlike", + paramtype = "light", + paramtype2 = "leveled", + tiles = { + { name = "testnodes_plantlike_leveled.png", tileable_vertical = true }, + }, + + + -- We set a default param2 here only for convenience, to make the "plant" visible after placement + place_param2 = 8, + walkable = false, + sunlight_propagates = true, + groups = { dig_immediate = 3 }, +}) + +-- param2 changes shape +core.register_node("testnodes:plantlike_meshoptions", { + description = S("Meshoptions \"plantlike\" Drawtype Test Node").."\n".. + S("param2 = plant shape"), + drawtype = "plantlike", + paramtype = "light", + paramtype2 = "meshoptions", + tiles = { "testnodes_plantlike_meshoptions.png" }, + + + walkable = false, + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:plantlike_rooted", { + description = S("\"rooted_plantlike\" Drawtype Test Node"), + drawtype = "plantlike_rooted", + paramtype = "light", + tiles = { "testnodes_plantlike_rooted_base.png" }, + special_tiles = { "testnodes_plantlike_rooted.png" }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:plantlike_rooted_wallmounted", { + description = S("Wallmounted \"rooted_plantlike\" Drawtype Test Node").."\n".. + S("param2 = wallmounted rotation (0..7)"), + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "wallmounted", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_wallmounted.png" }, + special_tiles = { "testnodes_plantlike_rooted_wallmounted.png" }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:plantlike_rooted_waving", { + description = S("Waving \"rooted_plantlike\" Drawtype Test Node").."\n".. + S("Waves if waving plants are enabled by client"), + drawtype = "plantlike_rooted", + paramtype = "light", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_waving.png", + }, + special_tiles = { "testnodes_plantlike_rooted_waving.png" }, + waving = 1, + + groups = { dig_immediate = 3 }, +}) + +-- param2 changes height +core.register_node("testnodes:plantlike_rooted_leveled", { + description = S("Leveled \"rooted_plantlike\" Drawtype Test Node").."\n".. + S("param2 = height (0..255)"), + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "leveled", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_leveled.png", + }, + special_tiles = { + { name = "testnodes_plantlike_rooted_leveled.png", tileable_vertical = true }, + }, + + + -- We set a default param2 here only for convenience, to make the "plant" visible after placement + place_param2 = 8, + groups = { dig_immediate = 3 }, +}) + +-- param2 changes shape +core.register_node("testnodes:plantlike_rooted_meshoptions", { + description = S("Meshoptions \"rooted_plantlike\" Drawtype Test Node").."\n".. + S("param2 = plant shape"), + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "meshoptions", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_meshoptions.png", + }, + special_tiles = { + "testnodes_plantlike_rooted_meshoptions.png", + }, + + groups = { dig_immediate = 3 }, +}) + +-- param2 changes rotation +core.register_node("testnodes:plantlike_rooted_degrotate", { + description = S("Degrotate \"rooted_plantlike\" Drawtype Test Node").."\n".. + S("param2 = horizontal rotation (0..239)"), + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "degrotate", + tiles = { + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base.png", + "testnodes_plantlike_rooted_base_side_degrotate.png", + }, + special_tiles = { + "testnodes_plantlike_rooted_degrotate.png", + }, + + groups = { dig_immediate = 3 }, +}) + +-- Demonstrative liquid nodes, source and flowing form. +-- DRAWTYPE ONLY, NO LIQUID PHYSICS! +-- Liquid ranges 0 to 8 +for r = 0, 8 do + core.register_node("testnodes:liquid_"..r, { + description = S("\"liquid\" Drawtype Test Node, Range @1", r).."\n".. + S("Drawtype only; all liquid physics are disabled"), + drawtype = "liquid", + paramtype = "light", + tiles = { + "testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", + }, + special_tiles = { + {name="testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false}, + {name="testnodes_liquidsource_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=true}, + }, + use_texture_alpha = "blend", + + + walkable = false, + liquid_range = r, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquid_flowing_"..r, + liquid_alternative_source = "testnodes:liquid_"..r, + groups = { dig_immediate = 3 }, + }) + core.register_node("testnodes:liquid_flowing_"..r, { + description = S("\"flowingliquid\" Drawtype Test Node, Range @1", r).."\n".. + S("Drawtype only; all liquid physics are disabled").."\n".. + S("param2 = flowing liquid level"), + drawtype = "flowingliquid", + paramtype = "light", + paramtype2 = "flowingliquid", + tiles = { + "testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", + }, + special_tiles = { + {name="testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false}, + {name="testnodes_liquidflowing_r"..r..".png^[colorize:#FFFFFF:100", backface_culling=false}, + }, + use_texture_alpha = "blend", + + + walkable = false, + liquid_range = r, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquid_flowing_"..r, + liquid_alternative_source = "testnodes:liquid_"..r, + groups = { dig_immediate = 3 }, + }) + +end + +-- Waving liquid test (drawtype only) +core.register_node("testnodes:liquid_waving", { + description = S("Waving \"liquid\" Drawtype Test Node").."\n".. + S("Drawtype only; all liquid physics are disabled").."\n".. + S("Waves if waving liquids are enabled by client"), + drawtype = "liquid", + paramtype = "light", + tiles = { + "testnodes_liquidsource.png^[colorize:#0000FF:127", + }, + special_tiles = { + {name="testnodes_liquidsource.png^[colorize:#0000FF:127", backface_culling=false}, + {name="testnodes_liquidsource.png^[colorize:#0000FF:127", backface_culling=true}, + }, + use_texture_alpha = "blend", + waving = 3, + + + walkable = false, + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquid_flowing_waving", + liquid_alternative_source = "testnodes:liquid_waving", + groups = { dig_immediate = 3 }, +}) +core.register_node("testnodes:liquid_flowing_waving", { + description = S("Waving \"flowingliquid\" Drawtype Test Node").."\n".. + S("Drawtype only; all liquid physics are disabled").."\n".. + S("param2 = flowing liquid level").."\n".. + S("Waves if waving liquids are enabled by client"), + drawtype = "flowingliquid", + paramtype = "light", + paramtype2 = "flowingliquid", + tiles = { + "testnodes_liquidflowing.png^[colorize:#0000FF:127", + }, + special_tiles = { + {name="testnodes_liquidflowing.png^[colorize:#0000FF:127", backface_culling=false}, + {name="testnodes_liquidflowing.png^[colorize:#0000FF:127", backface_culling=false}, + }, + use_texture_alpha = "blend", + waving = 3, + + + walkable = false, + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquid_flowing_waving", + liquid_alternative_source = "testnodes:liquid_waving", + groups = { dig_immediate = 3 }, +}) + +-- Invisible node +core.register_node("testnodes:airlike", { + description = S("\"airlike\" Drawtype Test Node").."\n".. + S("Invisible node").."\n".. + S("Inventory/wield image = no_texture_airlike.png"), + drawtype = "airlike", + paramtype = "light", + -- inventory/wield images are left empty to make sure the 'no texture' + -- fallback for airlike nodes is working properly. + + + walkable = false, + groups = { dig_immediate = 3 }, + sunlight_propagates = true, +}) + +-- param2 changes liquid height +core.register_node("testnodes:glassliquid", { + description = S("\"glasslike_framed\" Drawtype with Liquid Test Node").."\n".. + S("param2 = liquid level (0..63)"), + drawtype = "glasslike_framed", + paramtype = "light", + paramtype2 = "glasslikeliquidlevel", + tiles = { + "testnodes_glasslikeliquid.png", + }, + special_tiles = { + "testnodes_liquid.png", + }, + + groups = { dig_immediate = 3 }, +}) + +-- Adding many raillike examples, primarily to demonstrate the behavior of +-- "raillike groups". Nodes of the same type (rail, groupless, line, street) +-- should connect to nodes of the same "rail type" (=same shape, different +-- color) only. +local rails = { + { "rail", {"testnodes_rail_straight.png", "testnodes_rail_curved.png", "testnodes_rail_t_junction.png", "testnodes_rail_crossing.png"}, S("Connects to rails")}, + { "line", {"testnodes_line_straight.png", "testnodes_line_curved.png", "testnodes_line_t_junction.png", "testnodes_line_crossing.png"}, S("Connects to lines")}, + { "street", {"testnodes_street_straight.png", "testnodes_street_curved.png", "testnodes_street_t_junction.png", "testnodes_street_crossing.png"}, S("Connects to streets")}, + -- the "groupless" nodes are nodes in which the "connect_to_raillike" group is not set + { "groupless", {"testnodes_rail2_straight.png", "testnodes_rail2_curved.png", "testnodes_rail2_t_junction.png", "testnodes_rail2_crossing.png"}, S("Connects to 'groupless' rails") }, +} +local colors = { "", "cyan", "red" } + +for r=1, #rails do + local id = rails[r][1] + local tiles = rails[r][2] + local tt = rails[r][3] + local raillike_group + if id ~= "groupless" then + raillike_group = core.raillike_group(id) + end + for c=1, #colors do + local color + if colors[c] ~= "" then + color = colors[c] + end + core.register_node("testnodes:raillike_"..id..c, { + description = S("\"raillike\" Drawtype Test Node: @1 @2", id, c).."\n".. + tt, + drawtype = "raillike", + paramtype = "light", + tiles = tiles, + groups = { connect_to_raillike = raillike_group, dig_immediate = 3 }, + + + color = color, + selection_box = { + type = "fixed", + fixed = {{-0.5, -0.5, -0.5, 0.5, -0.4, 0.5}}, + }, + sunlight_propagates = true, + walkable = false, + }) + end +end + + + +-- Add visual_scale variants of previous nodes for half and double size +local scale = function(subname, append) + local original = "testnodes:"..subname + local def = table.copy(core.registered_items[original]) + local orig_desc + if append and type(append) == "string" then + orig_desc = ItemStack(original):get_short_description() + orig_desc = orig_desc .. "\n" .. append + elseif append ~= false then + orig_desc = ItemStack(original):get_description() + else + orig_desc = ItemStack(original):get_short_description() + end + def.visual_scale = 2.0 + def.description = S("Double-sized @1", orig_desc) + core.register_node("testnodes:"..subname.."_double", def) + def = table.copy(core.registered_items[original]) + def.visual_scale = 0.5 + def.description = S("Half-sized @1", orig_desc) + core.register_node("testnodes:"..subname.."_half", def) +end + +local allfaces_newsize_tt = "".. + S("Rendering depends on 'leaves_style' setting:").."\n".. + S("* 'fancy'/'simple': transparent").."\n".. + S("* 'opaque': opaque") + +scale("allfaces", S("Transparent node")) +scale("allfaces_optional", allfaces_newsize_tt) +scale("allfaces_optional_waving", allfaces_newsize_tt .. "\n" .. S("Waving if waving leaves are enabled by client")) +scale("plantlike") +scale("plantlike_wallmounted") +scale("torchlike_wallmounted") +scale("signlike_wallmounted") +scale("firelike") diff --git a/data/games/garage/mods/testnodes/init.lua b/data/games/garage/mods/testnodes/init.lua new file mode 100644 index 0000000..49a45e0 --- /dev/null +++ b/data/games/garage/mods/testnodes/init.lua @@ -0,0 +1,13 @@ +local path = core.get_modpath(core.get_current_modname()) + +dofile(path.."/drawtypes.lua") +dofile(path.."/meshes.lua") +dofile(path.."/nodeboxes.lua") +dofile(path.."/param2.lua") +dofile(path.."/performance_test_nodes.lua") +dofile(path.."/properties.lua") +dofile(path.."/liquids.lua") +dofile(path.."/light.lua") +dofile(path.."/textures.lua") +dofile(path.."/overlays.lua") +dofile(path.."/commands.lua") diff --git a/data/games/garage/mods/testnodes/light.lua b/data/games/garage/mods/testnodes/light.lua new file mode 100644 index 0000000..0f1ccb7 --- /dev/null +++ b/data/games/garage/mods/testnodes/light.lua @@ -0,0 +1,50 @@ +-- Test Nodes: Light test + +local S = core.get_translator("testnodes") + +-- All possible light levels +for i=1, core.LIGHT_MAX do + core.register_node("testnodes:light"..string.format("%02d", i), { + description = S("Light Source (@1)", i), + paramtype = "light", + light_source = i, + + + tiles ={"testnodes_light_"..i..".png"}, + drawtype = "glasslike", + walkable = false, + sunlight_propagates = true, + is_ground_content = false, + groups = {dig_immediate=3}, + }) +end + +-- Lets light through, but not sunlight, leading to a +-- reduction in light level when light passes through +core.register_node("testnodes:sunlight_filter", { + description = S("Sunlight Filter") .."\n".. + S("Lets light through, but weakens sunlight"), + paramtype = "light", + + + drawtype = "glasslike", + tiles = { + "testnodes_sunlight_filter.png", + }, + groups = { dig_immediate = 3 }, +}) + +-- Lets light and sunlight through without obstruction +core.register_node("testnodes:sunlight_propagator", { + description = S("Sunlight Propagator") .."\n".. + S("Lets all light through"), + paramtype = "light", + sunlight_propagates = true, + + + drawtype = "glasslike", + tiles = { + "testnodes_sunlight_filter.png^[brighten", + }, + groups = { dig_immediate = 3 }, +}) diff --git a/data/games/garage/mods/testnodes/liquids.lua b/data/games/garage/mods/testnodes/liquids.lua new file mode 100644 index 0000000..130b2a7 --- /dev/null +++ b/data/games/garage/mods/testnodes/liquids.lua @@ -0,0 +1,157 @@ +-- Add liquids for ranges and viscosity levels 0-8 + +for d=0, 8 do + local tt_normal + if d == 0 then + tt_normal = "\n".."Swimmable, renewable liquid" + else + tt_normal = "\n".."Swimmable, spreading, renewable liquid" + end + core.register_node("testnodes:rliquid_"..d, { + description = "Test Liquid Source, Range "..d.. + tt_normal .. "\n" .. "(falling & floating node)", + drawtype = "liquid", + tiles = {"testnodes_liquidsource_r"..d..".png"}, + special_tiles = { + {name = "testnodes_liquidsource_r"..d..".png", backface_culling = false}, + {name = "testnodes_liquidsource_r"..d..".png", backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "source", + liquid_alternative_flowing = "testnodes:rliquid_flowing_"..d, + liquid_alternative_source = "testnodes:rliquid_"..d, + liquid_range = d, + -- Also use these nodes to test falling, floating liquid source nodes + groups = {float = 1, falling_node = 1}, + }) + + core.register_node("testnodes:rliquid_flowing_"..d, { + description = "Flowing Test Liquid, Range "..d.. + tt_normal, + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing_r"..d..".png"}, + special_tiles = { + {name = "testnodes_liquidflowing_r"..d..".png", backface_culling = false}, + {name = "testnodes_liquidflowing_r"..d..".png", backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "flowing", + liquid_alternative_flowing = "testnodes:rliquid_flowing_"..d, + liquid_alternative_source = "testnodes:rliquid_"..d, + liquid_range = d, + }) + + if d <= 7 then + + local tt_reduced = "" + if d > 0 then + tt_reduced = "\n".."Reduced swimming/spreading speed" + end + + local mod = "^[colorize:#000000:127" + core.register_node("testnodes:vliquid_"..d, { + description = "Test Liquid Source, Viscosity/Resistance "..d.."\n".. + "Swimmable, spreading, renewable liquid".. + tt_reduced, + drawtype = "liquid", + tiles = {"testnodes_liquidsource_r"..d..".png"..mod}, + special_tiles = { + {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = false}, + {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "source", + liquid_alternative_flowing = "testnodes:vliquid_flowing_"..d, + liquid_alternative_source = "testnodes:vliquid_"..d, + liquid_viscosity = d, + }) + + core.register_node("testnodes:vliquid_flowing_"..d, { + description = "Flowing Test Liquid, Viscosity/Resistance "..d.."\n".. + "Swimmable, spreading, renewable liquid".. + tt_reduced, + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing_r"..d..".png"..mod}, + special_tiles = { + {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false}, + {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "flowing", + liquid_alternative_flowing = "testnodes:vliquid_flowing_"..d, + liquid_alternative_source = "testnodes:vliquid_"..d, + liquid_viscosity = d, + }) + + mod = "^[colorize:#000000:192" + local v = 4 + core.register_node("testnodes:vrliquid_"..d, { + description = "Test Liquid Source, Viscosity "..v..", Resistance "..d.."\n".. + "Swimmable, spreading, renewable liquid".. + tt_reduced, + drawtype = "liquid", + tiles = {"testnodes_liquidsource_r"..d..".png"..mod}, + special_tiles = { + {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = false}, + {name = "testnodes_liquidsource_r"..d..".png"..mod, backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "source", + liquid_alternative_flowing = "testnodes:vrliquid_flowing_"..d, + liquid_alternative_source = "testnodes:vrliquid_"..d, + liquid_viscosity = v, + move_resistance = d, + }) + + core.register_node("testnodes:vrliquid_flowing_"..d, { + description = "Flowing Test Liquid, Viscosity "..v..", Resistance "..d.."\n".. + "Swimmable, spreading, renewable liquid".. + tt_reduced, + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing_r"..d..".png"..mod}, + special_tiles = { + {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false}, + {name = "testnodes_liquidflowing_r"..d..".png"..mod, backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + liquidtype = "flowing", + liquid_alternative_flowing = "testnodes:vrliquid_flowing_"..d, + liquid_alternative_source = "testnodes:vrliquid_"..d, + liquid_viscosity = v, + move_resistance = d, + }) + + end + +end diff --git a/data/games/garage/mods/testnodes/meshes.lua b/data/games/garage/mods/testnodes/meshes.lua new file mode 100644 index 0000000..4fafa8a --- /dev/null +++ b/data/games/garage/mods/testnodes/meshes.lua @@ -0,0 +1,179 @@ +-- Meshes + +local S = core.get_translator("testnodes") + +local ocorner_cbox = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + {-0.5, -0.25, -0.25, 0.25, 0, 0.5}, + {-0.5, 0, 0, 0, 0.25, 0.5}, + {-0.5, 0.25, 0.25, -0.25, 0.5, 0.5} + } +} + +local tall_pyr_cbox = { + type = "fixed", + fixed = { + { -0.5, -0.5, -0.5, 0.5, -0.25, 0.5 }, + { -0.375, -0.25, -0.375, 0.375, 0, 0.375}, + { -0.25, 0, -0.25, 0.25, 0.25, 0.25}, + { -0.125, 0.25, -0.125, 0.125, 0.5, 0.125} + } +} + +-- Normal mesh +core.register_node("testnodes:mesh", { + description = S("Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes2.png"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + + groups = {dig_immediate=3}, +}) + +-- Facedir mesh: outer corner slope +core.register_node("testnodes:mesh_facedir", { + description = S("Facedir Mesh Test Node").."\n".. + S("param2 = facedir rotation (0..23)"), + drawtype = "mesh", + mesh = "testnodes_ocorner.obj", + tiles = {"testnodes_mesh_stripes.png"}, + paramtype = "light", + paramtype2 = "facedir", + collision_box = ocorner_cbox, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:mesh_colorfacedir", { + description = S("Color Facedir Mesh Test Node").."\n".. + S("param2 = color + facedir rotation (0..23, 32..55, ...)"), + drawtype = "mesh", + mesh = "testnodes_ocorner.obj", + tiles = {"testnodes_mesh_stripes3.png"}, + paramtype = "light", + paramtype2 = "colorfacedir", + palette = "testnodes_palette_facedir.png", + collision_box = ocorner_cbox, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:mesh_4dir", { + description = S("4dir Mesh Test Node").."\n".. + S("param2 = 4dir rotation (0..3)"), + drawtype = "mesh", + mesh = "testnodes_ocorner.obj", + tiles = {"testnodes_mesh_stripes5.png"}, + paramtype = "light", + paramtype2 = "4dir", + collision_box = ocorner_cbox, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:mesh_color4dir", { + description = S("Color 4dir Mesh Test Node").."\n".. + S("param2 = color + 4dir rotation (0..255)"), + drawtype = "mesh", + mesh = "testnodes_ocorner.obj", + tiles = {"testnodes_mesh_stripes6.png"}, + paramtype = "light", + paramtype2 = "color4dir", + palette = "testnodes_palette_4dir.png", + collision_box = ocorner_cbox, + + groups = {dig_immediate=3}, +}) + +-- Wallmounted mesh: pyramid +core.register_node("testnodes:mesh_wallmounted", { + description = S("Wallmounted Mesh Test Node").."\n".. + S("param2 = wallmounted rotation (0..7)"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes9.png"}, + paramtype = "light", + paramtype2 = "wallmounted", + collision_box = tall_pyr_cbox, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:mesh_colorwallmounted", { + description = S("Color Wallmounted Mesh Test Node").."\n".. + S("param2 = color + wallmounted rotation (0..7, 8..15, ...)"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes10.png"}, + paramtype = "light", + paramtype2 = "colorwallmounted", + palette = "testnodes_palette_wallmounted.png", + collision_box = tall_pyr_cbox, + + groups = {dig_immediate=3}, +}) + + +core.register_node("testnodes:mesh_double", { + description = S("Double-sized Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes2.png"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + visual_scale = 2, + + groups = {dig_immediate=3}, +}) +core.register_node("testnodes:mesh_half", { + description = S("Half-sized Mesh Test Node"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes2.png"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + visual_scale = 0.5, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:mesh_waving1", { + description = S("Plantlike-waving Mesh Test Node").."\n".. + S("Waves if waving plants are enabled by client"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes4.png^[multiply:#B0FFB0"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + waving = 1, + + groups = {dig_immediate=3}, +}) +core.register_node("testnodes:mesh_waving2", { + description = S("Leaflike-waving Mesh Test Node").."\n".. + S("Waves if waving leaves are enabled by client"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes4.png^[multiply:#FFFFB0"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + waving = 2, + + groups = {dig_immediate=3}, +}) +core.register_node("testnodes:mesh_waving3", { + description = S("Liquidlike-waving Mesh Test Node").."\n".. + S("Waves if waving liquids are enabled by client"), + drawtype = "mesh", + mesh = "testnodes_pyramid.obj", + tiles = {"testnodes_mesh_stripes4.png^[multiply:#B0B0FF"}, + paramtype = "light", + collision_box = tall_pyr_cbox, + waving = 3, + + groups = {dig_immediate=3}, +}) diff --git a/data/games/garage/mods/testnodes/mod.conf b/data/games/garage/mods/testnodes/mod.conf new file mode 100644 index 0000000..d894c34 --- /dev/null +++ b/data/games/garage/mods/testnodes/mod.conf @@ -0,0 +1,3 @@ +name = testnodes +description = Contains a bunch of basic example nodes for demonstrative purposes, development and testing +depends = stairs diff --git a/data/games/garage/mods/testnodes/models/testnodes_marble_glass.obj b/data/games/garage/mods/testnodes/models/testnodes_marble_glass.obj new file mode 100644 index 0000000..5acd93e --- /dev/null +++ b/data/games/garage/mods/testnodes/models/testnodes_marble_glass.obj @@ -0,0 +1,1619 @@ +# Blender 3.3.1 +# www.blender.org +o Cube +v 0.323728 0.323728 -0.323728 +v 0.323728 -0.323728 -0.323728 +v 0.323728 0.323728 0.323728 +v 0.323728 -0.323728 0.323728 +v -0.323728 0.323728 -0.323728 +v -0.323728 -0.323728 -0.323728 +v -0.323728 0.323728 0.323728 +v -0.323728 -0.323728 0.323728 +v -0.396318 -0.396318 0.000000 +v 0.000000 -0.396318 -0.396318 +v 0.396318 0.000000 -0.396318 +v -0.396318 0.000000 0.396318 +v 0.396318 0.000000 0.396318 +v -0.396318 0.000000 -0.396318 +v 0.000000 0.396318 0.396318 +v 0.396318 0.396318 0.000000 +v 0.000000 -0.396318 0.396318 +v -0.396318 0.396318 0.000000 +v 0.000000 0.396318 -0.396318 +v 0.396318 -0.396318 0.000000 +v 0.000000 0.561355 -0.000000 +v 0.000000 0.000000 0.561355 +v -0.561355 0.000000 0.000000 +v 0.000000 -0.561355 -0.000000 +v 0.561355 0.000000 -0.000000 +v -0.000000 0.000000 -0.561355 +v -0.378043 -0.378043 -0.169966 +v -0.378043 -0.378043 0.169966 +v 0.169966 -0.378043 -0.378043 +v -0.169966 -0.378043 -0.378043 +v 0.378043 0.169966 -0.378043 +v 0.378043 -0.169966 -0.378043 +v -0.378043 -0.169966 0.378043 +v -0.378043 0.169966 0.378043 +v 0.378043 0.169966 0.378043 +v 0.378043 -0.169966 0.378043 +v -0.378043 0.169966 -0.378043 +v -0.378043 -0.169966 -0.378043 +v 0.169966 0.378043 0.378043 +v -0.169966 0.378043 0.378043 +v 0.378043 0.378043 -0.169966 +v 0.378043 0.378043 0.169966 +v -0.169966 -0.378043 0.378043 +v 0.169966 -0.378043 0.378043 +v -0.378043 0.378043 0.169966 +v -0.378043 0.378043 -0.169966 +v -0.169966 0.378043 -0.378043 +v 0.169966 0.378043 -0.378043 +v 0.378043 -0.378043 0.169966 +v 0.378043 -0.378043 -0.169966 +v 0.000000 0.518474 -0.214562 +v -0.214562 0.518474 -0.000000 +v 0.000000 0.518474 0.214562 +v 0.214562 0.518474 -0.000000 +v 0.214562 0.000000 0.518474 +v 0.000000 0.214562 0.518474 +v -0.214562 0.000000 0.518474 +v 0.000000 -0.214562 0.518474 +v -0.518474 0.000000 0.214562 +v -0.518474 0.214562 0.000000 +v -0.518474 0.000000 -0.214562 +v -0.518474 -0.214562 0.000000 +v 0.000000 -0.518474 -0.214562 +v 0.214562 -0.518474 -0.000000 +v 0.000000 -0.518474 0.214562 +v -0.214562 -0.518474 -0.000000 +v 0.518474 0.000000 -0.214562 +v 0.518474 0.214562 -0.000000 +v 0.518474 0.000000 0.214562 +v 0.518474 -0.214562 -0.000000 +v -0.214562 0.000000 -0.518474 +v -0.000000 0.214562 -0.518474 +v 0.214562 0.000000 -0.518474 +v -0.000000 -0.214562 -0.518474 +v 0.205792 0.479498 -0.205792 +v -0.205792 0.479498 -0.205792 +v -0.205792 0.479498 0.205792 +v 0.205792 0.479498 0.205792 +v 0.205792 -0.205792 0.479498 +v 0.205792 0.205792 0.479498 +v -0.205792 0.205792 0.479498 +v -0.205792 -0.205792 0.479498 +v -0.479498 -0.205792 0.205792 +v -0.479498 0.205792 0.205792 +v -0.479498 0.205792 -0.205792 +v -0.479498 -0.205792 -0.205792 +v -0.205792 -0.479498 -0.205792 +v 0.205792 -0.479498 -0.205792 +v 0.205792 -0.479498 0.205792 +v -0.205792 -0.479498 0.205792 +v 0.479498 -0.205792 -0.205792 +v 0.479498 0.205792 -0.205792 +v 0.479498 0.205792 0.205792 +v 0.479498 -0.205792 0.205792 +v -0.205792 -0.205792 -0.479498 +v -0.205792 0.205792 -0.479498 +v 0.205792 0.205792 -0.479498 +v 0.205792 -0.205792 -0.479498 +v -0.355165 -0.355165 -0.249858 +v -0.391777 -0.391777 -0.085992 +v -0.391777 -0.391777 0.085992 +v -0.355165 -0.355165 0.249858 +v 0.249858 -0.355165 -0.355165 +v 0.085992 -0.391777 -0.391777 +v -0.085992 -0.391777 -0.391777 +v -0.249858 -0.355165 -0.355165 +v 0.355165 0.249858 -0.355165 +v 0.391777 0.085992 -0.391777 +v 0.391777 -0.085992 -0.391777 +v 0.355165 -0.249858 -0.355165 +v -0.355165 -0.249858 0.355165 +v -0.391777 -0.085992 0.391777 +v -0.391777 0.085992 0.391777 +v -0.355165 0.249858 0.355165 +v 0.355165 0.249858 0.355165 +v 0.391777 0.085992 0.391777 +v 0.391777 -0.085992 0.391777 +v 0.355165 -0.249858 0.355165 +v -0.355165 0.249858 -0.355165 +v -0.391777 0.085992 -0.391777 +v -0.391777 -0.085992 -0.391777 +v -0.355165 -0.249858 -0.355165 +v 0.249858 0.355165 0.355165 +v 0.085992 0.391777 0.391777 +v -0.085992 0.391777 0.391777 +v -0.249858 0.355165 0.355165 +v 0.355165 0.355165 -0.249858 +v 0.391777 0.391777 -0.085992 +v 0.391777 0.391777 0.085992 +v 0.355165 0.355165 0.249858 +v -0.249858 -0.355165 0.355165 +v -0.085992 -0.391777 0.391777 +v 0.085992 -0.391777 0.391777 +v 0.249858 -0.355165 0.355165 +v -0.355165 0.355165 0.249858 +v -0.391777 0.391777 0.085992 +v -0.391777 0.391777 -0.085992 +v -0.355165 0.355165 -0.249858 +v -0.249858 0.355165 -0.355165 +v -0.085992 0.391777 -0.391777 +v 0.085992 0.391777 -0.391777 +v 0.249858 0.355165 -0.355165 +v 0.355165 -0.355165 0.249858 +v 0.391777 -0.391777 0.085992 +v 0.391777 -0.391777 -0.085992 +v 0.355165 -0.355165 -0.249858 +v 0.000000 0.466551 -0.311553 +v 0.000000 0.550455 -0.109376 +v -0.311553 0.466551 0.000000 +v -0.109376 0.550455 0.000000 +v 0.000000 0.466551 0.311553 +v 0.000000 0.550455 0.109376 +v 0.311553 0.466551 0.000000 +v 0.109376 0.550455 0.000000 +v 0.311553 0.000000 0.466551 +v 0.109376 0.000000 0.550455 +v 0.000000 0.311553 0.466551 +v 0.000000 0.109376 0.550455 +v -0.311553 0.000000 0.466551 +v -0.109376 0.000000 0.550455 +v 0.000000 -0.311553 0.466551 +v 0.000000 -0.109376 0.550455 +v -0.466551 0.000000 0.311553 +v -0.550455 0.000000 0.109376 +v -0.466551 0.311553 0.000000 +v -0.550455 0.109376 0.000000 +v -0.466551 0.000000 -0.311553 +v -0.550455 0.000000 -0.109376 +v -0.466551 -0.311553 0.000000 +v -0.550455 -0.109376 0.000000 +v 0.000000 -0.466551 -0.311553 +v 0.000000 -0.550455 -0.109376 +v 0.311553 -0.466551 0.000000 +v 0.109376 -0.550455 0.000000 +v 0.000000 -0.466551 0.311553 +v 0.000000 -0.550455 0.109376 +v -0.311553 -0.466551 0.000000 +v -0.109376 -0.550455 0.000000 +v 0.466551 0.000000 -0.311553 +v 0.550455 0.000000 -0.109376 +v 0.466551 0.311553 0.000000 +v 0.550455 0.109376 0.000000 +v 0.466551 0.000000 0.311553 +v 0.550455 0.000000 0.109376 +v 0.466551 -0.311553 0.000000 +v 0.550455 -0.109376 0.000000 +v -0.311553 0.000000 -0.466551 +v -0.109376 0.000000 -0.550455 +v 0.000000 0.311553 -0.466551 +v 0.000000 0.109376 -0.550455 +v 0.311553 0.000000 -0.466551 +v 0.109376 0.000000 -0.550455 +v 0.000000 -0.311553 -0.466551 +v 0.000000 -0.109376 -0.550455 +v 0.190929 0.435731 -0.296656 +v 0.104690 0.507685 -0.213841 +v 0.213841 0.507685 -0.104690 +v 0.296656 0.435731 -0.190929 +v -0.190929 0.435731 -0.296656 +v -0.296656 0.435731 -0.190929 +v -0.213841 0.507685 -0.104690 +v -0.104690 0.507685 -0.213841 +v -0.213841 0.507685 0.104690 +v -0.296656 0.435731 0.190929 +v -0.190929 0.435731 0.296656 +v -0.104690 0.507685 0.213841 +v 0.213841 0.507685 0.104690 +v 0.104690 0.507685 0.213841 +v 0.190929 0.435731 0.296656 +v 0.296656 0.435731 0.190929 +v 0.296656 -0.190929 0.435731 +v 0.213841 -0.104690 0.507685 +v 0.104690 -0.213841 0.507685 +v 0.190929 -0.296656 0.435731 +v 0.296656 0.190929 0.435731 +v 0.190929 0.296656 0.435731 +v 0.104690 0.213841 0.507685 +v 0.213841 0.104690 0.507685 +v -0.104690 0.213841 0.507685 +v -0.190929 0.296656 0.435731 +v -0.296656 0.190929 0.435731 +v -0.213841 0.104690 0.507685 +v -0.104690 -0.213841 0.507685 +v -0.213841 -0.104690 0.507685 +v -0.296656 -0.190929 0.435731 +v -0.190929 -0.296656 0.435731 +v -0.435731 -0.190929 0.296656 +v -0.507685 -0.104690 0.213841 +v -0.507685 -0.213841 0.104690 +v -0.435731 -0.296656 0.190929 +v -0.435731 0.190929 0.296656 +v -0.435731 0.296656 0.190929 +v -0.507685 0.213841 0.104690 +v -0.507685 0.104690 0.213841 +v -0.507685 0.213841 -0.104690 +v -0.435731 0.296656 -0.190929 +v -0.435731 0.190929 -0.296656 +v -0.507685 0.104690 -0.213841 +v -0.507685 -0.213841 -0.104690 +v -0.507685 -0.104690 -0.213841 +v -0.435731 -0.190929 -0.296656 +v -0.435731 -0.296656 -0.190929 +v -0.190929 -0.435731 -0.296656 +v -0.104690 -0.507685 -0.213841 +v -0.213841 -0.507685 -0.104690 +v -0.296656 -0.435731 -0.190929 +v 0.190929 -0.435731 -0.296656 +v 0.296656 -0.435731 -0.190929 +v 0.213841 -0.507685 -0.104690 +v 0.104690 -0.507685 -0.213841 +v 0.213841 -0.507685 0.104690 +v 0.296656 -0.435731 0.190929 +v 0.190929 -0.435731 0.296656 +v 0.104690 -0.507685 0.213841 +v -0.213841 -0.507685 0.104690 +v -0.104690 -0.507685 0.213841 +v -0.190929 -0.435731 0.296656 +v -0.296656 -0.435731 0.190929 +v 0.435731 -0.190929 -0.296656 +v 0.507685 -0.104690 -0.213841 +v 0.507685 -0.213841 -0.104690 +v 0.435731 -0.296656 -0.190929 +v 0.435731 0.190929 -0.296656 +v 0.435731 0.296656 -0.190929 +v 0.507685 0.213841 -0.104690 +v 0.507685 0.104690 -0.213841 +v 0.507685 0.213841 0.104690 +v 0.435731 0.296656 0.190929 +v 0.435731 0.190929 0.296656 +v 0.507685 0.104690 0.213841 +v 0.507685 -0.213841 0.104690 +v 0.507685 -0.104690 0.213841 +v 0.435731 -0.190929 0.296656 +v 0.435731 -0.296656 0.190929 +v -0.296656 -0.190929 -0.435731 +v -0.213841 -0.104690 -0.507685 +v -0.104690 -0.213841 -0.507685 +v -0.190929 -0.296656 -0.435731 +v -0.296656 0.190929 -0.435731 +v -0.190929 0.296656 -0.435731 +v -0.104690 0.213841 -0.507685 +v -0.213841 0.104690 -0.507685 +v 0.104690 0.213841 -0.507685 +v 0.190929 0.296656 -0.435731 +v 0.296656 0.190929 -0.435731 +v 0.213841 0.104690 -0.507685 +v 0.104690 -0.213841 -0.507685 +v 0.213841 -0.104690 -0.507685 +v 0.296656 -0.190929 -0.435731 +v 0.190929 -0.296656 -0.435731 +v 0.277006 0.400861 -0.277006 +v 0.097104 0.458010 -0.308740 +v 0.109074 0.539153 -0.109074 +v 0.308740 0.458010 -0.097104 +v -0.097104 0.458010 -0.308740 +v -0.277006 0.400861 -0.277006 +v -0.308740 0.458010 -0.097104 +v -0.109074 0.539153 -0.109074 +v -0.109074 0.539153 0.109074 +v -0.308740 0.458010 0.097104 +v -0.277006 0.400861 0.277006 +v -0.097104 0.458010 0.308740 +v 0.308740 0.458010 0.097104 +v 0.109074 0.539153 0.109074 +v 0.097104 0.458010 0.308740 +v 0.277006 0.400861 0.277006 +v 0.277006 -0.277006 0.400861 +v 0.308740 -0.097104 0.458010 +v 0.109074 -0.109074 0.539153 +v 0.097104 -0.308740 0.458010 +v 0.308740 0.097104 0.458010 +v 0.277006 0.277006 0.400861 +v 0.097104 0.308740 0.458010 +v 0.109074 0.109074 0.539153 +v -0.109074 0.109074 0.539153 +v -0.097104 0.308740 0.458010 +v -0.277006 0.277006 0.400861 +v -0.308740 0.097104 0.458010 +v -0.097104 -0.308740 0.458010 +v -0.109074 -0.109074 0.539153 +v -0.308740 -0.097104 0.458010 +v -0.277006 -0.277006 0.400861 +v -0.400861 -0.277006 0.277006 +v -0.458010 -0.097104 0.308740 +v -0.539153 -0.109074 0.109074 +v -0.458010 -0.308740 0.097104 +v -0.458010 0.097104 0.308740 +v -0.400861 0.277006 0.277006 +v -0.458010 0.308740 0.097104 +v -0.539153 0.109074 0.109074 +v -0.539153 0.109074 -0.109074 +v -0.458010 0.308740 -0.097104 +v -0.400861 0.277006 -0.277006 +v -0.458010 0.097104 -0.308740 +v -0.458010 -0.308740 -0.097104 +v -0.539153 -0.109074 -0.109074 +v -0.458010 -0.097104 -0.308740 +v -0.400861 -0.277006 -0.277006 +v -0.277006 -0.400861 -0.277006 +v -0.097104 -0.458010 -0.308740 +v -0.109074 -0.539153 -0.109074 +v -0.308740 -0.458010 -0.097104 +v 0.097104 -0.458010 -0.308740 +v 0.277006 -0.400861 -0.277006 +v 0.308740 -0.458010 -0.097104 +v 0.109074 -0.539153 -0.109074 +v 0.109074 -0.539153 0.109074 +v 0.308740 -0.458010 0.097104 +v 0.277006 -0.400861 0.277006 +v 0.097104 -0.458010 0.308740 +v -0.308740 -0.458010 0.097104 +v -0.109074 -0.539153 0.109074 +v -0.097104 -0.458010 0.308740 +v -0.277006 -0.400861 0.277006 +v 0.400861 -0.277006 -0.277006 +v 0.458010 -0.097104 -0.308740 +v 0.539153 -0.109074 -0.109074 +v 0.458010 -0.308740 -0.097104 +v 0.458010 0.097104 -0.308740 +v 0.400861 0.277006 -0.277006 +v 0.458010 0.308740 -0.097104 +v 0.539153 0.109074 -0.109074 +v 0.539153 0.109074 0.109074 +v 0.458010 0.308740 0.097104 +v 0.400861 0.277006 0.277006 +v 0.458010 0.097104 0.308740 +v 0.458010 -0.308740 0.097104 +v 0.539153 -0.109074 0.109074 +v 0.458010 -0.097104 0.308740 +v 0.400861 -0.277006 0.277006 +v -0.277006 -0.277006 -0.400861 +v -0.308740 -0.097104 -0.458010 +v -0.109074 -0.109074 -0.539153 +v -0.097104 -0.308740 -0.458010 +v -0.308740 0.097104 -0.458010 +v -0.277006 0.277006 -0.400861 +v -0.097104 0.308740 -0.458010 +v -0.109074 0.109074 -0.539153 +v 0.109074 0.109074 -0.539153 +v 0.097104 0.308740 -0.458010 +v 0.277006 0.277006 -0.400861 +v 0.308740 0.097104 -0.458010 +v 0.097104 -0.308740 -0.458010 +v 0.109074 -0.109074 -0.539153 +v 0.308740 -0.097104 -0.458010 +v 0.277006 -0.277006 -0.400861 +vn 0.5774 0.5774 -0.5774 +vn 0.4530 0.6304 -0.6304 +vn 0.4902 0.7207 -0.4902 +vn 0.6304 0.6304 -0.4530 +vn 0.3090 0.6725 -0.6725 +vn 0.3371 0.7812 -0.5254 +vn 0.3638 0.8575 -0.3638 +vn 0.5254 0.7812 -0.3371 +vn 0.6725 0.6725 -0.3090 +vn 0.1560 0.6984 -0.6984 +vn 0.1715 0.8189 -0.5477 +vn -0.0000 0.7071 -0.7071 +vn -0.0000 0.8326 -0.5539 +vn -0.0000 0.9246 -0.3809 +vn 0.1869 0.9066 -0.3783 +vn 0.1950 0.9612 -0.1950 +vn 0.3783 0.9066 -0.1869 +vn -0.0000 0.9806 -0.1961 +vn -0.0000 1.0000 -0.0000 +vn 0.1961 0.9806 -0.0000 +vn 0.3809 0.9246 -0.0000 +vn 0.5477 0.8189 -0.1715 +vn 0.6984 0.6984 -0.1560 +vn 0.5539 0.8326 -0.0000 +vn 0.7071 0.7071 -0.0000 +vn -0.1560 0.6984 -0.6984 +vn -0.1715 0.8189 -0.5477 +vn -0.3090 0.6725 -0.6725 +vn -0.3371 0.7812 -0.5254 +vn -0.3638 0.8575 -0.3638 +vn -0.1869 0.9066 -0.3783 +vn -0.4530 0.6304 -0.6304 +vn -0.4902 0.7207 -0.4902 +vn -0.5774 0.5774 -0.5774 +vn -0.6304 0.6304 -0.4530 +vn -0.6725 0.6725 -0.3090 +vn -0.5254 0.7812 -0.3371 +vn -0.5477 0.8189 -0.1715 +vn -0.3783 0.9066 -0.1869 +vn -0.6984 0.6984 -0.1560 +vn -0.7071 0.7071 -0.0000 +vn -0.5539 0.8326 -0.0000 +vn -0.3809 0.9246 -0.0000 +vn -0.1950 0.9612 -0.1950 +vn -0.1961 0.9806 -0.0000 +vn -0.1950 0.9612 0.1950 +vn -0.0000 0.9806 0.1961 +vn -0.3783 0.9066 0.1869 +vn -0.3638 0.8575 0.3638 +vn -0.1869 0.9066 0.3783 +vn -0.0000 0.9246 0.3809 +vn -0.5477 0.8189 0.1715 +vn -0.6984 0.6984 0.1560 +vn -0.6725 0.6725 0.3090 +vn -0.5254 0.7812 0.3371 +vn -0.4902 0.7207 0.4902 +vn -0.3371 0.7812 0.5254 +vn -0.6304 0.6304 0.4530 +vn -0.5774 0.5774 0.5774 +vn -0.4530 0.6304 0.6304 +vn -0.3090 0.6725 0.6725 +vn -0.1715 0.8189 0.5477 +vn -0.0000 0.8326 0.5539 +vn -0.1560 0.6984 0.6984 +vn -0.0000 0.7071 0.7071 +vn 0.5477 0.8189 0.1715 +vn 0.6984 0.6984 0.1560 +vn 0.3783 0.9066 0.1869 +vn 0.3638 0.8575 0.3638 +vn 0.5254 0.7812 0.3371 +vn 0.6725 0.6725 0.3090 +vn 0.1950 0.9612 0.1950 +vn 0.1869 0.9066 0.3783 +vn 0.1715 0.8189 0.5477 +vn 0.3371 0.7812 0.5254 +vn 0.1560 0.6984 0.6984 +vn 0.3090 0.6725 0.6725 +vn 0.4902 0.7207 0.4902 +vn 0.6304 0.6304 0.4530 +vn 0.4530 0.6304 0.6304 +vn 0.5774 0.5774 0.5774 +vn 0.5774 -0.5774 0.5774 +vn 0.6304 -0.4530 0.6304 +vn 0.4902 -0.4902 0.7207 +vn 0.4530 -0.6304 0.6304 +vn 0.6725 -0.3090 0.6725 +vn 0.5254 -0.3371 0.7812 +vn 0.3638 -0.3638 0.8575 +vn 0.3371 -0.5254 0.7812 +vn 0.3090 -0.6725 0.6725 +vn 0.6984 -0.1560 0.6984 +vn 0.5477 -0.1715 0.8189 +vn 0.7071 -0.0000 0.7071 +vn 0.5539 -0.0000 0.8326 +vn 0.3809 -0.0000 0.9246 +vn 0.3783 -0.1869 0.9066 +vn 0.1950 -0.1950 0.9612 +vn 0.1869 -0.3783 0.9066 +vn 0.1961 -0.0000 0.9806 +vn -0.0000 -0.0000 1.0000 +vn -0.0000 -0.1961 0.9806 +vn -0.0000 -0.3809 0.9246 +vn 0.1715 -0.5477 0.8189 +vn 0.1560 -0.6984 0.6984 +vn -0.0000 -0.5539 0.8326 +vn -0.0000 -0.7071 0.7071 +vn 0.6984 0.1560 0.6984 +vn 0.5477 0.1715 0.8189 +vn 0.6725 0.3090 0.6725 +vn 0.5254 0.3371 0.7812 +vn 0.3638 0.3638 0.8575 +vn 0.3783 0.1869 0.9066 +vn 0.6304 0.4530 0.6304 +vn 0.4902 0.4902 0.7207 +vn 0.3371 0.5254 0.7812 +vn 0.1715 0.5477 0.8189 +vn 0.1869 0.3783 0.9066 +vn -0.0000 0.5539 0.8326 +vn -0.0000 0.3809 0.9246 +vn 0.1950 0.1950 0.9612 +vn -0.0000 0.1961 0.9806 +vn -0.1950 0.1950 0.9612 +vn -0.1961 -0.0000 0.9806 +vn -0.1869 0.3783 0.9066 +vn -0.3638 0.3638 0.8575 +vn -0.3783 0.1869 0.9066 +vn -0.3809 -0.0000 0.9246 +vn -0.1715 0.5477 0.8189 +vn -0.3371 0.5254 0.7812 +vn -0.4902 0.4902 0.7207 +vn -0.5254 0.3371 0.7812 +vn -0.6304 0.4530 0.6304 +vn -0.6725 0.3090 0.6725 +vn -0.5477 0.1715 0.8189 +vn -0.5539 -0.0000 0.8326 +vn -0.6984 0.1560 0.6984 +vn -0.7071 -0.0000 0.7071 +vn -0.1715 -0.5477 0.8189 +vn -0.1560 -0.6984 0.6984 +vn -0.1869 -0.3783 0.9066 +vn -0.3638 -0.3638 0.8575 +vn -0.3371 -0.5254 0.7812 +vn -0.3090 -0.6725 0.6725 +vn -0.1950 -0.1950 0.9612 +vn -0.3783 -0.1869 0.9066 +vn -0.5477 -0.1715 0.8189 +vn -0.5254 -0.3371 0.7812 +vn -0.6984 -0.1560 0.6984 +vn -0.6725 -0.3090 0.6725 +vn -0.4902 -0.4902 0.7207 +vn -0.4530 -0.6304 0.6304 +vn -0.6304 -0.4530 0.6304 +vn -0.5774 -0.5774 0.5774 +vn -0.7207 -0.4902 0.4902 +vn -0.6304 -0.6304 0.4530 +vn -0.7812 -0.3371 0.5254 +vn -0.8575 -0.3638 0.3638 +vn -0.7812 -0.5254 0.3371 +vn -0.6725 -0.6725 0.3090 +vn -0.8189 -0.1715 0.5477 +vn -0.8326 -0.0000 0.5539 +vn -0.9246 -0.0000 0.3809 +vn -0.9066 -0.1869 0.3783 +vn -0.9612 -0.1950 0.1950 +vn -0.9066 -0.3783 0.1869 +vn -0.9806 -0.0000 0.1961 +vn -1.0000 -0.0000 -0.0000 +vn -0.9806 -0.1961 -0.0000 +vn -0.9246 -0.3809 -0.0000 +vn -0.8189 -0.5477 0.1715 +vn -0.6984 -0.6984 0.1560 +vn -0.8326 -0.5539 -0.0000 +vn -0.7071 -0.7071 -0.0000 +vn -0.8189 0.1715 0.5477 +vn -0.7812 0.3371 0.5254 +vn -0.8575 0.3638 0.3638 +vn -0.9066 0.1869 0.3783 +vn -0.7207 0.4902 0.4902 +vn -0.7812 0.5254 0.3371 +vn -0.8189 0.5477 0.1715 +vn -0.9066 0.3783 0.1869 +vn -0.8326 0.5539 -0.0000 +vn -0.9246 0.3809 -0.0000 +vn -0.9612 0.1950 0.1950 +vn -0.9806 0.1961 -0.0000 +vn -0.9612 0.1950 -0.1950 +vn -0.9806 -0.0000 -0.1961 +vn -0.9066 0.3783 -0.1869 +vn -0.8575 0.3638 -0.3638 +vn -0.9066 0.1869 -0.3783 +vn -0.9246 -0.0000 -0.3809 +vn -0.8189 0.5477 -0.1715 +vn -0.7812 0.5254 -0.3371 +vn -0.7207 0.4902 -0.4902 +vn -0.7812 0.3371 -0.5254 +vn -0.6304 0.4530 -0.6304 +vn -0.6725 0.3090 -0.6725 +vn -0.8189 0.1715 -0.5477 +vn -0.8326 -0.0000 -0.5539 +vn -0.6984 0.1560 -0.6984 +vn -0.7071 -0.0000 -0.7071 +vn -0.8189 -0.5477 -0.1715 +vn -0.6984 -0.6984 -0.1560 +vn -0.9066 -0.3783 -0.1869 +vn -0.8575 -0.3638 -0.3638 +vn -0.7812 -0.5254 -0.3371 +vn -0.6725 -0.6725 -0.3090 +vn -0.9612 -0.1950 -0.1950 +vn -0.9066 -0.1869 -0.3783 +vn -0.8189 -0.1715 -0.5477 +vn -0.7812 -0.3371 -0.5254 +vn -0.6984 -0.1560 -0.6984 +vn -0.6725 -0.3090 -0.6725 +vn -0.7207 -0.4902 -0.4902 +vn -0.6304 -0.6304 -0.4530 +vn -0.6304 -0.4530 -0.6304 +vn -0.5774 -0.5774 -0.5774 +vn -0.4530 -0.6304 -0.6304 +vn -0.4902 -0.7207 -0.4902 +vn -0.3090 -0.6725 -0.6725 +vn -0.3371 -0.7812 -0.5254 +vn -0.3638 -0.8575 -0.3638 +vn -0.5254 -0.7812 -0.3371 +vn -0.1560 -0.6984 -0.6984 +vn -0.1715 -0.8189 -0.5477 +vn -0.0000 -0.7071 -0.7071 +vn -0.0000 -0.8326 -0.5539 +vn -0.0000 -0.9246 -0.3809 +vn -0.1869 -0.9066 -0.3783 +vn -0.1950 -0.9612 -0.1950 +vn -0.3783 -0.9066 -0.1869 +vn -0.0000 -0.9806 -0.1961 +vn -0.0000 -1.0000 -0.0000 +vn -0.1961 -0.9806 -0.0000 +vn -0.3809 -0.9246 -0.0000 +vn -0.5477 -0.8189 -0.1715 +vn -0.5539 -0.8326 -0.0000 +vn 0.1560 -0.6984 -0.6984 +vn 0.1715 -0.8189 -0.5477 +vn 0.3090 -0.6725 -0.6725 +vn 0.3371 -0.7812 -0.5254 +vn 0.3638 -0.8575 -0.3638 +vn 0.1869 -0.9066 -0.3783 +vn 0.4530 -0.6304 -0.6304 +vn 0.4902 -0.7207 -0.4902 +vn 0.5774 -0.5774 -0.5774 +vn 0.6304 -0.6304 -0.4530 +vn 0.6725 -0.6725 -0.3090 +vn 0.5254 -0.7812 -0.3371 +vn 0.5477 -0.8189 -0.1715 +vn 0.3783 -0.9066 -0.1869 +vn 0.6984 -0.6984 -0.1560 +vn 0.7071 -0.7071 -0.0000 +vn 0.5539 -0.8326 -0.0000 +vn 0.3809 -0.9246 -0.0000 +vn 0.1950 -0.9612 -0.1950 +vn 0.1961 -0.9806 -0.0000 +vn 0.1950 -0.9612 0.1950 +vn -0.0000 -0.9806 0.1961 +vn 0.3783 -0.9066 0.1869 +vn 0.3638 -0.8575 0.3638 +vn 0.1869 -0.9066 0.3783 +vn -0.0000 -0.9246 0.3809 +vn 0.5477 -0.8189 0.1715 +vn 0.6984 -0.6984 0.1560 +vn 0.6725 -0.6725 0.3090 +vn 0.5254 -0.7812 0.3371 +vn 0.4902 -0.7207 0.4902 +vn 0.3371 -0.7812 0.5254 +vn 0.6304 -0.6304 0.4530 +vn 0.1715 -0.8189 0.5477 +vn -0.0000 -0.8326 0.5539 +vn -0.5477 -0.8189 0.1715 +vn -0.3783 -0.9066 0.1869 +vn -0.3638 -0.8575 0.3638 +vn -0.5254 -0.7812 0.3371 +vn -0.1950 -0.9612 0.1950 +vn -0.1869 -0.9066 0.3783 +vn -0.1715 -0.8189 0.5477 +vn -0.3371 -0.7812 0.5254 +vn -0.4902 -0.7207 0.4902 +vn 0.6304 -0.4530 -0.6304 +vn 0.7207 -0.4902 -0.4902 +vn 0.6725 -0.3090 -0.6725 +vn 0.7812 -0.3371 -0.5254 +vn 0.8575 -0.3638 -0.3638 +vn 0.7812 -0.5254 -0.3371 +vn 0.6984 -0.1560 -0.6984 +vn 0.8189 -0.1715 -0.5477 +vn 0.7071 -0.0000 -0.7071 +vn 0.8326 -0.0000 -0.5539 +vn 0.9246 -0.0000 -0.3809 +vn 0.9066 -0.1869 -0.3783 +vn 0.9612 -0.1950 -0.1950 +vn 0.9066 -0.3783 -0.1869 +vn 0.9806 -0.0000 -0.1961 +vn 1.0000 -0.0000 -0.0000 +vn 0.9806 -0.1961 -0.0000 +vn 0.9246 -0.3809 -0.0000 +vn 0.8189 -0.5477 -0.1715 +vn 0.8326 -0.5539 -0.0000 +vn 0.6984 0.1560 -0.6984 +vn 0.8189 0.1715 -0.5477 +vn 0.6725 0.3090 -0.6725 +vn 0.7812 0.3371 -0.5254 +vn 0.8575 0.3638 -0.3638 +vn 0.9066 0.1869 -0.3783 +vn 0.6304 0.4530 -0.6304 +vn 0.7207 0.4902 -0.4902 +vn 0.7812 0.5254 -0.3371 +vn 0.8189 0.5477 -0.1715 +vn 0.9066 0.3783 -0.1869 +vn 0.8326 0.5539 -0.0000 +vn 0.9246 0.3809 -0.0000 +vn 0.9612 0.1950 -0.1950 +vn 0.9806 0.1961 -0.0000 +vn 0.9612 0.1950 0.1950 +vn 0.9806 -0.0000 0.1961 +vn 0.9066 0.3783 0.1869 +vn 0.8575 0.3638 0.3638 +vn 0.9066 0.1869 0.3783 +vn 0.9246 -0.0000 0.3809 +vn 0.8189 0.5477 0.1715 +vn 0.7812 0.5254 0.3371 +vn 0.7207 0.4902 0.4902 +vn 0.7812 0.3371 0.5254 +vn 0.8189 0.1715 0.5477 +vn 0.8326 -0.0000 0.5539 +vn 0.8189 -0.5477 0.1715 +vn 0.9066 -0.3783 0.1869 +vn 0.8575 -0.3638 0.3638 +vn 0.7812 -0.5254 0.3371 +vn 0.9612 -0.1950 0.1950 +vn 0.9066 -0.1869 0.3783 +vn 0.8189 -0.1715 0.5477 +vn 0.7812 -0.3371 0.5254 +vn 0.7207 -0.4902 0.4902 +vn -0.4902 -0.4902 -0.7207 +vn -0.5254 -0.3371 -0.7812 +vn -0.3638 -0.3638 -0.8575 +vn -0.3371 -0.5254 -0.7812 +vn -0.5477 -0.1715 -0.8189 +vn -0.5539 -0.0000 -0.8326 +vn -0.3809 -0.0000 -0.9246 +vn -0.3783 -0.1869 -0.9066 +vn -0.1950 -0.1950 -0.9612 +vn -0.1869 -0.3783 -0.9066 +vn -0.1961 -0.0000 -0.9806 +vn -0.0000 -0.0000 -1.0000 +vn -0.0000 -0.1961 -0.9806 +vn -0.0000 -0.3809 -0.9246 +vn -0.1715 -0.5477 -0.8189 +vn -0.0000 -0.5539 -0.8326 +vn -0.5477 0.1715 -0.8189 +vn -0.5254 0.3371 -0.7812 +vn -0.3638 0.3638 -0.8575 +vn -0.3783 0.1869 -0.9066 +vn -0.4902 0.4902 -0.7207 +vn -0.3371 0.5254 -0.7812 +vn -0.1715 0.5477 -0.8189 +vn -0.1869 0.3783 -0.9066 +vn -0.0000 0.5539 -0.8326 +vn -0.0000 0.3809 -0.9246 +vn -0.1950 0.1950 -0.9612 +vn -0.0000 0.1961 -0.9806 +vn 0.1950 0.1950 -0.9612 +vn 0.1961 -0.0000 -0.9806 +vn 0.1869 0.3783 -0.9066 +vn 0.3638 0.3638 -0.8575 +vn 0.3783 0.1869 -0.9066 +vn 0.3809 -0.0000 -0.9246 +vn 0.1715 0.5477 -0.8189 +vn 0.3371 0.5254 -0.7812 +vn 0.4902 0.4902 -0.7207 +vn 0.5254 0.3371 -0.7812 +vn 0.5477 0.1715 -0.8189 +vn 0.5539 -0.0000 -0.8326 +vn 0.1715 -0.5477 -0.8189 +vn 0.1869 -0.3783 -0.9066 +vn 0.3638 -0.3638 -0.8575 +vn 0.3371 -0.5254 -0.7812 +vn 0.1950 -0.1950 -0.9612 +vn 0.3783 -0.1869 -0.9066 +vn 0.5477 -0.1715 -0.8189 +vn 0.5254 -0.3371 -0.7812 +vn 0.4902 -0.4902 -0.7207 +vt 0.500000 1.000000 +vt 1.000000 0.500000 +vt -0.000000 0.500000 +vt 0.500000 1.000000 +vt 1.000000 0.000000 +vt -0.000000 0.000000 +vt 0.500000 0.500000 +vt 0.500000 0.500000 +vt 0.500000 0.000000 +vt -0.000000 1.000000 +vt 0.500000 0.500000 +vt 1.000000 1.000000 +vt 0.500000 0.000000 +vt -0.000000 0.500000 +vt 1.000000 0.500000 +vt -0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.500000 +vt 0.750000 0.000000 +vt 1.000000 0.750000 +vt 0.750000 1.000000 +vt 0.250000 0.000000 +vt 1.000000 0.250000 +vt -0.000000 0.250000 +vt -0.000000 0.250000 +vt 1.000000 0.250000 +vt 0.500000 0.250000 +vt 0.500000 0.250000 +vt 0.250000 0.500000 +vt 0.500000 0.750000 +vt 0.750000 0.500000 +vt 0.250000 0.000000 +vt 0.750000 0.500000 +vt -0.000000 0.750000 +vt 0.750000 0.500000 +vt 0.250000 1.000000 +vt 0.250000 0.500000 +vt 0.500000 0.750000 +vt 0.750000 0.000000 +vt 0.250000 0.750001 +vt 0.250000 0.250000 +vt 0.750000 0.250000 +vt 0.750000 0.750000 +vt 0.750000 0.250000 +vt 0.250000 0.250000 +vt 0.625000 0.000000 +vt 1.000000 0.875000 +vt 0.875000 0.000000 +vt 1.000000 0.625000 +vt 0.625000 1.000000 +vt 0.125000 0.000000 +vt 0.875000 1.000000 +vt 0.375000 0.000000 +vt 1.000000 0.375000 +vt -0.000000 0.375000 +vt 1.000000 0.125000 +vt -0.000000 0.125000 +vt -0.000000 0.125000 +vt 1.000000 0.125000 +vt -0.000000 0.375000 +vt 1.000000 0.375000 +vt 0.500000 0.375000 +vt 0.500000 0.125000 +vt 0.500000 0.375000 +vt 0.500000 0.125000 +vt 0.375000 0.500000 +vt 0.125000 0.500000 +vt 0.500000 0.875000 +vt 0.875000 0.500000 +vt 0.500000 0.625000 +vt 0.625000 0.500000 +vt 0.125000 0.000000 +vt 0.875000 0.500000 +vt 0.375000 -0.000000 +vt 0.625000 0.500000 +vt -0.000000 0.625000 +vt 0.875000 0.500000 +vt -0.000000 0.875000 +vt 0.625000 0.500000 +vt 0.125000 1.000000 +vt 0.375000 0.500000 +vt 0.375000 1.000000 +vt 0.125000 0.500000 +vt 0.500000 0.625000 +vt 0.625000 0.000000 +vt 0.500000 0.875000 +vt 0.875000 0.000000 +vt 0.250000 0.875000 +vt 0.125000 0.750000 +vt 0.250000 0.625000 +vt 0.375000 0.750000 +vt 0.375000 0.250000 +vt 0.250000 0.375000 +vt 0.125000 0.250000 +vt 0.250000 0.125000 +vt 0.875000 0.250000 +vt 0.750000 0.375000 +vt 0.625000 0.250000 +vt 0.750000 0.125000 +vt 0.750000 0.875000 +vt 0.625000 0.750000 +vt 0.750000 0.625000 +vt 0.875000 0.750000 +vt 0.875000 0.250000 +vt 0.750000 0.375000 +vt 0.625000 0.250000 +vt 0.750000 0.125000 +vt 0.375000 0.250000 +vt 0.250000 0.375000 +vt 0.125000 0.250000 +vt 0.250000 0.125000 +vt 0.375000 0.875000 +vt 0.125000 0.875000 +vt 0.125000 0.625000 +vt 0.375000 0.625000 +vt 0.375000 0.125000 +vt 0.375000 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.125000 +vt 0.875000 0.125000 +vt 0.875000 0.375000 +vt 0.625000 0.375000 +vt 0.625000 0.125000 +vt 0.875000 0.875000 +vt 0.625000 0.875000 +vt 0.625000 0.625000 +vt 0.875000 0.625000 +vt 0.875000 0.125000 +vt 0.875000 0.375000 +vt 0.625000 0.375000 +vt 0.625000 0.125000 +vt 0.375000 0.125000 +vt 0.375000 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.125000 +vt 0.562500 0.000000 +vt 1.000000 0.937500 +vt 0.687500 0.000000 +vt 1.000000 0.812500 +vt 0.812500 0.000000 +vt 1.000000 0.687500 +vt 0.937500 0.000000 +vt 1.000000 0.562500 +vt 0.562500 1.000000 +vt 0.062500 0.000000 +vt 0.687500 1.000000 +vt 0.187500 0.000000 +vt 0.812500 1.000000 +vt 0.312500 0.000000 +vt 0.937500 1.000000 +vt 0.437500 0.000000 +vt 1.000000 0.437500 +vt -0.000000 0.437500 +vt 1.000000 0.312500 +vt -0.000000 0.312500 +vt 1.000000 0.187500 +vt -0.000000 0.187500 +vt 1.000000 0.062500 +vt -0.000000 0.062500 +vt -0.000000 0.062500 +vt 1.000000 0.062500 +vt -0.000000 0.187500 +vt 1.000000 0.187500 +vt -0.000000 0.312500 +vt 1.000000 0.312500 +vt -0.000000 0.437500 +vt 1.000000 0.437500 +vt 0.500000 0.437500 +vt 0.500000 0.312500 +vt 0.500000 0.187500 +vt 0.500000 0.062500 +vt 0.500000 0.437500 +vt 0.500000 0.312500 +vt 0.500000 0.187500 +vt 0.500000 0.062500 +vt 0.437500 0.500000 +vt 0.312500 0.500000 +vt 0.187500 0.500000 +vt 0.062500 0.500000 +vt 0.500000 0.937500 +vt 0.937500 0.500000 +vt 0.500000 0.812500 +vt 0.812500 0.500000 +vt 0.500000 0.687500 +vt 0.687500 0.500000 +vt 0.500000 0.562500 +vt 0.562500 0.500000 +vt 0.062500 0.000000 +vt 0.937500 0.500000 +vt 0.187500 0.000000 +vt 0.812500 0.500000 +vt 0.312500 -0.000000 +vt 0.687500 0.500000 +vt 0.437500 0.000000 +vt 0.562500 0.500000 +vt -0.000000 0.562500 +vt 0.937500 0.500000 +vt -0.000000 0.687500 +vt 0.812500 0.500000 +vt -0.000000 0.812500 +vt 0.687500 0.500000 +vt -0.000000 0.937500 +vt 0.562500 0.500000 +vt 0.062500 1.000000 +vt 0.437500 0.500000 +vt 0.187500 1.000000 +vt 0.312500 0.500000 +vt 0.312500 1.000000 +vt 0.187500 0.500000 +vt 0.437500 1.000000 +vt 0.062500 0.500000 +vt 0.500000 0.562500 +vt 0.562500 0.000000 +vt 0.500000 0.687500 +vt 0.687500 0.000000 +vt 0.500000 0.812500 +vt 0.812500 0.000000 +vt 0.500000 0.937500 +vt 0.937500 0.000000 +vt 0.250000 0.937500 +vt 0.250000 0.812501 +vt 0.062500 0.750000 +vt 0.187500 0.750001 +vt 0.250000 0.562500 +vt 0.250000 0.687500 +vt 0.437500 0.750000 +vt 0.312500 0.750001 +vt 0.437500 0.250000 +vt 0.312500 0.250000 +vt 0.250000 0.437500 +vt 0.250000 0.312500 +vt 0.062500 0.250000 +vt 0.187500 0.250000 +vt 0.250000 0.062500 +vt 0.250000 0.187500 +vt 0.937500 0.250000 +vt 0.812500 0.250000 +vt 0.750000 0.437500 +vt 0.750000 0.312500 +vt 0.562500 0.250000 +vt 0.687500 0.250000 +vt 0.750000 0.062500 +vt 0.750000 0.187500 +vt 0.750000 0.937500 +vt 0.750000 0.812500 +vt 0.562500 0.750000 +vt 0.687500 0.750000 +vt 0.750000 0.562500 +vt 0.750000 0.687500 +vt 0.937500 0.750000 +vt 0.812500 0.750000 +vt 0.937500 0.250000 +vt 0.812500 0.250000 +vt 0.750000 0.437500 +vt 0.750000 0.312500 +vt 0.562500 0.250000 +vt 0.687500 0.250000 +vt 0.750000 0.062500 +vt 0.750000 0.187500 +vt 0.437500 0.250000 +vt 0.312500 0.250000 +vt 0.250000 0.437500 +vt 0.250000 0.312500 +vt 0.062500 0.250000 +vt 0.187500 0.250000 +vt 0.250000 0.062500 +vt 0.250000 0.187500 +vt 0.375000 0.937500 +vt 0.312500 0.875000 +vt 0.375000 0.812500 +vt 0.437500 0.875000 +vt 0.125000 0.937500 +vt 0.062500 0.875000 +vt 0.125000 0.812500 +vt 0.187500 0.875000 +vt 0.125000 0.687500 +vt 0.062500 0.625000 +vt 0.125000 0.562500 +vt 0.187500 0.625000 +vt 0.375000 0.687500 +vt 0.312500 0.625000 +vt 0.375000 0.562500 +vt 0.437500 0.625000 +vt 0.437500 0.125000 +vt 0.375000 0.187500 +vt 0.312500 0.125000 +vt 0.375000 0.062500 +vt 0.437500 0.375000 +vt 0.375000 0.437500 +vt 0.312500 0.375000 +vt 0.375000 0.312500 +vt 0.187500 0.375000 +vt 0.125000 0.437500 +vt 0.062500 0.375000 +vt 0.125000 0.312500 +vt 0.187500 0.125000 +vt 0.125000 0.187500 +vt 0.062500 0.125000 +vt 0.125000 0.062500 +vt 0.937500 0.125000 +vt 0.875000 0.187500 +vt 0.812500 0.125000 +vt 0.875000 0.062500 +vt 0.937500 0.375000 +vt 0.875000 0.437500 +vt 0.812500 0.375000 +vt 0.875000 0.312500 +vt 0.687500 0.375000 +vt 0.625000 0.437500 +vt 0.562500 0.375000 +vt 0.625000 0.312500 +vt 0.687500 0.125000 +vt 0.625000 0.187500 +vt 0.562500 0.125000 +vt 0.625000 0.062500 +vt 0.875000 0.937500 +vt 0.812500 0.875000 +vt 0.875000 0.812500 +vt 0.937500 0.875000 +vt 0.625000 0.937500 +vt 0.562500 0.875000 +vt 0.625000 0.812500 +vt 0.687500 0.875000 +vt 0.625000 0.687500 +vt 0.562500 0.625000 +vt 0.625000 0.562500 +vt 0.687500 0.625000 +vt 0.875000 0.687500 +vt 0.812500 0.625000 +vt 0.875000 0.562500 +vt 0.937500 0.625000 +vt 0.937500 0.125000 +vt 0.875000 0.187500 +vt 0.812500 0.125000 +vt 0.875000 0.062500 +vt 0.937500 0.375000 +vt 0.875000 0.437500 +vt 0.812500 0.375000 +vt 0.875000 0.312500 +vt 0.687500 0.375000 +vt 0.625000 0.437500 +vt 0.562500 0.375000 +vt 0.625000 0.312500 +vt 0.687500 0.125000 +vt 0.625000 0.187500 +vt 0.562500 0.125000 +vt 0.625000 0.062500 +vt 0.437500 0.125000 +vt 0.375000 0.187500 +vt 0.312500 0.125000 +vt 0.375000 0.062500 +vt 0.437500 0.375000 +vt 0.375000 0.437500 +vt 0.312500 0.375000 +vt 0.375000 0.312500 +vt 0.187500 0.375000 +vt 0.125000 0.437500 +vt 0.062500 0.375000 +vt 0.125000 0.312500 +vt 0.187500 0.125000 +vt 0.125000 0.187500 +vt 0.062500 0.125000 +vt 0.125000 0.062500 +vt 0.437500 0.937500 +vt 0.312500 0.937500 +vt 0.312500 0.812500 +vt 0.437500 0.812500 +vt 0.187500 0.937500 +vt 0.062500 0.937500 +vt 0.062500 0.812500 +vt 0.187500 0.812501 +vt 0.187500 0.687500 +vt 0.062500 0.687500 +vt 0.062500 0.562500 +vt 0.187500 0.562500 +vt 0.437500 0.687500 +vt 0.312500 0.687500 +vt 0.312500 0.562500 +vt 0.437500 0.562500 +vt 0.437500 0.062500 +vt 0.437500 0.187500 +vt 0.312500 0.187500 +vt 0.312500 0.062500 +vt 0.437500 0.312500 +vt 0.437500 0.437500 +vt 0.312500 0.437500 +vt 0.312500 0.312500 +vt 0.187500 0.312500 +vt 0.187500 0.437500 +vt 0.062500 0.437500 +vt 0.062500 0.312500 +vt 0.187500 0.062500 +vt 0.187500 0.187500 +vt 0.062500 0.187500 +vt 0.062500 0.062500 +vt 0.937500 0.062500 +vt 0.937500 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.062500 +vt 0.937500 0.312500 +vt 0.937500 0.437500 +vt 0.812500 0.437500 +vt 0.812500 0.312500 +vt 0.687500 0.312500 +vt 0.687500 0.437500 +vt 0.562500 0.437500 +vt 0.562500 0.312500 +vt 0.687500 0.062500 +vt 0.687500 0.187500 +vt 0.562500 0.187500 +vt 0.562500 0.062500 +vt 0.937500 0.937500 +vt 0.812500 0.937500 +vt 0.812500 0.812500 +vt 0.937500 0.812500 +vt 0.687500 0.937500 +vt 0.562500 0.937500 +vt 0.562500 0.812500 +vt 0.687500 0.812500 +vt 0.687500 0.687500 +vt 0.562500 0.687500 +vt 0.562500 0.562500 +vt 0.687500 0.562500 +vt 0.937500 0.687500 +vt 0.812500 0.687500 +vt 0.812500 0.562500 +vt 0.937500 0.562500 +vt 0.937500 0.062500 +vt 0.937500 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.062500 +vt 0.937500 0.312500 +vt 0.937500 0.437500 +vt 0.812500 0.437500 +vt 0.812500 0.312500 +vt 0.687500 0.312500 +vt 0.687500 0.437500 +vt 0.562500 0.437500 +vt 0.562500 0.312500 +vt 0.687500 0.062500 +vt 0.687500 0.187500 +vt 0.562500 0.187500 +vt 0.562500 0.062500 +vt 0.437500 0.062500 +vt 0.437500 0.187500 +vt 0.312500 0.187500 +vt 0.312500 0.062500 +vt 0.437500 0.312500 +vt 0.437500 0.437500 +vt 0.312500 0.437500 +vt 0.312500 0.312500 +vt 0.187500 0.312500 +vt 0.187500 0.437500 +vt 0.062500 0.437500 +vt 0.062500 0.312500 +vt 0.187500 0.062500 +vt 0.187500 0.187500 +vt 0.062500 0.187500 +vt 0.062500 0.062500 +s 1 +f 1/1/1 142/210/2 291/364/3 127/180/4 +f 142/210/2 48/82/5 195/268/6 291/364/3 +f 291/364/3 195/268/6 75/112/7 198/271/8 +f 127/180/4 291/364/3 198/271/8 41/68/9 +f 48/82/5 141/208/10 292/365/11 195/268/6 +f 141/208/10 19/36/12 147/220/13 292/365/11 +f 292/365/11 147/220/13 51/88/14 196/269/15 +f 195/268/6 292/365/11 196/269/15 75/112/7 +f 75/112/7 196/269/15 293/366/16 197/270/17 +f 196/269/15 51/88/14 148/221/18 293/366/16 +f 293/366/16 148/221/18 21/40/19 154/227/20 +f 197/270/17 293/366/16 154/227/20 54/91/21 +f 41/68/9 198/271/8 294/367/22 128/182/23 +f 198/271/8 75/112/7 197/270/17 294/367/22 +f 294/367/22 197/270/17 54/91/21 153/226/24 +f 128/182/23 294/367/22 153/226/24 16/30/25 +f 19/36/12 140/206/26 295/368/27 147/220/13 +f 140/206/26 47/80/28 199/272/29 295/368/27 +f 295/368/27 199/272/29 76/113/30 202/275/31 +f 147/220/13 295/368/27 202/275/31 51/88/14 +f 47/80/28 139/204/32 296/369/33 199/272/29 +f 139/204/32 5/10/34 138/202/35 296/369/33 +f 296/369/33 138/202/35 46/78/36 200/273/37 +f 199/272/29 296/369/33 200/273/37 76/113/30 +f 76/113/30 200/273/37 297/370/38 201/274/39 +f 200/273/37 46/78/36 137/200/40 297/370/38 +f 297/370/38 137/200/40 18/34/41 149/222/42 +f 201/274/39 297/370/38 149/222/42 52/89/43 +f 51/88/14 202/275/31 298/371/44 148/221/18 +f 202/275/31 76/113/30 201/274/39 298/371/44 +f 298/371/44 201/274/39 52/89/43 150/223/45 +f 148/221/18 298/371/44 150/223/45 21/40/19 +f 21/40/19 150/223/45 299/372/46 152/225/47 +f 150/223/45 52/89/43 203/276/48 299/372/46 +f 299/372/46 203/276/48 77/114/49 206/279/50 +f 152/225/47 299/372/46 206/279/50 53/90/51 +f 52/89/43 149/222/42 300/373/52 203/276/48 +f 149/222/42 18/34/41 136/198/53 300/373/52 +f 300/373/52 136/198/53 45/76/54 204/277/55 +f 203/276/48 300/373/52 204/277/55 77/114/49 +f 77/114/49 204/277/55 301/374/56 205/278/57 +f 204/277/55 45/76/54 135/196/58 301/374/56 +f 301/374/56 135/196/58 7/14/59 126/179/60 +f 205/278/57 301/374/56 126/179/60 40/67/61 +f 53/90/51 206/279/50 302/375/62 151/224/63 +f 206/279/50 77/114/49 205/278/57 302/375/62 +f 302/375/62 205/278/57 40/67/61 125/178/64 +f 151/224/63 302/375/62 125/178/64 15/29/65 +f 16/30/25 153/226/24 303/376/66 129/184/67 +f 153/226/24 54/91/21 207/280/68 303/376/66 +f 303/376/66 207/280/68 78/115/69 210/283/70 +f 129/184/67 303/376/66 210/283/70 42/70/71 +f 54/91/21 154/227/20 304/377/72 207/280/68 +f 154/227/20 21/40/19 152/225/47 304/377/72 +f 304/377/72 152/225/47 53/90/51 208/281/73 +f 207/280/68 304/377/72 208/281/73 78/115/69 +f 78/115/69 208/281/73 305/378/74 209/282/75 +f 208/281/73 53/90/51 151/224/63 305/378/74 +f 305/378/74 151/224/63 15/29/65 124/177/76 +f 209/282/75 305/378/74 124/177/76 39/66/77 +f 42/70/71 210/283/70 306/379/78 130/186/79 +f 210/283/70 78/115/69 209/282/75 306/379/78 +f 306/379/78 209/282/75 39/66/77 123/176/80 +f 130/186/79 306/379/78 123/176/80 3/7/81 +f 4/9/82 118/171/83 307/380/84 134/194/85 +f 118/171/83 36/63/86 211/284/87 307/380/84 +f 307/380/84 211/284/87 79/116/88 214/287/89 +f 134/194/85 307/380/84 214/287/89 44/74/90 +f 36/63/86 117/170/91 308/381/92 211/284/87 +f 117/170/91 13/27/93 155/228/94 308/381/92 +f 308/381/92 155/228/94 55/92/95 212/285/96 +f 211/284/87 308/381/92 212/285/96 79/116/88 +f 79/116/88 212/285/96 309/382/97 213/286/98 +f 212/285/96 55/92/95 156/229/99 309/382/97 +f 309/382/97 156/229/99 22/41/100 162/235/101 +f 213/286/98 309/382/97 162/235/101 58/95/102 +f 44/74/90 214/287/89 310/383/103 133/192/104 +f 214/287/89 79/116/88 213/286/98 310/383/103 +f 310/383/103 213/286/98 58/95/102 161/234/105 +f 133/192/104 310/383/103 161/234/105 17/32/106 +f 13/27/93 116/169/107 311/384/108 155/228/94 +f 116/169/107 35/62/109 215/288/110 311/384/108 +f 311/384/108 215/288/110 80/117/111 218/291/112 +f 155/228/94 311/384/108 218/291/112 55/92/95 +f 35/62/109 115/168/113 312/385/114 215/288/110 +f 115/168/113 3/7/81 123/176/80 312/385/114 +f 312/385/114 123/176/80 39/66/77 216/289/115 +f 215/288/110 312/385/114 216/289/115 80/117/111 +f 80/117/111 216/289/115 313/386/116 217/290/117 +f 216/289/115 39/66/77 124/177/76 313/386/116 +f 313/386/116 124/177/76 15/29/65 157/230/118 +f 217/290/117 313/386/116 157/230/118 56/93/119 +f 55/92/95 218/291/112 314/387/120 156/229/99 +f 218/291/112 80/117/111 217/290/117 314/387/120 +f 314/387/120 217/290/117 56/93/119 158/231/121 +f 156/229/99 314/387/120 158/231/121 22/41/100 +f 22/41/100 158/231/121 315/388/122 160/233/123 +f 158/231/121 56/93/119 219/292/124 315/388/122 +f 315/388/122 219/292/124 81/118/125 222/295/126 +f 160/233/123 315/388/122 222/295/126 57/94/127 +f 56/93/119 157/230/118 316/389/128 219/292/124 +f 157/230/118 15/29/65 125/178/64 316/389/128 +f 316/389/128 125/178/64 40/67/61 220/293/129 +f 219/292/124 316/389/128 220/293/129 81/118/125 +f 81/118/125 220/293/129 317/390/130 221/294/131 +f 220/293/129 40/67/61 126/179/60 317/390/130 +f 317/390/130 126/179/60 7/14/59 114/166/132 +f 221/294/131 317/390/130 114/166/132 34/60/133 +f 57/94/127 222/295/126 318/391/134 159/232/135 +f 222/295/126 81/118/125 221/294/131 318/391/134 +f 318/391/134 221/294/131 34/60/133 113/164/136 +f 159/232/135 318/391/134 113/164/136 12/25/137 +f 17/32/106 161/234/105 319/392/138 132/190/139 +f 161/234/105 58/95/102 223/296/140 319/392/138 +f 319/392/138 223/296/140 82/119/141 226/299/142 +f 132/190/139 319/392/138 226/299/142 43/72/143 +f 58/95/102 162/235/101 320/393/144 223/296/140 +f 162/235/101 22/41/100 160/233/123 320/393/144 +f 320/393/144 160/233/123 57/94/127 224/297/145 +f 223/296/140 320/393/144 224/297/145 82/119/141 +f 82/119/141 224/297/145 321/394/146 225/298/147 +f 224/297/145 57/94/127 159/232/135 321/394/146 +f 321/394/146 159/232/135 12/25/137 112/162/148 +f 225/298/147 321/394/146 112/162/148 33/58/149 +f 43/72/143 226/299/142 322/395/150 131/188/151 +f 226/299/142 82/119/141 225/298/147 322/395/150 +f 322/395/150 225/298/147 33/58/149 111/160/152 +f 131/188/151 322/395/150 111/160/152 8/16/153 +f 8/17/153 111/161/152 323/396/154 102/142/155 +f 111/161/152 33/59/149 227/300/156 323/396/154 +f 323/396/154 227/300/156 83/120/157 230/303/158 +f 102/142/155 323/396/154 230/303/158 28/48/159 +f 33/59/149 112/163/148 324/397/160 227/300/156 +f 112/163/148 12/26/137 163/236/161 324/397/160 +f 324/397/160 163/236/161 59/96/162 228/301/163 +f 227/300/156 324/397/160 228/301/163 83/120/157 +f 83/120/157 228/301/163 325/398/164 229/302/165 +f 228/301/163 59/96/162 164/237/166 325/398/164 +f 325/398/164 164/237/166 23/42/167 170/243/168 +f 229/302/165 325/398/164 170/243/168 62/99/169 +f 28/48/159 230/303/158 326/399/170 101/140/171 +f 230/303/158 83/120/157 229/302/165 326/399/170 +f 326/399/170 229/302/165 62/99/169 169/242/172 +f 101/140/171 326/399/170 169/242/172 9/19/173 +f 12/26/137 113/165/136 327/400/174 163/236/161 +f 113/165/136 34/61/133 231/304/175 327/400/174 +f 327/400/174 231/304/175 84/121/176 234/307/177 +f 163/236/161 327/400/174 234/307/177 59/96/162 +f 34/61/133 114/167/132 328/401/178 231/304/175 +f 114/167/132 7/15/59 135/197/58 328/401/178 +f 328/401/178 135/197/58 45/77/54 232/305/179 +f 231/304/175 328/401/178 232/305/179 84/121/176 +f 84/121/176 232/305/179 329/402/180 233/306/181 +f 232/305/179 45/77/54 136/199/53 329/402/180 +f 329/402/180 136/199/53 18/35/41 165/238/182 +f 233/306/181 329/402/180 165/238/182 60/97/183 +f 59/96/162 234/307/177 330/403/184 164/237/166 +f 234/307/177 84/121/176 233/306/181 330/403/184 +f 330/403/184 233/306/181 60/97/183 166/239/185 +f 164/237/166 330/403/184 166/239/185 23/42/167 +f 23/42/167 166/239/185 331/404/186 168/241/187 +f 166/239/185 60/97/183 235/308/188 331/404/186 +f 331/404/186 235/308/188 85/122/189 238/311/190 +f 168/241/187 331/404/186 238/311/190 61/98/191 +f 60/97/183 165/238/182 332/405/192 235/308/188 +f 165/238/182 18/35/41 137/201/40 332/405/192 +f 332/405/192 137/201/40 46/79/36 236/309/193 +f 235/308/188 332/405/192 236/309/193 85/122/189 +f 85/122/189 236/309/193 333/406/194 237/310/195 +f 236/309/193 46/79/36 138/203/35 333/406/194 +f 333/406/194 138/203/35 5/11/34 119/172/196 +f 237/310/195 333/406/194 119/172/196 37/64/197 +f 61/98/191 238/311/190 334/407/198 167/240/199 +f 238/311/190 85/122/189 237/310/195 334/407/198 +f 334/407/198 237/310/195 37/64/197 120/173/200 +f 167/240/199 334/407/198 120/173/200 14/28/201 +f 9/19/173 169/242/172 335/408/202 100/138/203 +f 169/242/172 62/99/169 239/312/204 335/408/202 +f 335/408/202 239/312/204 86/123/205 242/315/206 +f 100/138/203 335/408/202 242/315/206 27/46/207 +f 62/99/169 170/243/168 336/409/208 239/312/204 +f 170/243/168 23/42/167 168/241/187 336/409/208 +f 336/409/208 168/241/187 61/98/191 240/313/209 +f 239/312/204 336/409/208 240/313/209 86/123/205 +f 86/123/205 240/313/209 337/410/210 241/314/211 +f 240/313/209 61/98/191 167/240/199 337/410/210 +f 337/410/210 167/240/199 14/28/201 121/174/212 +f 241/314/211 337/410/210 121/174/212 38/65/213 +f 27/46/207 242/315/206 338/411/214 99/136/215 +f 242/315/206 86/123/205 241/314/211 338/411/214 +f 338/411/214 241/314/211 38/65/213 122/175/216 +f 99/136/215 338/411/214 122/175/216 6/13/217 +f 6/12/217 106/150/218 339/412/219 99/137/215 +f 106/150/218 30/52/220 243/316/221 339/412/219 +f 339/412/219 243/316/221 87/124/222 246/319/223 +f 99/137/215 339/412/219 246/319/223 27/47/207 +f 30/52/220 105/148/224 340/413/225 243/316/221 +f 105/148/224 10/21/226 171/244/227 340/413/225 +f 340/413/225 171/244/227 63/100/228 244/317/229 +f 243/316/221 340/413/225 244/317/229 87/124/222 +f 87/124/222 244/317/229 341/414/230 245/318/231 +f 244/317/229 63/100/228 172/245/232 341/414/230 +f 341/414/230 172/245/232 24/43/233 178/251/234 +f 245/318/231 341/414/230 178/251/234 66/103/235 +f 27/47/207 246/319/223 342/415/236 100/139/203 +f 246/319/223 87/124/222 245/318/231 342/415/236 +f 342/415/236 245/318/231 66/103/235 177/250/237 +f 100/139/203 342/415/236 177/250/237 9/20/173 +f 10/21/226 104/146/238 343/416/239 171/244/227 +f 104/146/238 29/50/240 247/320/241 343/416/239 +f 343/416/239 247/320/241 88/125/242 250/323/243 +f 171/244/227 343/416/239 250/323/243 63/100/228 +f 29/50/240 103/144/244 344/417/245 247/320/241 +f 103/144/244 2/4/246 146/218/247 344/417/245 +f 344/417/245 146/218/247 50/86/248 248/321/249 +f 247/320/241 344/417/245 248/321/249 88/125/242 +f 88/125/242 248/321/249 345/418/250 249/322/251 +f 248/321/249 50/86/248 145/216/252 345/418/250 +f 345/418/250 145/216/252 20/38/253 173/246/254 +f 249/322/251 345/418/250 173/246/254 64/101/255 +f 63/100/228 250/323/243 346/419/256 172/245/232 +f 250/323/243 88/125/242 249/322/251 346/419/256 +f 346/419/256 249/322/251 64/101/255 174/247/257 +f 172/245/232 346/419/256 174/247/257 24/43/233 +f 24/43/233 174/247/257 347/420/258 176/249/259 +f 174/247/257 64/101/255 251/324/260 347/420/258 +f 347/420/258 251/324/260 89/126/261 254/327/262 +f 176/249/259 347/420/258 254/327/262 65/102/263 +f 64/101/255 173/246/254 348/421/264 251/324/260 +f 173/246/254 20/38/253 144/214/265 348/421/264 +f 348/421/264 144/214/265 49/84/266 252/325/267 +f 251/324/260 348/421/264 252/325/267 89/126/261 +f 89/126/261 252/325/267 349/422/268 253/326/269 +f 252/325/267 49/84/266 143/212/270 349/422/268 +f 349/422/268 143/212/270 4/8/82 134/195/85 +f 253/326/269 349/422/268 134/195/85 44/75/90 +f 65/102/263 254/327/262 350/423/271 175/248/272 +f 254/327/262 89/126/261 253/326/269 350/423/271 +f 350/423/271 253/326/269 44/75/90 133/193/104 +f 175/248/272 350/423/271 133/193/104 17/33/106 +f 9/20/173 177/250/237 351/424/273 101/141/171 +f 177/250/237 66/103/235 255/328/274 351/424/273 +f 351/424/273 255/328/274 90/127/275 258/331/276 +f 101/141/171 351/424/273 258/331/276 28/49/159 +f 66/103/235 178/251/234 352/425/277 255/328/274 +f 178/251/234 24/43/233 176/249/259 352/425/277 +f 352/425/277 176/249/259 65/102/263 256/329/278 +f 255/328/274 352/425/277 256/329/278 90/127/275 +f 90/127/275 256/329/278 353/426/279 257/330/280 +f 256/329/278 65/102/263 175/248/272 353/426/279 +f 353/426/279 175/248/272 17/33/106 132/191/139 +f 257/330/280 353/426/279 132/191/139 43/73/143 +f 28/49/159 258/331/276 354/427/281 102/143/155 +f 258/331/276 90/127/275 257/330/280 354/427/281 +f 354/427/281 257/330/280 43/73/143 131/189/151 +f 102/143/155 354/427/281 131/189/151 8/18/153 +f 2/5/246 110/158/282 355/428/283 146/219/247 +f 110/158/282 32/56/284 259/332/285 355/428/283 +f 355/428/283 259/332/285 91/128/286 262/335/287 +f 146/219/247 355/428/283 262/335/287 50/87/248 +f 32/56/284 109/156/288 356/429/289 259/332/285 +f 109/156/288 11/23/290 179/252/291 356/429/289 +f 356/429/289 179/252/291 67/104/292 260/333/293 +f 259/332/285 356/429/289 260/333/293 91/128/286 +f 91/128/286 260/333/293 357/430/294 261/334/295 +f 260/333/293 67/104/292 180/253/296 357/430/294 +f 357/430/294 180/253/296 25/44/297 186/259/298 +f 261/334/295 357/430/294 186/259/298 70/107/299 +f 50/87/248 262/335/287 358/431/300 145/217/252 +f 262/335/287 91/128/286 261/334/295 358/431/300 +f 358/431/300 261/334/295 70/107/299 185/258/301 +f 145/217/252 358/431/300 185/258/301 20/39/253 +f 11/23/290 108/154/302 359/432/303 179/252/291 +f 108/154/302 31/54/304 263/336/305 359/432/303 +f 359/432/303 263/336/305 92/129/306 266/339/307 +f 179/252/291 359/432/303 266/339/307 67/104/292 +f 31/54/304 107/152/308 360/433/309 263/336/305 +f 107/152/308 1/2/1 127/181/4 360/433/309 +f 360/433/309 127/181/4 41/69/9 264/337/310 +f 263/336/305 360/433/309 264/337/310 92/129/306 +f 92/129/306 264/337/310 361/434/311 265/338/312 +f 264/337/310 41/69/9 128/183/23 361/434/311 +f 361/434/311 128/183/23 16/31/25 181/254/313 +f 265/338/312 361/434/311 181/254/313 68/105/314 +f 67/104/292 266/339/307 362/435/315 180/253/296 +f 266/339/307 92/129/306 265/338/312 362/435/315 +f 362/435/315 265/338/312 68/105/314 182/255/316 +f 180/253/296 362/435/315 182/255/316 25/44/297 +f 25/44/297 182/255/316 363/436/317 184/257/318 +f 182/255/316 68/105/314 267/340/319 363/436/317 +f 363/436/317 267/340/319 93/130/320 270/343/321 +f 184/257/318 363/436/317 270/343/321 69/106/322 +f 68/105/314 181/254/313 364/437/323 267/340/319 +f 181/254/313 16/31/25 129/185/67 364/437/323 +f 364/437/323 129/185/67 42/71/71 268/341/324 +f 267/340/319 364/437/323 268/341/324 93/130/320 +f 93/130/320 268/341/324 365/438/325 269/342/326 +f 268/341/324 42/71/71 130/187/79 365/438/325 +f 365/438/325 130/187/79 3/7/81 115/168/113 +f 269/342/326 365/438/325 115/168/113 35/62/109 +f 69/106/322 270/343/321 366/439/327 183/256/328 +f 270/343/321 93/130/320 269/342/326 366/439/327 +f 366/439/327 269/342/326 35/62/109 116/169/107 +f 183/256/328 366/439/327 116/169/107 13/27/93 +f 20/39/253 185/258/301 367/440/329 144/215/265 +f 185/258/301 70/107/299 271/344/330 367/440/329 +f 367/440/329 271/344/330 94/131/331 274/347/332 +f 144/215/265 367/440/329 274/347/332 49/85/266 +f 70/107/299 186/259/298 368/441/333 271/344/330 +f 186/259/298 25/44/297 184/257/318 368/441/333 +f 368/441/333 184/257/318 69/106/322 272/345/334 +f 271/344/330 368/441/333 272/345/334 94/131/331 +f 94/131/331 272/345/334 369/442/335 273/346/336 +f 272/345/334 69/106/322 183/256/328 369/442/335 +f 369/442/335 183/256/328 13/27/93 117/170/91 +f 273/346/336 369/442/335 117/170/91 36/63/86 +f 49/85/266 274/347/332 370/443/337 143/213/270 +f 274/347/332 94/131/331 273/346/336 370/443/337 +f 370/443/337 273/346/336 36/63/86 118/171/83 +f 143/213/270 370/443/337 118/171/83 4/9/82 +f 6/13/217 122/175/216 371/444/338 106/151/218 +f 122/175/216 38/65/213 275/348/339 371/444/338 +f 371/444/338 275/348/339 95/132/340 278/351/341 +f 106/151/218 371/444/338 278/351/341 30/53/220 +f 38/65/213 121/174/212 372/445/342 275/348/339 +f 121/174/212 14/28/201 187/260/343 372/445/342 +f 372/445/342 187/260/343 71/108/344 276/349/345 +f 275/348/339 372/445/342 276/349/345 95/132/340 +f 95/132/340 276/349/345 373/446/346 277/350/347 +f 276/349/345 71/108/344 188/261/348 373/446/346 +f 373/446/346 188/261/348 26/45/349 194/267/350 +f 277/350/347 373/446/346 194/267/350 74/111/351 +f 30/53/220 278/351/341 374/447/352 105/149/224 +f 278/351/341 95/132/340 277/350/347 374/447/352 +f 374/447/352 277/350/347 74/111/351 193/266/353 +f 105/149/224 374/447/352 193/266/353 10/22/226 +f 14/28/201 120/173/200 375/448/354 187/260/343 +f 120/173/200 37/64/197 279/352/355 375/448/354 +f 375/448/354 279/352/355 96/133/356 282/355/357 +f 187/260/343 375/448/354 282/355/357 71/108/344 +f 37/64/197 119/172/196 376/449/358 279/352/355 +f 119/172/196 5/11/34 139/205/32 376/449/358 +f 376/449/358 139/205/32 47/81/28 280/353/359 +f 279/352/355 376/449/358 280/353/359 96/133/356 +f 96/133/356 280/353/359 377/450/360 281/354/361 +f 280/353/359 47/81/28 140/207/26 377/450/360 +f 377/450/360 140/207/26 19/37/12 189/262/362 +f 281/354/361 377/450/360 189/262/362 72/109/363 +f 71/108/344 282/355/357 378/451/364 188/261/348 +f 282/355/357 96/133/356 281/354/361 378/451/364 +f 378/451/364 281/354/361 72/109/363 190/263/365 +f 188/261/348 378/451/364 190/263/365 26/45/349 +f 26/45/349 190/263/365 379/452/366 192/265/367 +f 190/263/365 72/109/363 283/356/368 379/452/366 +f 379/452/366 283/356/368 97/134/369 286/359/370 +f 192/265/367 379/452/366 286/359/370 73/110/371 +f 72/109/363 189/262/362 380/453/372 283/356/368 +f 189/262/362 19/37/12 141/209/10 380/453/372 +f 380/453/372 141/209/10 48/83/5 284/357/373 +f 283/356/368 380/453/372 284/357/373 97/134/369 +f 97/134/369 284/357/373 381/454/374 285/358/375 +f 284/357/373 48/83/5 142/211/2 381/454/374 +f 381/454/374 142/211/2 1/3/1 107/153/308 +f 285/358/375 381/454/374 107/153/308 31/55/304 +f 73/110/371 286/359/370 382/455/376 191/264/377 +f 286/359/370 97/134/369 285/358/375 382/455/376 +f 382/455/376 285/358/375 31/55/304 108/155/302 +f 191/264/377 382/455/376 108/155/302 11/24/290 +f 10/22/226 193/266/353 383/456/378 104/147/238 +f 193/266/353 74/111/351 287/360/379 383/456/378 +f 383/456/378 287/360/379 98/135/380 290/363/381 +f 104/147/238 383/456/378 290/363/381 29/51/240 +f 74/111/351 194/267/350 384/457/382 287/360/379 +f 194/267/350 26/45/349 192/265/367 384/457/382 +f 384/457/382 192/265/367 73/110/371 288/361/383 +f 287/360/379 384/457/382 288/361/383 98/135/380 +f 98/135/380 288/361/383 385/458/384 289/362/385 +f 288/361/383 73/110/371 191/264/377 385/458/384 +f 385/458/384 191/264/377 11/24/290 109/157/288 +f 289/362/385 385/458/384 109/157/288 32/57/284 +f 29/51/240 290/363/381 386/459/386 103/145/244 +f 290/363/381 98/135/380 289/362/385 386/459/386 +f 386/459/386 289/362/385 32/57/284 110/159/282 +f 103/145/244 386/459/386 110/159/282 2/6/246 diff --git a/data/games/garage/mods/testnodes/models/testnodes_marble_metal.obj b/data/games/garage/mods/testnodes/models/testnodes_marble_metal.obj new file mode 100644 index 0000000..c3bc70c --- /dev/null +++ b/data/games/garage/mods/testnodes/models/testnodes_marble_metal.obj @@ -0,0 +1,2470 @@ +# Blender 3.3.1 +# www.blender.org +o Sphere +v 0.000000 0.465623 -0.311119 +v 0.000000 0.395980 -0.395980 +v 0.000000 0.214303 -0.517373 +v 0.000000 0.109251 -0.549240 +v 0.000000 0.000000 -0.560000 +v 0.000000 -0.109251 -0.549240 +v 0.000000 -0.214303 -0.517373 +v 0.000000 -0.311119 -0.465623 +v 0.000000 -0.465623 -0.311119 +v 0.021314 0.549240 -0.107151 +v 0.041808 0.517373 -0.210185 +v 0.060696 0.465623 -0.305141 +v 0.077252 0.395980 -0.388371 +v 0.090839 0.311119 -0.456676 +v 0.100934 0.214303 -0.507431 +v 0.107151 0.109251 -0.538686 +v 0.109251 0.000000 -0.549240 +v 0.107151 -0.109251 -0.538686 +v 0.100934 -0.214303 -0.507431 +v 0.090839 -0.311119 -0.456676 +v 0.077252 -0.395980 -0.388371 +v 0.060696 -0.465623 -0.305141 +v 0.041808 -0.517373 -0.210185 +v 0.021314 -0.549240 -0.107151 +v 0.041808 0.549240 -0.100934 +v 0.082010 0.517373 -0.197990 +v 0.119060 0.465623 -0.287437 +v 0.151535 0.395980 -0.365838 +v 0.178186 0.311119 -0.430180 +v 0.197990 0.214303 -0.477990 +v 0.210185 0.109251 -0.507431 +v 0.214303 0.000000 -0.517373 +v 0.210185 -0.109251 -0.507431 +v 0.197990 -0.214303 -0.477990 +v 0.178186 -0.311119 -0.430180 +v 0.151535 -0.395980 -0.365838 +v 0.119060 -0.465623 -0.287437 +v 0.082010 -0.517373 -0.197990 +v 0.041808 -0.549240 -0.100934 +v 0.060696 0.549240 -0.090839 +v 0.119060 0.517373 -0.178186 +v 0.172849 0.465623 -0.258686 +v 0.219995 0.395980 -0.329245 +v 0.258686 0.311119 -0.387151 +v 0.287437 0.214303 -0.430180 +v 0.305141 0.109251 -0.456676 +v 0.311119 0.000000 -0.465623 +v 0.305141 -0.109251 -0.456676 +v 0.287437 -0.214303 -0.430180 +v 0.258686 -0.311119 -0.387151 +v 0.219995 -0.395980 -0.329245 +v 0.172849 -0.465623 -0.258686 +v 0.119060 -0.517373 -0.178186 +v 0.060696 -0.549240 -0.090839 +v 0.000000 -0.560000 0.000000 +v 0.077252 0.549240 -0.077252 +v 0.151535 0.517373 -0.151535 +v 0.219995 0.465623 -0.219995 +v 0.280000 0.395980 -0.280000 +v 0.329245 0.311119 -0.329245 +v 0.365838 0.214303 -0.365838 +v 0.388371 0.109251 -0.388371 +v 0.395980 0.000000 -0.395980 +v 0.388371 -0.109251 -0.388371 +v 0.365838 -0.214303 -0.365838 +v 0.329245 -0.311119 -0.329245 +v 0.280000 -0.395980 -0.280000 +v 0.219995 -0.465623 -0.219995 +v 0.151535 -0.517373 -0.151535 +v 0.077252 -0.549240 -0.077252 +v 0.090839 0.549240 -0.060696 +v 0.178186 0.517373 -0.119060 +v 0.258686 0.465623 -0.172849 +v 0.329245 0.395980 -0.219995 +v 0.387151 0.311119 -0.258686 +v 0.430180 0.214303 -0.287437 +v 0.456676 0.109251 -0.305141 +v 0.465623 0.000000 -0.311119 +v 0.456676 -0.109251 -0.305141 +v 0.430180 -0.214303 -0.287437 +v 0.387151 -0.311119 -0.258686 +v 0.329245 -0.395980 -0.219995 +v 0.258686 -0.465623 -0.172849 +v 0.178186 -0.517373 -0.119060 +v 0.090839 -0.549240 -0.060696 +v 0.100934 0.549240 -0.041808 +v 0.197990 0.517373 -0.082010 +v 0.287437 0.465623 -0.119060 +v 0.365838 0.395980 -0.151535 +v 0.430179 0.311119 -0.178186 +v 0.477990 0.214303 -0.197990 +v 0.507431 0.109251 -0.210185 +v 0.517372 0.000000 -0.214303 +v 0.507431 -0.109251 -0.210185 +v 0.477990 -0.214303 -0.197990 +v 0.430179 -0.311119 -0.178186 +v 0.365838 -0.395980 -0.151535 +v 0.287437 -0.465623 -0.119060 +v 0.197990 -0.517373 -0.082010 +v 0.100934 -0.549240 -0.041808 +v 0.107151 0.549240 -0.021314 +v 0.210185 0.517373 -0.041808 +v 0.305141 0.465623 -0.060696 +v 0.388371 0.395980 -0.077252 +v 0.456676 0.311119 -0.090838 +v 0.507431 0.214303 -0.100934 +v 0.538686 0.109251 -0.107151 +v 0.549240 0.000000 -0.109251 +v 0.538686 -0.109251 -0.107151 +v 0.507431 -0.214303 -0.100934 +v 0.456676 -0.311119 -0.090838 +v 0.388371 -0.395980 -0.077252 +v 0.305141 -0.465623 -0.060696 +v 0.210185 -0.517373 -0.041808 +v 0.107151 -0.549240 -0.021314 +v 0.109251 0.549240 0.000000 +v 0.214303 0.517373 0.000000 +v 0.311119 0.465623 0.000000 +v 0.395980 0.395980 0.000000 +v 0.465623 0.311119 0.000000 +v 0.517372 0.214303 0.000000 +v 0.549240 0.109251 0.000000 +v 0.560000 0.000000 -0.000000 +v 0.549240 -0.109251 0.000000 +v 0.517372 -0.214303 0.000000 +v 0.465623 -0.311119 0.000000 +v 0.395980 -0.395980 0.000000 +v 0.311119 -0.465623 0.000000 +v 0.214303 -0.517373 0.000000 +v 0.109251 -0.549240 0.000000 +v 0.107151 0.549240 0.021314 +v 0.210185 0.517373 0.041808 +v 0.305141 0.465623 0.060696 +v 0.388371 0.395980 0.077252 +v 0.456676 0.311119 0.090839 +v 0.507431 0.214303 0.100934 +v 0.538686 0.109251 0.107151 +v 0.549240 0.000000 0.109251 +v 0.538686 -0.109251 0.107151 +v 0.507431 -0.214303 0.100934 +v 0.456676 -0.311119 0.090839 +v 0.388371 -0.395980 0.077252 +v 0.305141 -0.465623 0.060696 +v 0.210185 -0.517373 0.041808 +v 0.107151 -0.549240 0.021314 +v 0.100934 0.549240 0.041808 +v 0.197990 0.517373 0.082010 +v 0.287437 0.465623 0.119060 +v 0.365838 0.395980 0.151535 +v 0.430179 0.311119 0.178186 +v 0.477990 0.214303 0.197990 +v 0.507431 0.109251 0.210185 +v 0.517372 0.000000 0.214303 +v 0.507431 -0.109251 0.210185 +v 0.477990 -0.214303 0.197990 +v 0.430179 -0.311119 0.178186 +v 0.365838 -0.395980 0.151535 +v 0.287437 -0.465623 0.119060 +v 0.197990 -0.517373 0.082010 +v 0.100934 -0.549240 0.041808 +v 0.090839 0.549240 0.060696 +v 0.178186 0.517373 0.119060 +v 0.258686 0.465623 0.172849 +v 0.329245 0.395980 0.219995 +v 0.387151 0.311119 0.258686 +v 0.430179 0.214303 0.287437 +v 0.456676 0.109251 0.305141 +v 0.465623 0.000000 0.311119 +v 0.456676 -0.109251 0.305141 +v 0.430179 -0.214303 0.287437 +v 0.387151 -0.311119 0.258686 +v 0.329245 -0.395980 0.219995 +v 0.258686 -0.465623 0.172849 +v 0.178186 -0.517373 0.119060 +v 0.090839 -0.549240 0.060696 +v 0.077252 0.549240 0.077252 +v 0.151535 0.517373 0.151535 +v 0.219995 0.465623 0.219995 +v 0.280000 0.395980 0.280000 +v 0.329245 0.311119 0.329245 +v 0.365838 0.214303 0.365838 +v 0.388371 0.109251 0.388371 +v 0.395980 0.000000 0.395980 +v 0.388371 -0.109251 0.388371 +v 0.365838 -0.214303 0.365838 +v 0.329245 -0.311119 0.329245 +v 0.280000 -0.395980 0.280000 +v 0.219995 -0.465623 0.219995 +v 0.151535 -0.517373 0.151535 +v 0.077252 -0.549240 0.077252 +v 0.060696 0.549240 0.090839 +v 0.119060 0.517373 0.178186 +v 0.172849 0.465623 0.258686 +v 0.219995 0.395980 0.329245 +v 0.258686 0.311119 0.387151 +v 0.287437 0.214303 0.430179 +v 0.305141 0.109251 0.456676 +v 0.311119 0.000000 0.465623 +v 0.305141 -0.109251 0.456676 +v 0.287437 -0.214303 0.430179 +v 0.258686 -0.311119 0.387151 +v 0.219995 -0.395980 0.329245 +v 0.172849 -0.465623 0.258686 +v 0.119060 -0.517373 0.178186 +v 0.060696 -0.549240 0.090839 +v 0.041808 0.549240 0.100934 +v 0.082010 0.517373 0.197990 +v 0.119060 0.465623 0.287437 +v 0.151535 0.395980 0.365838 +v 0.178186 0.311119 0.430179 +v 0.197990 0.214303 0.477990 +v 0.210185 0.109251 0.507431 +v 0.214303 0.000000 0.517372 +v 0.210185 -0.109251 0.507431 +v 0.197990 -0.214303 0.477990 +v 0.178186 -0.311119 0.430179 +v 0.151535 -0.395980 0.365838 +v 0.119060 -0.465623 0.287437 +v 0.082010 -0.517373 0.197990 +v 0.041808 -0.549240 0.100934 +v 0.021314 0.549240 0.107151 +v 0.041808 0.517373 0.210185 +v 0.060696 0.465623 0.305141 +v 0.077252 0.395980 0.388371 +v 0.090838 0.311119 0.456676 +v 0.100934 0.214303 0.507431 +v 0.107151 0.109251 0.538686 +v 0.109251 0.000000 0.549240 +v 0.107151 -0.109251 0.538686 +v 0.100934 -0.214303 0.507431 +v 0.090838 -0.311119 0.456676 +v 0.077252 -0.395980 0.388371 +v 0.060696 -0.465623 0.305141 +v 0.041808 -0.517373 0.210185 +v 0.021314 -0.549240 0.107151 +v -0.000000 0.549240 0.109251 +v -0.000000 0.517373 0.214303 +v -0.000000 0.465623 0.311119 +v 0.000000 0.395980 0.395980 +v -0.000000 0.311119 0.465623 +v -0.000000 0.214303 0.517372 +v -0.000000 0.109251 0.549240 +v -0.000000 0.000000 0.560000 +v -0.000000 -0.109251 0.549240 +v -0.000000 -0.214303 0.517372 +v -0.000000 -0.311119 0.465623 +v 0.000000 -0.395980 0.395980 +v -0.000000 -0.465623 0.311119 +v -0.000000 -0.517373 0.214303 +v -0.000000 -0.549240 0.109251 +v 0.000000 0.560000 0.000000 +v -0.021314 0.549240 0.107151 +v -0.041808 0.517373 0.210185 +v -0.060696 0.465623 0.305141 +v -0.077252 0.395980 0.388371 +v -0.090839 0.311119 0.456676 +v -0.100934 0.214303 0.507431 +v -0.107151 0.109251 0.538686 +v -0.109251 0.000000 0.549240 +v -0.107151 -0.109251 0.538686 +v -0.100934 -0.214303 0.507431 +v -0.090839 -0.311119 0.456676 +v -0.077252 -0.395980 0.388371 +v -0.060696 -0.465623 0.305141 +v -0.041808 -0.517373 0.210185 +v -0.021314 -0.549240 0.107151 +v -0.041808 0.549240 0.100934 +v -0.082010 0.517373 0.197990 +v -0.119060 0.465623 0.287437 +v -0.151535 0.395980 0.365838 +v -0.178186 0.311119 0.430179 +v -0.197990 0.214303 0.477990 +v -0.210185 0.109251 0.507431 +v -0.214303 0.000000 0.517372 +v -0.210185 -0.109251 0.507431 +v -0.197990 -0.214303 0.477990 +v -0.178186 -0.311119 0.430179 +v -0.151535 -0.395980 0.365838 +v -0.119060 -0.465623 0.287437 +v -0.082010 -0.517373 0.197990 +v -0.041808 -0.549240 0.100934 +v -0.060696 0.549240 0.090838 +v -0.119060 0.517373 0.178186 +v -0.172849 0.465623 0.258686 +v -0.219995 0.395980 0.329245 +v -0.258686 0.311119 0.387151 +v -0.287437 0.214303 0.430179 +v -0.305141 0.109251 0.456676 +v -0.311119 0.000000 0.465623 +v -0.305141 -0.109251 0.456676 +v -0.287437 -0.214303 0.430179 +v -0.258686 -0.311119 0.387151 +v -0.219995 -0.395980 0.329245 +v -0.172849 -0.465623 0.258686 +v -0.119060 -0.517373 0.178186 +v -0.060696 -0.549240 0.090838 +v -0.077252 0.549240 0.077252 +v -0.151535 0.517373 0.151535 +v -0.219995 0.465623 0.219994 +v -0.280000 0.395980 0.280000 +v -0.329245 0.311119 0.329245 +v -0.365838 0.214303 0.365837 +v -0.388371 0.109251 0.388371 +v -0.395980 0.000000 0.395980 +v -0.388371 -0.109251 0.388371 +v -0.365838 -0.214303 0.365837 +v -0.329245 -0.311119 0.329245 +v -0.280000 -0.395980 0.280000 +v -0.219995 -0.465623 0.219994 +v -0.151535 -0.517373 0.151535 +v -0.077252 -0.549240 0.077252 +v -0.090838 0.549240 0.060696 +v -0.178186 0.517373 0.119060 +v -0.258686 0.465623 0.172849 +v -0.329245 0.395980 0.219995 +v -0.387151 0.311119 0.258686 +v -0.430179 0.214303 0.287437 +v -0.456676 0.109251 0.305141 +v -0.465623 0.000000 0.311119 +v -0.456676 -0.109251 0.305141 +v -0.430179 -0.214303 0.287437 +v -0.387151 -0.311119 0.258686 +v -0.329245 -0.395980 0.219995 +v -0.258686 -0.465623 0.172849 +v -0.178186 -0.517373 0.119060 +v -0.090838 -0.549240 0.060696 +v -0.100934 0.549240 0.041808 +v -0.197990 0.517373 0.082010 +v -0.287437 0.465623 0.119060 +v -0.365838 0.395980 0.151535 +v -0.430179 0.311119 0.178186 +v -0.477990 0.214303 0.197990 +v -0.507431 0.109251 0.210185 +v -0.517372 0.000000 0.214303 +v -0.507431 -0.109251 0.210185 +v -0.477990 -0.214303 0.197990 +v -0.430179 -0.311119 0.178186 +v -0.365838 -0.395980 0.151535 +v -0.287437 -0.465623 0.119060 +v -0.197990 -0.517373 0.082010 +v -0.100934 -0.549240 0.041808 +v -0.107151 0.549240 0.021314 +v -0.210185 0.517373 0.041808 +v -0.305141 0.465623 0.060696 +v -0.388371 0.395980 0.077252 +v -0.456676 0.311119 0.090838 +v -0.507431 0.214303 0.100934 +v -0.538686 0.109251 0.107151 +v -0.549240 0.000000 0.109251 +v -0.538686 -0.109251 0.107151 +v -0.507431 -0.214303 0.100934 +v -0.456676 -0.311119 0.090838 +v -0.388371 -0.395980 0.077252 +v -0.305141 -0.465623 0.060696 +v -0.210185 -0.517373 0.041808 +v -0.107151 -0.549240 0.021314 +v -0.109251 0.549240 -0.000000 +v -0.214303 0.517373 -0.000000 +v -0.311119 0.465623 -0.000000 +v -0.395980 0.395980 -0.000000 +v -0.465623 0.311119 -0.000000 +v -0.517372 0.214303 -0.000000 +v -0.549240 0.109251 -0.000000 +v -0.560000 0.000000 -0.000000 +v -0.549240 -0.109251 -0.000000 +v -0.517372 -0.214303 -0.000000 +v -0.465623 -0.311119 -0.000000 +v -0.395980 -0.395980 -0.000000 +v -0.311119 -0.465623 -0.000000 +v -0.214303 -0.517373 -0.000000 +v -0.109251 -0.549240 -0.000000 +v -0.107151 0.549240 -0.021314 +v -0.210185 0.517373 -0.041808 +v -0.305141 0.465623 -0.060696 +v -0.388371 0.395980 -0.077252 +v -0.456676 0.311119 -0.090839 +v -0.507431 0.214303 -0.100934 +v -0.538686 0.109251 -0.107151 +v -0.549240 0.000000 -0.109251 +v -0.538686 -0.109251 -0.107151 +v -0.507431 -0.214303 -0.100934 +v -0.456676 -0.311119 -0.090839 +v -0.388371 -0.395980 -0.077252 +v -0.305141 -0.465623 -0.060696 +v -0.210185 -0.517373 -0.041808 +v -0.107151 -0.549240 -0.021314 +v -0.100934 0.549240 -0.041808 +v -0.197990 0.517373 -0.082010 +v -0.287437 0.465623 -0.119060 +v -0.365837 0.395980 -0.151535 +v -0.430179 0.311119 -0.178186 +v -0.477990 0.214303 -0.197990 +v -0.507431 0.109251 -0.210185 +v -0.517372 0.000000 -0.214303 +v -0.507431 -0.109251 -0.210185 +v -0.477990 -0.214303 -0.197990 +v -0.430179 -0.311119 -0.178186 +v -0.365837 -0.395980 -0.151535 +v -0.287437 -0.465623 -0.119060 +v -0.197990 -0.517373 -0.082010 +v -0.100934 -0.549240 -0.041808 +v -0.090838 0.549240 -0.060696 +v -0.178186 0.517373 -0.119060 +v -0.258686 0.465623 -0.172849 +v -0.329245 0.395980 -0.219995 +v -0.387151 0.311119 -0.258686 +v -0.430179 0.214303 -0.287437 +v -0.456676 0.109251 -0.305141 +v -0.465623 0.000000 -0.311119 +v -0.456676 -0.109251 -0.305141 +v -0.430179 -0.214303 -0.287437 +v -0.387151 -0.311119 -0.258686 +v -0.329245 -0.395980 -0.219995 +v -0.258686 -0.465623 -0.172849 +v -0.178186 -0.517373 -0.119060 +v -0.090838 -0.549240 -0.060696 +v -0.077252 0.549240 -0.077252 +v -0.151535 0.517373 -0.151535 +v -0.219994 0.465623 -0.219994 +v -0.280000 0.395980 -0.280000 +v -0.329245 0.311119 -0.329245 +v -0.365837 0.214303 -0.365838 +v -0.388371 0.109251 -0.388371 +v -0.395980 0.000000 -0.395980 +v -0.388371 -0.109251 -0.388371 +v -0.365837 -0.214303 -0.365838 +v -0.329245 -0.311119 -0.329245 +v -0.280000 -0.395980 -0.280000 +v -0.219994 -0.465623 -0.219994 +v -0.151535 -0.517373 -0.151535 +v -0.077252 -0.549240 -0.077252 +v -0.060696 0.549240 -0.090838 +v -0.119060 0.517373 -0.178186 +v -0.172848 0.465623 -0.258686 +v -0.219994 0.395980 -0.329245 +v -0.258686 0.311119 -0.387151 +v -0.287437 0.214303 -0.430179 +v -0.305141 0.109251 -0.456676 +v -0.311119 0.000000 -0.465623 +v -0.305141 -0.109251 -0.456676 +v -0.287437 -0.214303 -0.430179 +v -0.258686 -0.311119 -0.387151 +v -0.219994 -0.395980 -0.329245 +v -0.172848 -0.465623 -0.258686 +v -0.119060 -0.517373 -0.178186 +v -0.060696 -0.549240 -0.090838 +v -0.041808 0.549240 -0.100934 +v -0.082010 0.517373 -0.197990 +v -0.119060 0.465623 -0.287437 +v -0.151535 0.395980 -0.365837 +v -0.178186 0.311119 -0.430179 +v -0.197990 0.214303 -0.477990 +v -0.210185 0.109251 -0.507431 +v -0.214303 0.000000 -0.517372 +v -0.210185 -0.109251 -0.507431 +v -0.197990 -0.214303 -0.477990 +v -0.178186 -0.311119 -0.430179 +v -0.151535 -0.395980 -0.365837 +v -0.119060 -0.465623 -0.287437 +v -0.082010 -0.517373 -0.197990 +v -0.041808 -0.549240 -0.100934 +v -0.021314 0.549240 -0.107151 +v -0.041808 0.517373 -0.210185 +v -0.060696 0.465623 -0.305141 +v -0.077252 0.395980 -0.388371 +v -0.090838 0.311119 -0.456676 +v -0.100934 0.214303 -0.507431 +v -0.107151 0.109251 -0.538686 +v -0.109250 0.000000 -0.549240 +v -0.107151 -0.109251 -0.538686 +v -0.100934 -0.214303 -0.507431 +v -0.090838 -0.311119 -0.456676 +v -0.077252 -0.395980 -0.388371 +v -0.060696 -0.465623 -0.305141 +v -0.041808 -0.517373 -0.210185 +v -0.021314 -0.549240 -0.107151 +v 0.000000 0.549240 -0.109250 +v 0.000000 0.517373 -0.214303 +v 0.000000 0.311119 -0.465623 +v 0.000000 -0.395980 -0.395980 +v 0.000000 -0.517373 -0.214303 +v 0.000000 -0.549240 -0.109250 +vn -0.0000 -0.8286 -0.5598 +vn 0.0757 -0.9217 -0.3804 +vn -0.0000 -0.9217 -0.3879 +vn -0.0000 0.1939 -0.9810 +vn 0.1804 0.3805 -0.9070 +vn 0.1914 0.1939 -0.9622 +vn 0.0392 -0.9796 -0.1971 +vn -0.0000 -0.9796 -0.2010 +vn -0.0000 -0.0000 -1.0000 +vn 0.1951 -0.0000 -0.9808 +vn -0.0000 0.9796 -0.2010 +vn -0.0000 1.0000 -0.0000 +vn 0.0392 0.9796 -0.1971 +vn -0.0000 -1.0000 -0.0000 +vn 0.1914 -0.1939 -0.9622 +vn -0.0000 -0.1939 -0.9810 +vn -0.0000 0.9217 -0.3879 +vn 0.0757 0.9217 -0.3804 +vn 0.1804 -0.3805 -0.9070 +vn -0.0000 -0.3805 -0.9248 +vn -0.0000 0.8286 -0.5598 +vn 0.1092 0.8286 -0.5490 +vn 0.1626 -0.5528 -0.8173 +vn -0.0000 -0.5528 -0.8333 +vn -0.0000 0.7041 -0.7101 +vn 0.1385 0.7041 -0.6965 +vn 0.1385 -0.7041 -0.6965 +vn -0.0000 -0.7041 -0.7101 +vn -0.0000 0.5528 -0.8333 +vn 0.1626 0.5528 -0.8173 +vn 0.1092 -0.8286 -0.5490 +vn -0.0000 0.3805 -0.9248 +vn 0.2142 -0.8286 -0.5172 +vn 0.3189 0.5528 -0.7699 +vn 0.3539 0.3805 -0.8544 +vn 0.1484 -0.9217 -0.3584 +vn 0.3754 0.1939 -0.9063 +vn 0.0769 -0.9796 -0.1857 +vn 0.3827 -0.0000 -0.9239 +vn 0.0769 0.9796 -0.1857 +vn 0.3754 -0.1939 -0.9063 +vn 0.1484 0.9217 -0.3584 +vn 0.3539 -0.3805 -0.8544 +vn 0.2142 0.8286 -0.5172 +vn 0.3189 -0.5528 -0.7699 +vn 0.2718 0.7041 -0.6561 +vn 0.2718 -0.7041 -0.6561 +vn 0.1117 0.9796 -0.1671 +vn 0.2155 0.9217 -0.3225 +vn 0.5138 -0.3805 -0.7689 +vn 0.3110 0.8286 -0.4654 +vn 0.4630 -0.5528 -0.6929 +vn 0.3945 0.7041 -0.5905 +vn 0.3945 -0.7041 -0.5905 +vn 0.4630 0.5528 -0.6929 +vn 0.3110 -0.8286 -0.4654 +vn 0.5138 0.3805 -0.7689 +vn 0.2155 -0.9217 -0.3225 +vn 0.5450 0.1939 -0.8157 +vn 0.1117 -0.9796 -0.1671 +vn 0.5556 -0.0000 -0.8315 +vn 0.5450 -0.1939 -0.8157 +vn 0.5893 0.5528 -0.5893 +vn 0.6539 0.3805 -0.6539 +vn 0.2743 -0.9217 -0.2743 +vn 0.6937 0.1939 -0.6937 +vn 0.1421 -0.9796 -0.1421 +vn 0.7071 -0.0000 -0.7071 +vn 0.1421 0.9796 -0.1421 +vn 0.6937 -0.1939 -0.6937 +vn 0.2743 0.9217 -0.2743 +vn 0.6539 -0.3805 -0.6539 +vn 0.3958 0.8286 -0.3958 +vn 0.5893 -0.5528 -0.5893 +vn 0.5021 0.7041 -0.5021 +vn 0.5021 -0.7041 -0.5021 +vn 0.3958 -0.8286 -0.3958 +vn 0.7689 -0.3805 -0.5138 +vn 0.3225 0.9217 -0.2155 +vn 0.4654 0.8286 -0.3110 +vn 0.6929 -0.5528 -0.4630 +vn 0.5905 0.7041 -0.3945 +vn 0.5905 -0.7041 -0.3945 +vn 0.6929 0.5528 -0.4630 +vn 0.4654 -0.8286 -0.3110 +vn 0.7689 0.3805 -0.5138 +vn 0.3225 -0.9217 -0.2155 +vn 0.8157 0.1939 -0.5450 +vn 0.1671 -0.9796 -0.1117 +vn 0.8315 -0.0000 -0.5556 +vn 0.1671 0.9796 -0.1117 +vn 0.8157 -0.1939 -0.5450 +vn 0.3584 -0.9217 -0.1484 +vn 0.8544 0.3805 -0.3539 +vn 0.9063 0.1939 -0.3754 +vn 0.1857 -0.9796 -0.0769 +vn 0.9239 -0.0000 -0.3827 +vn 0.1857 0.9796 -0.0769 +vn 0.9063 -0.1939 -0.3754 +vn 0.3584 0.9217 -0.1484 +vn 0.8544 -0.3805 -0.3539 +vn 0.5172 0.8286 -0.2142 +vn 0.7699 -0.5528 -0.3189 +vn 0.6561 0.7041 -0.2718 +vn 0.6561 -0.7041 -0.2718 +vn 0.7699 0.5528 -0.3189 +vn 0.5172 -0.8286 -0.2142 +vn 0.8173 -0.5528 -0.1626 +vn 0.5490 0.8286 -0.1092 +vn 0.6965 0.7041 -0.1385 +vn 0.6965 -0.7041 -0.1385 +vn 0.8173 0.5528 -0.1626 +vn 0.5490 -0.8286 -0.1092 +vn 0.9070 0.3805 -0.1804 +vn 0.3804 -0.9217 -0.0757 +vn 0.9622 0.1939 -0.1914 +vn 0.1971 -0.9796 -0.0392 +vn 0.9808 -0.0000 -0.1951 +vn 0.1971 0.9796 -0.0392 +vn 0.9622 -0.1939 -0.1914 +vn 0.3804 0.9217 -0.0757 +vn 0.9070 -0.3805 -0.1804 +vn 0.2010 -0.9796 -0.0000 +vn 0.9810 0.1939 -0.0000 +vn 1.0000 -0.0000 -0.0000 +vn 0.2010 0.9796 -0.0000 +vn 0.9810 -0.1939 -0.0000 +vn 0.3879 0.9217 -0.0000 +vn 0.9248 -0.3805 -0.0000 +vn 0.5598 0.8286 -0.0000 +vn 0.8333 -0.5528 -0.0000 +vn 0.7101 0.7041 -0.0000 +vn 0.7101 -0.7041 -0.0000 +vn 0.8333 0.5528 -0.0000 +vn 0.5598 -0.8286 -0.0000 +vn 0.9248 0.3805 -0.0000 +vn 0.3879 -0.9217 -0.0000 +vn 0.6965 0.7041 0.1385 +vn 0.8173 -0.5528 0.1626 +vn 0.6965 -0.7041 0.1385 +vn 0.8173 0.5528 0.1626 +vn 0.5490 -0.8286 0.1092 +vn 0.9070 0.3805 0.1804 +vn 0.3804 -0.9217 0.0757 +vn 0.9622 0.1939 0.1914 +vn 0.1971 -0.9796 0.0392 +vn 0.9808 -0.0000 0.1951 +vn 0.1971 0.9796 0.0392 +vn 0.9622 -0.1939 0.1914 +vn 0.3804 0.9217 0.0757 +vn 0.9070 -0.3805 0.1804 +vn 0.5490 0.8286 0.1092 +vn 0.9239 -0.0000 0.3827 +vn 0.1857 0.9796 0.0769 +vn 0.1857 -0.9796 0.0769 +vn 0.9063 -0.1939 0.3754 +vn 0.3584 0.9217 0.1484 +vn 0.8544 -0.3805 0.3539 +vn 0.5172 0.8286 0.2142 +vn 0.7699 -0.5528 0.3189 +vn 0.6561 0.7041 0.2718 +vn 0.6561 -0.7041 0.2718 +vn 0.7699 0.5528 0.3189 +vn 0.5172 -0.8286 0.2142 +vn 0.8544 0.3805 0.3539 +vn 0.3584 -0.9217 0.1484 +vn 0.9063 0.1939 0.3754 +vn 0.6929 -0.5528 0.4630 +vn 0.5905 -0.7041 0.3945 +vn 0.6929 0.5528 0.4630 +vn 0.4654 -0.8286 0.3110 +vn 0.7689 0.3805 0.5138 +vn 0.3225 -0.9217 0.2155 +vn 0.8157 0.1939 0.5450 +vn 0.1671 -0.9796 0.1117 +vn 0.8315 -0.0000 0.5556 +vn 0.1671 0.9796 0.1117 +vn 0.8157 -0.1939 0.5450 +vn 0.3225 0.9217 0.2155 +vn 0.7689 -0.3805 0.5138 +vn 0.4654 0.8286 0.3110 +vn 0.5905 0.7041 0.3945 +vn 0.1421 0.9796 0.1421 +vn 0.1421 -0.9796 0.1421 +vn 0.7071 -0.0000 0.7071 +vn 0.6937 -0.1939 0.6937 +vn 0.2743 0.9217 0.2743 +vn 0.6539 -0.3805 0.6539 +vn 0.3958 0.8286 0.3958 +vn 0.5893 -0.5528 0.5893 +vn 0.5021 0.7041 0.5021 +vn 0.5021 -0.7041 0.5021 +vn 0.5893 0.5528 0.5893 +vn 0.3958 -0.8286 0.3958 +vn 0.6539 0.3805 0.6539 +vn 0.2743 -0.9217 0.2743 +vn 0.6937 0.1939 0.6937 +vn 0.4630 0.5528 0.6929 +vn 0.3945 -0.7041 0.5905 +vn 0.3110 -0.8286 0.4654 +vn 0.5138 0.3805 0.7689 +vn 0.2155 -0.9217 0.3225 +vn 0.5450 0.1939 0.8157 +vn 0.1117 -0.9796 0.1671 +vn 0.5556 -0.0000 0.8315 +vn 0.1117 0.9796 0.1671 +vn 0.5450 -0.1939 0.8157 +vn 0.2155 0.9217 0.3225 +vn 0.5138 -0.3805 0.7689 +vn 0.3110 0.8286 0.4654 +vn 0.4630 -0.5528 0.6929 +vn 0.3945 0.7041 0.5905 +vn 0.3827 -0.0000 0.9239 +vn 0.3754 -0.1939 0.9063 +vn 0.1484 0.9217 0.3584 +vn 0.3539 -0.3805 0.8544 +vn 0.2142 0.8286 0.5172 +vn 0.3189 -0.5528 0.7699 +vn 0.2718 0.7041 0.6561 +vn 0.2718 -0.7041 0.6561 +vn 0.3189 0.5528 0.7699 +vn 0.2142 -0.8286 0.5172 +vn 0.3539 0.3805 0.8544 +vn 0.1484 -0.9217 0.3584 +vn 0.3754 0.1939 0.9063 +vn 0.0769 -0.9796 0.1857 +vn 0.0769 0.9796 0.1857 +vn 0.1385 -0.7041 0.6965 +vn 0.1092 -0.8286 0.5490 +vn 0.1804 0.3805 0.9070 +vn 0.0757 -0.9217 0.3804 +vn 0.1914 0.1939 0.9622 +vn 0.0392 -0.9796 0.1971 +vn 0.1951 -0.0000 0.9808 +vn 0.0392 0.9796 0.1971 +vn 0.1914 -0.1939 0.9622 +vn 0.0757 0.9217 0.3804 +vn 0.1804 -0.3805 0.9070 +vn 0.1092 0.8286 0.5490 +vn 0.1626 -0.5528 0.8173 +vn 0.1385 0.7041 0.6965 +vn 0.1626 0.5528 0.8173 +vn -0.0000 -0.1939 0.9810 +vn -0.0000 -0.3805 0.9248 +vn -0.0000 0.8286 0.5598 +vn -0.0000 -0.5528 0.8333 +vn -0.0000 0.7041 0.7101 +vn -0.0000 -0.7041 0.7101 +vn -0.0000 0.5528 0.8333 +vn -0.0000 -0.8286 0.5598 +vn -0.0000 0.3805 0.9248 +vn -0.0000 -0.9217 0.3879 +vn -0.0000 0.1939 0.9810 +vn -0.0000 -0.9796 0.2010 +vn -0.0000 -0.0000 1.0000 +vn -0.0000 0.9796 0.2010 +vn -0.0000 0.9217 0.3879 +vn -0.0757 -0.9217 0.3804 +vn -0.1804 0.3805 0.9070 +vn -0.1914 0.1939 0.9622 +vn -0.0392 -0.9796 0.1971 +vn -0.1951 -0.0000 0.9808 +vn -0.0392 0.9796 0.1971 +vn -0.1914 -0.1939 0.9622 +vn -0.0757 0.9217 0.3804 +vn -0.1804 -0.3805 0.9070 +vn -0.1092 0.8286 0.5490 +vn -0.1626 -0.5528 0.8173 +vn -0.1385 0.7041 0.6965 +vn -0.1385 -0.7041 0.6965 +vn -0.1626 0.5528 0.8173 +vn -0.1092 -0.8286 0.5490 +vn -0.1484 0.9217 0.3584 +vn -0.2142 0.8286 0.5172 +vn -0.3189 -0.5528 0.7699 +vn -0.2718 0.7041 0.6561 +vn -0.2718 -0.7041 0.6561 +vn -0.3189 0.5528 0.7699 +vn -0.2142 -0.8286 0.5172 +vn -0.3539 0.3805 0.8544 +vn -0.1484 -0.9217 0.3584 +vn -0.3754 0.1939 0.9063 +vn -0.0769 -0.9796 0.1857 +vn -0.3827 -0.0000 0.9239 +vn -0.0769 0.9796 0.1857 +vn -0.3754 -0.1939 0.9063 +vn -0.3539 -0.3805 0.8544 +vn -0.5138 0.3805 0.7689 +vn -0.5450 0.1939 0.8157 +vn -0.1117 -0.9796 0.1671 +vn -0.5556 -0.0000 0.8315 +vn -0.1117 0.9796 0.1671 +vn -0.5450 -0.1939 0.8157 +vn -0.2155 0.9217 0.3225 +vn -0.5138 -0.3805 0.7689 +vn -0.3110 0.8286 0.4654 +vn -0.4630 -0.5528 0.6929 +vn -0.3945 0.7041 0.5905 +vn -0.3945 -0.7041 0.5905 +vn -0.4630 0.5528 0.6929 +vn -0.3110 -0.8286 0.4654 +vn -0.2155 -0.9217 0.3225 +vn -0.5893 -0.5528 0.5893 +vn -0.3958 0.8286 0.3958 +vn -0.5021 0.7041 0.5021 +vn -0.5021 -0.7041 0.5021 +vn -0.5893 0.5528 0.5893 +vn -0.3958 -0.8286 0.3958 +vn -0.6539 0.3805 0.6539 +vn -0.2743 -0.9217 0.2743 +vn -0.6937 0.1939 0.6937 +vn -0.1421 -0.9796 0.1421 +vn -0.7071 -0.0000 0.7071 +vn -0.1421 0.9796 0.1421 +vn -0.6937 -0.1939 0.6937 +vn -0.2743 0.9217 0.2743 +vn -0.6539 -0.3805 0.6539 +vn -0.1671 -0.9796 0.1117 +vn -0.8157 0.1939 0.5450 +vn -0.8315 -0.0000 0.5556 +vn -0.1671 0.9796 0.1117 +vn -0.8157 -0.1939 0.5450 +vn -0.3225 0.9217 0.2155 +vn -0.7689 -0.3805 0.5138 +vn -0.4654 0.8286 0.3110 +vn -0.6929 -0.5528 0.4630 +vn -0.5905 0.7041 0.3945 +vn -0.5905 -0.7041 0.3945 +vn -0.6929 0.5528 0.4630 +vn -0.4654 -0.8286 0.3110 +vn -0.7689 0.3805 0.5138 +vn -0.3225 -0.9217 0.2155 +vn -0.5172 0.8286 0.2142 +vn -0.6561 0.7041 0.2718 +vn -0.6561 -0.7041 0.2718 +vn -0.7699 0.5528 0.3189 +vn -0.5172 -0.8286 0.2142 +vn -0.8544 0.3805 0.3539 +vn -0.3584 -0.9217 0.1484 +vn -0.9063 0.1939 0.3754 +vn -0.1857 -0.9796 0.0769 +vn -0.9239 -0.0000 0.3827 +vn -0.1857 0.9796 0.0769 +vn -0.9063 -0.1939 0.3754 +vn -0.3584 0.9217 0.1484 +vn -0.8544 -0.3805 0.3539 +vn -0.7699 -0.5528 0.3189 +vn -0.9622 0.1939 0.1914 +vn -0.9808 -0.0000 0.1951 +vn -0.1971 0.9796 0.0392 +vn -0.1971 -0.9796 0.0392 +vn -0.9622 -0.1939 0.1914 +vn -0.3804 0.9217 0.0757 +vn -0.9070 -0.3805 0.1804 +vn -0.5490 0.8286 0.1092 +vn -0.8173 -0.5528 0.1626 +vn -0.6965 0.7041 0.1385 +vn -0.6965 -0.7041 0.1385 +vn -0.8173 0.5528 0.1626 +vn -0.5490 -0.8286 0.1092 +vn -0.9070 0.3805 0.1804 +vn -0.3804 -0.9217 0.0757 +vn -0.7101 -0.7041 -0.0000 +vn -0.7101 0.7041 -0.0000 +vn -0.8333 0.5528 -0.0000 +vn -0.5598 -0.8286 -0.0000 +vn -0.9248 0.3805 -0.0000 +vn -0.3879 -0.9217 -0.0000 +vn -0.9810 0.1939 -0.0000 +vn -0.2010 -0.9796 -0.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.2010 0.9796 -0.0000 +vn -0.9810 -0.1939 -0.0000 +vn -0.3879 0.9217 -0.0000 +vn -0.9248 -0.3805 -0.0000 +vn -0.5598 0.8286 -0.0000 +vn -0.8333 -0.5528 -0.0000 +vn -0.1971 -0.9796 -0.0392 +vn -0.9808 -0.0000 -0.1951 +vn -0.9622 -0.1939 -0.1914 +vn -0.3804 0.9217 -0.0757 +vn -0.9070 -0.3805 -0.1804 +vn -0.5490 0.8286 -0.1092 +vn -0.8173 -0.5528 -0.1626 +vn -0.6965 0.7041 -0.1385 +vn -0.6965 -0.7041 -0.1385 +vn -0.8173 0.5528 -0.1626 +vn -0.5490 -0.8286 -0.1092 +vn -0.9070 0.3805 -0.1804 +vn -0.3804 -0.9217 -0.0757 +vn -0.9622 0.1939 -0.1914 +vn -0.1971 0.9796 -0.0392 +vn -0.6561 -0.7041 -0.2718 +vn -0.5172 -0.8286 -0.2142 +vn -0.8544 0.3805 -0.3539 +vn -0.3584 -0.9217 -0.1484 +vn -0.9063 0.1939 -0.3754 +vn -0.1857 -0.9796 -0.0769 +vn -0.9239 -0.0000 -0.3827 +vn -0.1857 0.9796 -0.0769 +vn -0.9063 -0.1939 -0.3754 +vn -0.3584 0.9217 -0.1484 +vn -0.8544 -0.3805 -0.3539 +vn -0.5172 0.8286 -0.2142 +vn -0.7699 -0.5528 -0.3189 +vn -0.6561 0.7041 -0.2718 +vn -0.7699 0.5528 -0.3189 +vn -0.3225 0.9217 -0.2155 +vn -0.8157 -0.1939 -0.5450 +vn -0.7689 -0.3805 -0.5138 +vn -0.4654 0.8286 -0.3110 +vn -0.6929 -0.5528 -0.4630 +vn -0.5905 0.7041 -0.3945 +vn -0.5905 -0.7041 -0.3945 +vn -0.6929 0.5528 -0.4630 +vn -0.4654 -0.8286 -0.3110 +vn -0.7689 0.3805 -0.5138 +vn -0.3225 -0.9217 -0.2155 +vn -0.8157 0.1939 -0.5450 +vn -0.1671 -0.9796 -0.1117 +vn -0.8315 -0.0000 -0.5556 +vn -0.1671 0.9796 -0.1117 +vn -0.6539 0.3805 -0.6539 +vn -0.3958 -0.8286 -0.3958 +vn -0.2743 -0.9217 -0.2743 +vn -0.6937 0.1939 -0.6937 +vn -0.1421 -0.9796 -0.1421 +vn -0.7071 -0.0000 -0.7071 +vn -0.1421 0.9796 -0.1421 +vn -0.6937 -0.1939 -0.6937 +vn -0.2743 0.9217 -0.2743 +vn -0.6539 -0.3805 -0.6539 +vn -0.3958 0.8286 -0.3958 +vn -0.5893 -0.5528 -0.5893 +vn -0.5021 0.7041 -0.5021 +vn -0.5021 -0.7041 -0.5021 +vn -0.5893 0.5528 -0.5893 +vn -0.5450 -0.1939 -0.8157 +vn -0.5138 -0.3805 -0.7689 +vn -0.3110 0.8286 -0.4654 +vn -0.4630 -0.5528 -0.6929 +vn -0.3945 0.7041 -0.5905 +vn -0.3945 -0.7041 -0.5905 +vn -0.4630 0.5528 -0.6929 +vn -0.3110 -0.8286 -0.4654 +vn -0.5138 0.3805 -0.7689 +vn -0.2155 -0.9217 -0.3225 +vn -0.5450 0.1939 -0.8157 +vn -0.1117 -0.9796 -0.1671 +vn -0.5556 -0.0000 -0.8315 +vn -0.1117 0.9796 -0.1671 +vn -0.2155 0.9217 -0.3225 +vn -0.2142 -0.8286 -0.5172 +vn -0.1484 -0.9217 -0.3584 +vn -0.3754 0.1939 -0.9063 +vn -0.0769 -0.9796 -0.1857 +vn -0.3827 -0.0000 -0.9239 +vn -0.0769 0.9796 -0.1857 +vn -0.3754 -0.1939 -0.9063 +vn -0.1484 0.9217 -0.3584 +vn -0.3539 -0.3805 -0.8544 +vn -0.2142 0.8286 -0.5172 +vn -0.3189 -0.5528 -0.7699 +vn -0.2718 0.7041 -0.6561 +vn -0.2718 -0.7041 -0.6561 +vn -0.3189 0.5528 -0.7699 +vn -0.3539 0.3805 -0.8544 +vn -0.1092 0.8286 -0.5490 +vn -0.1804 -0.3805 -0.9070 +vn -0.1626 -0.5528 -0.8173 +vn -0.1385 0.7041 -0.6965 +vn -0.1385 -0.7041 -0.6965 +vn -0.1626 0.5528 -0.8173 +vn -0.1092 -0.8286 -0.5490 +vn -0.1804 0.3805 -0.9070 +vn -0.0757 -0.9217 -0.3804 +vn -0.1914 0.1939 -0.9622 +vn -0.0392 -0.9796 -0.1971 +vn -0.1951 -0.0000 -0.9808 +vn -0.0392 0.9796 -0.1971 +vn -0.1914 -0.1939 -0.9622 +vn -0.0757 0.9217 -0.3804 +vt 0.500000 0.812500 +vt 0.500000 0.750000 +vt 0.500000 0.625000 +vt 0.500000 0.562500 +vt 0.500000 0.500000 +vt 0.500000 0.437500 +vt 0.500000 0.375000 +vt 0.500000 0.312500 +vt 0.500000 0.187500 +vt 0.437500 0.937500 +vt 0.437500 0.875000 +vt 0.437500 0.812500 +vt 0.437500 0.750000 +vt 0.437500 0.687500 +vt 0.437500 0.625000 +vt 0.437500 0.562500 +vt 0.437500 0.500000 +vt 0.437500 0.437500 +vt 0.437500 0.375000 +vt 0.437500 0.312500 +vt 0.437500 0.250000 +vt 0.437500 0.187500 +vt 0.437500 0.125000 +vt 0.437500 0.062500 +vt 0.375000 0.937500 +vt 0.375000 0.875000 +vt 0.375000 0.812500 +vt 0.375000 0.750000 +vt 0.375000 0.687500 +vt 0.375000 0.625000 +vt 0.375000 0.562500 +vt 0.375000 0.500000 +vt 0.375000 0.437500 +vt 0.375000 0.375000 +vt 0.375000 0.312500 +vt 0.375000 0.250000 +vt 0.375000 0.187500 +vt 0.375000 0.125000 +vt 0.375000 0.062500 +vt 0.312500 0.937500 +vt 0.312500 0.875000 +vt 0.312500 0.812500 +vt 0.312500 0.750000 +vt 0.312500 0.687500 +vt 0.312500 0.625000 +vt 0.312500 0.562500 +vt 0.312500 0.500000 +vt 0.312500 0.437500 +vt 0.312500 0.375000 +vt 0.312500 0.312500 +vt 0.312500 0.250000 +vt 0.312500 0.187500 +vt 0.312500 0.125000 +vt 0.312500 0.062500 +vt 0.468750 0.000000 +vt 0.406250 0.000000 +vt 0.343750 0.000000 +vt 0.281250 0.000000 +vt 0.218750 0.000000 +vt 0.156250 0.000000 +vt 0.093750 0.000000 +vt 0.031250 0.000000 +vt 0.968750 0.000000 +vt 0.906250 0.000000 +vt 0.843750 0.000000 +vt 0.781250 0.000000 +vt 0.718750 0.000000 +vt 0.656250 0.000000 +vt 0.593750 0.000000 +vt 0.531250 0.000000 +vt 0.250000 0.937500 +vt 0.250000 0.875000 +vt 0.250000 0.812500 +vt 0.250000 0.750000 +vt 0.250000 0.687500 +vt 0.250000 0.625000 +vt 0.250000 0.562500 +vt 0.250000 0.500000 +vt 0.250000 0.437500 +vt 0.250000 0.375000 +vt 0.250000 0.312500 +vt 0.250000 0.250000 +vt 0.250000 0.187500 +vt 0.250000 0.125000 +vt 0.250000 0.062500 +vt 0.187500 0.937500 +vt 0.187500 0.875000 +vt 0.187500 0.812500 +vt 0.187500 0.750000 +vt 0.187500 0.687500 +vt 0.187500 0.625000 +vt 0.187500 0.562500 +vt 0.187500 0.500000 +vt 0.187500 0.437500 +vt 0.187500 0.375000 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.187500 0.187500 +vt 0.187500 0.125000 +vt 0.187500 0.062500 +vt 0.125000 0.937500 +vt 0.125000 0.875000 +vt 0.125000 0.812500 +vt 0.125000 0.750000 +vt 0.125000 0.687500 +vt 0.125000 0.625000 +vt 0.125000 0.562500 +vt 0.125000 0.500000 +vt 0.125000 0.437500 +vt 0.125000 0.375000 +vt 0.125000 0.312500 +vt 0.125000 0.250000 +vt 0.125000 0.187500 +vt 0.125000 0.125000 +vt 0.125000 0.062500 +vt 0.062500 0.937500 +vt 0.062500 0.875000 +vt 0.062500 0.812500 +vt 0.062500 0.750000 +vt 0.062500 0.687500 +vt 0.062500 0.625000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.062500 0.437500 +vt 0.062500 0.375000 +vt 0.062500 0.312500 +vt 0.062500 0.250000 +vt 0.062500 0.187500 +vt 0.062500 0.125000 +vt 0.062500 0.062500 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt -0.000000 0.875000 +vt 1.000000 0.875000 +vt 0.000000 0.812500 +vt 1.000000 0.812500 +vt 0.000000 0.750000 +vt 1.000000 0.750000 +vt 0.000000 0.687500 +vt 1.000000 0.687500 +vt 0.000000 0.625000 +vt 1.000000 0.625000 +vt 0.000000 0.562500 +vt 1.000000 0.562500 +vt 1.000000 0.500000 +vt 0.000000 0.500000 +vt 1.000000 0.437500 +vt 0.000000 0.437500 +vt 1.000000 0.375000 +vt 0.000000 0.375000 +vt 1.000000 0.312500 +vt 0.000000 0.312500 +vt 1.000000 0.250000 +vt 0.000000 0.250000 +vt 1.000000 0.187500 +vt 0.000000 0.187500 +vt 1.000000 0.125000 +vt -0.000000 0.125000 +vt 1.000000 0.062500 +vt 0.000000 0.062500 +vt 0.937500 0.937500 +vt 0.937500 0.875000 +vt 0.937500 0.812500 +vt 0.937500 0.750000 +vt 0.937500 0.687500 +vt 0.937500 0.625000 +vt 0.937500 0.562500 +vt 0.937500 0.500000 +vt 0.937500 0.437500 +vt 0.937500 0.375000 +vt 0.937500 0.312500 +vt 0.937500 0.250000 +vt 0.937500 0.187500 +vt 0.937500 0.125000 +vt 0.937500 0.062500 +vt 0.875000 0.937500 +vt 0.875000 0.875000 +vt 0.875000 0.812500 +vt 0.875000 0.750000 +vt 0.875000 0.687500 +vt 0.875000 0.625000 +vt 0.875000 0.562500 +vt 0.875000 0.500000 +vt 0.875000 0.437500 +vt 0.875000 0.375000 +vt 0.875000 0.312500 +vt 0.875000 0.250000 +vt 0.875000 0.187500 +vt 0.875000 0.125000 +vt 0.875000 0.062500 +vt 0.812500 0.937500 +vt 0.812500 0.875000 +vt 0.812500 0.812500 +vt 0.812500 0.750000 +vt 0.812500 0.687500 +vt 0.812500 0.625000 +vt 0.812500 0.562500 +vt 0.812500 0.500000 +vt 0.812500 0.437500 +vt 0.812500 0.375000 +vt 0.812500 0.312500 +vt 0.812500 0.250000 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.812500 0.062500 +vt 0.750000 0.937500 +vt 0.750000 0.875000 +vt 0.750000 0.812500 +vt 0.750000 0.750000 +vt 0.750000 0.687500 +vt 0.750000 0.625000 +vt 0.750000 0.562500 +vt 0.750000 0.500000 +vt 0.750000 0.437500 +vt 0.750000 0.375000 +vt 0.750000 0.312500 +vt 0.750000 0.250000 +vt 0.750000 0.187500 +vt 0.750000 0.125000 +vt 0.750000 0.062500 +vt 0.687500 0.937500 +vt 0.687500 0.875000 +vt 0.687500 0.812500 +vt 0.687500 0.750000 +vt 0.687500 0.687500 +vt 0.687500 0.625000 +vt 0.687500 0.562500 +vt 0.687500 0.500000 +vt 0.687500 0.437500 +vt 0.687500 0.375000 +vt 0.687500 0.312500 +vt 0.687500 0.250000 +vt 0.687500 0.187500 +vt 0.687500 0.125000 +vt 0.687500 0.062500 +vt 0.625000 0.937500 +vt 0.625000 0.875000 +vt 0.625000 0.812500 +vt 0.625000 0.750000 +vt 0.625000 0.687500 +vt 0.625000 0.625000 +vt 0.625000 0.562500 +vt 0.625000 0.500000 +vt 0.625000 0.437500 +vt 0.625000 0.375000 +vt 0.625000 0.312500 +vt 0.625000 0.250000 +vt 0.625000 0.187500 +vt 0.625000 0.125000 +vt 0.625000 0.062500 +vt 0.562500 0.937500 +vt 0.562500 0.875000 +vt 0.562500 0.812500 +vt 0.562500 0.750000 +vt 0.562500 0.687500 +vt 0.562500 0.625000 +vt 0.562500 0.562500 +vt 0.562500 0.500000 +vt 0.562500 0.437500 +vt 0.562500 0.375000 +vt 0.562500 0.312500 +vt 0.562500 0.250000 +vt 0.562500 0.187500 +vt 0.562500 0.125000 +vt 0.562500 0.062500 +vt 0.500000 0.937500 +vt 0.500000 0.875000 +vt 0.500000 0.812500 +vt 0.500000 0.750000 +vt 0.500000 0.687500 +vt 0.500000 0.625000 +vt 0.500000 0.562500 +vt 0.500000 0.500000 +vt 0.500000 0.437500 +vt 0.500000 0.375000 +vt 0.500000 0.312500 +vt 0.500000 0.250000 +vt 0.500000 0.187500 +vt 0.500000 0.125000 +vt 0.500000 0.062500 +vt 0.468750 1.000000 +vt 0.406250 1.000000 +vt 0.343750 1.000000 +vt 0.281250 1.000000 +vt 0.218750 1.000000 +vt 0.156250 1.000000 +vt 0.093750 1.000000 +vt 0.031250 1.000000 +vt 0.968750 1.000000 +vt 0.906250 1.000000 +vt 0.843750 1.000000 +vt 0.781250 1.000000 +vt 0.718750 1.000000 +vt 0.656250 1.000000 +vt 0.593750 1.000000 +vt 0.531250 1.000000 +vt 0.437500 0.937500 +vt 0.437500 0.875000 +vt 0.437500 0.812500 +vt 0.437500 0.750000 +vt 0.437500 0.687500 +vt 0.437500 0.625000 +vt 0.437500 0.562500 +vt 0.437500 0.500000 +vt 0.437500 0.437500 +vt 0.437500 0.375000 +vt 0.437500 0.312500 +vt 0.437500 0.250000 +vt 0.437500 0.187500 +vt 0.437500 0.125000 +vt 0.437500 0.062500 +vt 0.375000 0.937500 +vt 0.375000 0.875000 +vt 0.375000 0.812500 +vt 0.375000 0.750000 +vt 0.375000 0.687500 +vt 0.375000 0.625000 +vt 0.375000 0.562500 +vt 0.375000 0.500000 +vt 0.375000 0.437500 +vt 0.375000 0.375000 +vt 0.375000 0.312500 +vt 0.375000 0.250000 +vt 0.375000 0.187500 +vt 0.375000 0.125000 +vt 0.375000 0.062500 +vt 0.312500 0.937500 +vt 0.312500 0.875000 +vt 0.312500 0.812500 +vt 0.312500 0.750000 +vt 0.312500 0.687500 +vt 0.312500 0.625000 +vt 0.312500 0.562500 +vt 0.312500 0.500000 +vt 0.312500 0.437500 +vt 0.312500 0.375000 +vt 0.312500 0.312500 +vt 0.312500 0.250000 +vt 0.312500 0.187500 +vt 0.312500 0.125000 +vt 0.312500 0.062500 +vt 0.250000 0.937500 +vt 0.250000 0.875000 +vt 0.250000 0.812500 +vt 0.250000 0.750000 +vt 0.250000 0.687500 +vt 0.250000 0.625000 +vt 0.250000 0.562500 +vt 0.250000 0.500000 +vt 0.250000 0.437500 +vt 0.250000 0.375000 +vt 0.250000 0.312500 +vt 0.250000 0.250000 +vt 0.250000 0.187500 +vt 0.250000 0.125000 +vt 0.250000 0.062500 +vt 0.187500 0.937500 +vt 0.187500 0.875000 +vt 0.187500 0.812500 +vt 0.187500 0.750000 +vt 0.187500 0.687500 +vt 0.187500 0.625000 +vt 0.187500 0.562500 +vt 0.187500 0.500000 +vt 0.187500 0.437500 +vt 0.187500 0.375000 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.187500 0.187500 +vt 0.187500 0.125000 +vt 0.187500 0.062500 +vt 0.125000 0.937500 +vt 0.125000 0.875000 +vt 0.125000 0.812500 +vt 0.125000 0.750000 +vt 0.125000 0.687500 +vt 0.125000 0.625000 +vt 0.125000 0.562500 +vt 0.125000 0.500000 +vt 0.125000 0.437500 +vt 0.125000 0.375000 +vt 0.125000 0.312500 +vt 0.125000 0.250000 +vt 0.125000 0.187500 +vt 0.125000 0.125000 +vt 0.125000 0.062500 +vt 0.062500 0.937500 +vt 0.062500 0.875000 +vt 0.062500 0.812500 +vt 0.062500 0.750000 +vt 0.062500 0.687500 +vt 0.062500 0.625000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.062500 0.437500 +vt 0.062500 0.375000 +vt 0.062500 0.312500 +vt 0.062500 0.250000 +vt 0.062500 0.187500 +vt 0.062500 0.125000 +vt 0.062500 0.062500 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt 0.000000 0.875000 +vt 1.000000 0.875000 +vt 0.000000 0.812500 +vt 1.000000 0.812500 +vt 0.000000 0.750000 +vt 1.000000 0.750000 +vt 0.000000 0.687500 +vt 1.000000 0.687500 +vt 0.000000 0.625000 +vt 1.000000 0.625000 +vt 0.000000 0.562500 +vt 1.000000 0.562500 +vt 1.000000 0.500000 +vt 0.000000 0.500000 +vt 1.000000 0.437500 +vt 0.000000 0.437500 +vt 1.000000 0.375000 +vt 0.000000 0.375000 +vt 1.000000 0.312500 +vt 0.000000 0.312500 +vt 1.000000 0.250000 +vt 0.000000 0.250000 +vt 1.000000 0.187500 +vt 0.000000 0.187500 +vt 1.000000 0.125000 +vt 0.000000 0.125000 +vt 1.000000 0.062500 +vt 0.000000 0.062500 +vt 0.937500 0.937500 +vt 0.937500 0.875000 +vt 0.937500 0.812500 +vt 0.937500 0.750000 +vt 0.937500 0.687500 +vt 0.937500 0.625000 +vt 0.937500 0.562500 +vt 0.937500 0.500000 +vt 0.937500 0.437500 +vt 0.937500 0.375000 +vt 0.937500 0.312500 +vt 0.937500 0.250000 +vt 0.937500 0.187500 +vt 0.937500 0.125000 +vt 0.937500 0.062500 +vt 0.875000 0.937500 +vt 0.875000 0.875000 +vt 0.875000 0.812500 +vt 0.875000 0.750000 +vt 0.875000 0.687500 +vt 0.875000 0.625000 +vt 0.875000 0.562500 +vt 0.875000 0.500000 +vt 0.875000 0.437500 +vt 0.875000 0.375000 +vt 0.875000 0.312500 +vt 0.875000 0.250000 +vt 0.875000 0.187500 +vt 0.875000 0.125000 +vt 0.875000 0.062500 +vt 0.812500 0.937500 +vt 0.812500 0.875000 +vt 0.812500 0.812500 +vt 0.812500 0.750000 +vt 0.812500 0.687500 +vt 0.812500 0.625000 +vt 0.812500 0.562500 +vt 0.812500 0.500000 +vt 0.812500 0.437500 +vt 0.812500 0.375000 +vt 0.812500 0.312500 +vt 0.812500 0.250000 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.812500 0.062500 +vt 0.750000 0.937500 +vt 0.750000 0.875000 +vt 0.750000 0.812500 +vt 0.750000 0.750000 +vt 0.750000 0.687500 +vt 0.750000 0.625000 +vt 0.750000 0.562500 +vt 0.750000 0.500000 +vt 0.750000 0.437500 +vt 0.750000 0.375000 +vt 0.750000 0.312500 +vt 0.750000 0.250000 +vt 0.750000 0.187500 +vt 0.750000 0.125000 +vt 0.750000 0.062500 +vt 0.687500 0.937500 +vt 0.687500 0.875000 +vt 0.687500 0.812500 +vt 0.687500 0.750000 +vt 0.687500 0.687500 +vt 0.687500 0.625000 +vt 0.687500 0.562500 +vt 0.687500 0.500000 +vt 0.687500 0.437500 +vt 0.687500 0.375000 +vt 0.687500 0.312500 +vt 0.687500 0.250000 +vt 0.687500 0.187500 +vt 0.687500 0.125000 +vt 0.687500 0.062500 +vt 0.625000 0.937500 +vt 0.625000 0.875000 +vt 0.625000 0.812500 +vt 0.625000 0.750000 +vt 0.625000 0.687500 +vt 0.625000 0.625000 +vt 0.625000 0.562500 +vt 0.625000 0.500000 +vt 0.625000 0.437500 +vt 0.625000 0.375000 +vt 0.625000 0.312500 +vt 0.625000 0.250000 +vt 0.625000 0.187500 +vt 0.625000 0.125000 +vt 0.625000 0.062500 +vt 0.562500 0.937500 +vt 0.562500 0.875000 +vt 0.562500 0.812500 +vt 0.562500 0.750000 +vt 0.562500 0.687500 +vt 0.562500 0.625000 +vt 0.562500 0.562500 +vt 0.562500 0.500000 +vt 0.562500 0.437500 +vt 0.562500 0.375000 +vt 0.562500 0.312500 +vt 0.562500 0.250000 +vt 0.562500 0.187500 +vt 0.562500 0.125000 +vt 0.562500 0.062500 +vt 0.500000 0.937500 +vt 0.500000 0.875000 +vt 0.500000 0.687500 +vt 0.500000 0.250000 +vt 0.500000 0.125000 +vt 0.500000 0.062500 +s 1 +f 9/9/1 23/23/2 481/541/3 +f 4/4/4 15/15/5 16/16/6 +f 481/541/3 24/24/7 482/542/8 +f 5/5/9 16/16/6 17/17/10 +f 477/537/11 251/281/12 10/10/13 +f 55/55/14 482/542/8 24/24/7 +f 5/5/9 18/18/15 6/6/16 +f 478/538/17 10/10/13 11/11/18 +f 6/6/16 19/19/19 7/7/20 +f 1/1/21 11/11/18 12/12/22 +f 7/7/20 20/20/23 8/8/24 +f 2/2/25 12/12/22 13/13/26 +f 8/8/24 21/21/27 480/540/28 +f 479/539/29 13/13/26 14/14/30 +f 480/540/28 22/22/31 9/9/1 +f 3/3/32 14/14/30 15/15/5 +f 21/21/27 37/37/33 22/22/31 +f 15/15/5 29/29/34 30/30/35 +f 22/22/31 38/38/36 23/23/2 +f 16/16/6 30/30/35 31/31/37 +f 23/23/2 39/39/38 24/24/7 +f 17/17/10 31/31/37 32/32/39 +f 10/10/13 251/282/12 25/25/40 +f 55/56/14 24/24/7 39/39/38 +f 17/17/10 33/33/41 18/18/15 +f 11/11/18 25/25/40 26/26/42 +f 18/18/15 34/34/43 19/19/19 +f 12/12/22 26/26/42 27/27/44 +f 19/19/19 35/35/45 20/20/23 +f 13/13/26 27/27/44 28/28/46 +f 20/20/23 36/36/47 21/21/27 +f 14/14/30 28/28/46 29/29/34 +f 26/26/42 40/40/48 41/41/49 +f 33/33/41 49/49/50 34/34/43 +f 27/27/44 41/41/49 42/42/51 +f 34/34/43 50/50/52 35/35/45 +f 28/28/46 42/42/51 43/43/53 +f 35/35/45 51/51/54 36/36/47 +f 29/29/34 43/43/53 44/44/55 +f 36/36/47 52/52/56 37/37/33 +f 30/30/35 44/44/55 45/45/57 +f 37/37/33 53/53/58 38/38/36 +f 31/31/37 45/45/57 46/46/59 +f 38/38/36 54/54/60 39/39/38 +f 32/32/39 46/46/59 47/47/61 +f 25/25/40 251/283/12 40/40/48 +f 55/57/14 39/39/38 54/54/60 +f 32/32/39 48/48/62 33/33/41 +f 45/45/57 60/75/63 61/76/64 +f 52/52/56 69/84/65 53/53/58 +f 46/46/59 61/76/64 62/77/66 +f 53/53/58 70/85/67 54/54/60 +f 47/47/61 62/77/66 63/78/68 +f 40/40/48 251/284/12 56/71/69 +f 55/58/14 54/54/60 70/85/67 +f 47/47/61 64/79/70 48/48/62 +f 41/41/49 56/71/69 57/72/71 +f 48/48/62 65/80/72 49/49/50 +f 42/42/51 57/72/71 58/73/73 +f 49/49/50 66/81/74 50/50/52 +f 43/43/53 58/73/73 59/74/75 +f 50/50/52 67/82/76 51/51/54 +f 44/44/55 59/74/75 60/75/63 +f 51/51/54 68/83/77 52/52/56 +f 64/79/70 80/95/78 65/80/72 +f 58/73/73 72/87/79 73/88/80 +f 65/80/72 81/96/81 66/81/74 +f 59/74/75 73/88/80 74/89/82 +f 66/81/74 82/97/83 67/82/76 +f 60/75/63 74/89/82 75/90/84 +f 67/82/76 83/98/85 68/83/77 +f 61/76/64 75/90/84 76/91/86 +f 68/83/77 84/99/87 69/84/65 +f 62/77/66 76/91/86 77/92/88 +f 69/84/65 85/100/89 70/85/67 +f 63/78/68 77/92/88 78/93/90 +f 56/71/69 251/285/12 71/86/91 +f 55/59/14 70/85/67 85/100/89 +f 63/78/68 79/94/92 64/79/70 +f 57/72/71 71/86/91 72/87/79 +f 83/98/85 99/114/93 84/99/87 +f 77/92/88 91/106/94 92/107/95 +f 84/99/87 100/115/96 85/100/89 +f 78/93/90 92/107/95 93/108/97 +f 71/86/91 251/286/12 86/101/98 +f 55/60/14 85/100/89 100/115/96 +f 78/93/90 94/109/99 79/94/92 +f 72/87/79 86/101/98 87/102/100 +f 79/94/92 95/110/101 80/95/78 +f 73/88/80 87/102/100 88/103/102 +f 80/95/78 96/111/103 81/96/81 +f 74/89/82 88/103/102 89/104/104 +f 81/96/81 97/112/105 82/97/83 +f 75/90/84 89/104/104 90/105/106 +f 82/97/83 98/113/107 83/98/85 +f 76/91/86 90/105/106 91/106/94 +f 95/110/101 111/126/108 96/111/103 +f 89/104/104 103/118/109 104/119/110 +f 96/111/103 112/127/111 97/112/105 +f 90/105/106 104/119/110 105/120/112 +f 97/112/105 113/128/113 98/113/107 +f 91/106/94 105/120/112 106/121/114 +f 98/113/107 114/129/115 99/114/93 +f 92/107/95 106/121/114 107/122/116 +f 99/114/93 115/130/117 100/115/96 +f 93/108/97 107/122/116 108/123/118 +f 86/101/98 251/287/12 101/116/119 +f 55/61/14 100/115/96 115/130/117 +f 93/108/97 109/124/120 94/109/99 +f 87/102/100 101/116/119 102/117/121 +f 94/109/99 110/125/122 95/110/101 +f 88/103/102 102/117/121 103/118/109 +f 114/129/115 130/160/123 115/130/117 +f 108/123/118 122/143/124 123/146/125 +f 101/116/119 251/288/12 116/131/126 +f 55/62/14 115/130/117 130/160/123 +f 108/123/118 124/148/127 109/124/120 +f 102/117/121 116/131/126 117/133/128 +f 109/124/120 125/150/129 110/125/122 +f 103/118/109 117/133/128 118/135/130 +f 110/125/122 126/152/131 111/126/108 +f 104/119/110 118/135/130 119/137/132 +f 111/126/108 127/154/133 112/127/111 +f 105/120/112 119/137/132 120/139/134 +f 112/127/111 128/156/135 113/128/113 +f 106/121/114 120/139/134 121/141/136 +f 113/128/113 129/158/137 114/129/115 +f 107/122/116 121/141/136 122/143/124 +f 118/136/130 134/164/138 119/138/132 +f 127/153/133 141/171/139 142/172/140 +f 119/138/132 135/165/141 120/140/134 +f 128/155/135 142/172/140 143/173/142 +f 120/140/134 136/166/143 121/142/136 +f 129/157/137 143/173/142 144/174/144 +f 121/142/136 137/167/145 122/144/124 +f 130/159/123 144/174/144 145/175/146 +f 122/144/124 138/168/147 123/145/125 +f 116/132/126 251/289/12 131/161/148 +f 55/63/14 130/159/123 145/175/146 +f 124/147/127 138/168/147 139/169/149 +f 116/132/126 132/162/150 117/134/128 +f 125/149/129 139/169/149 140/170/151 +f 117/134/128 133/163/152 118/136/130 +f 126/151/131 140/170/151 141/171/139 +f 137/167/145 153/183/153 138/168/147 +f 131/161/148 251/290/12 146/176/154 +f 55/64/14 145/175/146 160/190/155 +f 139/169/149 153/183/153 154/184/156 +f 131/161/148 147/177/157 132/162/150 +f 140/170/151 154/184/156 155/185/158 +f 132/162/150 148/178/159 133/163/152 +f 141/171/139 155/185/158 156/186/160 +f 133/163/152 149/179/161 134/164/138 +f 142/172/140 156/186/160 157/187/162 +f 134/164/138 150/180/163 135/165/141 +f 143/173/142 157/187/162 158/188/164 +f 135/165/141 151/181/165 136/166/143 +f 144/174/144 158/188/164 159/189/166 +f 136/166/143 152/182/167 137/167/145 +f 145/175/146 159/189/166 160/190/155 +f 157/187/162 171/201/168 172/202/169 +f 149/179/161 165/195/170 150/180/163 +f 158/188/164 172/202/169 173/203/171 +f 150/180/163 166/196/172 151/181/165 +f 159/189/166 173/203/171 174/204/173 +f 151/181/165 167/197/174 152/182/167 +f 160/190/155 174/204/173 175/205/175 +f 152/182/167 168/198/176 153/183/153 +f 146/176/154 251/291/12 161/191/177 +f 55/65/14 160/190/155 175/205/175 +f 154/184/156 168/198/176 169/199/178 +f 146/176/154 162/192/179 147/177/157 +f 155/185/158 169/199/178 170/200/180 +f 147/177/157 163/193/181 148/178/159 +f 156/186/160 170/200/180 171/201/168 +f 148/178/159 164/194/182 149/179/161 +f 161/191/177 251/292/12 176/206/183 +f 55/66/14 175/205/175 190/220/184 +f 169/199/178 183/213/185 184/214/186 +f 161/191/177 177/207/187 162/192/179 +f 170/200/180 184/214/186 185/215/188 +f 162/192/179 178/208/189 163/193/181 +f 171/201/168 185/215/188 186/216/190 +f 163/193/181 179/209/191 164/194/182 +f 172/202/169 186/216/190 187/217/192 +f 164/194/182 180/210/193 165/195/170 +f 173/203/171 187/217/192 188/218/194 +f 165/195/170 181/211/195 166/196/172 +f 174/204/173 188/218/194 189/219/196 +f 166/196/172 182/212/197 167/197/174 +f 175/205/175 189/219/196 190/220/184 +f 167/197/174 183/213/185 168/198/176 +f 179/209/191 195/225/198 180/210/193 +f 188/218/194 202/232/199 203/233/200 +f 180/210/193 196/226/201 181/211/195 +f 189/219/196 203/233/200 204/234/202 +f 181/211/195 197/227/203 182/212/197 +f 190/220/184 204/234/202 205/235/204 +f 182/212/197 198/228/205 183/213/185 +f 176/206/183 251/293/12 191/221/206 +f 55/67/14 190/220/184 205/235/204 +f 184/214/186 198/228/205 199/229/207 +f 176/206/183 192/222/208 177/207/187 +f 185/215/188 199/229/207 200/230/209 +f 177/207/187 193/223/210 178/208/189 +f 186/216/190 200/230/209 201/231/211 +f 178/208/189 194/224/212 179/209/191 +f 187/217/192 201/231/211 202/232/199 +f 199/229/207 213/243/213 214/244/214 +f 191/221/206 207/237/215 192/222/208 +f 200/230/209 214/244/214 215/245/216 +f 192/222/208 208/238/217 193/223/210 +f 201/231/211 215/245/216 216/246/218 +f 193/223/210 209/239/219 194/224/212 +f 202/232/199 216/246/218 217/247/220 +f 194/224/212 210/240/221 195/225/198 +f 203/233/200 217/247/220 218/248/222 +f 195/225/198 211/241/223 196/226/201 +f 204/234/202 218/248/222 219/249/224 +f 196/226/201 212/242/225 197/227/203 +f 205/235/204 219/249/224 220/250/226 +f 197/227/203 213/243/213 198/228/205 +f 191/221/206 251/294/12 206/236/227 +f 55/68/14 205/235/204 220/250/226 +f 218/248/222 232/262/228 233/263/229 +f 210/240/221 226/256/230 211/241/223 +f 219/249/224 233/263/229 234/264/231 +f 211/241/223 227/257/232 212/242/225 +f 220/250/226 234/264/231 235/265/233 +f 212/242/225 228/258/234 213/243/213 +f 206/236/227 251/295/12 221/251/235 +f 55/69/14 220/250/226 235/265/233 +f 214/244/214 228/258/234 229/259/236 +f 206/236/227 222/252/237 207/237/215 +f 215/245/216 229/259/236 230/260/238 +f 207/237/215 223/253/239 208/238/217 +f 216/246/218 230/260/238 231/261/240 +f 208/238/217 224/254/241 209/239/219 +f 217/247/220 231/261/240 232/262/228 +f 209/239/219 225/255/242 210/240/221 +f 230/260/238 244/274/243 245/275/244 +f 222/252/237 238/268/245 223/253/239 +f 231/261/240 245/275/244 246/276/246 +f 223/253/239 239/269/247 224/254/241 +f 232/262/228 246/276/246 247/277/248 +f 224/254/241 240/270/249 225/255/242 +f 233/263/229 247/277/248 248/278/250 +f 225/255/242 241/271/251 226/256/230 +f 234/264/231 248/278/250 249/279/252 +f 226/256/230 242/272/253 227/257/232 +f 235/265/233 249/279/252 250/280/254 +f 227/257/232 243/273/255 228/258/234 +f 221/251/235 251/296/12 236/266/256 +f 55/70/14 235/265/233 250/280/254 +f 229/259/236 243/273/255 244/274/243 +f 221/251/235 237/267/257 222/252/237 +f 248/278/250 265/310/258 249/279/252 +f 242/272/253 257/302/259 258/303/260 +f 249/279/252 266/311/261 250/280/254 +f 243/273/255 258/303/260 259/304/262 +f 236/266/256 251/281/12 252/297/263 +f 55/55/14 250/280/254 266/311/261 +f 243/273/255 260/305/264 244/274/243 +f 237/267/257 252/297/263 253/298/265 +f 244/274/243 261/306/266 245/275/244 +f 238/268/245 253/298/265 254/299/267 +f 245/275/244 262/307/268 246/276/246 +f 239/269/247 254/299/267 255/300/269 +f 246/276/246 263/308/270 247/277/248 +f 240/270/249 255/300/269 256/301/271 +f 247/277/248 264/309/272 248/278/250 +f 241/271/251 256/301/271 257/302/259 +f 254/299/267 268/313/273 269/314/274 +f 261/306/266 277/322/275 262/307/268 +f 255/300/269 269/314/274 270/315/276 +f 262/307/268 278/323/277 263/308/270 +f 256/301/271 270/315/276 271/316/278 +f 263/308/270 279/324/279 264/309/272 +f 257/302/259 271/316/278 272/317/280 +f 264/309/272 280/325/281 265/310/258 +f 258/303/260 272/317/280 273/318/282 +f 265/310/258 281/326/283 266/311/261 +f 259/304/262 273/318/282 274/319/284 +f 252/297/263 251/282/12 267/312/285 +f 55/56/14 266/311/261 281/326/283 +f 259/304/262 275/320/286 260/305/264 +f 253/298/265 267/312/285 268/313/273 +f 260/305/264 276/321/287 261/306/266 +f 273/318/282 287/332/288 288/333/289 +f 280/325/281 296/341/290 281/326/283 +f 274/319/284 288/333/289 289/334/291 +f 267/312/285 251/283/12 282/327/292 +f 55/57/14 281/326/283 296/341/290 +f 274/319/284 290/335/293 275/320/286 +f 268/313/273 282/327/292 283/328/294 +f 275/320/286 291/336/295 276/321/287 +f 269/314/274 283/328/294 284/329/296 +f 276/321/287 292/337/297 277/322/275 +f 270/315/276 284/329/296 285/330/298 +f 277/322/275 293/338/299 278/323/277 +f 271/316/278 285/330/298 286/331/300 +f 278/323/277 294/339/301 279/324/279 +f 272/317/280 286/331/300 287/332/288 +f 279/324/279 295/340/302 280/325/281 +f 291/336/295 307/352/303 292/337/297 +f 285/330/298 299/344/304 300/345/305 +f 292/337/297 308/353/306 293/338/299 +f 286/331/300 300/345/305 301/346/307 +f 293/338/299 309/354/308 294/339/301 +f 287/332/288 301/346/307 302/347/309 +f 294/339/301 310/355/310 295/340/302 +f 288/333/289 302/347/309 303/348/311 +f 295/340/302 311/356/312 296/341/290 +f 289/334/291 303/348/311 304/349/313 +f 282/327/292 251/284/12 297/342/314 +f 55/58/14 296/341/290 311/356/312 +f 289/334/291 305/350/315 290/335/293 +f 283/328/294 297/342/314 298/343/316 +f 290/335/293 306/351/317 291/336/295 +f 284/329/296 298/343/316 299/344/304 +f 310/355/310 326/371/318 311/356/312 +f 304/349/313 318/363/319 319/364/320 +f 297/342/314 251/285/12 312/357/321 +f 55/59/14 311/356/312 326/371/318 +f 304/349/313 320/365/322 305/350/315 +f 298/343/316 312/357/321 313/358/323 +f 305/350/315 321/366/324 306/351/317 +f 299/344/304 313/358/323 314/359/325 +f 306/351/317 322/367/326 307/352/303 +f 300/345/305 314/359/325 315/360/327 +f 307/352/303 323/368/328 308/353/306 +f 301/346/307 315/360/327 316/361/329 +f 308/353/306 324/369/330 309/354/308 +f 302/347/309 316/361/329 317/362/331 +f 309/354/308 325/370/332 310/355/310 +f 303/348/311 317/362/331 318/363/319 +f 315/360/327 329/374/333 330/375/334 +f 322/367/326 338/383/335 323/368/328 +f 316/361/329 330/375/334 331/376/336 +f 323/368/328 339/384/337 324/369/330 +f 317/362/331 331/376/336 332/377/338 +f 324/369/330 340/385/339 325/370/332 +f 318/363/319 332/377/338 333/378/340 +f 325/370/332 341/386/341 326/371/318 +f 319/364/320 333/378/340 334/379/342 +f 312/357/321 251/286/12 327/372/343 +f 55/60/14 326/371/318 341/386/341 +f 319/364/320 335/380/344 320/365/322 +f 313/358/323 327/372/343 328/373/345 +f 320/365/322 336/381/346 321/366/324 +f 314/359/325 328/373/345 329/374/333 +f 321/366/324 337/382/347 322/367/326 +f 334/379/342 348/393/348 349/394/349 +f 327/372/343 251/287/12 342/387/350 +f 55/61/14 341/386/341 356/401/351 +f 334/379/342 350/395/352 335/380/344 +f 328/373/345 342/387/350 343/388/353 +f 335/380/344 351/396/354 336/381/346 +f 329/374/333 343/388/353 344/389/355 +f 336/381/346 352/397/356 337/382/347 +f 330/375/334 344/389/355 345/390/357 +f 337/382/347 353/398/358 338/383/335 +f 331/376/336 345/390/357 346/391/359 +f 338/383/335 354/399/360 339/384/337 +f 332/377/338 346/391/359 347/392/361 +f 339/384/337 355/400/362 340/385/339 +f 333/378/340 347/392/361 348/393/348 +f 340/385/339 356/401/351 341/386/341 +f 352/397/356 368/425/363 353/398/358 +f 346/391/359 360/408/364 361/410/365 +f 353/398/358 369/427/366 354/399/360 +f 347/392/361 361/410/365 362/412/367 +f 354/399/360 370/429/368 355/400/362 +f 348/393/348 362/412/367 363/414/369 +f 355/400/362 371/431/370 356/401/351 +f 349/394/349 363/414/369 364/417/371 +f 342/387/350 251/288/12 357/402/372 +f 55/62/14 356/401/351 371/431/370 +f 349/394/349 365/419/373 350/395/352 +f 343/388/353 357/402/372 358/404/374 +f 350/395/352 366/421/375 351/396/354 +f 344/389/355 358/404/374 359/406/376 +f 351/396/354 367/423/377 352/397/356 +f 345/390/357 359/406/376 360/408/364 +f 55/63/14 371/430/370 386/446/378 +f 365/418/373 379/439/379 380/440/380 +f 357/403/372 373/433/381 358/405/374 +f 366/420/375 380/440/380 381/441/382 +f 358/405/374 374/434/383 359/407/376 +f 367/422/377 381/441/382 382/442/384 +f 359/407/376 375/435/385 360/409/364 +f 368/424/363 382/442/384 383/443/386 +f 360/409/364 376/436/387 361/411/365 +f 369/426/366 383/443/386 384/444/388 +f 361/411/365 377/437/389 362/413/367 +f 370/428/368 384/444/388 385/445/390 +f 362/413/367 378/438/391 363/415/369 +f 371/430/370 385/445/390 386/446/378 +f 363/415/369 379/439/379 364/416/371 +f 357/403/372 251/289/12 372/432/392 +f 384/444/388 398/458/393 399/459/394 +f 376/436/387 392/452/395 377/437/389 +f 385/445/390 399/459/394 400/460/396 +f 377/437/389 393/453/397 378/438/391 +f 386/446/378 400/460/396 401/461/398 +f 378/438/391 394/454/399 379/439/379 +f 372/432/392 251/290/12 387/447/400 +f 55/64/14 386/446/378 401/461/398 +f 380/440/380 394/454/399 395/455/401 +f 372/432/392 388/448/402 373/433/381 +f 381/441/382 395/455/401 396/456/403 +f 373/433/381 389/449/404 374/434/383 +f 382/442/384 396/456/403 397/457/405 +f 374/434/383 390/450/406 375/435/385 +f 383/443/386 397/457/405 398/458/393 +f 375/435/385 391/451/407 376/436/387 +f 387/447/400 403/463/408 388/448/402 +f 396/456/403 410/470/409 411/471/410 +f 388/448/402 404/464/411 389/449/404 +f 397/457/405 411/471/410 412/472/412 +f 389/449/404 405/465/413 390/450/406 +f 398/458/393 412/472/412 413/473/414 +f 390/450/406 406/466/415 391/451/407 +f 399/459/394 413/473/414 414/474/416 +f 391/451/407 407/467/417 392/452/395 +f 400/460/396 414/474/416 415/475/418 +f 392/452/395 408/468/419 393/453/397 +f 401/461/398 415/475/418 416/476/420 +f 393/453/397 409/469/421 394/454/399 +f 387/447/400 251/291/12 402/462/422 +f 55/65/14 401/461/398 416/476/420 +f 395/455/401 409/469/421 410/470/409 +f 406/466/415 422/482/423 407/467/417 +f 415/475/418 429/489/424 430/490/425 +f 407/467/417 423/483/426 408/468/419 +f 416/476/420 430/490/425 431/491/427 +f 408/468/419 424/484/428 409/469/421 +f 402/462/422 251/292/12 417/477/429 +f 55/66/14 416/476/420 431/491/427 +f 410/470/409 424/484/428 425/485/430 +f 402/462/422 418/478/431 403/463/408 +f 411/471/410 425/485/430 426/486/432 +f 403/463/408 419/479/433 404/464/411 +f 412/472/412 426/486/432 427/487/434 +f 404/464/411 420/480/435 405/465/413 +f 413/473/414 427/487/434 428/488/436 +f 405/465/413 421/481/437 406/466/415 +f 414/474/416 428/488/436 429/489/424 +f 426/486/432 440/500/438 441/501/439 +f 418/478/431 434/494/440 419/479/433 +f 427/487/434 441/501/439 442/502/441 +f 419/479/433 435/495/442 420/480/435 +f 428/488/436 442/502/441 443/503/443 +f 420/480/435 436/496/444 421/481/437 +f 429/489/424 443/503/443 444/504/445 +f 421/481/437 437/497/446 422/482/423 +f 430/490/425 444/504/445 445/505/447 +f 422/482/423 438/498/448 423/483/426 +f 431/491/427 445/505/447 446/506/449 +f 423/483/426 439/499/450 424/484/428 +f 417/477/429 251/293/12 432/492/451 +f 55/67/14 431/491/427 446/506/449 +f 425/485/430 439/499/450 440/500/438 +f 417/477/429 433/493/452 418/478/431 +f 445/505/447 459/519/453 460/520/454 +f 437/497/446 453/513/455 438/498/448 +f 446/506/449 460/520/454 461/521/456 +f 438/498/448 454/514/457 439/499/450 +f 432/492/451 251/294/12 447/507/458 +f 55/68/14 446/506/449 461/521/456 +f 440/500/438 454/514/457 455/515/459 +f 432/492/451 448/508/460 433/493/452 +f 441/501/439 455/515/459 456/516/461 +f 433/493/452 449/509/462 434/494/440 +f 442/502/441 456/516/461 457/517/463 +f 434/494/440 450/510/464 435/495/442 +f 443/503/443 457/517/463 458/518/465 +f 435/495/442 451/511/466 436/496/444 +f 444/504/445 458/518/465 459/519/453 +f 436/496/444 452/512/467 437/497/446 +f 448/508/460 464/524/468 449/509/462 +f 457/517/463 471/531/469 472/532/470 +f 449/509/462 465/525/471 450/510/464 +f 458/518/465 472/532/470 473/533/472 +f 450/510/464 466/526/473 451/511/466 +f 459/519/453 473/533/472 474/534/474 +f 451/511/466 467/527/475 452/512/467 +f 460/520/454 474/534/474 475/535/476 +f 452/512/467 468/528/477 453/513/455 +f 461/521/456 475/535/476 476/536/478 +f 453/513/455 469/529/479 454/514/457 +f 447/507/458 251/295/12 462/522/480 +f 55/69/14 461/521/456 476/536/478 +f 455/515/459 469/529/479 470/530/481 +f 447/507/458 463/523/482 448/508/460 +f 456/516/461 470/530/481 471/531/469 +f 467/527/475 4/4/4 468/528/477 +f 476/536/478 481/541/3 482/542/8 +f 468/528/477 5/5/9 469/529/479 +f 462/522/480 251/296/12 477/537/11 +f 55/70/14 476/536/478 482/542/8 +f 470/530/481 5/5/9 6/6/16 +f 462/522/480 478/538/17 463/523/482 +f 471/531/469 6/6/16 7/7/20 +f 463/523/482 1/1/21 464/524/468 +f 472/532/470 7/7/20 8/8/24 +f 464/524/468 2/2/25 465/525/471 +f 473/533/472 8/8/24 480/540/28 +f 465/525/471 479/539/29 466/526/473 +f 474/534/474 480/540/28 9/9/1 +f 466/526/473 3/3/32 467/527/475 +f 475/535/476 9/9/1 481/541/3 +f 4/4/4 3/3/32 15/15/5 +f 5/5/9 4/4/4 16/16/6 +f 478/538/17 477/537/11 10/10/13 +f 1/1/21 478/538/17 11/11/18 +f 2/2/25 1/1/21 12/12/22 +f 479/539/29 2/2/25 13/13/26 +f 3/3/32 479/539/29 14/14/30 +f 15/15/5 14/14/30 29/29/34 +f 16/16/6 15/15/5 30/30/35 +f 17/17/10 16/16/6 31/31/37 +f 11/11/18 10/10/13 25/25/40 +f 12/12/22 11/11/18 26/26/42 +f 13/13/26 12/12/22 27/27/44 +f 14/14/30 13/13/26 28/28/46 +f 26/26/42 25/25/40 40/40/48 +f 27/27/44 26/26/42 41/41/49 +f 28/28/46 27/27/44 42/42/51 +f 29/29/34 28/28/46 43/43/53 +f 30/30/35 29/29/34 44/44/55 +f 31/31/37 30/30/35 45/45/57 +f 32/32/39 31/31/37 46/46/59 +f 45/45/57 44/44/55 60/75/63 +f 46/46/59 45/45/57 61/76/64 +f 47/47/61 46/46/59 62/77/66 +f 41/41/49 40/40/48 56/71/69 +f 42/42/51 41/41/49 57/72/71 +f 43/43/53 42/42/51 58/73/73 +f 44/44/55 43/43/53 59/74/75 +f 58/73/73 57/72/71 72/87/79 +f 59/74/75 58/73/73 73/88/80 +f 60/75/63 59/74/75 74/89/82 +f 61/76/64 60/75/63 75/90/84 +f 62/77/66 61/76/64 76/91/86 +f 63/78/68 62/77/66 77/92/88 +f 57/72/71 56/71/69 71/86/91 +f 77/92/88 76/91/86 91/106/94 +f 78/93/90 77/92/88 92/107/95 +f 72/87/79 71/86/91 86/101/98 +f 73/88/80 72/87/79 87/102/100 +f 74/89/82 73/88/80 88/103/102 +f 75/90/84 74/89/82 89/104/104 +f 76/91/86 75/90/84 90/105/106 +f 89/104/104 88/103/102 103/118/109 +f 90/105/106 89/104/104 104/119/110 +f 91/106/94 90/105/106 105/120/112 +f 92/107/95 91/106/94 106/121/114 +f 93/108/97 92/107/95 107/122/116 +f 87/102/100 86/101/98 101/116/119 +f 88/103/102 87/102/100 102/117/121 +f 108/123/118 107/122/116 122/143/124 +f 102/117/121 101/116/119 116/131/126 +f 103/118/109 102/117/121 117/133/128 +f 104/119/110 103/118/109 118/135/130 +f 105/120/112 104/119/110 119/137/132 +f 106/121/114 105/120/112 120/139/134 +f 107/122/116 106/121/114 121/141/136 +f 127/153/133 126/151/131 141/171/139 +f 128/155/135 127/153/133 142/172/140 +f 129/157/137 128/155/135 143/173/142 +f 130/159/123 129/157/137 144/174/144 +f 124/147/127 123/145/125 138/168/147 +f 125/149/129 124/147/127 139/169/149 +f 126/151/131 125/149/129 140/170/151 +f 139/169/149 138/168/147 153/183/153 +f 140/170/151 139/169/149 154/184/156 +f 141/171/139 140/170/151 155/185/158 +f 142/172/140 141/171/139 156/186/160 +f 143/173/142 142/172/140 157/187/162 +f 144/174/144 143/173/142 158/188/164 +f 145/175/146 144/174/144 159/189/166 +f 157/187/162 156/186/160 171/201/168 +f 158/188/164 157/187/162 172/202/169 +f 159/189/166 158/188/164 173/203/171 +f 160/190/155 159/189/166 174/204/173 +f 154/184/156 153/183/153 168/198/176 +f 155/185/158 154/184/156 169/199/178 +f 156/186/160 155/185/158 170/200/180 +f 169/199/178 168/198/176 183/213/185 +f 170/200/180 169/199/178 184/214/186 +f 171/201/168 170/200/180 185/215/188 +f 172/202/169 171/201/168 186/216/190 +f 173/203/171 172/202/169 187/217/192 +f 174/204/173 173/203/171 188/218/194 +f 175/205/175 174/204/173 189/219/196 +f 188/218/194 187/217/192 202/232/199 +f 189/219/196 188/218/194 203/233/200 +f 190/220/184 189/219/196 204/234/202 +f 184/214/186 183/213/185 198/228/205 +f 185/215/188 184/214/186 199/229/207 +f 186/216/190 185/215/188 200/230/209 +f 187/217/192 186/216/190 201/231/211 +f 199/229/207 198/228/205 213/243/213 +f 200/230/209 199/229/207 214/244/214 +f 201/231/211 200/230/209 215/245/216 +f 202/232/199 201/231/211 216/246/218 +f 203/233/200 202/232/199 217/247/220 +f 204/234/202 203/233/200 218/248/222 +f 205/235/204 204/234/202 219/249/224 +f 218/248/222 217/247/220 232/262/228 +f 219/249/224 218/248/222 233/263/229 +f 220/250/226 219/249/224 234/264/231 +f 214/244/214 213/243/213 228/258/234 +f 215/245/216 214/244/214 229/259/236 +f 216/246/218 215/245/216 230/260/238 +f 217/247/220 216/246/218 231/261/240 +f 230/260/238 229/259/236 244/274/243 +f 231/261/240 230/260/238 245/275/244 +f 232/262/228 231/261/240 246/276/246 +f 233/263/229 232/262/228 247/277/248 +f 234/264/231 233/263/229 248/278/250 +f 235/265/233 234/264/231 249/279/252 +f 229/259/236 228/258/234 243/273/255 +f 242/272/253 241/271/251 257/302/259 +f 243/273/255 242/272/253 258/303/260 +f 237/267/257 236/266/256 252/297/263 +f 238/268/245 237/267/257 253/298/265 +f 239/269/247 238/268/245 254/299/267 +f 240/270/249 239/269/247 255/300/269 +f 241/271/251 240/270/249 256/301/271 +f 254/299/267 253/298/265 268/313/273 +f 255/300/269 254/299/267 269/314/274 +f 256/301/271 255/300/269 270/315/276 +f 257/302/259 256/301/271 271/316/278 +f 258/303/260 257/302/259 272/317/280 +f 259/304/262 258/303/260 273/318/282 +f 253/298/265 252/297/263 267/312/285 +f 273/318/282 272/317/280 287/332/288 +f 274/319/284 273/318/282 288/333/289 +f 268/313/273 267/312/285 282/327/292 +f 269/314/274 268/313/273 283/328/294 +f 270/315/276 269/314/274 284/329/296 +f 271/316/278 270/315/276 285/330/298 +f 272/317/280 271/316/278 286/331/300 +f 285/330/298 284/329/296 299/344/304 +f 286/331/300 285/330/298 300/345/305 +f 287/332/288 286/331/300 301/346/307 +f 288/333/289 287/332/288 302/347/309 +f 289/334/291 288/333/289 303/348/311 +f 283/328/294 282/327/292 297/342/314 +f 284/329/296 283/328/294 298/343/316 +f 304/349/313 303/348/311 318/363/319 +f 298/343/316 297/342/314 312/357/321 +f 299/344/304 298/343/316 313/358/323 +f 300/345/305 299/344/304 314/359/325 +f 301/346/307 300/345/305 315/360/327 +f 302/347/309 301/346/307 316/361/329 +f 303/348/311 302/347/309 317/362/331 +f 315/360/327 314/359/325 329/374/333 +f 316/361/329 315/360/327 330/375/334 +f 317/362/331 316/361/329 331/376/336 +f 318/363/319 317/362/331 332/377/338 +f 319/364/320 318/363/319 333/378/340 +f 313/358/323 312/357/321 327/372/343 +f 314/359/325 313/358/323 328/373/345 +f 334/379/342 333/378/340 348/393/348 +f 328/373/345 327/372/343 342/387/350 +f 329/374/333 328/373/345 343/388/353 +f 330/375/334 329/374/333 344/389/355 +f 331/376/336 330/375/334 345/390/357 +f 332/377/338 331/376/336 346/391/359 +f 333/378/340 332/377/338 347/392/361 +f 346/391/359 345/390/357 360/408/364 +f 347/392/361 346/391/359 361/410/365 +f 348/393/348 347/392/361 362/412/367 +f 349/394/349 348/393/348 363/414/369 +f 343/388/353 342/387/350 357/402/372 +f 344/389/355 343/388/353 358/404/374 +f 345/390/357 344/389/355 359/406/376 +f 365/418/373 364/416/371 379/439/379 +f 366/420/375 365/418/373 380/440/380 +f 367/422/377 366/420/375 381/441/382 +f 368/424/363 367/422/377 382/442/384 +f 369/426/366 368/424/363 383/443/386 +f 370/428/368 369/426/366 384/444/388 +f 371/430/370 370/428/368 385/445/390 +f 384/444/388 383/443/386 398/458/393 +f 385/445/390 384/444/388 399/459/394 +f 386/446/378 385/445/390 400/460/396 +f 380/440/380 379/439/379 394/454/399 +f 381/441/382 380/440/380 395/455/401 +f 382/442/384 381/441/382 396/456/403 +f 383/443/386 382/442/384 397/457/405 +f 396/456/403 395/455/401 410/470/409 +f 397/457/405 396/456/403 411/471/410 +f 398/458/393 397/457/405 412/472/412 +f 399/459/394 398/458/393 413/473/414 +f 400/460/396 399/459/394 414/474/416 +f 401/461/398 400/460/396 415/475/418 +f 395/455/401 394/454/399 409/469/421 +f 415/475/418 414/474/416 429/489/424 +f 416/476/420 415/475/418 430/490/425 +f 410/470/409 409/469/421 424/484/428 +f 411/471/410 410/470/409 425/485/430 +f 412/472/412 411/471/410 426/486/432 +f 413/473/414 412/472/412 427/487/434 +f 414/474/416 413/473/414 428/488/436 +f 426/486/432 425/485/430 440/500/438 +f 427/487/434 426/486/432 441/501/439 +f 428/488/436 427/487/434 442/502/441 +f 429/489/424 428/488/436 443/503/443 +f 430/490/425 429/489/424 444/504/445 +f 431/491/427 430/490/425 445/505/447 +f 425/485/430 424/484/428 439/499/450 +f 445/505/447 444/504/445 459/519/453 +f 446/506/449 445/505/447 460/520/454 +f 440/500/438 439/499/450 454/514/457 +f 441/501/439 440/500/438 455/515/459 +f 442/502/441 441/501/439 456/516/461 +f 443/503/443 442/502/441 457/517/463 +f 444/504/445 443/503/443 458/518/465 +f 457/517/463 456/516/461 471/531/469 +f 458/518/465 457/517/463 472/532/470 +f 459/519/453 458/518/465 473/533/472 +f 460/520/454 459/519/453 474/534/474 +f 461/521/456 460/520/454 475/535/476 +f 455/515/459 454/514/457 469/529/479 +f 456/516/461 455/515/459 470/530/481 +f 476/536/478 475/535/476 481/541/3 +f 470/530/481 469/529/479 5/5/9 +f 471/531/469 470/530/481 6/6/16 +f 472/532/470 471/531/469 7/7/20 +f 473/533/472 472/532/470 8/8/24 +f 474/534/474 473/533/472 480/540/28 +f 475/535/476 474/534/474 9/9/1 +f 9/9/1 22/22/31 23/23/2 +f 481/541/3 23/23/2 24/24/7 +f 5/5/9 17/17/10 18/18/15 +f 6/6/16 18/18/15 19/19/19 +f 7/7/20 19/19/19 20/20/23 +f 8/8/24 20/20/23 21/21/27 +f 480/540/28 21/21/27 22/22/31 +f 21/21/27 36/36/47 37/37/33 +f 22/22/31 37/37/33 38/38/36 +f 23/23/2 38/38/36 39/39/38 +f 17/17/10 32/32/39 33/33/41 +f 18/18/15 33/33/41 34/34/43 +f 19/19/19 34/34/43 35/35/45 +f 20/20/23 35/35/45 36/36/47 +f 33/33/41 48/48/62 49/49/50 +f 34/34/43 49/49/50 50/50/52 +f 35/35/45 50/50/52 51/51/54 +f 36/36/47 51/51/54 52/52/56 +f 37/37/33 52/52/56 53/53/58 +f 38/38/36 53/53/58 54/54/60 +f 32/32/39 47/47/61 48/48/62 +f 52/52/56 68/83/77 69/84/65 +f 53/53/58 69/84/65 70/85/67 +f 47/47/61 63/78/68 64/79/70 +f 48/48/62 64/79/70 65/80/72 +f 49/49/50 65/80/72 66/81/74 +f 50/50/52 66/81/74 67/82/76 +f 51/51/54 67/82/76 68/83/77 +f 64/79/70 79/94/92 80/95/78 +f 65/80/72 80/95/78 81/96/81 +f 66/81/74 81/96/81 82/97/83 +f 67/82/76 82/97/83 83/98/85 +f 68/83/77 83/98/85 84/99/87 +f 69/84/65 84/99/87 85/100/89 +f 63/78/68 78/93/90 79/94/92 +f 83/98/85 98/113/107 99/114/93 +f 84/99/87 99/114/93 100/115/96 +f 78/93/90 93/108/97 94/109/99 +f 79/94/92 94/109/99 95/110/101 +f 80/95/78 95/110/101 96/111/103 +f 81/96/81 96/111/103 97/112/105 +f 82/97/83 97/112/105 98/113/107 +f 95/110/101 110/125/122 111/126/108 +f 96/111/103 111/126/108 112/127/111 +f 97/112/105 112/127/111 113/128/113 +f 98/113/107 113/128/113 114/129/115 +f 99/114/93 114/129/115 115/130/117 +f 93/108/97 108/123/118 109/124/120 +f 94/109/99 109/124/120 110/125/122 +f 114/129/115 129/158/137 130/160/123 +f 108/123/118 123/146/125 124/148/127 +f 109/124/120 124/148/127 125/150/129 +f 110/125/122 125/150/129 126/152/131 +f 111/126/108 126/152/131 127/154/133 +f 112/127/111 127/154/133 128/156/135 +f 113/128/113 128/156/135 129/158/137 +f 118/136/130 133/163/152 134/164/138 +f 119/138/132 134/164/138 135/165/141 +f 120/140/134 135/165/141 136/166/143 +f 121/142/136 136/166/143 137/167/145 +f 122/144/124 137/167/145 138/168/147 +f 116/132/126 131/161/148 132/162/150 +f 117/134/128 132/162/150 133/163/152 +f 137/167/145 152/182/167 153/183/153 +f 131/161/148 146/176/154 147/177/157 +f 132/162/150 147/177/157 148/178/159 +f 133/163/152 148/178/159 149/179/161 +f 134/164/138 149/179/161 150/180/163 +f 135/165/141 150/180/163 151/181/165 +f 136/166/143 151/181/165 152/182/167 +f 149/179/161 164/194/182 165/195/170 +f 150/180/163 165/195/170 166/196/172 +f 151/181/165 166/196/172 167/197/174 +f 152/182/167 167/197/174 168/198/176 +f 146/176/154 161/191/177 162/192/179 +f 147/177/157 162/192/179 163/193/181 +f 148/178/159 163/193/181 164/194/182 +f 161/191/177 176/206/183 177/207/187 +f 162/192/179 177/207/187 178/208/189 +f 163/193/181 178/208/189 179/209/191 +f 164/194/182 179/209/191 180/210/193 +f 165/195/170 180/210/193 181/211/195 +f 166/196/172 181/211/195 182/212/197 +f 167/197/174 182/212/197 183/213/185 +f 179/209/191 194/224/212 195/225/198 +f 180/210/193 195/225/198 196/226/201 +f 181/211/195 196/226/201 197/227/203 +f 182/212/197 197/227/203 198/228/205 +f 176/206/183 191/221/206 192/222/208 +f 177/207/187 192/222/208 193/223/210 +f 178/208/189 193/223/210 194/224/212 +f 191/221/206 206/236/227 207/237/215 +f 192/222/208 207/237/215 208/238/217 +f 193/223/210 208/238/217 209/239/219 +f 194/224/212 209/239/219 210/240/221 +f 195/225/198 210/240/221 211/241/223 +f 196/226/201 211/241/223 212/242/225 +f 197/227/203 212/242/225 213/243/213 +f 210/240/221 225/255/242 226/256/230 +f 211/241/223 226/256/230 227/257/232 +f 212/242/225 227/257/232 228/258/234 +f 206/236/227 221/251/235 222/252/237 +f 207/237/215 222/252/237 223/253/239 +f 208/238/217 223/253/239 224/254/241 +f 209/239/219 224/254/241 225/255/242 +f 222/252/237 237/267/257 238/268/245 +f 223/253/239 238/268/245 239/269/247 +f 224/254/241 239/269/247 240/270/249 +f 225/255/242 240/270/249 241/271/251 +f 226/256/230 241/271/251 242/272/253 +f 227/257/232 242/272/253 243/273/255 +f 221/251/235 236/266/256 237/267/257 +f 248/278/250 264/309/272 265/310/258 +f 249/279/252 265/310/258 266/311/261 +f 243/273/255 259/304/262 260/305/264 +f 244/274/243 260/305/264 261/306/266 +f 245/275/244 261/306/266 262/307/268 +f 246/276/246 262/307/268 263/308/270 +f 247/277/248 263/308/270 264/309/272 +f 261/306/266 276/321/287 277/322/275 +f 262/307/268 277/322/275 278/323/277 +f 263/308/270 278/323/277 279/324/279 +f 264/309/272 279/324/279 280/325/281 +f 265/310/258 280/325/281 281/326/283 +f 259/304/262 274/319/284 275/320/286 +f 260/305/264 275/320/286 276/321/287 +f 280/325/281 295/340/302 296/341/290 +f 274/319/284 289/334/291 290/335/293 +f 275/320/286 290/335/293 291/336/295 +f 276/321/287 291/336/295 292/337/297 +f 277/322/275 292/337/297 293/338/299 +f 278/323/277 293/338/299 294/339/301 +f 279/324/279 294/339/301 295/340/302 +f 291/336/295 306/351/317 307/352/303 +f 292/337/297 307/352/303 308/353/306 +f 293/338/299 308/353/306 309/354/308 +f 294/339/301 309/354/308 310/355/310 +f 295/340/302 310/355/310 311/356/312 +f 289/334/291 304/349/313 305/350/315 +f 290/335/293 305/350/315 306/351/317 +f 310/355/310 325/370/332 326/371/318 +f 304/349/313 319/364/320 320/365/322 +f 305/350/315 320/365/322 321/366/324 +f 306/351/317 321/366/324 322/367/326 +f 307/352/303 322/367/326 323/368/328 +f 308/353/306 323/368/328 324/369/330 +f 309/354/308 324/369/330 325/370/332 +f 322/367/326 337/382/347 338/383/335 +f 323/368/328 338/383/335 339/384/337 +f 324/369/330 339/384/337 340/385/339 +f 325/370/332 340/385/339 341/386/341 +f 319/364/320 334/379/342 335/380/344 +f 320/365/322 335/380/344 336/381/346 +f 321/366/324 336/381/346 337/382/347 +f 334/379/342 349/394/349 350/395/352 +f 335/380/344 350/395/352 351/396/354 +f 336/381/346 351/396/354 352/397/356 +f 337/382/347 352/397/356 353/398/358 +f 338/383/335 353/398/358 354/399/360 +f 339/384/337 354/399/360 355/400/362 +f 340/385/339 355/400/362 356/401/351 +f 352/397/356 367/423/377 368/425/363 +f 353/398/358 368/425/363 369/427/366 +f 354/399/360 369/427/366 370/429/368 +f 355/400/362 370/429/368 371/431/370 +f 349/394/349 364/417/371 365/419/373 +f 350/395/352 365/419/373 366/421/375 +f 351/396/354 366/421/375 367/423/377 +f 357/403/372 372/432/392 373/433/381 +f 358/405/374 373/433/381 374/434/383 +f 359/407/376 374/434/383 375/435/385 +f 360/409/364 375/435/385 376/436/387 +f 361/411/365 376/436/387 377/437/389 +f 362/413/367 377/437/389 378/438/391 +f 363/415/369 378/438/391 379/439/379 +f 376/436/387 391/451/407 392/452/395 +f 377/437/389 392/452/395 393/453/397 +f 378/438/391 393/453/397 394/454/399 +f 372/432/392 387/447/400 388/448/402 +f 373/433/381 388/448/402 389/449/404 +f 374/434/383 389/449/404 390/450/406 +f 375/435/385 390/450/406 391/451/407 +f 387/447/400 402/462/422 403/463/408 +f 388/448/402 403/463/408 404/464/411 +f 389/449/404 404/464/411 405/465/413 +f 390/450/406 405/465/413 406/466/415 +f 391/451/407 406/466/415 407/467/417 +f 392/452/395 407/467/417 408/468/419 +f 393/453/397 408/468/419 409/469/421 +f 406/466/415 421/481/437 422/482/423 +f 407/467/417 422/482/423 423/483/426 +f 408/468/419 423/483/426 424/484/428 +f 402/462/422 417/477/429 418/478/431 +f 403/463/408 418/478/431 419/479/433 +f 404/464/411 419/479/433 420/480/435 +f 405/465/413 420/480/435 421/481/437 +f 418/478/431 433/493/452 434/494/440 +f 419/479/433 434/494/440 435/495/442 +f 420/480/435 435/495/442 436/496/444 +f 421/481/437 436/496/444 437/497/446 +f 422/482/423 437/497/446 438/498/448 +f 423/483/426 438/498/448 439/499/450 +f 417/477/429 432/492/451 433/493/452 +f 437/497/446 452/512/467 453/513/455 +f 438/498/448 453/513/455 454/514/457 +f 432/492/451 447/507/458 448/508/460 +f 433/493/452 448/508/460 449/509/462 +f 434/494/440 449/509/462 450/510/464 +f 435/495/442 450/510/464 451/511/466 +f 436/496/444 451/511/466 452/512/467 +f 448/508/460 463/523/482 464/524/468 +f 449/509/462 464/524/468 465/525/471 +f 450/510/464 465/525/471 466/526/473 +f 451/511/466 466/526/473 467/527/475 +f 452/512/467 467/527/475 468/528/477 +f 453/513/455 468/528/477 469/529/479 +f 447/507/458 462/522/480 463/523/482 +f 467/527/475 3/3/32 4/4/4 +f 468/528/477 4/4/4 5/5/9 +f 462/522/480 477/537/11 478/538/17 +f 463/523/482 478/538/17 1/1/21 +f 464/524/468 1/1/21 2/2/25 +f 465/525/471 2/2/25 479/539/29 +f 466/526/473 479/539/29 3/3/32 diff --git a/data/games/garage/mods/testnodes/models/testnodes_ocorner.obj b/data/games/garage/mods/testnodes/models/testnodes_ocorner.obj new file mode 100644 index 0000000..231d705 --- /dev/null +++ b/data/games/garage/mods/testnodes/models/testnodes_ocorner.obj @@ -0,0 +1,23 @@ +# Blender v2.73 (sub 0) OBJ File: 'slope_test_ocorner_onetexture.blend' +# www.blender.org +o Cube_Cube.002 +v 0.500000 0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vn 0.000000 -1.000000 -0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 -0.000000 1.000000 +vn -0.707100 0.707100 0.000000 +vn 0.000000 0.707100 -0.707100 +s off +f 3/1/1 2/2/1 4/3/1 5/4/1 +f 1/2/2 3/3/2 5/4/2 +f 1/1/3 2/3/3 3/4/3 +f 1/1/4 4/3/4 2/4/4 +f 1/2/5 5/3/5 4/4/5 diff --git a/data/games/garage/mods/testnodes/models/testnodes_pyramid.obj b/data/games/garage/mods/testnodes/models/testnodes_pyramid.obj new file mode 100644 index 0000000..b305af2 --- /dev/null +++ b/data/games/garage/mods/testnodes/models/testnodes_pyramid.obj @@ -0,0 +1,24 @@ +# Blender v2.73 (sub 0) OBJ File: 'slope_test_pyramid_onetexture.blend' +# www.blender.org +o Cube +v 0.500000 -0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.000000 0.500000 -0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 1.000000 +vn 0.000000 -1.000000 0.000000 +vn -0.894400 0.447200 -0.000000 +vn 0.000000 0.447200 -0.894400 +vn 0.894400 0.447200 0.000000 +vn -0.000000 0.447200 0.894400 +s off +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 3/4/2 5/5/2 4/3/2 +f 5/5/3 1/3/3 4/4/3 +f 1/4/4 5/5/4 2/3/4 +f 2/4/5 5/5/5 3/3/5 diff --git a/data/games/garage/mods/testnodes/nodeboxes.lua b/data/games/garage/mods/testnodes/nodeboxes.lua new file mode 100644 index 0000000..0025ee0 --- /dev/null +++ b/data/games/garage/mods/testnodes/nodeboxes.lua @@ -0,0 +1,242 @@ +local S = core.get_translator("testnodes") + +-- Nodebox examples and tests. + +-- An simple example nodebox with one centered box +core.register_node("testnodes:nodebox_fixed", { + description = S("Fixed Nodebox Test Node").."\n".. + S("Nodebox is always the same"), + tiles = {"testnodes_nodebox.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, + }, + + groups = {dig_immediate=3}, +}) + +-- 50% higher than a regular node +core.register_node("testnodes:nodebox_overhigh", { + description = S("+50% high Nodebox Test Node"), + tiles = {"testnodes_nodebox.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 1, 0.5}, + }, + + groups = {dig_immediate=3}, +}) + +-- 95% higher than a regular node +core.register_node("testnodes:nodebox_overhigh2", { + description = S("+95% high Nodebox Test Node"), + tiles = {"testnodes_nodebox.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + -- Y max: more is possible, but glitchy + fixed = {-0.5, -0.5, -0.5, 0.5, 1.45, 0.5}, + }, + + groups = {dig_immediate=3}, +}) + +-- Height of nodebox changes with its param2 value +core.register_node("testnodes:nodebox_leveled", { + description = S("Leveled Nodebox Test Node").."\n".. + S("param2 = height (0..127)"), + tiles = {"testnodes_nodebox.png^[colorize:#0F0:32"}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "leveled", + node_box = { + type = "leveled", + fixed = {-0.5, 0.0, -0.5, 0.5, -0.499, 0.5}, + }, + + groups = {dig_immediate=3}, +}) + + +local nodebox_wall = { + type = "connected", + fixed = {-0.125, -0.500, -0.125, 0.125, 0.500, 0.125}, + connect_front = {-0.125, -0.500, -0.500, 0.125, 0.400, -0.125}, + connect_back = {-0.125, -0.500, 0.125, 0.125, 0.400, 0.500}, + connect_left = {-0.500, -0.500, -0.125, -0.125, 0.400, 0.125}, + connect_right = {0.125, -0.500, -0.125, 0.500, 0.400, 0.125}, +} + +local nodebox_cable = { + type = "connected", + fixed = {-2/16, -2/16, -2/16, 2/16, 2/16, 2/16}, + connect_front = {-1/16, -1/16, -8/16, 1/16, 1/16, -2/16}, + connect_back = {-1/16, -1/16, 2/16, 1/16, 1/16, 8/16}, + connect_left = {-8/16, -1/16, -1/16, -2/16, 1/16, 1/16}, + connect_right = { 2/16, -1/16, -1/16, 8/16, 1/16, 1/16}, + connect_bottom = {-1/16, -8/16, -1/16, 1/16, -2/16, 1/16}, + connect_top = {-1/16, 2/16, -1/16, 1/16, 8/16, 1/16}, +} + +local nodebox_wall_thick = { + type = "connected", + fixed = {-0.25, -0.500, -0.25, 0.25, 0.500, 0.25}, + connect_front = {-0.25, -0.500, -0.500, 0.25, 0.400, -0.25}, + connect_back = {-0.25, -0.500, 0.25, 0.25, 0.400, 0.500}, + connect_left = {-0.500, -0.500, -0.25, -0.25, 0.400, 0.25}, + connect_right = {0.25, -0.500, -0.25, 0.500, 0.400, 0.25}, +} + +-- Wall-like nodebox that connects to 4 neighbors +core.register_node("testnodes:nodebox_connected", { + description = S("Connected Nodebox Test Node (4 Side Wall)").."\n".. + S("Connects to 4 neighbors sideways"), + tiles = {"testnodes_nodebox.png^[colorize:#F00:32"}, + groups = {connected_nodebox=1, dig_immediate=3}, + drawtype = "nodebox", + paramtype = "light", + connects_to = {"group:connected_nodebox"}, + connect_sides = {"front", "back", "left", "right"}, + node_box = nodebox_wall, +}) + +-- Cable-like nodebox that connects to 6 neighbors +core.register_node("testnodes:nodebox_connected_6side", { + description = S("Connected Nodebox Test Node (6 Side Cable)").."\n".. + S("Connects to 6 neighbors"), + tiles = {"testnodes_nodebox.png^[colorize:#F00:32"}, + groups = {connected_nodebox=1, dig_immediate=3}, + drawtype = "nodebox", + paramtype = "light", + connects_to = {"group:connected_nodebox"}, + connect_sides = {"front", "back", "left", "right", "top", "bottom"}, + node_box = nodebox_cable, +}) + +-- More walls +core.register_node("testnodes:nodebox_connected_facedir", { + description = S("Facedir Connected Nodebox Test Node (4 Side Wall)").."\n".. + S("Connects to neighbors").."\n".. + S("param2 = facedir rotation of textures (not of the nodebox!)"), + tiles = { + "testnodes_1.png", + "testnodes_2.png", + "testnodes_3.png", + "testnodes_4.png", + "testnodes_5.png", + "testnodes_6.png", + }, + groups = {connected_nodebox=1, dig_immediate=3}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + connects_to = {"group:connected_nodebox"}, + connect_sides = {"front", "back", "left", "right"}, + node_box = nodebox_wall_thick, +}) + +core.register_node("testnodes:nodebox_connected_4dir", { + description = S("4Dir Connected Nodebox Test Node").."\n".. + S("Connects to neighbors").."\n".. + S("param2 = 4dir rotation of textures (not of the nodebox!)"), + tiles = { + "testnodes_1f.png", + "testnodes_2f.png", + "testnodes_3f.png", + "testnodes_4f.png", + "testnodes_5f.png", + "testnodes_6f.png", + }, + groups = {connected_nodebox=1, dig_immediate=3}, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "4dir", + connects_to = {"group:connected_nodebox"}, + connect_sides = {"front", "back", "left", "right"}, + node_box = nodebox_wall_thick, +}) + +-- Doesn't connect, but lets other nodes connect +core.register_node("testnodes:facedir_to_connect_to", { + description = S("Facedir Node that connected Nodeboxes connect to").."\n".. + S("Neighbors connect only to left (blue 4) and top (yellow 1) face").."\n".. + S("(Currently broken for param2 >= 4, see FIXME in nodedef.cpp)").."\n".. + S("param2 = facedir"), + tiles = { + "testnodes_1.png", + "testnodes_2.png", + "testnodes_3.png", + "testnodes_4.png", + "testnodes_5.png", + "testnodes_6.png", + }, + groups = {connected_nodebox=1, dig_immediate=3}, + drawtype = "normal", + paramtype2 = "facedir", + connect_sides = {"left", "top"}, +}) + +-- 3D sign and button: +-- These are example nodes for more realistic example uses +-- of wallmounted_rotate_vertical +core.register_node("testnodes:sign3d", { + description = S("Nodebox Sign, Nodebox Type \"fixed\""), + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "wallmounted", + wallmounted_rotate_vertical = true, + sunlight_propagates = true, + walkable = false, + tiles = { + "testnodes_sign3d.png", + }, + groups = { dig_immediate = 3 }, + node_box = { + type = "fixed", + fixed = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, + }, +}) + +core.register_node("testnodes:sign3d_wallmounted", { + description = S("Nodebox Sign, Nodebox Type \"wallmounted\""), + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "wallmounted", + wallmounted_rotate_vertical = true, + sunlight_propagates = true, + walkable = false, + tiles = { + "testnodes_sign3d.png^[colorize:#ff0000:127", + }, + groups = { dig_immediate = 3 }, + node_box = { + type = "wallmounted", + wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}, + wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, + wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}, + }, +}) + +core.register_node("testnodes:button", { + description = S("Button Nodebox Test Node"), + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "wallmounted", + wallmounted_rotate_vertical = true, + sunlight_propagates = true, + walkable = false, + tiles = { + "testnodes_nodebox.png", + }, + groups = { dig_immediate = 3 }, + node_box = { + type = "fixed", + fixed = { -4/16, -8/16, -2/16, 4/16, -6/16, 2/16 }, + }, +}) + diff --git a/data/games/garage/mods/testnodes/overlays.lua b/data/games/garage/mods/testnodes/overlays.lua new file mode 100644 index 0000000..7f7a1cd --- /dev/null +++ b/data/games/garage/mods/testnodes/overlays.lua @@ -0,0 +1,93 @@ +local S = core.get_translator("testnodes") + +core.register_node("testnodes:overlay", { + description = S("Texture Overlay Test Node") .. "\n" .. + S("Uncolorized"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:overlay_color_all", { + description = S("Texture Overlay Test Node, Colorized") .. "\n" .. + S("param2 changes color"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:overlay_color_overlay", { + description = S("Texture Overlay Test Node, Colorized Overlay") .. "\n" .. + S("param2 changes color of overlay"), + tiles = {{name = "testnodes_overlayable.png", color="white"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:overlay_color_overlayed", { + description = S("Texture Overlay Test Node, Colorized Base") .. "\n" .. + S("param2 changes color of base texture"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png", color="white"}}, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) + +local global_overlay_color = "#FF2000" +core.register_node("testnodes:overlay_global", { + description = S("Texture Overlay Test Node, Global Color") .. "\n" .. + S("Global color = @1", global_overlay_color), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + color = global_overlay_color, + + + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:overlay_global_color_all", { + description = S("Texture Overlay Test Node, Global Color + Colorized") .. "\n" .. + S("Global color = @1", global_overlay_color) .. "\n" .. + S("param2 changes color"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + color = global_overlay_color, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:overlay_global_color_overlay", { + description = S("Texture Overlay Test Node, Global Color + Colorized Overlay") .. "\n" .. + S("Global color = @1", global_overlay_color) .. "\n" .. + S("param2 changes color of overlay"), + tiles = {{name = "testnodes_overlayable.png", color=global_overlay_color}}, + overlay_tiles = {{name = "testnodes_overlay.png"}}, + color = global_overlay_color, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:overlay_global_color_overlayed", { + description = S("Texture Overlay Test Node, Global Color + Colorized Base") .. "\n" .. + S("Global color = @1", global_overlay_color) .. "\n" .. + S("param2 changes color of base texture"), + tiles = {{name = "testnodes_overlayable.png"}}, + overlay_tiles = {{name = "testnodes_overlay.png", color=global_overlay_color}}, + color = global_overlay_color, + paramtype2 = "color", + palette = "testnodes_palette_full.png", + + + groups = { dig_immediate = 2 }, +}) diff --git a/data/games/garage/mods/testnodes/param2.lua b/data/games/garage/mods/testnodes/param2.lua new file mode 100644 index 0000000..aec1fd4 --- /dev/null +++ b/data/games/garage/mods/testnodes/param2.lua @@ -0,0 +1,321 @@ +-- This file is for misc. param2 tests that aren't covered in drawtypes.lua already. + +local S = core.get_translator("testnodes") + +core.register_node("testnodes:facedir", { + description = S("Facedir Test Node").."\n".. + S("param2 = facedir rotation (0..23)"), + paramtype2 = "facedir", + tiles = { + "testnodes_1.png", + "testnodes_2.png", + "testnodes_3.png", + "testnodes_4.png", + "testnodes_5.png", + "testnodes_6.png", + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:4dir", { + description = S("4dir Test Node").."\n".. + S("param2 = 4dir rotation (0..3)"), + paramtype2 = "4dir", + tiles = { + "testnodes_1f.png", + "testnodes_2f.png", + "testnodes_3f.png", + "testnodes_4f.png", + "testnodes_5f.png", + "testnodes_6f.png", + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:facedir_nodebox", { + description = S("Facedir Nodebox Test Node").."\n".. + S("param2 = facedir rotation (0..23)"), + tiles = { + "testnodes_1.png", + "testnodes_2.png", + "testnodes_3.png", + "testnodes_4.png", + "testnodes_5.png", + "testnodes_6.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2}, + }, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:4dir_nodebox", { + description = S("4dir Nodebox Test Node").."\n".. + S("param2 = 4dir rotation (0..3)"), + tiles = { + "testnodes_1f.png", + "testnodes_2f.png", + "testnodes_3f.png", + "testnodes_4f.png", + "testnodes_5f.png", + "testnodes_6f.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "4dir", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2}, + }, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:4dir_nodebox_stair", { + description = S("4dir Nodebox Stair Test Node").."\n".. + S("param2 = 4dir rotation (0..3)"), + tiles = { + "testnodes_1f.png", + "testnodes_2f.png", + "testnodes_3f.png", + "testnodes_4f.png", + "testnodes_5f.png", + "testnodes_6f.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "4dir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5}, + }, + }, + + groups = { dig_immediate = 3 }, +}) + + +core.register_node("testnodes:wallmounted", { + description = S("Wallmounted Test Node").."\n".. + S("param2 = wallmounted rotation (0..7)"), + paramtype2 = "wallmounted", + tiles = { + "testnodes_1w.png", + "testnodes_2w.png", + "testnodes_3w.png", + "testnodes_4w.png", + "testnodes_5w.png", + "testnodes_6w.png", + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:wallmounted_rot", { + description = S("Wallmounted Rotatable Test Node"), + paramtype2 = "wallmounted", + wallmounted_rotate_vertical = true, + tiles = { + "testnodes_1w.png^[colorize:#FFFF00:40", + "testnodes_2w.png^[colorize:#FFFF00:40", + "testnodes_3w.png^[colorize:#FFFF00:40", + "testnodes_4w.png^[colorize:#FFFF00:40", + "testnodes_5w.png^[colorize:#FFFF00:40", + "testnodes_6w.png^[colorize:#FFFF00:40", + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:wallmounted_nodebox", { + description = S("Wallmounted Nodebox Test Node").."\n".. + S("param2 = wallmounted rotation (0..7)"), + paramtype2 = "wallmounted", + paramtype = "light", + tiles = { + "testnodes_1w.png", + "testnodes_2w.png", + "testnodes_3w.png", + "testnodes_4w.png", + "testnodes_5w.png", + "testnodes_6w.png", + }, + drawtype = "nodebox", + node_box = { + type = "wallmounted", + wall_top = { -0.5, 0, -0.5, 0.5, 0.5, 0.5 }, + wall_bottom = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 }, + wall_side = { -0.5, -0.5, -0.5, 0, 0.5, 0.5 }, + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:wallmounted_nodebox_rot", { + description = S("Wallmounted Rotatable Nodebox Test Node"), + paramtype2 = "wallmounted", + wallmounted_rotate_vertical = true, + paramtype = "light", + tiles = { + "testnodes_1w.png^[colorize:#FFFF00:40", + "testnodes_2w.png^[colorize:#FFFF00:40", + "testnodes_3w.png^[colorize:#FFFF00:40", + "testnodes_4w.png^[colorize:#FFFF00:40", + "testnodes_5w.png^[colorize:#FFFF00:40", + "testnodes_6w.png^[colorize:#FFFF00:40", + }, + drawtype = "nodebox", + node_box = { + type = "wallmounted", + wall_top = { -0.5, 0, -0.5, 0.5, 0.5, 0.5 }, + wall_bottom = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 }, + wall_side = { -0.5, -0.5, -0.5, 0, 0.5, 0.5 }, + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:color", { + description = S("Color Test Node").."\n".. + S("param2 = color (0..255)"), + paramtype2 = "color", + palette = "testnodes_palette_full.png", + tiles = { + "testnodes_node.png", + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:colorfacedir", { + description = S("Color Facedir Test Node").."\n".. + S("param2 = color + facedir rotation (0..23, 32..55, ...)"), + paramtype2 = "colorfacedir", + palette = "testnodes_palette_facedir.png", + tiles = { + "testnodes_1g.png", + "testnodes_2g.png", + "testnodes_3g.png", + "testnodes_4g.png", + "testnodes_5g.png", + "testnodes_6g.png", + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:colorfacedir_nodebox", { + description = S("Color Facedir Nodebox Test Node").."\n".. + S("param2 = color + facedir rotation (0..23, 32..55, ...)"), + tiles = { + "testnodes_1g.png", + "testnodes_2g.png", + "testnodes_3g.png", + "testnodes_4g.png", + "testnodes_5g.png", + "testnodes_6g.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "colorfacedir", + palette = "testnodes_palette_facedir.png", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2}, + }, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:color4dir", { + description = S("Color 4dir Test Node").."\n".. + S("param2 = color + 4dir rotation (0..255)"), + paramtype2 = "color4dir", + palette = "testnodes_palette_4dir.png", + tiles = { + "testnodes_1fg.png", + "testnodes_2fg.png", + "testnodes_3fg.png", + "testnodes_4fg.png", + "testnodes_5fg.png", + "testnodes_6fg.png", + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:color4dir_nodebox", { + description = S("Color 4dir Nodebox Test Node").."\n".. + S("param2 = color + 4dir rotation (0..255)"), + tiles = { + "testnodes_1fg.png", + "testnodes_2fg.png", + "testnodes_3fg.png", + "testnodes_4fg.png", + "testnodes_5fg.png", + "testnodes_6fg.png", + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "color4dir", + palette = "testnodes_palette_4dir.png", + node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.2, 0.2, 0.2}, + }, + + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:colorwallmounted", { + description = S("Color Wallmounted Test Node").."\n".. + S("param2 = color + wallmounted rotation (0..7, 8..15, ...)"), + paramtype2 = "colorwallmounted", + paramtype = "light", + palette = "testnodes_palette_wallmounted.png", + tiles = { + "testnodes_1wg.png", + "testnodes_2wg.png", + "testnodes_3wg.png", + "testnodes_4wg.png", + "testnodes_5wg.png", + "testnodes_6wg.png", + }, + + groups = { dig_immediate = 3 }, +}) + +core.register_node("testnodes:colorwallmounted_nodebox", { + description = S("Color Wallmounted Nodebox Test Node").."\n".. + S("param2 = color + wallmounted rotation (0..7, 8..15, ...)"), + paramtype2 = "colorwallmounted", + paramtype = "light", + palette = "testnodes_palette_wallmounted.png", + tiles = { + "testnodes_1wg.png", + "testnodes_2wg.png", + "testnodes_3wg.png", + "testnodes_4wg.png", + "testnodes_5wg.png", + "testnodes_6wg.png", + }, + drawtype = "nodebox", + node_box = { + type = "wallmounted", + wall_top = { -0.5, 0, -0.5, 0.5, 0.5, 0.5 }, + wall_bottom = { -0.5, -0.5, -0.5, 0.5, 0, 0.5 }, + wall_side = { -0.5, -0.5, -0.5, 0, 0.5, 0.5 }, + }, + + groups = { dig_immediate = 3 }, +}) + diff --git a/data/games/garage/mods/testnodes/performance_test_nodes.lua b/data/games/garage/mods/testnodes/performance_test_nodes.lua new file mode 100644 index 0000000..fc22db3 --- /dev/null +++ b/data/games/garage/mods/testnodes/performance_test_nodes.lua @@ -0,0 +1,59 @@ +-- Performance test mesh nodes + +local S = core.get_translator("testnodes") + +-- Complex mesh +core.register_node("testnodes:performance_mesh_clip", { + description = S("Performance Test Node") .. "\n" .. S("Marble with 'clip' transparency"), + drawtype = "mesh", + mesh = "testnodes_marble_glass.obj", + tiles = {"testnodes_marble_glass.png"}, + paramtype = "light", + use_texture_alpha = "clip", + + groups = {dig_immediate=3}, +}) + +-- Complex mesh, alpha blending +core.register_node("testnodes:performance_mesh_blend", { + description = S("Performance Test Node") .. "\n" .. S("Marble with 'blend' transparency"), + drawtype = "mesh", + mesh = "testnodes_marble_glass.obj", + tiles = {"testnodes_marble_glass.png"}, + paramtype = "light", + use_texture_alpha = "blend", + + groups = {dig_immediate=3}, +}) + +-- Overlay +core.register_node("testnodes:performance_overlay_clip", { + description = S("Performance Test Node") .. "\n" .. S("Marble with overlay with 'clip' transparency") .. "\n" .. S("Palette for demonstration"), + drawtype = "mesh", + mesh = "testnodes_marble_metal.obj", + tiles = {"testnodes_marble_metal.png"}, + overlay_tiles = {{name = "testnodes_marble_metal_overlay.png", color = "white"}}, + paramtype = "light", + paramtype2 = "color", + palette = "testnodes_palette_metal.png", + color = "#705216"; + use_texture_alpha = "clip", + + groups = {dig_immediate=3}, +}) + +-- Overlay +core.register_node("testnodes:performance_overlay_blend", { + description = S("Performance Test Node") .. "\n" .. S("Marble with overlay with 'blend' transparency") .. "\n" .. S("Palette for demonstration"), + drawtype = "mesh", + mesh = "testnodes_marble_metal.obj", + tiles = {"testnodes_marble_metal.png"}, + overlay_tiles = {{name = "testnodes_marble_metal_overlay.png", color = "white"}}, + paramtype = "light", + paramtype2 = "color", + palette = "testnodes_palette_metal.png", + color = "#705216"; + use_texture_alpha = "blend", + + groups = {dig_immediate=3}, +}) diff --git a/data/games/garage/mods/testnodes/properties.lua b/data/games/garage/mods/testnodes/properties.lua new file mode 100644 index 0000000..29dc14a --- /dev/null +++ b/data/games/garage/mods/testnodes/properties.lua @@ -0,0 +1,685 @@ +-- Test Nodes: Node property tests + +local S = core.get_translator("testnodes") + +-- Is supposed to fall when it doesn't rest on solid ground +core.register_node("testnodes:falling", { + description = S("Falling Node").."\n".. + S("Falls down if no node below"), + tiles = { + "testnodes_node.png", + "testnodes_node.png", + "testnodes_node_falling.png", + }, + groups = { falling_node = 1, dig_immediate = 3 }, +}) + +core.register_node("testnodes:falling_facedir", { + description = S("Falling Facedir Node").."\n".. + S("Falls down if no node below").."\n".. + S("param2 = facedir rotation"), + tiles = { + "testnodes_node_falling_1.png", + "testnodes_node_falling_2.png", + "testnodes_node_falling_3.png", + "testnodes_node_falling_4.png", + "testnodes_node_falling_5.png", + "testnodes_node_falling_6.png", + }, + paramtype2 = "facedir", + groups = { falling_node = 1, dig_immediate = 3 }, +}) + +-- Same as falling node, but will stop falling on top of liquids +core.register_node("testnodes:falling_float", { + description = S("Falling+Floating Node").."\n".. + S("Falls down if no node below, floats on liquids (liquidtype ~= \"none\")"), + groups = { falling_node = 1, float = 1, dig_immediate = 3 }, + + + tiles = { + "testnodes_node.png", + "testnodes_node.png", + "testnodes_node_falling.png", + }, + color = "cyan", +}) + +-- This node attaches to the floor and drops as item +-- when the floor is gone. +core.register_node("testnodes:attached", { + description = S("Floor-Attached Node").."\n".. + S("Drops as item if no solid node below"), + tiles = { + "testnodes_attached_top.png", + "testnodes_attached_bottom.png", + "testnodes_attached_side.png", + }, + groups = { attached_node = 1, dig_immediate = 3 }, +}) +-- This node attaches to the side of a node and drops as item +-- when the node it attaches to is gone. +core.register_node("testnodes:attached_wallmounted", { + description = S("Wallmounted Attached Node").."\n".. + S("Attaches to solid node it was placed on; drops as item if neighbor node is gone").."\n".. + S("param2 = wallmounted rotation (0..7)"), + paramtype2 = "wallmounted", + tiles = { + "testnodes_attachedw_top.png", + "testnodes_attachedw_bottom.png", + "testnodes_attachedw_side.png", + }, + groups = { attached_node = 1, dig_immediate = 3 }, +}) + +-- This node attaches to the side of a node and drops as item +-- when the node it attaches to is gone. +-- Also adds vertical 90° rotation variants. +core.register_node("testnodes:attached_wallmounted_rot", { + description = S("Rotatable Wallmounted Attached Node").."\n".. + S("Attaches to solid node it was placed on; drops as item if neighbor node is gone").."\n".. + S("param2 = wallmounted rotation (0..7)").."\n".. + S("May be rotated by 90° if placed at floor or ceiling"), + paramtype2 = "wallmounted", + tiles = { + "testnodes_attachedwr_top.png", + "testnodes_attachedwr_bottom.png", + "testnodes_attachedwr_side.png", + }, + wallmounted_rotate_vertical = true, + groups = { attached_node = 1, dig_immediate = 3 }, +}) + +-- Wallmounted node that always attaches to the floor +core.register_node("testnodes:attached_wallmounted_floor", { + description = S("Floor-Attached Wallmounted Node").."\n".. + S("Drops as item if no solid node below (regardless of rotation)").."\n".. + S("param2 = wallmounted rotation (visual only) (0..7)"), + paramtype2 = "wallmounted", + tiles = { + "testnodes_attached_top.png", + "testnodes_attached_bottom.png", + "testnodes_attached_side.png", + }, + groups = { attached_node = 3, dig_immediate = 3 }, + color = "#FF8080", +}) + +-- Wallmounted node that always attaches to the floor. +-- Also adds 90° rotation variants. +core.register_node("testnodes:attached_wallmounted_floor_rot", { + description = S("Rotatable Floor-Attached Wallmounted Node").."\n".. + S("Drops as item if no solid node below (regardless of rotation)").."\n".. + S("param2 = wallmounted rotation (visual only) (0..7)").."\n".. + S("May be rotated by 90° if placed at floor or ceiling"), + paramtype2 = "wallmounted", + tiles = { + "testnodes_attachedfr_top.png", + "testnodes_attachedfr_bottom.png", + "testnodes_attachedfr_side.png", + }, + wallmounted_rotate_vertical = true, + groups = { attached_node = 3, dig_immediate = 3 }, +}) + +-- This node attaches to the ceiling and drops as item +-- when the ceiling is gone. +core.register_node("testnodes:attached_top", { + description = S("Ceiling-Attached Node").."\n".. + S("Drops as item if no solid node above"), + tiles = { + "testnodes_attached_bottom.png", + "testnodes_attached_top.png", + "testnodes_attached_side.png^[transformR180", + }, + groups = { attached_node = 4, dig_immediate = 3 }, +}) + +-- Same as wallmounted attached, but for facedir +core.register_node("testnodes:attached_facedir", { + description = S("Facedir Attached Node").."\n".. + S("Attaches to a neighboring solid node; drops as item if that node is gone").."\n".. + S("param2 = facedir rotation (0..23)"), + paramtype2 = "facedir", + tiles = { + "testnodes_attachedf_side.png^[transformR180", + "testnodes_attachedf_side.png", + "testnodes_attachedf_side.png^[transformR90", + "testnodes_attachedf_side.png^[transformR270", + "testnodes_attachedf_bottom.png", + "testnodes_attachedf_top.png", + }, + groups = { attached_node = 2, dig_immediate = 3 }, +}) + +-- Same as facedir attached, but for 4dir +core.register_node("testnodes:attached_4dir", { + description = S("4dir Attached Node").."\n".. + S("Attaches to the side of a solid node; drops as item if that node is gone").."\n".. + S("param2 = 4dir rotation (0..3)"), + paramtype2 = "4dir", + tiles = { + "testnodes_attached4_side.png^[transformR180", + "testnodes_attached4_side.png", + "testnodes_attached4_side.png^[transformR90", + "testnodes_attached4_side.png^[transformR270", + "testnodes_attached4_bottom.png", + "testnodes_attached4_top.png", + }, + groups = { attached_node = 2, dig_immediate = 3 }, +}) + +-- Jump disabled +core.register_node("testnodes:nojump", { + description = S("Non-jumping Node").."\n".. + S("You can't jump on it"), + groups = {disable_jump=1, dig_immediate=3}, + tiles = {"testnodes_nojump_top.png", "testnodes_nojump_side.png"}, +}) + +-- Jump disabled plant +core.register_node("testnodes:nojump_walkable", { + description = S("Non-jumping Plant Node").."\n".. + S("You can't jump while your feet are in it"), + drawtype = "plantlike", + groups = {disable_jump=1, dig_immediate=3}, + walkable = false, + tiles = {"testnodes_nojump_top.png"}, +}) + +local climbable_nodebox = { + type = "regular", +} + +-- Climbable up and down with jump and sneak keys +core.register_node("testnodes:climbable", { + description = S("Climbable Node").."\n".. + S("You can climb up and down"), + climbable = true, + walkable = false, + + + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + tiles = {"testnodes_climbable_top.png","testnodes_climbable_top.png","testnodes_climbable_side.png"}, + use_texture_alpha = "clip", + drawtype = "nodebox", + node_box = climbable_nodebox, + groups = {dig_immediate=3}, +}) + +-- Climbable only downwards with sneak key +core.register_node("testnodes:climbable_nojump", { + description = S("Downwards-climbable Node").."\n".. + S("You can climb only downwards"), + climbable = true, + walkable = false, + + groups = {disable_jump=1, dig_immediate=3}, + drawtype = "nodebox", + node_box = climbable_nodebox, + tiles = {"testnodes_climbable_nojump_top.png","testnodes_climbable_nojump_top.png","testnodes_climbable_nojump_side.png"}, + use_texture_alpha = "clip", + paramtype = "light", + sunlight_propagates = true, +}) + + +core.register_node("testnodes:climbable_nodescend", { + description = S("Upwards-climbable Node"), + climbable = true, + walkable = false, + + groups = {disable_descend=1, dig_immediate=3}, + drawtype = "nodebox", + node_box = climbable_nodebox, + tiles = {"testnodes_climbable_nodescend_top.png","testnodes_climbable_nodescend_top.png","testnodes_climbable_nodescend_side.png"}, + use_texture_alpha = "clip", + paramtype = "light", + sunlight_propagates = true, +}) + +core.register_node("testnodes:climbable_nodescend_nojump", { + description = S("Horizontal-only Climbable Node"), + climbable = true, + walkable = false, + + groups = {disable_jump=1, disable_descend=1, dig_immediate=3}, + drawtype = "nodebox", + node_box = climbable_nodebox, + tiles = {"testnodes_climbable_noclimb_top.png","testnodes_climbable_noclimb_top.png","testnodes_climbable_noclimb_side.png"}, + use_texture_alpha = "clip", + paramtype = "light", + sunlight_propagates = true, +}) + +-- A liquid in which you can't rise +core.register_node("testnodes:liquid_nojump", { + description = S("Non-jumping Liquid Source Node").."\n".. + S("Swimmable liquid, but you can't swim upwards"), + liquidtype = "source", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_nojump", + liquid_alternative_source = "testnodes:liquid_nojump", + liquid_renewable = false, + groups = {disable_jump=1, dig_immediate=3}, + walkable = false, + + drawtype = "liquid", + tiles = {"testnodes_liquidsource.png^[colorize:#FF0000:127"}, + special_tiles = { + {name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = false}, + {name = "testnodes_liquidsource.png^[colorize:#FF0000:127", backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + pointable = false, + liquids_pointable = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 0, b = 200}, +}) + +-- A liquid in which you can't rise (flowing variant) +core.register_node("testnodes:liquidflowing_nojump", { + description = S("Non-jumping Flowing Liquid Node").."\n".. + S("Swimmable liquid, but you can't swim upwards"), + liquidtype = "flowing", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_nojump", + liquid_alternative_source = "testnodes:liquid_nojump", + liquid_renewable = false, + groups = {disable_jump=1, dig_immediate=3}, + walkable = false, + + + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing.png^[colorize:#FF0000:127"}, + special_tiles = { + {name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false}, + {name = "testnodes_liquidflowing.png^[colorize:#FF0000:127", backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + pointable = false, + liquids_pointable = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 0, b = 200}, +}) + +-- A liquid which doesn't have liquid movement physics (source variant) +core.register_node("testnodes:liquid_noswim", { + description = S("No-swim Liquid Source Node").."\n".. + S("Liquid node, but swimming is disabled"), + liquidtype = "source", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_noswim", + liquid_alternative_source = "testnodes:liquid_noswim", + liquid_renewable = false, + liquid_move_physics = false, + groups = {dig_immediate=3}, + walkable = false, + + drawtype = "liquid", + tiles = {"testnodes_liquidsource.png^[colorize:#FF00FF:127"}, + special_tiles = { + {name = "testnodes_liquidsource.png^[colorize:#FF00FF:127", backface_culling = false}, + {name = "testnodes_liquidsource.png^[colorize:#FF00FF:127", backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + pointable = false, + liquids_pointable = true, + buildable_to = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 200, b = 200}, +}) + +-- A liquid which doen't have liquid movement physics (flowing variant) +core.register_node("testnodes:liquidflowing_noswim", { + description = S("No-swim Flowing Liquid Node").."\n".. + S("Liquid node, but swimming is disabled"), + liquidtype = "flowing", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_noswim", + liquid_alternative_source = "testnodes:liquid_noswim", + liquid_renewable = false, + liquid_move_physics = false, + groups = {dig_immediate=3}, + walkable = false, + + + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing.png^[colorize:#FF00FF:127"}, + special_tiles = { + {name = "testnodes_liquidflowing.png^[colorize:#FF00FF:127", backface_culling = false}, + {name = "testnodes_liquidflowing.png^[colorize:#FF00FF:127", backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + pointable = false, + liquids_pointable = true, + buildable_to = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 200, b = 200}, +}) + +-- A liquid in which you can't actively descend. +-- Note: You'll still descend slowly by doing nothing. +core.register_node("testnodes:liquid_nodescend", { + description = S("No-descending Liquid Source Node"), + liquidtype = "source", + liquid_range = 0, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_nodescend", + liquid_alternative_source = "testnodes:liquid_nodescend", + liquid_renewable = false, + groups = {disable_descend=1, dig_immediate=3}, + walkable = false, + + drawtype = "liquid", + tiles = {"testnodes_liquidsource.png^[colorize:#FFFF00:127"}, + special_tiles = { + {name = "testnodes_liquidsource.png^[colorize:#FFFF00:127", backface_culling = false}, + {name = "testnodes_liquidsource.png^[colorize:#FFFF00:127", backface_culling = true}, + }, + use_texture_alpha = "blend", + paramtype = "light", + pointable = false, + liquids_pointable = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 255, b = 200}, +}) + +-- A liquid in which you can't actively descend (flowing variant) +core.register_node("testnodes:liquidflowing_nodescend", { + description = S("No-descending Flowing Liquid Node"), + liquidtype = "flowing", + liquid_range = 1, + liquid_viscosity = 0, + liquid_alternative_flowing = "testnodes:liquidflowing_nodescend", + liquid_alternative_source = "testnodes:liquid_nodescend", + liquid_renewable = false, + groups = {disable_descend=1, dig_immediate=3}, + walkable = false, + + + drawtype = "flowingliquid", + tiles = {"testnodes_liquidflowing.png^[colorize:#FFFF00:127"}, + special_tiles = { + {name = "testnodes_liquidflowing.png^[colorize:#FFFF00:127", backface_culling = false}, + {name = "testnodes_liquidflowing.png^[colorize:#FFFF00:127", backface_culling = false}, + }, + use_texture_alpha = "blend", + paramtype = "light", + paramtype2 = "flowingliquid", + pointable = false, + liquids_pointable = true, + is_ground_content = false, + post_effect_color = {a = 70, r = 255, g = 255, b = 200}, +}) + +-- Nodes that modify fall damage (various damage modifiers) +for i=-100, 100, 25 do + if i ~= 0 then + local subname, descnum + if i < 0 then + subname = "NEG"..string.format("%03d", math.abs(i)) + descnum = tostring(i) + else + subname = string.format("%03d", i) + descnum = S("+@1", i) + end + local tex, color, desc + if i > 0 then + local val = math.floor((i/100)*255) + tex = "testnodes_fall_damage_plus.png" + color = { b=0, g=255-val, r=255, a=255 } + desc = S("Fall Damage Node (+@1%)", i) + else + tex = "testnodes_fall_damage_minus.png" + if i == -100 then + color = { r=0, b=0, g=255, a=255 } + else + local val = math.floor((math.abs(i)/100)*255) + color = { r=0, b=255, g=255-val, a=255 } + end + desc = S("Fall Damage Node (-@1%)", math.abs(i)) + end + core.register_node("testnodes:damage"..subname, { + description = desc, + groups = {fall_damage_add_percent=i, dig_immediate=3}, + + + tiles = { tex }, + is_ground_content = false, + color = color, + }) + end +end + +-- Bouncy nodes (various bounce levels) +local MAX_BOUNCE_JUMPY = 180 +local MAX_BOUNCE_NONJUMPY = 140 +for i=-MAX_BOUNCE_NONJUMPY, MAX_BOUNCE_JUMPY, 20 do + if i ~= 0 then + local desc + local val = math.floor((math.abs(i) - 20) / 200 * 255) + local val2 = math.max(0, 255 - val) + local num = string.format("%03d", math.abs(i)) + if i > 0 then + desc = S("Bouncy Node (@1%), jumpy", i).."\n".. + S("Sneaking/jumping affects bounce") + color = { r=val2, g=val2, b=255, a=255 } + else + desc = S("Bouncy Node (@1%), non-jumpy", math.abs(i)).."\n".. + S("Sneaking/jumping does not affect bounce") + color = { r=val2, g=255, b=val2, a=255 } + num = "NEG"..num + end + core.register_node("testnodes:bouncy"..num, { + description = desc, + groups = {bouncy=i, dig_immediate=3}, + + + color = color, + tiles ={"testnodes_bouncy.png"}, + is_ground_content = false, + }) + end +end + +-- Slippery nodes (various slippery levels) +for i=1, 5 do + core.register_node("testnodes:slippery"..i, { + description = S("Slippery Node (@1)", i), + tiles ={"testnodes_slippery.png"}, + is_ground_content = false, + groups = {slippery=i, dig_immediate=3}, + color = { r=0, g=255, b=math.floor((i/5)*255), a=255 }, + }) +end + +-- Move resistance nodes (various resistance levels) +for r=0, 7 do + if r > 0 then + core.register_node("testnodes:move_resistance"..r, { + description = S("Move-resistant Node (@1)", r).."\n".. + S("Reduces movement speed"), + walkable = false, + move_resistance = r, + + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_move_resistance.png" }, + is_ground_content = false, + groups = { dig_immediate = 3 }, + color = { b = 0, g = 255, r = math.floor((r/7)*255), a = 255 }, + }) + end + + local mdesc, mcolor + if r == 0 then + mdesc = S("Liquidlike Movement Node").."\n".. + S("Swimmable (no move resistance)") + mcolor = { b = 255, g = 255, r = 128 } + else + mdesc = S("Move-resistant Node (@1), liquidlike", r).."\n".. + S("Reduces movement speed; swimmable") + mcolor = { b = 255, g = 0, r = math.floor((r/7)*255), a = 255 } + end + + + core.register_node("testnodes:move_resistance_liquidlike"..r, { + description = mdesc, + walkable = false, + move_resistance = r, + liquid_move_physics = true, + + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_move_resistance.png" }, + is_ground_content = false, + groups = { dig_immediate = 3 }, + color = mcolor, + }) +end + +core.register_node("testnodes:climbable_move_resistance_4", { + description = S("Climbable Move-resistant Node (4)").."\n".. + S("You can climb up and down; reduced movement speed"), + walkable = false, + climbable = true, + move_resistance = 4, + + drawtype = "nodebox", + paramtype = "light", + sunlight_propagates = true, + tiles = {"testnodes_climbable_top.png","testnodes_climbable_top.png","testnodes_climbable_resistance_side.png"}, + use_texture_alpha = "clip", + is_ground_content = false, + groups = { dig_immediate = 3 }, +}) + +-- By placing something on the node, the node itself will be replaced +core.register_node("testnodes:buildable_to", { + description = S("\"buildable_to\" Node").."\n".. + S("Placing a node on it will replace it"), + buildable_to = true, + tiles = {"testnodes_buildable_to.png"}, + is_ground_content = false, + groups = {dig_immediate=3}, +}) + +-- Nodes that deal damage to players that are inside them. +-- Negative damage nodes should heal. +for d=-3,3 do + if d ~= 0 then + local sub, tile, desc + if d > 0 then + sub = tostring(d) + tile = "testnodes_damage.png" + desc = S("Damage Node (@1 damage per second)", d) + else + sub = "m" .. tostring(math.abs(d)) + tile = "testnodes_damage_neg.png" + desc = S("Healing Node (@1 HP per second)", math.abs(d)) + end + if math.abs(d) == 2 then + tile = tile .. "^[colorize:#000000:70" + elseif math.abs(d) == 3 then + tile = tile .. "^[colorize:#000000:140" + end + core.register_node("testnodes:damage_"..sub, { + description = desc, + damage_per_second = d, + + + walkable = false, + is_ground_content = false, + drawtype = "allfaces", + paramtype = "light", + sunlight_propagates = true, + tiles = { tile }, + groups = {dig_immediate=3}, + }) + end +end + +-- Causes drowning damage +core.register_node("testnodes:drowning_1", { + description = S("Drowning Node (@1 damage)", 1).."\n".. + S("You'll drown inside it"), + drowning = 1, + + + walkable = false, + is_ground_content = false, + drawtype = "allfaces", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_drowning.png" }, + groups = {dig_immediate=3}, +}) + +-- post_effect_color_shaded + +core.register_node("testnodes:post_effect_color_shaded_false", { + description = S("\"post_effect_color_shaded = false\" Node"), + + drawtype = "allfaces", + tiles = {"testnodes_post_effect_color_shaded_false.png"}, + use_texture_alpha = "blend", + paramtype = "light", + sunlight_propagates = true, + post_effect_color = {a = 128, r = 255, g = 255, b = 255}, + post_effect_color_shaded = false, + + walkable = false, + is_ground_content = false, + groups = {dig_immediate=3}, +}) + +core.register_node("testnodes:post_effect_color_shaded_true", { + description = S("\"post_effect_color_shaded = true\" Node"), + + drawtype = "allfaces", + tiles = {"testnodes_post_effect_color_shaded_true.png"}, + use_texture_alpha = "blend", + paramtype = "light", + sunlight_propagates = true, + post_effect_color = {a = 128, r = 255, g = 255, b = 255}, + post_effect_color_shaded = true, + + walkable = false, + is_ground_content = false, + groups = {dig_immediate=3}, +}) + +-- Pointability + +-- Register wrapper for compactness +local function register_pointable_test_node(name, description, pointable) + local texture = "testnodes_"..name..".png" + core.register_node("testnodes:"..name, { + description = S(description), + tiles = {texture}, + drawtype = "glasslike_framed", + paramtype = "light", + walkable = false, + pointable = pointable, + groups = {dig_immediate=3, [name.."_test"]=1}, + }) +end + +register_pointable_test_node("pointable", "Pointable Node", true) +register_pointable_test_node("not_pointable", "Not Pointable Node", false) +register_pointable_test_node("blocking_pointable", "Blocking Pointable Node", "blocking") diff --git a/data/games/garage/mods/testnodes/textures.lua b/data/games/garage/mods/testnodes/textures.lua new file mode 100644 index 0000000..0d41947 --- /dev/null +++ b/data/games/garage/mods/testnodes/textures.lua @@ -0,0 +1,369 @@ +-- Node texture tests + +local S = core.get_translator("testnodes") + +core.register_node("testnodes:6sides", { + description = S("Six Textures Test Node").."\n".. + S("Has 1 texture per face"), + tiles = { + "testnodes_normal1.png", + "testnodes_normal2.png", + "testnodes_normal3.png", + "testnodes_normal4.png", + "testnodes_normal5.png", + "testnodes_normal6.png", + }, + + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:anim", { + description = S("Animated Test Node").."\n".. + S("Tiles animate from A to D in 4s cycle"), + tiles = { + { name = "testnodes_anim.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 4.0, + }, }, + }, + + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:fill_positioning", { + description = S("Fill Modifier Test Node") .. "\n" .. + S("The node should have the same look as " .. + "testnodes:fill_positioning_reference."), + drawtype = "glasslike", + paramtype = "light", + tiles = {"[fill:16x16:#ffffff^[fill:6x6:1,1:#00ffdc" .. + "^[fill:6x6:1,9:#00ffdc^[fill:6x6:9,1:#00ffdc^[fill:6x6:9,9:#00ffdc"}, + groups = {dig_immediate = 3}, +}) + +core.register_node("testnodes:fill_positioning_reference", { + description = S("Fill Modifier Test Node Reference"), + drawtype = "glasslike", + paramtype = "light", + tiles = {"testnodes_fill_positioning_reference.png"}, + groups = {dig_immediate = 3}, +}) + +core.register_node("testnodes:modifier_mask", { + description = S("[mask Modifier Test Node"), + tiles = {"testnodes_128x128_rgb.png^[mask:testnodes_mask_WRGBKW.png"}, + groups = {dig_immediate = 3}, +}) + +-- Node texture transparency test + +local alphas = { 64, 128, 191 } + +for a=1,#alphas do + local alpha = alphas[a] + + -- Transparency taken from texture + core.register_node("testnodes:alpha_texture_"..alpha, { + description = S("Texture Alpha Test Node (@1)", alpha).."\n".. + S("Semi-transparent"), + drawtype = "glasslike", + paramtype = "light", + tiles = { + "testnodes_alpha"..alpha..".png", + }, + use_texture_alpha = "blend", + + groups = { dig_immediate = 3 }, + }) + + -- Transparency set via texture modifier + core.register_node("testnodes:alpha_"..alpha, { + description = S("Alpha Test Node (@1)", alpha).."\n".. + S("Semi-transparent"), + drawtype = "glasslike", + paramtype = "light", + tiles = { + "testnodes_alpha.png^[opacity:" .. alpha, + }, + use_texture_alpha = "blend", + + groups = { dig_immediate = 3 }, + }) +end + +core.register_node("testnodes:alpha_compositing", { + description = S("Texture Overlay Test Node") .. "\n" .. + S("A regular grid should be visible where each cell contains two " .. + "texels with the same color.") .. "\n" .. + S("Texture overlay is gamma-incorrect, " .. + "and in general it does not do alpha compositing, " .. + "both for backwards compatibility."), + drawtype = "glasslike", + paramtype = "light", + tiles = {"testnodes_alpha_compositing_bottom.png^" .. + "testnodes_alpha_compositing_top.png"}, + use_texture_alpha = "blend", + groups = {dig_immediate = 3}, +}) + +-- Generate PNG textures + +local function mandelbrot(w, h, iterations) + local r = {} + for y=0, h-1 do + for x=0, w-1 do + local re = (x - w/2) * 4/w + local im = (y - h/2) * 4/h + -- zoom in on a nice view + re = re / 128 - 0.23 + im = im / 128 - 0.82 + + local px, py = 0, 0 + local i = 0 + while px*px + py*py <= 4 and i < iterations do + px, py = px*px - py*py + re, 2 * px * py + im + i = i + 1 + end + r[w*y+x+1] = i / iterations + end + end + return r +end + +local function gen_checkers(w, h, tile) + local r = {} + for y=0, h-1 do + for x=0, w-1 do + local hori = math.floor(x / tile) % 2 == 0 + local vert = math.floor(y / tile) % 2 == 0 + r[w*y+x+1] = hori ~= vert and 1 or 0 + end + end + return r +end + +-- The engine should perform color reduction of the generated PNG in certain +-- cases, so we have this helper to check the result +local function encode_and_check(w, h, ctype, data) + local ret = core.encode_png(w, h, data) + assert(ret:sub(1, 8) == "\137PNG\r\n\026\n", "missing png signature") + assert(ret:sub(9, 16) == "\000\000\000\rIHDR", "didn't find ihdr chunk") + local ctype_actual = ret:byte(26) -- Color Type (1 byte) + ctype = ({rgba=6, rgb=2, gray=0})[ctype] + assert(ctype_actual == ctype, "png should have color type " .. ctype .. + " but actually has " .. ctype_actual) + return ret +end + +local fractal = mandelbrot(512, 512, 128) +local frac_emb = mandelbrot(64, 64, 64) +local checker = gen_checkers(512, 512, 32) + +local floor = math.floor +local abs = math.abs +local data_emb = {} +local data_mb = {} +local data_ck = {} +for i=1, #frac_emb do + data_emb[i] = { + r = floor(abs(frac_emb[i] * 2 - 1) * 255), + g = floor(abs(1 - frac_emb[i]) * 255), + b = floor(frac_emb[i] * 255), + a = frac_emb[i] < 0.95 and 255 or 0, + } +end +for i=1, #fractal do + data_mb[i] = { + r = floor(fractal[i] * 255), + g = floor(abs(fractal[i] * 2 - 1) * 255), + b = floor(abs(1 - fractal[i]) * 255), + a = 255, + } + data_ck[i] = checker[i] > 0 and "#888" or "#000" +end + +fractal = nil +frac_emb = nil +checker = nil + +local textures_path = core.get_worldpath() .. "/" +core.safe_file_write( + textures_path .. "testnodes1.png", + encode_and_check(512, 512, "rgb", data_mb) +) +local png_ck = encode_and_check(512, 512, "gray", data_ck) +core.dynamic_add_media({ + filename = "testnodes_generated_mb.png", + filepath = textures_path .. "testnodes1.png" +}) +core.dynamic_add_media({ + filename = "testnodes_generated_ck.png", + filedata = png_ck, +}) + +core.register_node("testnodes:generated_png_mb", { + description = S("Generated Mandelbrot PNG Test Node"), + tiles = { "testnodes_generated_mb.png" }, + + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:generated_png_ck", { + description = S("Generated Checker PNG Test Node"), + tiles = { "testnodes_generated_ck.png" }, + + groups = { dig_immediate = 2 }, +}) + +local png_emb = "[png:" .. core.encode_base64( + encode_and_check(64, 64, "rgba", data_emb)) + +core.register_node("testnodes:generated_png_emb", { + description = S("Generated In-Band Mandelbrot PNG Test Node"), + tiles = { png_emb }, + + drawtype = "allfaces", -- required because of transparent pixels + use_texture_alpha = "clip", + paramtype = "light", + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:generated_png_src_emb", { + description = S("Generated In-Band Source Blit Mandelbrot PNG Test Node"), + tiles = { png_emb .. "^testnodes_damage_neg.png" }, + + drawtype = "allfaces", -- required because of transparent pixels + use_texture_alpha = "clip", + paramtype = "light", + groups = { dig_immediate = 2 }, +}) +core.register_node("testnodes:generated_png_dst_emb", { + description = S("Generated In-Band Dest Blit Mandelbrot PNG Test Node"), + tiles = { "testnodes_generated_ck.png^" .. png_emb }, + + groups = { dig_immediate = 2 }, +}) + +png_ck = nil +png_emb = nil +data_emb = nil +data_mb = nil +data_ck = nil + +--[[ + +The following nodes can be used to demonstrate the TGA format support. + +Luanti supports TGA types 1, 2, 3 & 10. While adding the support for +TGA type 9 (RLE-compressed, color-mapped) is easy, it is not advisable +to do so, as it is not backwards compatible with any engine version pre-5.5; +content creators should therefore either use TGA type 1 or 10, or PNG. + +TODO: Types 1, 2 & 10 should have two test nodes each (i.e. bottom-top +and top-bottom) for 16bpp (A1R5G5B5), 24bpp (B8G8R8), 32bpp (B8G8R8A8) +colors. + +Note: Luanti requires the optional TGA footer for a texture to load. +If a TGA image does not load in Luanti, append eight (8) null bytes, +then the string “TRUEVISION-XFILE.”, then another null byte. + +]]-- + +core.register_node("testnodes:tga_type1_24bpp_bt", { + description = S("TGA Type 1 (color-mapped RGB) 24bpp bottom-top Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type1_24bpp_bt.tga" }, + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type1_24bpp_tb", { + description = S("TGA Type 1 (color-mapped RGB) 24bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type1_24bpp_tb.tga" }, + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type2_16bpp_bt", { + description = S("TGA Type 2 (uncompressed RGB) 16bpp bottom-top Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type2_16bpp_bt.tga" }, + use_texture_alpha = "clip", + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type2_16bpp_tb", { + description = S("TGA Type 2 (uncompressed RGB) 16bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type2_16bpp_tb.tga" }, + use_texture_alpha = "clip", + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type2_32bpp_bt", { + description = S("TGA Type 2 (uncompressed RGB) 32bpp bottom-top Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type2_32bpp_bt.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type2_32bpp_tb", { + description = S("TGA Type 2 (uncompressed RGB) 32bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type2_32bpp_tb.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type3_16bpp_bt", { + description = S("TGA Type 3 (uncompressed grayscale) 16bpp bottom-top Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type3_16bpp_bt.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type3_16bpp_tb", { + description = S("TGA Type 3 (uncompressed grayscale) 16bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type3_16bpp_tb.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type10_32bpp_bt", { + description = S("TGA Type 10 (RLE-compressed RGB) 32bpp bottom-top Test Node"), + tiles = { "testnodes_tga_type10_32bpp_bt.tga" }, + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) + +core.register_node("testnodes:tga_type10_32bpp_tb", { + description = S("TGA Type 10 (RLE-compressed RGB) 32bpp top-bottom Test Node"), + drawtype = "glasslike", + paramtype = "light", + sunlight_propagates = true, + tiles = { "testnodes_tga_type10_32bpp_tb.tga" }, + use_texture_alpha = "blend", + groups = { dig_immediate = 2 }, +}) diff --git a/data/games/garage/mods/testnodes/textures/testnodes_1.png b/data/games/garage/mods/testnodes/textures/testnodes_1.png new file mode 100644 index 0000000000000000000000000000000000000000..6730997e2db9623daa1bb458e2b2a7e9156a8093 GIT binary patch literal 107 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;TYyi9>;Dfx76a#Wr#K*`;OXKR zQo)$)(7@()tcqf?4)78&qol`;+04y{Z AZ2$lO literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_128x128_rgb.png b/data/games/garage/mods/testnodes/textures/testnodes_128x128_rgb.png new file mode 100644 index 0000000000000000000000000000000000000000..060d8e67afc011f33683d706c56a1f13466ca67d GIT binary patch literal 1870 zcmV-U2eJ5xP)p|yj{wfht=m6#=n24OG&2Gu z{D4#yo0%0zL%%vz#e?s=%fB6ijN{c{oBh(OEdpjH25Rq?pZ9=wr>P{=#Kz>#4u>+rNp?IiGhZW{%8b@CI(btN)XVO7)a4CR)Tg+|b_AW(kwZDCSTe!~;LFRJiJ~vSn&oIqQ#;rt&0ri@;5F{Ou zNcHFgsUu;zRF%$}Fr8H}PC%wh8)783pzM5Y9Pday0%}uLoW>?XKwhefH^Pn^5V9sh zK#CY>HbI6jIvN>3&$eekiv!ww{mJozHdzRo z2LYIAGesm10ht2aRco`+;!&HbE{$}tIlcq5fZLgKd}*-3V=iREE z(Su*asK4VYBZgrdKx4gLjfOD>0jSoxN2J~e(CGC;iJ>0?NVDUQBZeCYh)?4_T)i9a zlLDNbm>BLM0Ml2+{IU9~Zeln*fXt%LoN3$^zyV#=vEwJ4c9tozaW~BA$oo8~X?xa8 z+&+h(%%acKG;YF+dW<2VIH{dsMzgw(;^KCsBWYp~CSjV6Y%9W%C=?{qP*x?roH>cj zg}!wZD!gXAwY)^V~=Xy|Pxtd3%n3_`6y9l6(-mO%os<$`* zm)%ZPp$-Ad>!mb|Vg%4~c2Qy|K)?$3Er=l(0n4=;5kndQ%j=sGL+m|Zh5HV~@Ock7 z%W!1RwV0fAbriWQBWZEEn7!O2Qu^u60^GIt(vITdHusBc_Fo&h$|B&Stg$jyP`bi% zMP^XaO5O@HNpB-idZ*Tz40+}#rxa>?c-ZFWgZXM-!;TmV* zfB@zVKN}$|f9&S<253+BHw648Mh5WJzRuvmMt&Z;BjEZNmbXefe&B`IN5Ii+=zU~a zb+`{#H3SiGgu*hZa9@moMGUgxKCH&Y5wM6sFx-djT{v0LUPQ5*MW1z&mUwlkTt{Wq zv;_$8pg?j(pICKOyt))6!abH&)4nUG%d!zEv*`1Vq*YX1dS{Y%c1L7VWwl)CZ4CmF zscL4?XO3~VGUXi^`Hsj-G2>;m!P47$1gun5q@Z>~KydL(7g|b_xQWOH@CDAEgj}v( z)0>y-vP(#j(RGQhG_CFkqXnrXRh=t2Pg{a5bzbmKs~0dH$}kA#L#J`b`JzhMGVx*@%tlS24W!WJQkf1pqLnF*h*FX z5fBu&uM&4s7fYVGqR&f53DqobWz#=xAi0y#=_aEPz(u6UglSWLHnBp|zi^*a&610! zdYW@`C!@cwk43<^h(uaei42Kx7!u|%y&p|%$xPz+wfU3zEI1}rO-|;HYk!_*r)b?u zs{{ePQdNBm1b-0FVRxH?n@FUpp0G@+9KV$ut&$i>^P2ot^8=93Fto24nhyaNVxSove|iM$Z_(y3)8D3c2r6Cu zG;=qiG=*2o#*w*IdNo!#1XOQ} zlYf)+?&e!WvQ_n(cj=V5ReUwpi4ah*vAmgQd%*1h1ougg?4?f3J~jDrTj>@#HHQr` zvo_OD!nclBga=x3`!8tY3LOa!*B!)7%PRd$oy8FlFS48CIEvem`p%rv&*Zrq z0_Hnxmk{*&h;dv6C-F13Bf^~OaIY#=ZA!uu4}G^(wOt7Mwxdz1+Jb}$zVv9v0W0PV zBL=De6Mn?dw;%?Qr3#*V2oS>!1keK=U!E9h5wM0{h8TYS2THf<#Ze@*iU0rr07*qo IM6N<$f(DOnVE_OC literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_1f.png b/data/games/garage/mods/testnodes/textures/testnodes_1f.png new file mode 100644 index 0000000000000000000000000000000000000000..f9a1b69e42cf8596aa29d9b41d4dbfd359248ca9 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|37#&FAr*|t3`}W@7(>4PfB)4* zX+hEoHZwD`2^ad=)^Mz2SjgyWx-3mZ`ofaJ$c~ka3#BwX9GI6ydv0iq;4LsYVWQx~ zX`HgrT_!8aA>+V2lLf~PGq?!o?(p=hQBlul=+4`CweW8Id7xbkp00i_>zopr0J8cp ASO5S3 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_1fg.png b/data/games/garage/mods/testnodes/textures/testnodes_1fg.png new file mode 100644 index 0000000000000000000000000000000000000000..5d0beb032789800b428fc97c7da56392f187e611 GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|#-1*YAr*|t3haASr4&paTxSb+ zXylzC^usivOXymIfYQyjhYJ|}xfZxxa_~+QQRg*cU~utyCb?{5*)^bc22WQ%mvv4F FO#m+e9V`F< literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_1g.png b/data/games/garage/mods/testnodes/textures/testnodes_1g.png new file mode 100644 index 0000000000000000000000000000000000000000..529298ece1d50bbfab913ac99e6a68c388d8bc0a GIT binary patch literal 104 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|`kpS1Ar*|t72Zk`4!k@(JU5OO zu2gemcF}a?<+!S1o#~R5;J|vtLyE_RxhRK$LGwo;+lH)}tU#>{p00i_>zopr04(np A-v9sr literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_1w.png b/data/games/garage/mods/testnodes/textures/testnodes_1w.png new file mode 100644 index 0000000000000000000000000000000000000000..d24e571cc90265d6dd09a15d3e8cb20bde91745a GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|4xTQKAr*{g&oZ(da1e1mxbuHz zb@P3v4GF=z-xQg8cAg2|Tluw4{92jQp(T46wlLk}SSfZXv*`-=O2IXM)xT6TH^=AC Ud;iH)251(8r>mdKI;Vst0AkQ89{>OV literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_1wg.png b/data/games/garage/mods/testnodes/textures/testnodes_1wg.png new file mode 100644 index 0000000000000000000000000000000000000000..b2eba0e9a60e0337062d4896c2bb6b781523b258 GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|j-D=#Ar*{g&oZ(#Fo-li{Qs}K zHa+6VBKBymzY@&y#>y+>ul4_qieP=nHQ_W<`dS7X!5H-&@?1Mq)_65m-{-F6Psrb) Ux9;A$MxbE~p00i_>zopr0L0}c82|tP literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_2.png b/data/games/garage/mods/testnodes/textures/testnodes_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6c87c868df0db96160b5fadaef616a5db8ee3ff4 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|=AJH&Ar*|tKk_p@g`}jUBm@{{ z>nzJM(Myzmv4XK*o@2FJ$KxR1s11_@_<1B6qzunGm?#`)V{l&M^nr!Vs1;}ggQu&X J%Q~loCIDWb96$g7 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_2f.png b/data/games/garage/mods/testnodes/textures/testnodes_2f.png new file mode 100644 index 0000000000000000000000000000000000000000..a26f840e3e35cc9e8a0593a131a641e02502a9b6 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|A)YRdAr*|t3`}W@7(>4Pw=C{( zaX1>lo0F4Mam7(Y!6e}nBWt6IpY(+g<;|QK2c|6RWiy)Va^Z4I=wt3MCc$<&PJ@Q4 n{37bSKGF{!rQC8T`ozYtcwU`Zc=ha9p!p1*u6{1-oD!MW4D)mZzHj`$Wi3z} NgQu&X%Q~loCIED>A{_t# literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_2g.png b/data/games/garage/mods/testnodes/textures/testnodes_2g.png new file mode 100644 index 0000000000000000000000000000000000000000..cb9060f7b9f45b814a0f00b7eb13dfe95d897a09 GIT binary patch literal 110 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|rk*a2Ar*|t72Zk`Qc@BE46}8X zWtr$DO21ga*e}nq+O6YpkZ;t6Ndo*l5)D#@XB|uwjU5fdinu6;4R_>Z62$75x&TR6+&AGO)5?bEvRtG@AD$OK!Fl=H2>9x<5- h-ck_BY394q#(p%g-uj-Kg&xpg22WQ%mvv4FO#sisFH-;j literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_2wg.png b/data/games/garage/mods/testnodes/textures/testnodes_2wg.png new file mode 100644 index 0000000000000000000000000000000000000000..108dc87bb7e2a89f110ce607604b6e9b279d452a GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|ex5FlAr*{U`x)673%deiNt56bi%PMV)k jTfFU4yhDrlhKI~aQM;In-reN{n#|zo>gTe~DWM4fhUhQV literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_3.png b/data/games/garage/mods/testnodes/textures/testnodes_3.png new file mode 100644 index 0000000000000000000000000000000000000000..05b45629afb1547e6c062c465e3305f2385e7ae7 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;TYyi9>lw@cK<38E-E2Tg&eO#) zq=GTof$a=0j}9LXj{-}Iv!qUfnZT9*%t8!aS}gs?^abVtRWf+G`njxgN@xNA;o=qW literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_3f.png b/data/games/garage/mods/testnodes/textures/testnodes_3f.png new file mode 100644 index 0000000000000000000000000000000000000000..d007ee4457ab151a765be19ab6b251004af7c1f9 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|sh%#5Ar*{UCo!@e2;gx({^BqH zhSzJa-)PE{`UHx3v IIVCg!00fyj=l}o! literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_3fg.png b/data/games/garage/mods/testnodes/textures/testnodes_3fg.png new file mode 100644 index 0000000000000000000000000000000000000000..01e4276b1b0ebc1728a4dd1a4732d60b8bdbc25d GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;TYyi9E0BKs_N}4W%LpJ#-P6S} zq=GS-q3KsW&&T}|S+68keK)+)EHHsLHKh550;^z{gU|{whUq5+wx@>P_XTQU@O1Ta JS?83{1OU-nAAtY> literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_3g.png b/data/games/garage/mods/testnodes/textures/testnodes_3g.png new file mode 100644 index 0000000000000000000000000000000000000000..5c84f5882b9a185af33e59270ff59ae890f0bc39 GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|dY&$hAr*|t72Zk`Qc@BL4Exzy yvP{epr8CwrUgrN&F0@R^>KEg3Hnv5KmLTC literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_3w.png b/data/games/garage/mods/testnodes/textures/testnodes_3w.png new file mode 100644 index 0000000000000000000000000000000000000000..8b435cf013556c82faea0d69b3e3901ac7f71c47 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|uK)l42QtrC{y&3Z+LPAJTkW;$hf=yNmJgou(-K@Q>6IdCX8u+LGy&0hhRL$V&>gTe~ HDWM4fDn}p} literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_3wg.png b/data/games/garage/mods/testnodes/textures/testnodes_3wg.png new file mode 100644 index 0000000000000000000000000000000000000000..9ee9006674e2192e3826177046228cff06c41391 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|uK)l42QuHjefx^x=P4jd z$|Q-*^C$%p731FPw)7(8>o}P)78&qol`;+09&LQ Ac>n+a literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_4g.png b/data/games/garage/mods/testnodes/textures/testnodes_4g.png new file mode 100644 index 0000000000000000000000000000000000000000..8f144fae037ca63b99d934ff197e2f6d597a916b GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|YMw5RAr*|t72Zk`SEM8)6mnR~ qADAXET(Yq}WFpX)$+n2m5~%L}uR=Bt-=oby9SokXelF{r5}E*yViy4b literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_4w.png b/data/games/garage/mods/testnodes/textures/testnodes_4w.png new file mode 100644 index 0000000000000000000000000000000000000000..214e0df9d29100d0629b2e70e28fd4de773377e3 GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|uK)l42Qoc^|L^gcVh>~) zdAc};R4^tBJbCdVK_Db3C`o{IqlBZ5n?N_C4qJMug9MkJ!Zhv@2?8NOK}iCv8zmfd+yuHAb=cBN9VEE)6sB=^h%zN@Y>3b)xGBKk Xl);~0>@>L?sGGsl)z4*}Q$iB}R~;kl literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_5.png b/data/games/garage/mods/testnodes/textures/testnodes_5.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef1c728ca262766ed4d4e897dbcf3844e75246f GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|nw~C>Ar*|t2|wy*tC)zGEMQt> wqEP&DRb!ET!lHwV7)1lLmvyo|xxv7&f5%LxHIp~q1!`jOboFyt=akR{0CFN6$N&HU literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_5f.png b/data/games/garage/mods/testnodes/textures/testnodes_5f.png new file mode 100644 index 0000000000000000000000000000000000000000..a4162db571367f98346c0953c3070b6210d39102 GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|$(}BbAr*{kCpEGiFc5Hd-+BMt z-w*o|t&6p6v=$3CKh?eVOp7;q?!5E4yAJWXxY!DJ{<*`*8dlYDEqoHMCWF*1YlWAS zc~|XZF7RS&xXv#9q-jlkfZN(kA7zopr E0M98lwEzGB literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_5fg.png b/data/games/garage/mods/testnodes/textures/testnodes_5fg.png new file mode 100644 index 0000000000000000000000000000000000000000..f21acbb18f9fd4347155df54e197cc249146d498 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|CY~;iAr*|t3haASr4&pAuCRr+ zWir>D-q^9I@a5{pB>M!WT^S4R@J~_a^^tz?DCMRD8w10^oU>9|6(+NQ`WZZ3{an^L HB{Ts5f$JXR literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_5g.png b/data/games/garage/mods/testnodes/textures/testnodes_5g.png new file mode 100644 index 0000000000000000000000000000000000000000..30da4793a153a639f718467ac465032117c34f15 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|nw~C>Ar*|t72Zk`Oi~g7jDb=U vc9vXq*eP$o7;7@&Is2*PS&bPEeY^}icc#8dw%o-B)WqQF>gTe~DWM4f^PCxH literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_5w.png b/data/games/garage/mods/testnodes/textures/testnodes_5w.png new file mode 100644 index 0000000000000000000000000000000000000000..b4cb42426ab0ae0d26f35c3badefe4cac2cf8cf0 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|uK)l42QnG{-~Lk)UkqfZ zd%8G=R4^tBJbm#ZK_DO~sA+@5Lmjq|F!q*(0!&Gk2O@P6#GJ$!eBSXt+BTo%CrGoW LtDnm{r-UW|(r+RX literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_5wg.png b/data/games/garage/mods/testnodes/textures/testnodes_5wg.png new file mode 100644 index 0000000000000000000000000000000000000000..fac9db28edfbf19a5bc2b6fceb8128b23a283651 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|uK)l42QuHjefx^x=P4jd z-P6S}q=GS7;OUDO2?7B@K}{PZ9_p}#gt50Q6ktlSJP@gqAm${-;Pa0E(YE<4KY>~p NJYD@<);T3K0RSy_BWeHu literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_6.png b/data/games/garage/mods/testnodes/textures/testnodes_6.png new file mode 100644 index 0000000000000000000000000000000000000000..805813e57509bf2bb6f7b4cbef5bfa5267243580 GIT binary patch literal 100 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|+MX_sAr*|t9Df&i2}wywNdzzk xN{vW}QAUu=+(W?0x@=I3@@3Unm?Ig z>!e1u0}edSjlciDw>1cqg@y8H9FY`%rh~_ZQ!1i$}9;qZ`Z+pn_uQ|0!?7>boFyt I=akR{0Ivrg{Qv*} literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_6g.png b/data/games/garage/mods/testnodes/textures/testnodes_6g.png new file mode 100644 index 0000000000000000000000000000000000000000..a88f4c9f8f4df85700d11b8174e4e9e3427d4656 GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|nw~C>Ar*|t72Zk`Qc@BDjDb=Q va*|9ZyiwWpJMn?(0;a4ZCd?NbWTYAXoQygb$RYk4sENVT)z4*}Q$iB}8_XJd literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_6w.png b/data/games/garage/mods/testnodes/textures/testnodes_6w.png new file mode 100644 index 0000000000000000000000000000000000000000..e6bbf97d977a3fd3091bcdeb0dbd3af99752890b GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|uK)l42QovysOo>(`UA*P z_jGX#sbEYNc>3Z+fmdKI;Vst0N0ozUH||9 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_6wg.png b/data/games/garage/mods/testnodes/textures/testnodes_6wg.png new file mode 100644 index 0000000000000000000000000000000000000000..29ca933e0aa8bb5307d63c289aaaff44821a9794 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9oB=)|uK)l42QuHjefx^x=P4jd z-P6S}q=GS7;OUDO2?7B@K}{Q29_p}#gt50Q6ktlSJP@guAm${-5b{pI=<)l`J3uWA Mp00i_>zopr04&8LmH+?% literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_airlike.png b/data/games/garage/mods/testnodes/textures/testnodes_airlike.png new file mode 100644 index 0000000000000000000000000000000000000000..5a5664a2ae2458eaff7ff3038b0278cb3f637fb2 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^0wBx?BpA#)4xIr~OeH~n!3+##lh0ZJd7_>!jv*C{ m$q`$-8XG4rY;4ppG7({zpupNzTxdBNq|MXS&t;ucLK6UCCl(?A literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_allfaces.png b/data/games/garage/mods/testnodes/textures/testnodes_allfaces.png new file mode 100644 index 0000000000000000000000000000000000000000..c0a7dc550c077d44a79e87a1b5ef72c8e98d344f GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1XA9fE{-7; zj8iX#iaIEYuwJ}uFU7cmd4D;tmH&s{bd|lG>zAzKKX|vG&NNk`#4!{-APz?J^B*Jcu!Y9mvv4FO#sKbZR;5g!S sJEVG|u-h?-mwyG5{X?qvMtoqOr1$L}kA1*jflQDEp00i_>zopr04K05-v9sr literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_alpha.png b/data/games/garage/mods/testnodes/textures/testnodes_alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..157fa7386865f5ec8a4cc616809dea4085890a2d GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|>Ygr+Ar*|t2_3v_3z=7QD6R0? tk(Kn7L37fD6>KsYA#gQu&X%Q~loCIJ0)8S?-D literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_alpha128.png b/data/games/garage/mods/testnodes/textures/testnodes_alpha128.png new file mode 100644 index 0000000000000000000000000000000000000000..16babf6c774bd887c6004f23702490b4c9fdf5ea GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`{+=$5Ar*|t4?Gfn@E=mzE+OS{ z(4dy*#H^EsEsRGNu<+M2yYXK5!M}K+#N>VhhJ_4s+Y;Y=;xS-z5|q?CaK&Yh_kx+6 jciA4rFkJF3EMsGMIH}CY@wi(x&}arvS3j3^P6fIprkTdZZS7ly`GBXzEX6Sf!ocufyXKa$jl220%q;m?^+3?T(9qCuD^mME zP!6c`|Nkbd&>Wyb-jX1{UlFzk+?jy&z-Nqf#*ou zJ!T%=KmQl&==chX`)ypKV#H9A;V}30w)s;IFzPS#p0`lJA}m!oWJSAsfiKe$FUd;+ z6RjU|ZfCf2?O%6Y9p`<;ZO;G7SG*0l&3L=8lb5@Ym$iFhycfu=p00i_>zopr0BGY~ A7XSbN literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_alpha_compositing_top.png b/data/games/garage/mods/testnodes/textures/testnodes_alpha_compositing_top.png new file mode 100644 index 0000000000000000000000000000000000000000..64b5664d8df4f1599d23330c685f54e730bccf48 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`>7Fi*Ar-fhPfVKs^?%rsZ}o4Z zy|-mtzw;~KPXDvLfXSc#=ReGEzopr0KU98tN;K2 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_anim.png b/data/games/garage/mods/testnodes/textures/testnodes_anim.png new file mode 100644 index 0000000000000000000000000000000000000000..d321fe8577e40cd6fe6c66c8672b9322e3df4c61 GIT binary patch literal 274 zcmV+t0qy>YP)+JYz0h0I#$9p(nz_t<(DJwe7_2EI^)pTKk|4Nqw#uZf)|62tm& z$4@99&40n(L%OdZ@QqXmD5@G@Dui0<6?h%!Fg=J*&>fC1pp+nlpkIyn%NLA(`;fDw zk&wm_DZ`||Yo@wGSil$+uTb&+2aaS+rNC;hz-l4zSN}N(PPY%QTqKQzXEqLS9g`L| zvKDyPJq6TNkoF%*Kc%+kAUNGV%uA6p67cMAmx;`aX<>8MT?8Xqz}&jS@dfWWD7x*# Y7a!BrN=(AEk^lez07*qoM6N<$f;qi&^Z)<= literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attached4_bottom.png b/data/games/garage/mods/testnodes/textures/testnodes_attached4_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..b7a7a2fdb7a8cb829bd2bc0104fe02a79e6e013a GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|PM$7~Ar*|tFZS1;GSqFWn8bKU zY2K0pZB1W4e^k&hdvLwseA|+lu?1|5(gvm%&ag=+7~ W%cq?`#&-y48iS{+pUXO@geCxoRw$zY literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attached4_side.png b/data/games/garage/mods/testnodes/textures/testnodes_attached4_side.png new file mode 100644 index 0000000000000000000000000000000000000000..869e0736a8acfe2c5f9de049b6d62937bc885eee GIT binary patch literal 111 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|W}YsNAr*|t5ug6EdU7mTnDDno z>EeWo6HGR9pOdhWdeC9wKY4LthD*%#EeWo6HGR9pOdhWdeC9wAMAM8peu8d0E7Fv*9HGG)Kh@k7(8A5T-G@yGywqVd>$GA literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attached_bottom.png b/data/games/garage/mods/testnodes/textures/testnodes_attached_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..e01ae576f5df74b8c0ce885a63826e94fdda2839 GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|vYsxEAr*|tJMPzOoi%K$n8bKU jX`YOgSgTe~DWM4fDkK)i literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attached_side.png b/data/games/garage/mods/testnodes/textures/testnodes_attached_side.png new file mode 100644 index 0000000000000000000000000000000000000000..9459cbb0568dde882a4082a42a50eec9b7dc9c9a GIT binary patch literal 98 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|nw~C>Ar*|tKlVSd^yFBQSbNY$ wNzl}^CrjdL!T$dtvyyo}sxY^>+Hf+QdVcHB>1%Q;fSMRQUHx3vIVCg!0GAIPX#fBK literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attached_top.png b/data/games/garage/mods/testnodes/textures/testnodes_attached_top.png new file mode 100644 index 0000000000000000000000000000000000000000..0148b41e069734f5937e4976e2dd95f9b3c35e85 GIT binary patch literal 87 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|a-J@ZAr*|tKlVSd^yFBQSbNY$ k>7qln#8rb;jVde*Hi2(toTrIi2dZT7boFyt=akR{07OX^;s5{u literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedf_bottom.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedf_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..f9ffdfdcbb6298909c032a27759a2a0e65c03441 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|&YmugAsQ2tU+mw1$M9@>#iT}+ zs}7SIYoxiZnLl=n$T_f{aXzo7arc7`4e1G21+$qm>kgFg^X4d=j XtG97($C~9p;}|?${an^LB{Ts5iH0Ys literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedf_side.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedf_side.png new file mode 100644 index 0000000000000000000000000000000000000000..93c0e82a8f4330fb1b96b891775792742c5b01f7 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|=AJH&AsXkCBR>6S@a$mh;J#)q z+}YOCwq&Mjfy)}UNx2G_J-2L0>~M|w|MzKMrrnXrJSr>MCNV_y?B0BZ=i4rz5e%NL KelF{r5}E+H3?(uE literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedf_top.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedf_top.png new file mode 100644 index 0000000000000000000000000000000000000000..978ef614052e13d8392e5f876c7bb5f91ebfd15c GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|dY&$hAsQ2tBR>6S@a$mh;J#)q z+}YOCwq&Mjfy)}UNx2G_J-2L0+;Ehc*JMHq!}8B(S*3S{uLbI4@O1TaS?83{1OPJ| B9})ln literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedfr_bottom.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedfr_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..21ece33dcc09655cc25a2aa1e45c9092c2d01bec GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|hMq2tAr*|tJN9q4*S#~bViMya zrFlyZw0#Zc{-B^^_TajMzO-Ae#m;4-{EOR3aFXE)78&qol`;+ E0Isbc-~a#s literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedfr_side.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedfr_side.png new file mode 100644 index 0000000000000000000000000000000000000000..1e6a69640153ed229fb5b12e27c20a2a9fd62a93 GIT binary patch literal 103 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|dY&$hAr*|tKkAD)Jvo*n{=LGa zbg|=#!K#N(W`)^wFiF3A|JI+oTxDKL!-fuZM)$_cYs3pRt^##3c)I$ztaD0e0sv>| BAT0m@ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedfr_top.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedfr_top.png new file mode 100644 index 0000000000000000000000000000000000000000..feef552773cd227a81b08ebc10c44af4d8a9e49c GIT binary patch literal 93 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|DxNNmAr*|tKkAD)Jvo*n{=LGa rbg|=#!K#N(W`)^wobyxSWMtT&|8&iR<1c0d)iZdy`njxgN@xNABpV!i literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedw_bottom.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedw_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..488ad23a90e3675a73e6e95d7dfd9c3f0983b06d GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-u7~>XM>?j>ELh)~H1mH$ z?H-`Gp{I*uNCjiE01FeFxI)8*J7H_H60Hs&IB@#Gw=C11t-obkj;4J2c_!U}dm-OK c@iR;e3Nu8kFVdQ&MBb@0E7H1%m4rY literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedw_side.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedw_side.png new file mode 100644 index 0000000000000000000000000000000000000000..a02facbc721cdb6e041a4f5467c65febcf542683 GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|j-D=#Ar*|tJN7@Z_vBcTn0ByA z>7u}e3$sjw&$)>&iD7nlK^u%1; UqHsXH5NH^Kr>mdKI;Vst094B&Y_ z(0~8eukZQ!YltKnoE+08^xr3*WFSeklVcjAlVh5nU*)Dv?fUwj47h>3yuqeT?S6ih zj1&6rLs$GO{bD4kr`VL`na`AJpbEB#I_~{iy(A+!}VlERzwVz)l16}}8 zgJOfcyaB|#kDp%s{P`8a;O7&AXduCckDp$B{PYTo4H6Qna8r?u|M~MPKc5&i{2(Er z%D}(?4=6MS+y+EET)Mmqj|~s*pM{vq1h-31*X_amv$#lv%Sla3B&SvYNAMiA19jSy P00000NkvXXu0mjf6Fqk4 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedwr_side.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedwr_side.png new file mode 100644 index 0000000000000000000000000000000000000000..382e2dafa72bbea3478b4a8f6962d2fe7ad72917 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|C7v#hAsXkCW41l9XVz?JZESq_ zWhSr7Dl=2ggd_#Q3&Dqv`>!`xYRIa&p>e)HPtrXg_W@6xo#CY1hS%;#m}jX91W)XB z-`4&p;i!q|S!tag&7zkT#C#N){HnhGI(W4E_S2`l9g5G-_@);W`OLmhKfgkVVUKud Uu5O+4WuW~Gp00i_>zopr0Q>Skk^lez literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_attachedwr_top.png b/data/games/garage/mods/testnodes/textures/testnodes_attachedwr_top.png new file mode 100644 index 0000000000000000000000000000000000000000..39ea67b8b3fd32226a6e7d8381dc8ed8654e492a GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|37#&FAsXkCW41l9XVz?JZESq_ zWhSr7Dl=2ggd_#Q3&Dqv`>!`xYRIa&p>e)HPtrXg_W@6xo#CY1hS%;#m}jX91W)XB z-`4&p;i!q|S!tag&7zkT#C#OBj+-d2JSola&qQM<_ohZ=pj`}}u6{1-oD!M<+XOSD literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_blocking_pointable.png b/data/games/garage/mods/testnodes/textures/testnodes_blocking_pointable.png new file mode 100644 index 0000000000000000000000000000000000000000..fa021041a6fb026f97bdca163edc8f39b11eaaf7 GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-u0T36GBPc~;Q#;shUrFU zfPBW1AirP+hi5m^fE)`?7sn6|+2n+c|CJ9Y9Aa=`Q%58^j@*QkjzBAu66X12r@?mB;F#W4JqwGgXpk@Y7S3j3^P6GAr*|tKh8I_)EyA?`{=lm m@t~sH=Y%T;QvA)%%nUWs)dGIXKXw7tGI+ZBxvX%a=e!$%mpjD?rplw{yP_|#l%%{^nFJ_b)$KbLh*2~7Y4pdHZw literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_climbable_nodescend_side.png b/data/games/garage/mods/testnodes/textures/testnodes_climbable_nodescend_side.png new file mode 100644 index 0000000000000000000000000000000000000000..d1c472673833349efa74735f63d442a114e27fae GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Wu7jMAr_~TD^7m+Z_nXA%g7+% zu!CjHql8+X787UDMtDnm{r-UW|2N^sF literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_climbable_nodescend_top.png b/data/games/garage/mods/testnodes/textures/testnodes_climbable_nodescend_top.png new file mode 100644 index 0000000000000000000000000000000000000000..63da83fb1bfd57cfa0f26bbe45f421282f372e0f GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`I-V|$Ar`&K6(>LZx94DHWY&~e y*54>|_C(u+rGk?EQU+NE3Je<_opH%5V`G?n`;T~3j$kNIAA_f>pUXO@geCy~jvbi* literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_climbable_nojump_side.png b/data/games/garage/mods/testnodes/textures/testnodes_climbable_nojump_side.png new file mode 100644 index 0000000000000000000000000000000000000000..d5ca13033cce6774ec2ed2ad6ffe907d4b7489a0 GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`*`6+rAr*|tKh`h)Cf}m$D=Fb| zprAH^Ew0u6gY=<>cw?T&VTTJgIQ_BDJNtvD@dc|Oi>b0f8)HJ#9Rr6Q4He88Pn!O> zJen<}FW{rTrI67{SZ($K?g^sFmuBcGyr^fI$-Agyg5r-S8t2Y21e?DLyZ=*fJ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_climbable_resistance_side.png b/data/games/garage/mods/testnodes/textures/testnodes_climbable_resistance_side.png new file mode 100644 index 0000000000000000000000000000000000000000..860e998c14a2bebcf1f41573cf4b92836ff3da72 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`<(@8%Ar`&KKmIpAwC8Z2Wn?g+ zDe;#CN9Hkgelvz+j7|Rydh)pKoF(|eI{vpyHuyN3F1qkymSdG8OBeSAljIE-c@Df~ zN;<@Fm^DSBp@7kHBSSIcQ8ob|gC9>aA2X%+?zq7c%Mje-m%O84!e>sk)GlM;r8gxR Yrs@e~@}Gzo1v-Jj)78&qol`;+0M0`?_5c6? literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_climbable_side.png b/data/games/garage/mods/testnodes/textures/testnodes_climbable_side.png new file mode 100644 index 0000000000000000000000000000000000000000..c56ea90d7814c10508a6fbfef1ad5f3afd18df73 GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`v7RoDAr*|tKmIpAwC8Z2Wn?g+ z;o+|XJWgC6PYP~noxm;07uNCr_*zNFWGSYL+)5uZj-@P?WKcW7%iO}PVbD+{e&IIv yj2UKn4jG41CQq4Qkl`a9FmHMh(P7{ryYh1JYRV$P6d`(oZubP0l+XkKkKH6} literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_drowning.png b/data/games/garage/mods/testnodes/textures/testnodes_drowning.png new file mode 100644 index 0000000000000000000000000000000000000000..57ffc8fcf996e68f091dcc05e758e8eaaf2fa132 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;TYyi9E6b$kK<2#}-!y;}Q%R6t z@PCG<+YP*cJT*@j$B+ufzopr03jzKWB>pF literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_fall_damage_minus.png b/data/games/garage/mods/testnodes/textures/testnodes_fall_damage_minus.png new file mode 100644 index 0000000000000000000000000000000000000000..88d3bdf58598e14081f21d398ee50f0fefedb24f GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|)}AhoAr*|tD^vv=O#Zkt@klU4 ziY;uE*!*%O0u+RK+_VB;W QKyw&8UHx3vIVCg!0MyeZ82|tP literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_fencelike.png b/data/games/garage/mods/testnodes/textures/testnodes_fencelike.png new file mode 100644 index 0000000000000000000000000000000000000000..84dea1b7c2ee318672987049eec68475bfc42820 GIT binary patch literal 90 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|ik>cxAr*|t89viBxt=S{OIhKc npx^sMZJvykSgTe~DWM4feG?d* literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_fill_positioning_reference.png b/data/games/garage/mods/testnodes/textures/testnodes_fill_positioning_reference.png new file mode 100644 index 0000000000000000000000000000000000000000..2ecd969550500f8fefe0d0c394ccfbd4e92722d3 GIT binary patch literal 92 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;TYyi9>;M1%8UEk#Y~Ju0C?e?T o;uunKE198bmsJT1i^UN}>HXXnS&wE103{hbUHx3vIVCg!0KC{3c>n+a literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_firelike.png b/data/games/garage/mods/testnodes/textures/testnodes_firelike.png new file mode 100644 index 0000000000000000000000000000000000000000..ee59b0db1be0b51619ad304cb17f44e41e4af283 GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-uGi)>T(f1UP-3{2$1poW zp#&)I;_2cTQo)!kz{|^&@pF}Jz?*;Z3W5JcJy;qz v%@hn9->N%bWBWJVf$7NI^g4)z4*}Q$iB}oT@G$ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_glasslike.png b/data/games/garage/mods/testnodes/textures/testnodes_glasslike.png new file mode 100644 index 0000000000000000000000000000000000000000..cf3e35414dbcb42b1d0b52990f97d2fe095251b9 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X5a_E{-7; zjLARFANcU)fBhptW)5LqjjIg_$*Y_%Is}-W^pjGPa(mpU!oqMT`B3H+^_WK>-JY&~ JF6*2UngA0mAgTZW literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_glasslike_detail.png b/data/games/garage/mods/testnodes/textures/testnodes_glasslike_detail.png new file mode 100644 index 0000000000000000000000000000000000000000..30c9586e84022c1817fb88f90fafad462589a706 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`d7dtgAr*{gCo{4+81gt5zhtz& z`Oe7U{KtJkbq6l=|GhBPMSGg>nNBvY3-_W!&U3}xGkw0)Q7@34vD9SZ=G4O{Kf7JO z9wqcZiScj7Eakt z!I=Ex{DBX9C$O*_`rpYmC3{9%yH2lK-vx&N)02Kua#C)O8%FVdQ&MBb@0P8Ly{r~^~ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_glasslike_framed_optional.png b/data/games/garage/mods/testnodes/textures/testnodes_glasslike_framed_optional.png new file mode 100644 index 0000000000000000000000000000000000000000..37de77dd1aa7e6d027ade771dc898f4fcd8bf6b7 GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`?w&4=Ar*|tKh7WcaR1W`^_w#o zT^JadEhUaNEI%RPtJr3v$Lvt@_W!*9GuRSNB}*|(bbP0l+XkK90Mnf literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_glasslikeliquid.png b/data/games/garage/mods/testnodes/textures/testnodes_glasslikeliquid.png new file mode 100644 index 0000000000000000000000000000000000000000..e1e96ffb9f62b37173e542bf05a0d84b58d2ef2f GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`j-D=#Ar*|tKh7Wcu)p$py@6fr zFB4{t=ARrr;qw@MCUCAuVmRSBqiF@hbQ=%-84AwEhZ-9Bngf~LE;Alt=-On=(9U+| V!ig*Y)q#dFc)I$ztaD0e0svo?C-wjU literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light.png b/data/games/garage/mods/testnodes/textures/testnodes_light.png new file mode 100644 index 0000000000000000000000000000000000000000..4ba0081c3dc0544e0fc5b3c3a692b3744ab52f1e GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X5a_E{-7; zjLAR#|F>t}$gu3kRpAuJ4vw;eg4_c4)YtTs@G6T=nDfKK?;b<@Q^mOlSEO78>GpK> Kb6Mw<&;$SqK_OcJ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light_1.png b/data/games/garage/mods/testnodes/textures/testnodes_light_1.png new file mode 100644 index 0000000000000000000000000000000000000000..57adf5a4a89572114625655181540ac70574685e GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`sh%#5Ar*|tKloXAo-nrD3-_0} zz}wjUcyhAD9EK-rd8N$^PMkW`WN>4?gOrNfmNbKH+qSV~A2Vs#plHB+z(kQ*K+)?4 zw?q|(Btv;)Umsr{vp~ZJ#up9O*b>?fK41|^SL@nr%&_*$ft189ZJ6T-G@y GGywoSv@(ML literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light_10.png b/data/games/garage/mods/testnodes/textures/testnodes_light_10.png new file mode 100644 index 0000000000000000000000000000000000000000..483834770e84a3072c88a2a20d48d423b5c1d50f GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`QJyZ2Ar*{gCo{4gFyL|h|JQ%A zGp|njiER%bDyO9WT5+L@Uv-sqEz5VCCxY*Go4@r8T^TpSU?QhW%RJ`<0moO&-xkZA v@L_tlh0*hj9z!$39|40cs;5tH*>g@@q3@Pjq4$LVpe+oZu6{1-oD!M7c&cgqa^Z81LJ+CtAB5sOPSD5XvC<_cc?x x9P0;r*(4tQ%s-k8mpCf?lk@h>KDm3YwcPtl3v4g_{{Xay!PC{xWt~$(69AaTHR%8V literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light_12.png b/data/games/garage/mods/testnodes/textures/testnodes_light_12.png new file mode 100644 index 0000000000000000000000000000000000000000..bc7946d09ec5a15edcceb96fda9590dd3cc9833c GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`fu1goAr*|tKloXAo-nrD3-_0} zz}wjUcyh8t3d2MF4fh31m;}~KCNgwcSn4U{FetfjRx`%($1y+n*dw4U(%Zu8z;0sB kV9dj&y1>FXaL!!DElY1b4l)Vk1RBoZ>FVdQ&MBb@0AdIx4gdfE literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light_13.png b/data/games/garage/mods/testnodes/textures/testnodes_light_13.png new file mode 100644 index 0000000000000000000000000000000000000000..0b63c84a65bd79fd05e5f57e84fac1eadaf57f14 GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`0iG_7Ar*|tKloXAo-nrD3-_0} zz}wjUcyh8t3d2MF4fh31m;}~KCNgwcSn4U{FetfjRx`%($1!i%*%e?SWX8aI;SR$Y k1BodOkIuLhma#Fcy?OD?9J^(&fMzpzy85}Sb4q9e0GZY)&j0`b literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light_14.png b/data/games/garage/mods/testnodes/textures/testnodes_light_14.png new file mode 100644 index 0000000000000000000000000000000000000000..a817bd3946eea313015daca3408ca40310ceca13 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`-kvUwAr*|tKloXAo-nrD3-_0} zz}wjUcyh8t3d2MF4fhjFHc4pC;*@sS$!*{)a+$%TVIBK=#v3uN8d99n4SX;14=i92 eNmuLIY|Ow_bo7Vg*^&gHu?(KBelF{r5}E)J!6(81 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light_2.png b/data/games/garage/mods/testnodes/textures/testnodes_light_2.png new file mode 100644 index 0000000000000000000000000000000000000000..852eaeff17dd01be999daad14b8829005ba934bc GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`@t!V@Ar*|tKloXAo-nrD3-_0} zz}wjUcyhAD9EK-rd8N%5GD8?dl%tF#qNAe^-;`hzFk?w%5O`q9Ah@VyZ^Od&21X8F zD=RAnL#K-#HyBDBvY8DICloMs84Dl1Dar7|dVl}lPp+qcRxx4T z4@?!*)Y=%&vbHRmxPkFS!!ovp#r(EX?CJ|Fj05M)WeoG$;dfta{ac`Y44$rjF6*2U FngG^JHGKd8 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light_5.png b/data/games/garage/mods/testnodes/textures/testnodes_light_5.png new file mode 100644 index 0000000000000000000000000000000000000000..b6eede0ae902569625cfecbc4a64a3ee519bd53a GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`v7RoDAr*|tKloXAo-nrD3-_0} zz}wjUcyhAD9EK-rd8N%5GD8?dl%tIAFi7m)xKYq$@;jy#YJ1oeoTh9LH~8|vR6$LR xEl)d+S)gG9N#X6B`_$ta8@%0^EWx~;TEXU_{OxB l_W)1xK~9ZxJ|gMq49CMR^d9wyP6wLK;OXk;vd$@?2>_TsC#(Pf literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_light_9.png b/data/games/garage/mods/testnodes/textures/testnodes_light_9.png new file mode 100644 index 0000000000000000000000000000000000000000..2aa9023585aba2055ec03f3ab5f34f89b01897d6 GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`F`h1tAr*|tKloXAo-nrD3-_0} zz}wjUcyhAD9EK-rd8N%5GD8?dl%tIAFqoKi>N#W_%4Se<;jCtK=8t1;VDNiv-cY13 v(8pTD+mN_JLX+Vx>lW{ABI#;fn~fR1dELvMuQ7iK&>jX)S3j3^P6%KW@e4PR>dp^ji1d1qPz`B cn>HCUeAvOg`bbC>C(uv^Pgg&ebxsLQ07FbC)Bpeg literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_line_curved.png b/data/games/garage/mods/testnodes/textures/testnodes_line_curved.png new file mode 100644 index 0000000000000000000000000000000000000000..ab9f8e7208af8577ebd5df34f7a1d2749b5a95d9 GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`PM$7~Ar*|tKl)ideg5ouOoPo} z0>=lbf>&2GQ+h5la4@nqpJQ;Ev4HV^=KjjoAV!UCni*d&lMusCd Wmz>)Cz@8Ck8iS{+pUXO@geCx7YA3`1 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_line_straight.png b/data/games/garage/mods/testnodes/textures/testnodes_line_straight.png new file mode 100644 index 0000000000000000000000000000000000000000..4f33d9c6d9e53ee5ae0b33099fc5995faabc6809 GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`R-P`7Ar*|tKl)ideg6FL$CZ`A zCnU7`IsNgEN;ICy8kMY&H<(ZAjX* a$(SLP>4->jjF%mdKI;Vst03c`@!~g&Q literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing.png new file mode 100644 index 0000000000000000000000000000000000000000..1736b89ba5501f6f87ae94546d71249c29948010 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`-kvUwAr*|t2_2SuS$nwa8w^+0 zoZ@wut}wIT*YWM0`MmlXVlbP0(e%&{mv%-U=9`HP$4}1qbJ1YI4Te8) f5{oJuL+lusj*9axK5RD!Xe@)LtDnm{r-UW|`Uotr literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r0.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r0.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a61039d7d4e5a725cf6d54c26e56c335757ed5 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`nVv3=Ar*|tFAP#|@EkflM`1>Y z-BY#&-V=@;PdqTOX#d&QT}_S>N7_Cc@*a4{TGCr!x6J#4v_qN1gOX1f5)L1JO)8LJ z`*hOaL5Ado)N^MPq)w>c7Fi*Ar*|tFFcZN@Ekg=r8pzR z?kU>>?+M3_CmxtsSvUK-F9%zqfb_ZJCJej9FPI+s;nL3N$2+6uPuzi(g(f^R96vdj z84FC#W4Mz&_oM=|$9E z+nLB?Jck09J-#t@ai2KFt%0oIjKR~@&t;ucLK6U4 CW;Ij* literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r3.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r3.png new file mode 100644 index 0000000000000000000000000000000000000000..bef77396844b1a924c2d32af9941ddecfc5b8691 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`NuDl_Ar*|t9Pbit@Ep=StuQ0R z?kU>>?+M3_CmwjCTsQmob=GEs4&LXyy1<(f!9wi8ZewbXfVOQ zjWP4|3`dD9hLdp)g^ZPzifblIJ`-)KY}{j@FqNO7ap}>$3>qtr0&QdPboFyt=akR{ E0G$3g4*&oF literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r4.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r4.png new file mode 100644 index 0000000000000000000000000000000000000000..de1001b2d9ebd15eb417b4ba002dc2025c6d7f5f GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`iJmTwAr*|t0k0Eo@EqE8T46?r z-BY#&-V=@;Pjombxc_YH>n2BuBW<4zc@Ml}E$J<=Tju>i+M!J1LFuOq35O><(+rz4 z6y_%}dwgf|kZC)4ntRsVGX~QqOci%HcU+!r$tT7Pg{guE*&1_!mN9s``njxgN@xNA DQCK(J literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r5.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r5.png new file mode 100644 index 0000000000000000000000000000000000000000..97b422e9a181b08932b7a4362ac976d75cd2e16e GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`NuDl_Ar*|t2`>_E^Bg;Ead1Y6 z-BY#&-V@FoUv}Vq$Ngs$N)IaVBpv=?!E?YwGFG|AzeM7I$pl%pA9HP_*c2=!*gl># zZm5*}p7zWyPhftEzQXQ?HG3E~OC~bN^*(83Tv@{~c~gm*pVP6|K-(BRUHx3vIVCg! E0B5E*o&W#< literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r6.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidflowing_r6.png new file mode 100644 index 0000000000000000000000000000000000000000..4cd8e4e8e551a3c8881ce47e3bcf788fdc065c2e GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`NuDl_Ar*|t2`>!p@ffnqJ zyQgdmyeFJFzU;vJ6LZcUeErKo;z--aLWzbgTe~DWM4fPvI)? literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r0.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r0.png new file mode 100644 index 0000000000000000000000000000000000000000..da0a99623d8f84189d3d46914f0b8e3f8b34bdac GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`F`h1tAr*|t8Rm&MdU~c?E=+Rz z)O@8u`DtCjo_#7ZZ5yQ=s)iq0&y27{e!38$DD?t89|zrC&{8)y%Mr>mdKI;Vst0A?yO-v9sr literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r1.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r1.png new file mode 100644 index 0000000000000000000000000000000000000000..66bf2be8f9ff80d2e3d76840a16e8d7315d46eec GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`@t!V@Ar*|t8U86ZdU~dZE=qFx z)O@8u`SYI#6@QNuNF2*!5R;y0x=^C+rP3a@gj*i<%pBE?TO3rZrB>!L%Vz?N< zJmaJ{yKLtfg+hT|Td@z-okh$S_PX3)aQei+yz_cqjQ*Mcpj8Z>u6{1-oD!M{`KlV9UgRYy#hyG8;Y0OoGlbl)Rrfo$r}m zGFzg+{52&Fi3-e}p5p5^?rfgP!>m!xxXgxOY5gxQr`@HyfmShiy85}Sb4q9e0CCtg AH2?qr literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r3.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r3.png new file mode 100644 index 0000000000000000000000000000000000000000..0f46e291e81e7da98816774f0d0994cb99afae91 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`@t!V@Ar*|t9C_(CdU}GVFHCa! z)O@AE(*4haich}^B#z}Vh)GX0T`1A^QfUuc!Yz+_W{&E{Eee{ji5+@w8F7dukVC$Tm$?#O~z!Y|d>32`RpRi-=5};KKp00i_>zopr0BO%R A7ytkO literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r4.png b/data/games/garage/mods/testnodes/textures/testnodes_liquidsource_r4.png new file mode 100644 index 0000000000000000000000000000000000000000..0693a04d7fc89f7acdd7bfbb06a724348cea3912 GIT binary patch literal 155 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 BJCXnZ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_marble_metal.png b/data/games/garage/mods/testnodes/textures/testnodes_marble_metal.png new file mode 100644 index 0000000000000000000000000000000000000000..205d4993d6db774b4314334b414f299738bcedf2 GIT binary patch literal 595 zcmV-Z0<8UsP)&BO)%-*iZ-P+52H7gz!o1Uuf>W}04x!%v$<5=F$_w%}5kL&vP z70WeU`*tkXm3J<_&o$p8H|Lt8e&?+tumwBUJlE^}JeI+O-0C90>yg*7ydH&xH8$Y~ z0R=hkWluZ-JJ&b|Xigyz0sD;rq;kj2paX&j))II(IMTd6uRP=6x$Ya^@eF_L!?18p z8U}1_W&v|7Wc#LNd~%V3QV~2_aDakB6Yx=%R3egDWeVmiM@%$+5dMgmp!bdPAeYBm z*isb46GPo+0X+(D2=K@u#FPJSq`1hd8ZDyM+PEXxLB+$-;A5jr5H_wr;cfW&HNXjK zYi#iC0b{_c*SU^lMv(1$-~yb~cq(ixX=BO8zVWk#>`bO%=m13wfn~f~Sw~E0?06}t z(}JB|QLCwyZ4%@(*A6<}NlcxJp?tW`BAH0ShS5f%Gk_SDL*2RWa*0AsM`(xY-UomA zaOeSNQ(cHT!2kQ8Z6P}{)o$}WK~J+so0j9L1BUN(MGy`ei|(G?7?G2js!>jkRB9Lv;+u4;B9 h$LDY%qFQQlEZ?HJ((wGn*uDS&002ovPDHLkV1k0i9PI!A literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_marble_metal_overlay.png b/data/games/garage/mods/testnodes/textures/testnodes_marble_metal_overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..e2bb431e8c3f060aca18a14ee618cfb7c2940507 GIT binary patch literal 526 zcmV+p0`dKcP)Ll^Z;p;AZ$+5_n<2lMpD9G)ef zraPv-DQp%JU+DZ!PnN-m8`De`nJRK+jlNM*Ei@EExv}Lldp1ZHI8owOo@etcWO$X~ z=}*R%I5a>qPZ$a1M17XdVS19B%`&~h%Q4>1^D)Qk4swCPh}18lY$zuZDLU6VFw40D z4?9@M@FB;i9B+T}c#Ja>#7TCQLOD@8PWue;GD8t}&ohTNc(=krhTIxMOQa{+buW|~ zJ7!5o^c5KG<$jXqW6a^vJXcHfmq^VJwS{t{?kgQJ=`{v!GFswxk~>RW&T{M~=>n}6 z*?Kx`2BIhIU8E<^$yqKW8HqSLM|zF+n7T`0vrzM!wmH&SdXpSq=SY@#nXYxVErrcS z^Dz4&;!zIf**`&Qg59;D5@;yWwn%D~IFR~9#|s*-hf1OO4qZi3t8~Zgd``_ks1zDo zXdS2P6s_YlehZaE-7w89v=nICpzcAaG!m0+|3Ttf_*SE`# zj`EL3bk-zn+Oz1yWxY8!x^}Rha~9nGA=`Y(;hk+CUw)7UTEyV#>gTe~DWM4fCj>d} literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes10.png b/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes10.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d569a072a6741d278982a4937009bc9dedf4e3 GIT binary patch literal 84 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|(w;7kAr*|t3hXipQao|I|2x^7 fuU=j}PmLKUclYcb8-w)UKxGV`u6{1-oD!MJ~6;QjYbmkmjlGkEiA&&NCweRD7DX_=sT@hheE31toGCtUqm sH*?lK&}q2Y9L8c?R&d0pNNc&gTH>zP-=D^O16sl0>FVdQ&MBb@001yGU;qFB literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes3.png b/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes3.png new file mode 100644 index 0000000000000000000000000000000000000000..96bc55ac5f3444eea6b725ec663f6a706ceed461 GIT binary patch literal 85 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|GM+AuAr*|t3hXipQVynn)TIK> hwgpPNn{So<}{xV9D%(8z!*!Oz4>|!%wU}zG0DDf?G77I{2gQu&X%Q~lo FCIC%T9gP40 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes6.png b/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes6.png new file mode 100644 index 0000000000000000000000000000000000000000..46c6e50198b1298407a8fff90fba65fe52658991 GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|vYsxEAr*|t3hXipQWI7`w7=Mp i!mE6Ye{r1xGXq1O-**w;-%(OPg$$mqelF{r5}E+hCloCJ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes7.png b/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes7.png new file mode 100644 index 0000000000000000000000000000000000000000..75b3bdd239cc83d5b98ceae482e74a81e47776ed GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|>Ygr+Ar*|t3haN>r6#OC__S4d tVunE0f@lp(w*3l1yiU9&9I8eP4BQ9i@d#WxVGq>8;OXk;vd$@?2>`}#7ajlr literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes8.png b/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes8.png new file mode 100644 index 0000000000000000000000000000000000000000..4b1885983afd9136141f926019215f4c071089d5 GIT binary patch literal 86 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|vYsxEAr*|t3haN>r6#O?$Z#=X jLzcvk04ZKoBL;>%zwaW?iquSi3K=|I{an^LB{Ts5^~n_W literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes9.png b/data/games/garage/mods/testnodes/textures/testnodes_mesh_stripes9.png new file mode 100644 index 0000000000000000000000000000000000000000..9902be89efde8345f8a3be758a428606160a9afb GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|TAnVBAr*|t3hXwGAr*|tKU|d(7!nsTIyvhK lGHh=PBNKfYA2vt22WQ%mvv4FO#m6}6{i3I literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_node_falling.png b/data/games/garage/mods/testnodes/textures/testnodes_node_falling.png new file mode 100644 index 0000000000000000000000000000000000000000..44153185c23c46924729b8735bd4b47968f0012b GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|=AJH&Ar*|tKm3&v7!nsTIyvhK zGR$xLZ!gin;ad>G93van63eV-`y=PT73YcaCp@K|sM-lJGF%g#=A(Dls0?TXgQu&X J%Q~loCIE(79ispM literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_node_falling_1.png b/data/games/garage/mods/testnodes/textures/testnodes_node_falling_1.png new file mode 100644 index 0000000000000000000000000000000000000000..74137b3adf1c371af2fcaac3a04d4787d9a1dae1 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|uAVNAAr*|tKm3&#GFPZdDVY5E zf51T?@j3$whZ)m@3k)nPq(0nYV39DJ@J7YxufsatFV`E`3`_&WF7vc7dN5aZ_Pa1J Y=-xiIvHeDWGSENDLqQ%^MU|7^Pnb+XdZ*7tDnm{r-UW|FGnIp literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_node_falling_4.png b/data/games/garage/mods/testnodes/textures/testnodes_node_falling_4.png new file mode 100644 index 0000000000000000000000000000000000000000..87fc2761245e3088151749f8cdab4a4a3c75ba65 GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|PM$7~Ar*|tKm3&#GFPZdDVS8S z{8#U|U}|7s;Gps#hfT#Hf_c`70~rpiCzNiO9uQo{>m0=Va7LN}6T{Sr(|>rdFl6*B V^eR^o+Xys`!PC{xWt~$(695{!B3}Ri literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_node_falling_5.png b/data/games/garage/mods/testnodes/textures/testnodes_node_falling_5.png new file mode 100644 index 0000000000000000000000000000000000000000..9a8ce2dc4ed6a79e08f6a005b915ba90e35ef156 GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|PM$7~Ar*|tKm3&#GFPZdDVP}i z+3zcmnBl-=pvRPOoxz-EvUfUf%io5TjAwI9q}hC!c^+JHNc0hAY&dnoyGDhH;q}ff Vf4ujLegm4u;OXk;vd$@?2>=D*BQyX2 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_node_falling_6.png b/data/games/garage/mods/testnodes/textures/testnodes_node_falling_6.png new file mode 100644 index 0000000000000000000000000000000000000000..9ad2f5b86c2c917a9a8820e864d30ef163fcba44 GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|j-D=#Ar*|tKm3&#GFPZdDVVg> z1*&#jFf~}fWFq)R>OtE<(+67^gJ=2he)-1y*HnQajCaaW6J|k%6+L^7xGOO*q{TD~ T_;$2|OlRbP0l+XkKHN_&q literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_nodebox.png b/data/games/garage/mods/testnodes/textures/testnodes_nodebox.png new file mode 100644 index 0000000000000000000000000000000000000000..66e8dd663e3a117d378b7b3eacd4e8bc0fc67b60 GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|=AJH&Ar*|tJ8FJ@S|7i^LtWBg zMh3$b=0gr)Zf^iD|ix_T}13HnQ|qzHd-`nXj~$~$Dreo9QAObm=w?m22WQ% Jmvv4FO#uGx9+?0D literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_nojump_side.png b/data/games/garage/mods/testnodes/textures/testnodes_nojump_side.png new file mode 100644 index 0000000000000000000000000000000000000000..6a64cfff0fb1339f4b1daf2a94c088eac96ecc48 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|s-7;6Ar*|t3haNb2Pz9Gnh0d- rHMw4xw{Uf02y?1uvxke{B{qg%(@scw8ej1QYGCkm^>bP0l+XkKwOkl} literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_nojump_top.png b/data/games/garage/mods/testnodes/textures/testnodes_nojump_top.png new file mode 100644 index 0000000000000000000000000000000000000000..fe770838f0cc6a6345c7c3308bc1ff89d7e8de0a GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;TYyi9E0F%LqxRu&av_kV=jq}Y zQo)$a(DbXGhtG%S<9>-l@rEwV!yy;u pmbNG*hCJTIQf{UbrvLC@VVJX~#qaC_e+{5=22WQ%mvv4FO#s;08E*gp literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_normal1.png b/data/games/garage/mods/testnodes/textures/testnodes_normal1.png new file mode 100644 index 0000000000000000000000000000000000000000..edaba77e4e602f12ec74e2a383e9a148838f52c0 GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|mYyz-Ar*|tKh7WcFkj>V!yy;u zmbU-$97;}74Gk>34h~Ih3JM2-_^PLJFf*5f$Hb{7C%kJ^m>9$gm%Z2N-Y^qr2!p4q KpUXO@geCwWXdguY literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_normal2.png b/data/games/garage/mods/testnodes/textures/testnodes_normal2.png new file mode 100644 index 0000000000000000000000000000000000000000..0080a9ee74ba07a7b0ba0f4c7f81c5548835a08e GIT binary patch literal 122 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|j-D=#Ar*|tKh7WcFkj>V!yy;u zmbU-Xrm+ZqHBs2zxPi^bwIz4KVzxtd2SR)Un4S8zB&aIN8BAt&HS~>pq%6q5z_B## V&-2Ty`ar`NJYD@<);T3K0RRBHC2;@% literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_normal3.png b/data/games/garage/mods/testnodes/textures/testnodes_normal3.png new file mode 100644 index 0000000000000000000000000000000000000000..0426ab216faf25f645c5b49d202c6f8f79f04318 GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|mYyz-Ar*|tKh7WcFkj>V!yy;u zmNw&Q|2dUbWjgGbpusyM=aAWj5awm_Z1+4B%w+#ItZdwK#9fJj;aKs;s7?7tRe^>u Nc)I$ztaD0e0s!SZBo_bx literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_normal4.png b/data/games/garage/mods/testnodes/textures/testnodes_normal4.png new file mode 100644 index 0000000000000000000000000000000000000000..0d1922eb6d383c17e8a9499a8fa7d64585dad665 GIT binary patch literal 106 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|hMq2tAr*|tKh7WcFkj>V!yy;u z7PkHe|5*e}O%B}Tcy}QC0K<~XswbHTuK2_~QWj)jaB`?Q^6;Y6G@xb%Pgg&ebxsLQ E0RP@1X8-^I literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_normal5.png b/data/games/garage/mods/testnodes/textures/testnodes_normal5.png new file mode 100644 index 0000000000000000000000000000000000000000..0b7dcd2da9d230c61c56d841a333ce36e3c297f3 GIT binary patch literal 109 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|CY~;iAr*|tKh7WcFkj>V!yy-D z72f~(!Y)@XHE?lcI|RFg^G^BAD9kIyyQ1OJ3^o0a6FC_2o=lY~F8=xisGq^p)z4*} HQ$iB}V!yy;u zmbMG}t5^i5nk?AaxPi^bERk2my7OI~LUTZn%?rCm3h~gQu&X J%Q~loCIDBLA_D*b literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_not_pointable.png b/data/games/garage/mods/testnodes/textures/testnodes_not_pointable.png new file mode 100644 index 0000000000000000000000000000000000000000..8509a68b7bcf87801570ed90a99ed937f8adcb53 GIT binary patch literal 152 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-u0T36GBVA;;Q#;sGgSE; zfPBW1AirP+hi5m^fE+7N7sn8e=;VZr|CJ9Y9Aa=`gTe~DWM4faB3Jd literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_palette_4dir.png b/data/games/garage/mods/testnodes/textures/testnodes_palette_4dir.png new file mode 100644 index 0000000000000000000000000000000000000000..7a26c9bbd2825eae8633e895234fbc40ebd15d45 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^4nWMv!2~29^4o(rKAtX)Aso@kfBql-DQ$h2olT>P z-_7Bedx#lxGXrz8!i*LLi)fZJVktjPF@^FfK0J2NW7&Cy(mx(niaZ>eOlmVF?H(F1 g9ZUP!wM>}d(hAkP_s(1E1I=adboFyt=akR{01j>_u>b%7 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_palette_facedir.png b/data/games/garage/mods/testnodes/textures/testnodes_palette_facedir.png new file mode 100644 index 0000000000000000000000000000000000000000..8cf47bbbe2693618e4d7851aa9837720df4deca6 GIT binary patch literal 87 zcmeAS@N?(olHy`uVBq!ia0vp^96-#-!2~38k}5=il$@uFV@L&Ka>|Qe>yOoY_kN!y l^*=XsUvyT2%Hgjp40(q*UX?A<{Q*?T;OXk;vd$@?2>^*(8T9}F literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_palette_full.png b/data/games/garage/mods/testnodes/textures/testnodes_palette_full.png new file mode 100644 index 0000000000000000000000000000000000000000..e0a5f8b349809a6a6d3febdca04f93a5b09ddebd GIT binary patch literal 568 zcmV-80>}M{P)3w&f$Iv9rqA>KLQFM?vn#O?xheA>$T~RDJszPs@-Y4PDymNTxp8tLM z?(|$5j6Z22wpVzX@QpQ*&XBH%?HI{776M%@W4^rt=9Fx2MY)PI8Rk=5s3?GUTPt%YbFEfz-=@7rv;FA<_P?-<(bc zh4N}S7xNnM6z0-xq+ctyW_~T*T84%0(uX6@TbtKDwGMSQwJu?atUTV?46<=}=V()V ztTTzuy?kkm%I=umNwZgW&&&a-%$_-|v;YIMdH}OJ<@Ac4TzoW`G#WG+Y!oz_ItQdd zx@L*id<>feqni&Oa7m<;kcv;ll_JUbvJ~T!f`KQbUNX9U{~i{k*jxYt;P+o@#+By#u%9iKQeqCdVTCz zZ?ewDN2F!pQ?>wybr$urZ(R80F^mp>I_Y9}TIE*KuV!c_wBi| z4sUzX;r!{tvoCx8|Fk*10H{X5)5S4_LpC`jBq%6JW)BMk*B@TS%%AryfN~6;u6{1- HoD!M<_VXk( literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_palette_wallmounted.png b/data/games/garage/mods/testnodes/textures/testnodes_palette_wallmounted.png new file mode 100644 index 0000000000000000000000000000000000000000..682f3ac84d7c43b9077e2bd1d6f50845245fe550 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0zk~f!2~4l^`Bk_r2IWy978G?Wj&7y9#9a7c~Wb1 zq2BeSg6fe8@qgMThn64R>0xn2{9`s(YR9673C{bU1*EjR;WvFNyHE3xSc#*z1vjW z=jMi-Q#Y*tU!ERc_uo9yKui7uC$D@#h(q@p>oa#hwM4bpZ%9a8)MV4&GV#qUhy2{b e4%fP3HcRUj%RjyK?T;eR3IXLf<0XvLn;`P6GU1V*iw@X3{+-5%*c`8N^99UYZjB_)1ygA zhuYeBx{kIUJ9uoNgWJxHD~mHWC^mZ~E?lu;qe6ghV&~=sGn6MheDp@?jZV&q06tcR YL))dFYUI1S0F7txboFyt=akR{09*G#o&W#< literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_plantlike_leveled.png b/data/games/garage/mods/testnodes/textures/testnodes_plantlike_leveled.png new file mode 100644 index 0000000000000000000000000000000000000000..53504dbcdd6224baf262d39e82327788cc7ec45b GIT binary patch literal 163 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|S)MMAAr*|tKMou)cqy>)#l1kb zw*UYC@Bgu1sHtfC&1-8D8wv%LRI9Vm@HtXVlugnK~L!S6vkU#>_A%? NJYD@<);T3K0RRupJlFsL literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_plantlike_meshoptions.png b/data/games/garage/mods/testnodes/textures/testnodes_plantlike_meshoptions.png new file mode 100644 index 0000000000000000000000000000000000000000..d504d459f30d387160543b1001824bcec1b56cf2 GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|*`6+rAr*|tKh7U8c&NeI@$mou z|N8&ds|fLy@m}o~HV8eiG{D56zopr08^_t1^@s6 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted.png b/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted.png new file mode 100644 index 0000000000000000000000000000000000000000..79cf2125e1aacf3924774801deff8fd2b5cc3942 GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|wVp1HAr*|tKh7U8c&NeI@z7pi zkAl#!H`{}JH}4a=;`XX~~!1~bnx31AjTjOxC?U?>{NKZjf8p%Mpgft?TQAt96J ziCGRBXXBo7Ja4)&L+U|Q!=-{vRfS9w7#&|MWHICnW)^UaXv literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png b/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_degrotate.png new file mode 100644 index 0000000000000000000000000000000000000000..85311cb2c388c32855fc67fe3c36f114a15da63f GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|5uPrNAr*|tKh7Tr5O!u_dYF(N znB=j8?a~*8kjIV|xebed`S@}iy26}#@ajR&9UOMj2EMHvk2W(lT`&>&z?^C3Afa-j t;i~P990!diavTE)IQ%i>Tzvy-WuZAFN(z}CMFD;wXLO%N#m;^nRuR)i0ZbE58FxWbkzLb6Mw<&;$V1wklQt literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png b/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_base_side_meshoptions.png new file mode 100644 index 0000000000000000000000000000000000000000..d100023750f43debb379fcff8fbfc71f959f2e17 GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|?w&4=Ar*|tKh7Tr5O!u_dYF(N znB=j8?a~*8kjIV|xhu|JaS3e~aNN$Q#~a-EKxhl2qfjcdTJxzo2M_)gyedaz_g)gp aQnxS_9RV81;OXk;vd$@?2>_CQC|Upj literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png b/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_degrotate.png new file mode 100644 index 0000000000000000000000000000000000000000..45e75bdd329f7ef429b53b89526f27ed0b310eeb GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDU{m;NK;V8p@Ab4>qdzEAL z;)L97wh7G)?mNzW1F8x3ba4!+U`$RBX<=YXO*Sx4nfWjyM}jM@W#_C}Op;HJCM6we zYvbuU+IsBZv4sw9J2$Q@&e)*X?3K81#fFUv0ltZyn-|Pbp78L|8>KfoIVS@6SQ!p& Wmwu{|@9qLLp25@A&t;ucLK6VX*+QTI literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png b/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_leveled.png new file mode 100644 index 0000000000000000000000000000000000000000..8954b2c34c5870465d8f3ff3a09086bbcd633136 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|nVv3=Ar*|tKMou)cqy>)#l1kb zw*L+v9*M9#&D*>-`Y^*|C6};R)ElW);_3;j8oU=~G;ln;&fxOGEM>V00nl7d>%w_foRSeU4Ig&jtH>?!7x%G*a=E9jKEDQ?0&cah3=JEk8W$<+M Kb6Mw<&;$TK1vFRy literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png b/data/games/garage/mods/testnodes/textures/testnodes_plantlike_rooted_wallmounted.png new file mode 100644 index 0000000000000000000000000000000000000000..0decffaf14112cca3aa4c6c3a7cd4d75c4e0ea30 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|>7Fi*AsWHSKh7U8c&NeI@z7pi zkA)I%vN|09Q88*?ngdl|1XJb9A0+4UOplSMO`1RZZMJUlE}Ak^Eqh|xFmo0fY@ zwSu357jv2V!LJ7d6L|$LzB+9%jUlj?+tF0TWO5sWQN5blnOT=!0;4xt(<3TqA15<@1f+}{rKi)cKcx0&Y aGBPkqyO>sxNj0Eat@O1TaS?83{ F1OUQdADRFF literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_post_effect_color_shaded_true.png b/data/games/garage/mods/testnodes/textures/testnodes_post_effect_color_shaded_true.png new file mode 100644 index 0000000000000000000000000000000000000000..448cf91c8c2200d863ec795fcb9cb32f47c88897 GIT binary patch literal 105 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf63_M*NLn>}1|G3{EZ^XmL%Jbh* zz{$BKLBh$YML~t_*m{P`EF8WESVDN4)fQ-kFfcgm$`er8$C3`z%i!ti=d#Wzp$PyH C4;vW( literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_rail2_crossing.png b/data/games/garage/mods/testnodes/textures/testnodes_rail2_crossing.png new file mode 100644 index 0000000000000000000000000000000000000000..530bbba7a598a7ea35ee4c6a6fe9f0f68c53a641 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF4e$wZ1=6jh(Yy9;3k?r$D~su< zh-)d0ZZD5*DT(eVkL{?4Z7+{$Esbd}i)k&3nZ0{SHc$g&NswPKgTu2MX+Tc7r;B4q z1!HnTNLgvIxM5L3L15m@cP~<(99pns4GW8#7tgVP0}oc{ybX#-x^m*d;x~b>A2EeI zUiapal3wl;<}{IA5>t(@Xnfzv(Z#%!Wom4SIFoC`u9&`*T@pK)ugZM1V7kI;E|A#D o9bkRofGLm8sYku%-4 z(e352?d378Wih+EL%t>l5ta*)J{+yB%qR1lKP%pplg{otAUN$_Q^p?d;^w7?r3;0HeQWsZ*KIGH zwR1sKeL&Xlrpf6%HHSJ6ZdRQ0?dS~&FGCl$M=Ix%vpT(+@9v(Z@#UVUd_c$6t(Up| vR`zYn)ks~r_o-;Qq`bS_gOa!XQ}pEno0Wq?O~T!QE@AL=^>bP0l+XkK#LHg* literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_rail2_straight.png b/data/games/garage/mods/testnodes/textures/testnodes_rail2_straight.png new file mode 100644 index 0000000000000000000000000000000000000000..8749330d85388acf6d84f0547b5eb4a69eafba7e GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF4e$wZZ7YibqFsBpg@y;WmPU6} z#I=-0x0lDZm&de}M7Ng3bd<-omd3OL85ObhWzR1IH8Pe2`2{mLJiCzwFN&du5Jd`8&l77%FW@Js5N~L-$o~ui+5Kr moY9!W5%xLY!_JP0%nafD($c*imkt7*z~JfX=d#Wzp$PzZH&^rk literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_rail2_t_junction.png b/data/games/garage/mods/testnodes/textures/testnodes_rail2_t_junction.png new file mode 100644 index 0000000000000000000000000000000000000000..0517f6570e8ee361ee9c4aa9cc719e4060c664e0 GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHF4e$wZ1=4M0F}wC|3k?r$EsgG| zh-)d0ZZD5*FOO+0i)k&5=>W3JVmc~fTS}t0EXWrDYG5o0@(X5gcy=QV$f@^qaSW+o zOil9x#z;hW2`3<0`F}K3=lXYAW}HRG>h?-mPlbaOVkV<%-Qx`IiGUfx*+&&t;ucLK6T$DJu8? literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_rail_curved.png b/data/games/garage/mods/testnodes/textures/testnodes_rail_curved.png new file mode 100644 index 0000000000000000000000000000000000000000..e4441984858011cd8eaaee23dea9e2a7bea979e6 GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?b1=1^O%sW#wckSI48Xnx6 zc&P{|#8?vK7tG-B>_!@p35kuZ z$CvMqJ^#RG!r!*1m-LhQPRe+f2X;6-S;QfD*EueIWrS9quQ~Ul&K04rfyOa-y85}S Ib4q9e0OdD1wg3PC literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_rail_straight.png b/data/games/garage/mods/testnodes/textures/testnodes_rail_straight.png new file mode 100644 index 0000000000000000000000000000000000000000..872d04fb9b6105e57f17f76c6e3cee0daf69f660 GIT binary patch literal 133 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?b1=73rZVL?$UQuh_nX2=y z#{4Q!h_NKdFPOpM*^M+HN5#{{F@)oKa)Lk-1CuKoTbg3BLV!s^f?yFNlPf#h4iQ

zopr07%Cn@&Et; literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_rail_t_junction.png b/data/games/garage/mods/testnodes/textures/testnodes_rail_t_junction.png new file mode 100644 index 0000000000000000000000000000000000000000..7e4af5182e1c185c5530ecd21cdddafea0fc31a3 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`6FprVLn;`P8yaJ)xBunm<^Oly zfuZ3_!<9uGdg~4U^BXgqIM%(8t>Nb0m$L+#8+axtL`vM{R!Lq}#i+xX^7ya>TS9N^ zr36a>d67pF8ynINBz$4ob=kY=spPE3S0$fKli*L&pVE5b@ZJr}4mKqw?$kW|$0)f+ zLW65cb7kYB7M8;))r{xVt*oE_KE0?Sk{4z BP9^{V literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_sign3d.png b/data/games/garage/mods/testnodes/textures/testnodes_sign3d.png new file mode 100644 index 0000000000000000000000000000000000000000..e4ad9479f039a00fd8ad1620ff4d3a8b4ddf4b17 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|oCO|{#S9F3${@^GvDCf{D9B#o z>Fdh=lv#j9Qs`4iEl8teiEBiObAE1aYF-J0b5UwyNotBhd1gt5g1e`0KzJjcI8af5 zr;B5V#`)ww|Nq-FGap_S=D+{d+YA-vFouf_o{yMxW=Gln|Np<=EidQeftAe_n>XHW zIG^Jq-ND!+9c}ZWl~Yf;gT1Fk)>lztqM54H9PY&6G-iRn|NqOMbJ&o`;L7a6q~4jyJj=6yZ57+8 y+=fXle;q1q793@mvt%2ufasNuOa(PgMg~6VK&zRnI6HtAF?hQAxvX*m}&=L$4|!PC{x JWt~$(69BMNAYT9g literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_street_crossing.png b/data/games/garage/mods/testnodes/textures/testnodes_street_crossing.png new file mode 100644 index 0000000000000000000000000000000000000000..d6e35ad7a6f2e10882ea20effae88edd05bd31d5 GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|0iG_7Ar*{gCo!@ea1dbr+`mWn zfBAZk*z1eJq8ndvuuIP2<(cq>Nq%M1lD|F&)tzq~Sp7*aL~pOA&w+;bEarO-`s)1o meEH?WPnl01PZl}*o1x{!=C_9zF>3Uv+{@ z!~X<^=Z8d(96M&jV7S**fx&mK$*cB2djvvZEIT<4b)W_iI>gTe~DWM4fCZ!(; literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_street_t_junction.png b/data/games/garage/mods/testnodes/textures/testnodes_street_t_junction.png new file mode 100644 index 0000000000000000000000000000000000000000..713621e0661b1b65e2bb8f3e3c6fb76fb31c43c8 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|uAVNAAr*|tKh7Ue(AE9>Uv?zrCvE@$ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_sunlight_filter.png b/data/games/garage/mods/testnodes/textures/testnodes_sunlight_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..b38ea40729b0a336119a8ffd154baf9fd2df8d60 GIT binary patch literal 113 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!9W@a@|Lkr1X60AE{-7; zjL8~mf(<4=gm^DqzPwOMLPDZLv3+7&Nzj1@9qkt@7#K>IpOjDDelZ%P)6><@Wt~$( F696qV9qIr8 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga b/data/games/garage/mods/testnodes/textures/testnodes_tga_type10_32bpp_bt.tga new file mode 100644 index 0000000000000000000000000000000000000000..2dc587bc39b9de661dd99bb3777c39398bfdab51 GIT binary patch literal 179 zcmY+6?FoP|3`EcVDo)`7x{_ki3^8K#fu!9*w^glM_H2iPKEx wc2Z@%$S+{pQS;7eX=enXf1gyv*pE#5)J;+)Z&b-@owu;ZB~D{|^l=Cs9$v37y#N3J literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga b/data/games/garage/mods/testnodes/textures/testnodes_tga_type10_32bpp_tb.tga new file mode 100644 index 0000000000000000000000000000000000000000..b44a81c799b56f08c3882a5f34075d47ceb6e2bf GIT binary patch literal 179 zcmZQz;9`IP4h9fZ&}d>{`2W8JDAvFTB0#)W6kZdE32DFP67DT}x_TNZMvc7@5NeD=w!vORxqrtI=8A(lkDMcg> f%;`l`{M{`AbvwC-qcyJME>At{zD@5^*D~V+v|bC* literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga b/data/games/garage/mods/testnodes/textures/testnodes_tga_type2_16bpp_bt.tga new file mode 100644 index 0000000000000000000000000000000000000000..0206216bb4bb6cc2d8d0ef5281c7de497ed8ca12 GIT binary patch literal 172 zcmZQzU}As)4h9Ye0Y-)f7?cOHKo|z)fjkKRK{E&<U literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga b/data/games/garage/mods/testnodes/textures/testnodes_tga_type2_32bpp_tb.tga new file mode 100644 index 0000000000000000000000000000000000000000..216de063444160b9e2e69dbc90b8ae35c6370b22 GIT binary patch literal 300 zcmZQzU}As(4h9fZ&|qNr{~v)F8i2A`Fh~tHahMoT9vNb&h00@y!}J4bkbaOnkVbM4 w!d@ivLGmEAFdE%$AaNK*mqXSE)ejV6U1(9v~k0JtfPDoIwYnW%Sr@x9)-gZOv;yMZA{1ft#zC(YfK;@zC2?+{y4f724^!L+^aP#zW)nfnv)Y?BP literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_torchlike_ceiling.png b/data/games/garage/mods/testnodes/textures/testnodes_torchlike_ceiling.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9862cc988af30c729428df42cf6731cdc5ac4e GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`DV{ElAr*|tKh7WcFkk2Z1B-)@ z@C=Vnf7uh+Lo)@^4lw?6?s%Af;6J|v8^h5KV}?}|l$aGNwr{t&!JxoA%2n6&H8TxOXX37~xpp00i_>zopr E02vuD$p8QV literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_torchlike_floor.png b/data/games/garage/mods/testnodes/textures/testnodes_torchlike_floor.png new file mode 100644 index 0000000000000000000000000000000000000000..adf1e002dd67b65035e93622ae3c93baef3f1c1d GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`A)YRdAr*|tKh86_Oi2)6R5{7| zUy((Z_s9RnhxQzkGZ>tdBiR&8ls@F;|NOsXH^V~7{fsOohYemPCMca`zwWb%QQ@q@ on+00DhZGcNNg8AwsOMs2(A<1MX+t4P3($N9Pgg&ebxsLQ0Ny1m6951J literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testnodes/textures/testnodes_torchlike_wall.png b/data/games/garage/mods/testnodes/textures/testnodes_torchlike_wall.png new file mode 100644 index 0000000000000000000000000000000000000000..cb442b22d84150cad41d4181a7cdca7a9ad64f09 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`sh%#5Ar*{g&urvu2oPv~=#!u? z7MAyb;alIEpgaN3k195SJ3{`&JXpowqBooA%L7UO4ZQky8A2Lrn2y_BW?ai;F^SoB zldiC`Lv}+LQ`BpV0OKXhOiOqygqZt|G;}e(k9ROBW!&Pn-?Jc)@deOA22WQ%mvv4F FO#r_LGkpL6 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testpathfinder/README.md b/data/games/garage/mods/testpathfinder/README.md new file mode 100644 index 0000000..2b9d46e --- /dev/null +++ b/data/games/garage/mods/testpathfinder/README.md @@ -0,0 +1,15 @@ +# Pathfinder Tester + +Usage: + +Use the Pathfinder Tester tool (`testpathfinder:testpathfinder`). +Here's how it works: + +* Place on node: Set destination position +* Punch: Find path +* Sneak+punch: Select pathfinding algorithm + +Information will be shown in chat. If a path was found, all waypoints +will be shown for a few seconds. + +See `init.lua` for config variables. diff --git a/data/games/garage/mods/testpathfinder/init.lua b/data/games/garage/mods/testpathfinder/init.lua new file mode 100644 index 0000000..a0f99f8 --- /dev/null +++ b/data/games/garage/mods/testpathfinder/init.lua @@ -0,0 +1,136 @@ +local S = core.get_translator("testpathfinder") + +-- Config parameters + +-- Maximum direct distance between start and end +local MAX_DIRECT_DISTANCE = 64 +-- Maximum search distance +local MAX_SEARCH_DISTANCE = 32 +-- Maximum permitted jump height +local MAX_JUMP = 1 +-- Maximum permitted drop height +local MAX_DROP = 5 +-- If true, mod won't refuse to run pathfinder even at long distances +local IGNORE_MAX_DISTANCE_SAFEGUARD = false + +-- End of config parameters + +local timer = 0 +local algorithms = { + "A*_noprefetch", + "A*", + "Dijkstra", +} + +local function find_path_for_player(player, itemstack) + local meta = itemstack:get_meta() + if not meta then + return + end + local x = meta:get_int("pos_x") + local y = meta:get_int("pos_y") + local z = meta:get_int("pos_z") + local algo = meta:get_int("algorithm") + if x and y and z then + local pos2 = {x=x, y=y, z=z} + algo = algorithms[algo+1] + local pos1 = vector.round(player:get_pos()) + -- Don't bother calling pathfinder for high distance to avoid freezing + if (not IGNORE_MAX_DISTANCE_SAFEGUARD) and (vector.distance(pos1, pos2) > MAX_DIRECT_DISTANCE) then + core.chat_send_player(player:get_player_name(), S("Destination too far away! Set a destination (via placing) within a distance of @1 and try again!", MAX_DIRECT_DISTANCE)) + return + end + local str = S("Path from @1 to @2:", + core.pos_to_string(pos1), + core.pos_to_string(pos2)) + + core.chat_send_player(player:get_player_name(), str) + local time_start = core.get_us_time() + local path = core.find_path(pos1, pos2, MAX_SEARCH_DISTANCE, MAX_JUMP, MAX_DROP, algo) + local time_end = core.get_us_time() + local time_diff = time_end - time_start + str = "" + if not path then + core.chat_send_player(player:get_player_name(), S("No path!")) + core.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000)) + return + end + for s=1, #path do + str = str .. core.pos_to_string(path[s]) .. "\n" + local t + if s == #path then + t = "testpathfinder_waypoint_end.png" + elseif s == 1 then + t = "testpathfinder_waypoint_start.png" + else + local c = math.floor(((#path-s)/#path)*255) + t = string.format("testpathfinder_waypoint.png^[multiply:#%02x%02x00", 0xFF-c, c) + end + core.add_particle({ + pos = path[s], + expirationtime = 5 + 0.2 * s, + playername = player:get_player_name(), + glow = core.LIGHT_MAX, + texture = t, + size = 3, + }) + end + core.chat_send_player(player:get_player_name(), str) + core.chat_send_player(player:get_player_name(), S("Path length: @1", #path)) + core.chat_send_player(player:get_player_name(), S("Time: @1 ms", time_diff/1000)) + end +end + +local function set_destination(itemstack, user, pointed_thing) + if not (user and user:is_player()) then + return + end + local name = user:get_player_name() + local obj + local meta = itemstack:get_meta() + if pointed_thing.type == "node" then + local pos = pointed_thing.above + meta:set_int("pos_x", pos.x) + meta:set_int("pos_y", pos.y) + meta:set_int("pos_z", pos.z) + core.chat_send_player(user:get_player_name(), S("Destination set to @1", core.pos_to_string(pos))) + return itemstack + end +end + +local function find_path_or_set_algorithm(itemstack, user, pointed_thing) + if not (user and user:is_player()) then + return + end + local ctrl = user:get_player_control() + -- No sneak: Find path + if not ctrl.sneak then + find_path_for_player(user, itemstack) + else + -- Sneak: Set algorithm + local meta = itemstack:get_meta() + local algo = meta:get_int("algorithm") + algo = (algo + 1) % #algorithms + meta:set_int("algorithm", algo) + core.chat_send_player(user:get_player_name(), S("Algorithm: @1", algorithms[algo+1])) + return itemstack + end +end + +-- Punch: Find path +-- Sneak+punch: Select pathfinding algorithm +-- Place: Select destination node +core.register_tool("testpathfinder:testpathfinder", { + description = S("Pathfinder Tester") .."\n".. + S("Finds path between 2 points") .."\n".. + S("Place on node: Select destination") .."\n".. + S("Punch: Find path from here") .."\n".. + S("Sneak+Punch: Change algorithm"), + inventory_image = "testpathfinder_testpathfinder.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = find_path_or_set_algorithm, + on_secondary_use = set_destination, + on_place = set_destination, +}) + + diff --git a/data/games/garage/mods/testpathfinder/mod.conf b/data/games/garage/mods/testpathfinder/mod.conf new file mode 100644 index 0000000..6b2c0e3 --- /dev/null +++ b/data/games/garage/mods/testpathfinder/mod.conf @@ -0,0 +1,2 @@ +name = testpathfinder +description = Tool to test Luanti's pathfinder function diff --git a/data/games/garage/mods/testpathfinder/textures/testpathfinder_testpathfinder.png b/data/games/garage/mods/testpathfinder/textures/testpathfinder_testpathfinder.png new file mode 100644 index 0000000000000000000000000000000000000000..37eef0565458e2210ff0d048e4d79edf5182887e GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`X`U{QAr*{s`xw~{I0!I*{_h{Z zP|^F@8tJgiRI93oEOmn0pL{>D#6f6&dtI4jdkEv7qxVy*lbo~F2vW5ESVHw|VrIq=swbQP`Iu>V^d&_)JNS3j3^ HP6=OqZvGJrUnZ`-?hK;kzL<+0d+BWy85}Sb4q9e0222ZV*mgE literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testpathfinder/textures/testpathfinder_waypoint_end.png b/data/games/garage/mods/testpathfinder/textures/testpathfinder_waypoint_end.png new file mode 100644 index 0000000000000000000000000000000000000000..41a1cc549a914cbf81ac93589f8c085df4dc4af9 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Y$ZW{!3_UF&^$uA7AWH3>Eakt z!8mnNBO8N)fb;wR^}mE>-0Uh3+wnHAbaQiwxCZmL#SB~Wr!nz`sKuVQ3|?E=wrPID ro_kLi?1lE5)Q9~mtTFlV!BBR_bfG^Xb_c!!&1CR&^>bP0l+XkK4*xP| literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testpathfinder/textures/testpathfinder_waypoint_start.png b/data/games/garage/mods/testpathfinder/textures/testpathfinder_waypoint_start.png new file mode 100644 index 0000000000000000000000000000000000000000..a22e31c3bcbf1cf62405a624430f5da27bbb7bb8 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`L7py-Ar*{!CpWSkFyL`{zx(@V z^DBvWoW4cO7ZK`T)|ql*r`<8<4U4(gt#~VE^*nS!la^>ru6{1-oD!M" for players. + +Use `testtools.get_branded_object(name)` to get an ObjRef. + +## Note Meta Privatizer +Sets the 'formspec' and 'infotext' metadata fields of a node +to private. This means that clients can no longer access these +fields. +This only works for chests [`chest:chest`] at the moment. + +Usage: +* Punch: Set metadata of pointed node to private + +## Light Tool +Show light level of node. + +Usage: +* Punch: Show light info of node in front of the punched node's side +* Place: Show light info of the node that you touched + +## Particle Spawner +Spawn a random animated particle. + +Usage: +* Punch: Spawn particle diff --git a/data/games/garage/mods/testtools/init.lua b/data/games/garage/mods/testtools/init.lua new file mode 100644 index 0000000..6586d87 --- /dev/null +++ b/data/games/garage/mods/testtools/init.lua @@ -0,0 +1,1067 @@ +local S = core.get_translator("testtools") +local F = core.formspec_escape + +testtools = {} + +dofile(core.get_modpath("testtools") .. "/light.lua") +dofile(core.get_modpath("testtools") .. "/privatizer.lua") +dofile(core.get_modpath("testtools") .. "/particles.lua") +dofile(core.get_modpath("testtools") .. "/node_box_visualizer.lua") + +local pointabilities_nodes = { + nodes = { + ["group:blocking_pointable_test"] = true, + ["group:not_pointable_test"] = true, + }, +} + +local pointabilities_objects = { + objects = { + ["group:blocking_pointable_test"] = true, + ["group:not_pointable_test"] = true, + }, +} + +core.register_tool("testtools:param2tool", { + description = S("Param2 Tool") .."\n".. + S("Modify param2 value of nodes") .."\n".. + S("Punch: +1") .."\n".. + S("Sneak+Punch: +8") .."\n".. + S("Place: -1") .."\n".. + S("Sneak+Place: -8"), + inventory_image = "testtools_param2tool.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_nodes, + on_use = function(itemstack, user, pointed_thing) + local pos = core.get_pointed_thing_position(pointed_thing) + if pointed_thing.type ~= "node" or (not pos) then + return + end + local add = 1 + if user then + local ctrl = user:get_player_control() + if ctrl.sneak then + add = 8 + end + end + local node = core.get_node(pos) + node.param2 = node.param2 + add + core.swap_node(pos, node) + end, + on_place = function(itemstack, user, pointed_thing) + local pos = core.get_pointed_thing_position(pointed_thing) + if pointed_thing.type ~= "node" or (not pos) then + return + end + local add = -1 + if user then + local ctrl = user:get_player_control() + if ctrl.sneak then + add = -8 + end + end + local node = core.get_node(pos) + node.param2 = node.param2 + add + core.swap_node(pos, node) + end, +}) + +core.register_tool("testtools:node_setter", { + description = S("Node Setter") .."\n".. + S("Replace pointed node with something else") .."\n".. + S("Punch: Select pointed node") .."\n".. + S("Place on node: Replace node with selected node") .."\n".. + S("Place in air: Manually select a node"), + inventory_image = "testtools_node_setter.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_nodes, + on_use = function(itemstack, user, pointed_thing) + local pos = core.get_pointed_thing_position(pointed_thing) + if pointed_thing.type == "nothing" then + local meta = itemstack:get_meta() + meta:set_string("node", "air") + meta:set_int("node_param2", 0) + if user and user:is_player() then + core.chat_send_player(user:get_player_name(), S("Now placing: @1 (param2=@2)", "air", 0)) + end + return itemstack + elseif pointed_thing.type ~= "node" or (not pos) then + return + end + local node = core.get_node(pos) + local meta = itemstack:get_meta() + meta:set_string("node", node.name) + meta:set_int("node_param2", node.param2) + if user and user:is_player() then + core.chat_send_player(user:get_player_name(), S("Now placing: @1 (param2=@2)", node.name, node.param2)) + end + return itemstack + end, + on_secondary_use = function(itemstack, user, pointed_thing) + local meta = itemstack:get_meta() + local nodename = meta:get_string("node") or "" + local param2 = meta:get_int("node_param2") or 0 + + core.show_formspec(user:get_player_name(), "testtools:node_setter", + "size[4,4]".. + "field[0.5,1;3,1;nodename;"..F(S("Node name (itemstring):"))..";"..F(nodename).."]".. + "field[0.5,2;3,1;param2;"..F(S("param2:"))..";"..F(tostring(param2)).."]".. + "button_exit[0.5,3;3,1;submit;"..F(S("Submit")).."]" + ) + end, + on_place = function(itemstack, user, pointed_thing) + local pos = core.get_pointed_thing_position(pointed_thing) + local meta = itemstack:get_meta() + local nodename = meta:get_string("node") + if nodename == "" and user and user:is_player() then + core.chat_send_player(user:get_player_name(), S("Punch a node first!")) + return + end + local param2 = meta:get_int("node_param2") + if not param2 then + param2 = 0 + end + local node = { name = nodename, param2 = param2 } + if not core.registered_nodes[nodename] then + core.chat_send_player(user:get_player_name(), S("Cannot set unknown node: @1", nodename)) + return + end + core.set_node(pos, node) + end, +}) + +core.register_tool("testtools:remover", { + description = S("Remover") .."\n".. + S("Punch: Remove pointed node or object"), + inventory_image = "testtools_remover.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = { + nodes = pointabilities_nodes.nodes, + objects = pointabilities_objects.objects, + }, + on_use = function(itemstack, user, pointed_thing) + local pos = core.get_pointed_thing_position(pointed_thing) + if pointed_thing.type == "node" and pos ~= nil then + core.remove_node(pos) + elseif pointed_thing.type == "object" then + local obj = pointed_thing.ref + if not obj:is_player() then + obj:remove() + else + core.chat_send_player(user:get_player_name(), S("Can't remove players!")) + end + end + end, +}) + +core.register_tool("testtools:falling_node_tool", { + description = S("Falling Node Tool") .."\n".. + S("Punch: Make pointed node fall") .."\n".. + S("Place: Move pointed node 2 units upwards, then make it fall"), + inventory_image = "testtools_falling_node_tool.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_nodes, + on_place = function(itemstack, user, pointed_thing) + -- Teleport node 1-2 units upwards (if possible) and make it fall + local pos = core.get_pointed_thing_position(pointed_thing) + if pointed_thing.type ~= "node" or (not pos) then + return + end + local ok = false + local highest + for i=1,2 do + local above = {x=pos.x,y=pos.y+i,z=pos.z} + local n2 = core.get_node(above) + local def2 = core.registered_nodes[n2.name] + if def2 and (not def2.walkable) then + highest = above + else + break + end + end + if highest then + local node = core.get_node(pos) + local metatable = core.get_meta(pos):to_table() + core.remove_node(pos) + core.set_node(highest, node) + local meta_highest = core.get_meta(highest) + meta_highest:from_table(metatable) + ok = core.spawn_falling_node(highest) + else + ok = core.spawn_falling_node(pos) + end + if not ok and user and user:is_player() then + core.chat_send_player(user:get_player_name(), S("Falling node could not be spawned!")) + end + end, + on_use = function(itemstack, user, pointed_thing) + local pos = core.get_pointed_thing_position(pointed_thing) + if pointed_thing.type ~= "node" or (not pos) then + return + end + local ok = core.spawn_falling_node(pos) + if not ok and user and user:is_player() then + core.chat_send_player(user:get_player_name(), S("Falling node could not be spawned!")) + end + end, +}) + +core.register_tool("testtools:rotator", { + description = S("Entity Rotator") .. "\n" .. + S("Rotate pointed entity") .."\n".. + S("Punch: Yaw") .."\n".. + S("Sneak+Punch: Pitch") .."\n".. + S("Aux1+Punch: Roll"), + inventory_image = "testtools_entity_rotator.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_objects, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "object" then + return + end + local obj = pointed_thing.ref + if obj:is_player() then + -- No player rotation + return + else + local axis = "y" + if user and user:is_player() then + local ctrl = user:get_player_control() + if ctrl.sneak then + axis = "x" + elseif ctrl.aux1 then + axis = "z" + end + end + local rot = obj:get_rotation() + rot[axis] = rot[axis] + math.pi/8 + if rot[axis] > math.pi*2 then + rot[axis] = rot[axis] - math.pi*2 + end + obj:set_rotation(rot) + end + end, +}) + +local mover_config = function(itemstack, user, pointed_thing) + if not (user and user:is_player()) then + return + end + local name = user:get_player_name() + local ctrl = user:get_player_control() + local meta = itemstack:get_meta() + local dist = 1.0 + if meta:contains("distance") then + dist = meta:get_int("distance") + end + if ctrl.sneak then + dist = dist - 1 + else + dist = dist + 1 + end + meta:set_int("distance", dist) + core.chat_send_player(user:get_player_name(), S("distance=@1/10", dist*2)) + return itemstack +end + +core.register_tool("testtools:object_mover", { + description = S("Object Mover") .."\n".. + S("Move pointed object towards or away from you") .."\n".. + S("Punch: Move by distance").."\n".. + S("Sneak+Punch: Move by negative distance").."\n".. + S("Place: Increase distance").."\n".. + S("Sneak+Place: Decrease distance"), + inventory_image = "testtools_object_mover.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_objects, + on_place = mover_config, + on_secondary_use = mover_config, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "object" then + return + end + local obj = pointed_thing.ref + if not (user and user:is_player()) then + return + end + local yaw = user:get_look_horizontal() + local dir = core.yaw_to_dir(yaw) + local pos = obj:get_pos() + local pitch = user:get_look_vertical() + if pitch > 0.25 * math.pi then + dir.y = -1 + dir.x = 0 + dir.z = 0 + elseif pitch < -0.25 * math.pi then + dir.y = 1 + dir.x = 0 + dir.z = 0 + end + local ctrl = user:get_player_control() + if ctrl.sneak then + dir = vector.multiply(dir, -1) + end + local meta = itemstack:get_meta() + if meta:contains("distance") then + local dist = meta:get_int("distance") + dir = vector.multiply(dir, dist*0.2) + end + pos = vector.add(pos, dir) + obj:set_pos(pos) + end, +}) + + + +core.register_tool("testtools:entity_scaler", { + description = S("Entity Visual Scaler") .."\n".. + S("Scale visual size of entities") .."\n".. + S("Punch: Increase size") .."\n".. + S("Sneak+Punch: Decrease scale"), + inventory_image = "testtools_entity_scaler.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_objects, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "object" then + return + end + local obj = pointed_thing.ref + if obj:is_player() then + -- No player scaling + return + else + local diff = 0.1 + if user and user:is_player() then + local ctrl = user:get_player_control() + if ctrl.sneak then + diff = -0.1 + end + end + local prop = obj:get_properties() + if not prop.visual_size then + prop.visual_size = { x=1, y=1, z=1 } + else + prop.visual_size = { x=prop.visual_size.x+diff, y=prop.visual_size.y+diff, z=prop.visual_size.z+diff } + if prop.visual_size.x <= 0.1 then + prop.visual_size.x = 0.1 + end + if prop.visual_size.y <= 0.1 then + prop.visual_size.y = 0.1 + end + if prop.visual_size.z <= 0.1 then + prop.visual_size.z = 0.1 + end + end + obj:set_properties(prop) + end + end, +}) + + +-- value-weak tables, because we don't want to keep the objrefs of unloaded objects +local branded_objects = setmetatable({}, {__mode = "v"}) +local next_brand_num = 1 + +function testtools.get_branded_object(name) + if name:sub(1, 7) == "player:" then + return core.get_player_by_name(name:sub(8)) + elseif name:sub(1, 4) == "obj:" then + return branded_objects[tonumber(name:sub(5)) or 0] + end + return nil +end + +core.register_tool("testtools:branding_iron", { + description = S("Branding Iron") .."\n".. + S("Give an object a temporary name.") .."\n".. + S("Punch object: Brand the object") .."\n".. + S("Punch air: Brand yourself") .."\n".. + S("The name is valid until the object unloads.") .."\n".. + S("Devices that accept the returned name also accept \"player:\" for players."), + inventory_image = "testtools_branding_iron.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_objects, + on_use = function(_itemstack, user, pointed_thing) + local obj + local msg + if pointed_thing.type == "object" then + obj = pointed_thing.ref + msg = "You can now refer to this object with: \"@1\"" + elseif pointed_thing.type == "nothing" then + obj = user + msg = "You can now refer to yourself with: \"@1\"" + else + return + end + + local brand_num = next_brand_num + next_brand_num = next_brand_num + 1 + branded_objects[brand_num] = obj + + core.chat_send_player(user:get_player_name(), S(msg, "obj:"..brand_num)) + end, +}) + + +local selections = {} +local entity_list +local function get_entity_list() + if entity_list then + return entity_list + end + local ents = core.registered_entities + local list = {} + for k,_ in pairs(ents) do + table.insert(list, k) + end + table.sort(list) + entity_list = list + return entity_list +end +core.register_tool("testtools:entity_spawner", { + description = S("Entity Spawner") .."\n".. + S("Spawns entities") .."\n".. + S("Punch: Select entity to spawn") .."\n".. + S("Place: Spawn selected entity"), + inventory_image = "testtools_entity_spawner.png", + groups = { testtool = 1, disable_repair = 1 }, + on_place = function(itemstack, user, pointed_thing) + local name = user:get_player_name() + if pointed_thing.type == "node" then + if selections[name] then + local pos = pointed_thing.above + core.add_entity(pos, get_entity_list()[selections[name]]) + else + core.chat_send_player(name, S("Select an entity first (with punch key)!")) + end + end + end, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "object" then + return + end + if user and user:is_player() then + local list = table.concat(get_entity_list(), ",") + local name = user:get_player_name() + local sel = selections[name] or "" + core.show_formspec(name, "testtools:entity_list", + "size[9,9]".. + "textlist[0,0;9,8;entity_list;"..list..";"..sel..";false]".. + "button[0,8;4,1;spawn;Spawn entity]" + ) + end + end, +}) + +local function prop_to_string(property) + if type(property) == "string" then + return "\"" .. property .. "\"" + elseif type(property) == "table" then + return tostring(dump(property)):gsub("\n", "") + else + return tostring(property) + end +end + +local property_formspec_data = {} +local property_formspec_index = {} +local selected_objects = {} +local function get_object_properties_form(obj, playername) + if not playername then return "" end + local props = obj:get_properties() + local str = "" + property_formspec_data[playername] = {} + local proplist = {} + for k,_ in pairs(props) do + table.insert(proplist, k) + end + table.sort(proplist) + for p=1, #proplist do + local k = proplist[p] + local v = props[k] + local newline = "" + newline = k .. " = " + newline = newline .. prop_to_string(v) + str = str .. F(newline) + if p < #proplist then + str = str .. "," + end + table.insert(property_formspec_data[playername], k) + end + return str +end + +local editor_formspec_selindex = {} + +local editor_formspec = function(playername, obj, value, sel) + if not value then + value = "" + end + if not sel then + sel = "" + end + local list = get_object_properties_form(obj, playername) + local title + if obj:is_player() then + title = S("Object properties of player “@1”", obj:get_player_name()) + else + local ent = obj:get_luaentity() + title = S("Object properties of @1", ent.name) + end + core.show_formspec(playername, "testtools:object_editor", + "size[9,9]".. + "label[0,0;"..F(title).."]".. + "textlist[0,0.5;9,7.5;object_props;"..list..";"..sel..";false]".. + "field[0.2,8.75;8,1;value;"..F(S("Value"))..";"..F(value).."]".. + "field_close_on_enter[value;false]".. + "button[8,8.5;1,1;submit;"..F(S("Submit")).."]" + ) +end + +core.register_tool("testtools:object_editor", { + description = S("Object Property Editor") .."\n".. + S("Edit properties of objects") .."\n".. + S("Punch object: Edit object") .."\n".. + S("Punch air: Edit yourself"), + inventory_image = "testtools_object_editor.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_objects, + on_use = function(itemstack, user, pointed_thing) + if user and user:is_player() then + local name = user:get_player_name() + + if pointed_thing.type == "object" then + selected_objects[name] = pointed_thing.ref + elseif pointed_thing.type == "nothing" then + -- Use on yourself if pointing nothing + selected_objects[name] = user + else + -- Unsupported pointed thing + return + end + + local sel = editor_formspec_selindex[name] + local val + if selected_objects[name] and selected_objects[name]:get_properties() then + local props = selected_objects[name]:get_properties() + local keys = property_formspec_data[name] + if property_formspec_index[name] and props then + local key = keys[property_formspec_index[name]] + val = prop_to_string(props[key]) + end + end + + editor_formspec(name, selected_objects[name], val, sel) + end + end, +}) + +local ent_parent = {} +local ent_child = {} +local DEFAULT_ATTACH_OFFSET_Y = 11 + +local attacher_config = function(itemstack, user, pointed_thing) + if not (user and user:is_player()) then + return + end + if pointed_thing.type == "object" then + return + end + local name = user:get_player_name() + local ctrl = user:get_player_control() + local meta = itemstack:get_meta() + if ctrl.aux1 then + local rot_x = meta:get_float("rot_x") + if ctrl.sneak then + rot_x = rot_x - math.pi/8 + else + rot_x = rot_x + math.pi/8 + end + if rot_x > 6.2 then + rot_x = 0 + elseif rot_x < 0 then + rot_x = math.pi * (15/8) + end + core.chat_send_player(name, S("rotation=@1", core.pos_to_string({x=rot_x,y=0,z=0}))) + meta:set_float("rot_x", rot_x) + else + local pos_y + if meta:contains("pos_y") then + pos_y = meta:get_int("pos_y") + else + pos_y = DEFAULT_ATTACH_OFFSET_Y + end + if ctrl.sneak then + pos_y = pos_y - 1 + else + pos_y = pos_y + 1 + end + core.chat_send_player(name, S("position=@1", core.pos_to_string({x=0,y=pos_y,z=0}))) + meta:set_int("pos_y", pos_y) + end + return itemstack +end + +core.register_tool("testtools:object_attacher", { + description = S("Object Attacher") .."\n".. + S("Attach object to another") .."\n".. + S("Punch objects to first select parent object, then the child object to attach") .."\n".. + S("Punch air to select yourself") .."\n".. + S("Place: Incease attachment Y offset") .."\n".. + S("Sneak+Place: Decease attachment Y offset") .."\n".. + S("Aux1+Place: Incease attachment rotation") .."\n".. + S("Aux1+Sneak+Place: Decrease attachment rotation"), + inventory_image = "testtools_object_attacher.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_objects, + on_place = attacher_config, + on_secondary_use = attacher_config, + on_use = function(itemstack, user, pointed_thing) + if user and user:is_player() then + local name = user:get_player_name() + local selected_object + if pointed_thing.type == "object" then + selected_object = pointed_thing.ref + elseif pointed_thing.type == "nothing" then + selected_object = user + else + return + end + local ctrl = user:get_player_control() + if ctrl.sneak then + if selected_object:get_attach() then + selected_object:set_detach() + core.chat_send_player(name, S("Object detached!")) + else + core.chat_send_player(name, S("Object is not attached!")) + end + return + end + local parent = ent_parent[name] + local child = ent_child[name] + local ename = S("") + if not parent then + parent = selected_object + ent_parent[name] = parent + elseif not child then + child = selected_object + ent_child[name] = child + end + local entity = selected_object:get_luaentity() + if entity then + ename = entity.name + elseif selected_object:is_player() then + ename = selected_object:get_player_name() + end + if selected_object == parent then + core.chat_send_player(name, S("Parent object selected: @1", ename)) + elseif selected_object == child then + core.chat_send_player(name, S("Child object selected: @1", ename)) + end + if parent and child then + if parent == child then + core.chat_send_player(name, S("Can't attach an object to itself!")) + ent_parent[name] = nil + ent_child[name] = nil + return + end + local meta = itemstack:get_meta() + local y + if meta:contains("pos_y") then + y = meta:get_int("pos_y") + else + y = DEFAULT_ATTACH_OFFSET_Y + end + local rx = meta:get_float("rot_x") or 0 + local offset = {x=0,y=y,z=0} + local angle = {x=rx,y=0,z=0} + child:set_attach(parent, "", offset, angle) + local check_parent = child:get_attach() + if check_parent then + core.chat_send_player(name, S("Object attached! position=@1, rotation=@2", + core.pos_to_string(offset), core.pos_to_string(angle))) + else + core.chat_send_player(name, S("Attachment failed!")) + end + ent_parent[name] = nil + ent_child[name] = nil + end + end + end, +}) + +local function print_object(obj) + if obj:is_player() then + return "player '"..obj:get_player_name().."'" + elseif obj:get_luaentity() then + return "LuaEntity '"..obj:get_luaentity().name.."'" + else + return "object" + end +end + +core.register_tool("testtools:children_getter", { + description = S("Children Getter") .."\n".. + S("Shows list of objects attached to object") .."\n".. + S("Punch object to show its 'children'") .."\n".. + S("Punch air to show your own 'children'"), + inventory_image = "testtools_children_getter.png", + groups = { testtool = 1, disable_repair = 1 }, + pointabilities = pointabilities_objects, + on_use = function(itemstack, user, pointed_thing) + if user and user:is_player() then + local name = user:get_player_name() + local selected_object + local self_name + if pointed_thing.type == "object" then + selected_object = pointed_thing.ref + elseif pointed_thing.type == "nothing" then + selected_object = user + else + return + end + self_name = print_object(selected_object) + local children = selected_object:get_children() + local ret = "" + for c=1, #children do + ret = ret .. "* " .. print_object(children[c]) + if c < #children then + ret = ret .. "\n" + end + end + if ret == "" then + ret = S("No children attached to @1.", self_name) + else + ret = S("Children of @1:", self_name) .. "\n" .. ret + end + core.chat_send_player(user:get_player_name(), ret) + end + end, +}) + +-- Use loadstring to parse param as a Lua value +local function use_loadstring(param, player) + -- For security reasons, require 'server' priv, just in case + -- someone is actually crazy enough to run this on a public server. + local privs = core.get_player_privs(player:get_player_name()) + if not privs.server then + return false, "You need 'server' privilege to change object properties!" + end + if not param then + return false, "Failed: parameter is nil" + end + --[[ DANGER ZONE ]] + -- Interpret string as Lua value + local func, errormsg = loadstring("return (" .. param .. ")") + if not func then + return false, "Failed: " .. errormsg + end + + -- Apply sandbox here using setfenv + setfenv(func, {}) + + -- Run it + local good, errOrResult = pcall(func) + if not good then + -- A Lua error was thrown + return false, "Failed: " .. errOrResult + end + + -- errOrResult will be the value + return true, errOrResult +end + +-- Item Meta Editor + Node Meta Editor +local node_meta_posses = {} +local meta_latest_keylist = {} + +local function show_meta_formspec(user, metatype, pos_or_item, key, value, keylist) + local textlist + if keylist then + textlist = "textlist[0,0.5;2.5,6.5;keylist;"..keylist.."]" + else + textlist = "" + end + + local form = "size[15,9]".. + "label[0,0;"..F(S("Current keys:")).."]".. + textlist.. + "field[3,0.5;12,1;key;"..F(S("Key"))..";"..F(key).."]".. + "textarea[3,1.5;12,6;value;"..F(S("Value (use empty value to delete key)"))..";"..F(value).."]".. + "button[4,8;3,1;set;"..F(S("Set value")).."]" + + local extra_label + local formname + if metatype == "node" then + formname = "testtools:node_meta_editor" + extra_label = S("pos = @1", core.pos_to_string(pos_or_item)) + else + formname = "testtools:item_meta_editor" + extra_label = S("item = @1", pos_or_item:get_name()) + end + form = form .. "label[0,7.2;"..F(extra_label).."]" + + core.show_formspec(user:get_player_name(), formname, form) +end + +local function get_meta_keylist(meta, playername, escaped) + local keys = {} + local ekeys = {} + local mtable = meta:to_table() + for k,_ in pairs(mtable.fields) do + table.insert(keys, k) + if escaped then + table.insert(ekeys, F(k)) + else + table.insert(ekeys, k) + end + end + if playername then + meta_latest_keylist[playername] = keys + end + return table.concat(ekeys, ",") +end + +core.register_tool("testtools:node_meta_editor", { + description = S("Node Meta Editor") .. "\n" .. + S("Place: Edit node metadata"), + inventory_image = "testtools_node_meta_editor.png", + groups = { testtool = 1, disable_repair = 1 }, + on_place = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + if not user:is_player() then + return itemstack + end + local pos = pointed_thing.under + node_meta_posses[user:get_player_name()] = pos + local meta = core.get_meta(pos) + local inv = meta:get_inventory() + show_meta_formspec(user, "node", pos, "", "", get_meta_keylist(meta, user:get_player_name(), true)) + return itemstack + end, +}) + +local function get_item_next_to_wielded_item(player) + local inv = player:get_inventory() + local wield = player:get_wield_index() + local itemstack = inv:get_stack("main", wield+1) + return itemstack +end +local function set_item_next_to_wielded_item(player, itemstack) + local inv = player:get_inventory() + local wield = player:get_wield_index() + inv:set_stack("main", wield+1, itemstack) +end + +local function use_item_meta_editor(itemstack, user, pointed_thing) + if not user:is_player() then + return itemstack + end + local item_to_edit = get_item_next_to_wielded_item(user) + if item_to_edit:is_empty() then + core.chat_send_player(user:get_player_name(), S("Place an item next to the Item Meta Editor in your inventory first!")) + return itemstack + end + local meta = item_to_edit:get_meta() + show_meta_formspec(user, "item", item_to_edit, "", "", get_meta_keylist(meta, user:get_player_name(), true)) + return itemstack +end + +core.register_tool("testtools:item_meta_editor", { + description = S("Item Meta Editor") .. "\n" .. + S("Punch/Place: Edit item metadata of item in the next inventory slot"), + inventory_image = "testtools_item_meta_editor.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = use_item_meta_editor, + on_secondary_use = use_item_meta_editor, + on_place = use_item_meta_editor, +}) + +core.register_on_player_receive_fields(function(player, formname, fields) + if not (player and player:is_player()) then + return + end + if formname == "testtools:entity_list" then + local name = player:get_player_name() + if fields.entity_list then + local expl = core.explode_textlist_event(fields.entity_list) + if expl.type == "DCL" then + local pos = vector.add(player:get_pos(), {x=0,y=1,z=0}) + selections[name] = expl.index + core.add_entity(pos, get_entity_list()[expl.index]) + return + elseif expl.type == "CHG" then + selections[name] = expl.index + return + end + elseif fields.spawn and selections[name] then + local pos = vector.add(player:get_pos(), {x=0,y=1,z=0}) + core.add_entity(pos, get_entity_list()[selections[name]]) + return + end + elseif formname == "testtools:object_editor" then + local name = player:get_player_name() + if fields.object_props then + local expl = core.explode_textlist_event(fields.object_props) + if expl.type == "DCL" or expl.type == "CHG" then + property_formspec_index[name] = expl.index + + local props = selected_objects[name]:get_properties() + local keys = property_formspec_data[name] + if (not property_formspec_index[name]) or (not props) then + return + end + local key = keys[property_formspec_index[name]] + editor_formspec_selindex[name] = expl.index + editor_formspec(name, selected_objects[name], prop_to_string(props[key]), expl.index) + return + end + end + if fields.key_enter_field == "value" or fields.submit then + local props = selected_objects[name]:get_properties() + local keys = property_formspec_data[name] + if (not property_formspec_index[name]) or (not props) then + return + end + local key = keys[property_formspec_index[name]] + if not key then + return + end + local success, str = use_loadstring(fields.value, player) + if success then + props[key] = str + else + core.chat_send_player(name, str) + return + end + selected_objects[name]:set_properties(props) + local sel = editor_formspec_selindex[name] + editor_formspec(name, selected_objects[name], prop_to_string(props[key]), sel) + return + end + elseif formname == "testtools:node_setter" then + local playername = player:get_player_name() + local witem = player:get_wielded_item() + if witem:get_name() == "testtools:node_setter" then + if fields.nodename and fields.param2 then + local param2 = tonumber(fields.param2) + if not param2 then + return + end + local meta = witem:get_meta() + meta:set_string("node", fields.nodename) + meta:set_int("node_param2", param2) + player:set_wielded_item(witem) + end + end + elseif formname == "testtools:node_meta_editor" or formname == "testtools:item_meta_editor" then + local name = player:get_player_name() + local metatype + local pos_or_item + if formname == "testtools:node_meta_editor" then + metatype = "node" + pos_or_item = node_meta_posses[name] + else + metatype = "item" + pos_or_item = get_item_next_to_wielded_item(player) + end + if fields.keylist then + local evnt = core.explode_textlist_event(fields.keylist) + if evnt.type == "DCL" or evnt.type == "CHG" then + local keylist_table = meta_latest_keylist[name] + if metatype == "node" and not pos_or_item then + return + end + local meta + if metatype == "node" then + meta = core.get_meta(pos_or_item) + else + meta = pos_or_item:get_meta() + end + if not keylist_table then + return + end + if #keylist_table == 0 then + return + end + local key = keylist_table[evnt.index] + local value = meta:get_string(key) + local keylist_escaped = {} + for k,v in pairs(keylist_table) do + keylist_escaped[k] = F(v) + end + local keylist = table.concat(keylist_escaped, ",") + show_meta_formspec(player, metatype, pos_or_item, key, value, keylist) + return + end + elseif fields.key and fields.key ~= "" and fields.value then + if metatype == "node" and not pos_or_item then + return + end + local meta + if metatype == "node" then + meta = core.get_meta(pos_or_item) + elseif metatype == "item" then + if pos_or_item:is_empty() then + return + end + meta = pos_or_item:get_meta() + end + if fields.set then + meta:set_string(fields.key, fields.value) + if metatype == "item" then + set_item_next_to_wielded_item(player, pos_or_item) + end + show_meta_formspec(player, metatype, pos_or_item, fields.key, fields.value, + get_meta_keylist(meta, name, true)) + end + return + end + end +end) + +core.register_on_leaveplayer(function(player) + local name = player:get_player_name() + meta_latest_keylist[name] = nil + node_meta_posses[name] = nil +end) + +-- Pointing Staffs + +core.register_tool("testtools:blocked_pointing_staff", { + description = S("Blocked Pointing Staff").."\n".. + S("Can point the Blocking Pointable Node/Object and ".. + "the Pointable Node/Object is point blocking."), + inventory_image = "testtools_blocked_pointing_staff.png", + pointabilities = { + nodes = { + ["testnodes:blocking_pointable"] = true, + ["group:pointable_test"] = "blocking" + }, + objects = { + ["testentities:blocking_pointable"] = true, + ["group:pointable_test"] = "blocking" + } + } +}) + +core.register_tool("testtools:ultimate_pointing_staff", { + description = S("Ultimate Pointing Staff").."\n".. + S("Can point all pointable test nodes, objects and liquids."), + inventory_image = "testtools_ultimate_pointing_staff.png", + liquids_pointable = true, + pointabilities = { + nodes = { + ["group:blocking_pointable_test"] = true, + ["group:pointable_test"] = true, + ["testnodes:not_pointable"] = true + }, + objects = { + ["group:blocking_pointable_test"] = true, + ["group:pointable_test"] = true, + ["testentities:not_pointable"] = true + } + } +}) diff --git a/data/games/garage/mods/testtools/light.lua b/data/games/garage/mods/testtools/light.lua new file mode 100644 index 0000000..861a358 --- /dev/null +++ b/data/games/garage/mods/testtools/light.lua @@ -0,0 +1,37 @@ + +local S = core.get_translator("testtools") + +local function get_func(is_place) + return function(itemstack, user, pointed_thing) + local pos + if is_place then + pos = pointed_thing.under + else + pos = pointed_thing.above + end + if pointed_thing.type ~= "node" or not pos then + return + end + + local node = core.get_node(pos) + local pstr = core.pos_to_string(pos) + local time = core.get_timeofday() + local sunlight = core.get_natural_light(pos) + local artificial = core.get_artificial_light(node.param1) + local message = ("pos=%s | param1=0x%02x | " .. + "sunlight=%d | artificial=%d | timeofday=%.5f" ) + :format(pstr, node.param1, sunlight, artificial, time) + core.chat_send_player(user:get_player_name(), message) + end +end + +core.register_tool("testtools:lighttool", { + description = S("Light Tool") .. "\n" .. + S("Show light values of node") .. "\n" .. + S("Punch: Light of node above touched node") .. "\n" .. + S("Place: Light of touched node itself"), + inventory_image = "testtools_lighttool.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = get_func(false), + on_place = get_func(true), +}) diff --git a/data/games/garage/mods/testtools/mod.conf b/data/games/garage/mods/testtools/mod.conf new file mode 100644 index 0000000..cde1b26 --- /dev/null +++ b/data/games/garage/mods/testtools/mod.conf @@ -0,0 +1,2 @@ +name = testtools +description = Some tools to directly manipulate nodes and entities. Great for development and testing diff --git a/data/games/garage/mods/testtools/node_box_visualizer.lua b/data/games/garage/mods/testtools/node_box_visualizer.lua new file mode 100644 index 0000000..444f939 --- /dev/null +++ b/data/games/garage/mods/testtools/node_box_visualizer.lua @@ -0,0 +1,79 @@ +local S = core.get_translator("testtools") + +core.register_entity("testtools:visual_box", { + initial_properties = { + visual = "cube", + textures = { + "blank.png", "blank.png", "blank.png", + "blank.png", "blank.png", "blank.png", + }, + use_texture_alpha = true, + physical = false, + pointable = false, + static_save = false, + }, + + on_activate = function(self) + self.timestamp = core.get_us_time() + 5000000 + end, + + on_step = function(self) + if core.get_us_time() >= self.timestamp then + self.object:remove() + end + end, +}) + +local BOX_TYPES = {"node_box", "collision_box", "selection_box"} +local DEFAULT_BOX_TYPE = "selection_box" + +local function visualizer_on_use(itemstack, user, pointed_thing) + if pointed_thing.type ~= "node" then + return + end + + local meta = itemstack:get_meta() + local box_type = meta:get("box_type") or DEFAULT_BOX_TYPE + + local result = core.get_node_boxes(box_type, pointed_thing.under) + local t = "testtools_visual_" .. box_type .. ".png" + + for _, box in ipairs(result) do + local box_min = pointed_thing.under + vector.new(box[1], box[2], box[3]) + local box_max = pointed_thing.under + vector.new(box[4], box[5], box[6]) + local box_center = (box_min + box_max) / 2 + local obj = core.add_entity(box_center, "testtools:visual_box") + if not obj then + break + end + obj:set_properties({ + textures = {t, t, t, t, t, t}, + -- Add a small offset to avoid Z-fighting. + visual_size = vector.add(box_max - box_min, 0.01), + }) + end +end + +local function visualizer_on_place(itemstack, placer, pointed_thing) + local meta = itemstack:get_meta() + local prev_value = meta:get("box_type") or DEFAULT_BOX_TYPE + local prev_index = table.indexof(BOX_TYPES, prev_value) + assert(prev_index ~= -1) + + local new_value = BOX_TYPES[(prev_index % #BOX_TYPES) + 1] + meta:set_string("box_type", new_value) + core.chat_send_player(placer:get_player_name(), S("[Node Box Visualizer] box_type = @1", new_value)) + + return itemstack +end + +core.register_tool("testtools:node_box_visualizer", { + description = S("Node Box Visualizer") .. "\n" .. + S("Punch: Show node/collision/selection boxes of the pointed node") .. "\n" .. + S("Place: Change selected box type (default: selection box)"), + inventory_image = "testtools_node_box_visualizer.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = visualizer_on_use, + on_place = visualizer_on_place, + on_secondary_use = visualizer_on_place, +}) diff --git a/data/games/garage/mods/testtools/particles.lua b/data/games/garage/mods/testtools/particles.lua new file mode 100644 index 0000000..17f4f5c --- /dev/null +++ b/data/games/garage/mods/testtools/particles.lua @@ -0,0 +1,36 @@ +core.register_tool("testtools:particle_spawner", { + description = "Particle Spawner".."\n".. + "Punch: Spawn random test particle", + inventory_image = "testtools_particle_spawner.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + local pos = core.get_pointed_thing_position(pointed_thing, true) + if pos == nil then + if user then + pos = user:get_pos() + end + end + pos = vector.add(pos, {x=0, y=0.5, z=0}) + local tex, anim + if math.random(0, 1) == 0 then + tex = "testtools_particle_sheet.png" + anim = {type="sheet_2d", frames_w=3, frames_h=2, frame_length=0.5} + else + tex = "testtools_particle_vertical.png" + anim = {type="vertical_frames", aspect_w=16, aspect_h=16, length=3.3} + end + + core.add_particle({ + pos = pos, + velocity = {x=0, y=0, z=0}, + acceleration = {x=0, y=0.04, z=0}, + expirationtime = 6, + collisiondetection = true, + texture = tex, + animation = anim, + size = 4, + glow = math.random(0, 5), + }) + end, +}) + diff --git a/data/games/garage/mods/testtools/privatizer.lua b/data/games/garage/mods/testtools/privatizer.lua new file mode 100644 index 0000000..54c3508 --- /dev/null +++ b/data/games/garage/mods/testtools/privatizer.lua @@ -0,0 +1,29 @@ +core.register_tool("testtools:privatizer", { + description = "Node Meta Privatizer".."\n".. + "Punch: Marks 'infotext' and 'formspec' meta fields of chest as private", + inventory_image = "testtools_privatizer.png", + groups = { testtool = 1, disable_repair = 1 }, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + local node = core.get_node(pointed_thing.under) + if core.get_item_group(node.name, "meta_is_privatizable") == 1 then + local p = pointed_thing.under + core.log("action", "[testtools] Privatizer used at "..core.pos_to_string(p)) + core.get_meta(p):mark_as_private({"infotext", "formspec"}) + if user and user:is_player() then + core.chat_send_player(user:get_player_name(), "Node metadata (infotext, formspec) set private!") + end + return + elseif node.name == "chest_of_everything:chest" then + if user and user:is_player() then + core.chat_send_player(user:get_player_name(), "Privatizer can't be used on the Chest of Everything. Use it on a normal chest.") + end + return + end + end + if user and user:is_player() then + core.chat_send_player(user:get_player_name(), "Privatizer can only be used on chest!") + end + end, +}) + diff --git a/data/games/garage/mods/testtools/textures/testtools_blocked_pointing_staff.png b/data/games/garage/mods/testtools/textures/testtools_blocked_pointing_staff.png new file mode 100644 index 0000000000000000000000000000000000000000..aa1cdb97aa1c8393e2272e4608406afc829a6370 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-u0T36GBPc~;Q#;shUrFU zfPBW1AirP+hi5m^fE+DP7sn8e=;Q*M=|9Gif;7(8A5T-G@yGywoL(jtfe literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_branding_iron.png b/data/games/garage/mods/testtools/textures/testtools_branding_iron.png new file mode 100644 index 0000000000000000000000000000000000000000..9ac2bb7f4558ff9ebd5aee7c7575d6a73444fbc5 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Hl8kyAr_~T6Bd~Luy1^5Z));S zG5m4;BwmNh9LbZP_Sy&hxqt22v>fLL>m*EBmMhk?-I-wDd`zH=w}F{qVUf|5mD`_W Q0nK6XboFyt=akR{0Oolp5dZ)H literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_children_getter.png b/data/games/garage/mods/testtools/textures/testtools_children_getter.png new file mode 100644 index 0000000000000000000000000000000000000000..763a1e3d7cc10edfd400561021b873e77b27ed66 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`X`U{QAr_~TKYaX{=)nA+Gr

z>-E2jU;hir|S8q+6U76}5_UGSR!`EDms*%A3b2d79c`Qh~`jk!6 zBj|v9FRQ`aI6sesdrY?Gr=CYkm~W4gk={I$B{}VLu9*4t!cQglwK>mdKI;Vst0Nn;f=>Px# literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_entity_spawner.png b/data/games/garage/mods/testtools/textures/testtools_entity_spawner.png new file mode 100644 index 0000000000000000000000000000000000000000..6199e0145fdb4252ba60c8bf6845a85f7104bf0e GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EuJopAr*{kCN;7hFyL`vKhW^^ z?=R2S`mH`Md~N1(+4ikG?Y-;S4ORJPGkJe&yN{1nQ*)ha-7Sm*nHd=7mwzn|Pyg2lbPt24tDnm{r-UW|C~!&j literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_falling_node_tool.png b/data/games/garage/mods/testtools/textures/testtools_falling_node_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..30099a7ef4201f6f6bfe8e8c52c3a5a371c6f615 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`!JaOTAr*|t2iX1enUXDj{CQ?F zLoMubeF~4LGEV}R;w%M;BW))xUSeR8Si|OE!oP&kCDY+J2eW};T(qH~=emUs#!9PB nT_j#Hntbdto z!S=Cz8F#`g#Tg|H1`Rs-3wJljFVdQ&MBb@0QKD@O#lD@ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_lighttool.png b/data/games/garage/mods/testtools/textures/testtools_lighttool.png new file mode 100644 index 0000000000000000000000000000000000000000..470adbac8815e3f5944dc64609f409553ac5e343 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`d7dtgAr_~T6BwH8|L^^0?7*mJ zW@os_^Bn7LNGV`7L}p}0zT-g5<@ O%?zHdelF{r5}E)c>osTq literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_node_box_visualizer.png b/data/games/garage/mods/testtools/textures/testtools_node_box_visualizer.png new file mode 100644 index 0000000000000000000000000000000000000000..1b16aa7941c133ccc4555904caef4cd829337cc0 GIT binary patch literal 108 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`#-1*YAr_~T6C`{d*bC0sz_?ue z;jtE;Ms20*0wu00)$B(Ziee127^W_oq{Z2#b#hi61B2$=k8UBM9bbXk89ZJ6T-G@y GGywpuqaRZM literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_node_meta_editor.png b/data/games/garage/mods/testtools/textures/testtools_node_meta_editor.png new file mode 100644 index 0000000000000000000000000000000000000000..89eafd65cf92dda7565c70cbbc46a4a2d20ca566 GIT binary patch literal 135 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`ex5FlAr*|t3M_v5Ovx5M{yZ~@ z`}*I|p!0$K1v8B{$%X>PDZaC~4R{yqXwsS}~a0j1cRaWG= iV3^44;d}223&YAw%kNGpxaI&fnZeW5&t;ucLK6THcPrii literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_node_setter.png b/data/games/garage/mods/testtools/textures/testtools_node_setter.png new file mode 100644 index 0000000000000000000000000000000000000000..8599438def3981bff86847fe5a77229a2e11d8c2 GIT binary patch literal 146 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k)AG&Ar*{gCo-}faNuG2&i(g_ zt;zkH?y)ZwG6XFb9kw#4_BJ_L_sCmy&lClrOlz)9&C};^J`fnw)bm5oi%Uj~VRLZK uiJeO{nZ+Y`f7Z@z<6$@Y6Uz3aGH;VuX2AJ-Qs04=FnGH9xvXgTe~DWM4f`a?yO literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_object_editor.png b/data/games/garage/mods/testtools/textures/testtools_object_editor.png new file mode 100644 index 0000000000000000000000000000000000000000..d1ce9cecdb5919c281848625c5532b808cdd4fe7 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`)t)YnAr*{!Cm!T%2;gz9{{HNY z-a_e>+M-%d-8me!_WogCnBeJiHSKW#kKplKo_R}8)Z{S+Hb|6Y9oTeB`oXK~YElB1 z4p{T<*ye2d+w@F`<XZ)VJs{4Hd<{lM9rXA`V0{1jJgu-6HmZTdi8<;z*m e=Pd2dJ~JFk?Y~=7lN}Cp27{-opUXO@geCx!4n@ZR literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_object_mover.png b/data/games/garage/mods/testtools/textures/testtools_object_mover.png new file mode 100644 index 0000000000000000000000000000000000000000..8b14e9fb2a680154ede93137b9a3928f6f4c9d7e GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Wu7jMAr*{gCKz%xIPkDszWwu= zjnm)2FM(Wn8=WM!?rANEF`TSw=(kN-L!HMu5QHW;!rZL8Jv zW&X0M!F>DSVW+d*Una7Vdud`{{%u8&cL)@lLejRR3)saP|u; Z!^#=iCm8NZ%L84&;OXk;vd$@?2>^_nK^p)7 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_param2tool.png b/data/games/garage/mods/testtools/textures/testtools_param2tool.png new file mode 100644 index 0000000000000000000000000000000000000000..dbc66357589142a637ad07b4a34e98b8e475bf87 GIT binary patch literal 127 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Zk{fVAr*|t3sisf_jq2bs1h_% zyQSd6%fakvz~J(D^5Uh8J46NE@=9f@op1OrlIfPQB*ZwA!S-w7aTcBf-JH@6BFoem Z7=kvodCdBH|2xn`22WQ%mvv4FO#n+?CY%5O literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_particle_sheet.png b/data/games/garage/mods/testtools/textures/testtools_particle_sheet.png new file mode 100644 index 0000000000000000000000000000000000000000..6d70394e48d6a2451598c9cd9cdb1947d0559f0c GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^20*O9#0(@gcM10cDb4_&5Z8bI{{8>|{~{aP0fk0G zpkR}yi(^OyWAAxJHfBSC)`unybCx_4v5jIiSRTRn(eGyci8U)OZPAhd>$41eISp(qEPCD+FS%uIwXWmMpZL3}N-F($_eJCV-!!dzR;RPR zYmj$VKk`Y=V1d}@#!C&CO%&okw5sR&A6Xpk)bRPaoxFnAoTCNvCYb_V!{F)a=d#Wz Gp$PzOI!(R+ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_particle_spawner.png b/data/games/garage/mods/testtools/textures/testtools_particle_spawner.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd276b61356f0a41e8fc41ccd37514617d68e01 GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`4xTQKAr*|t5+M)l1^z28;aK&| zKCDwZF7ChMq#rtst9~{IGX_eqaNKC(J#2dUTtgtUM*p$@Q`A&8qybby&bmt{iv Ulap6-fo3syy85}Sb4q9e011F71poj5 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_particle_vertical.png b/data/games/garage/mods/testtools/textures/testtools_particle_vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..0320b7545a55e89c7438a91c6fbf6a1b6590cc0c GIT binary patch literal 308 zcmV-40n7f0P)J+U(t5a@$ z(mz?V(v#q+82$ZHlD`kJh;e6F(!mBC#7p@03sKK`q=DTM^GS5zGi4M^vCbn>W0000d3L$m zz;I)mg0|biBT`M?4-ZH<>=Q3YoW$d>eXfpp!sE-=88!(E%h_-+GHm3V_35#-+e@G+ N44$rjF6*2Ung9*1Bmw{c literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_remover.png b/data/games/garage/mods/testtools/textures/testtools_remover.png new file mode 100644 index 0000000000000000000000000000000000000000..73f14cd549949a103d0799da7bdb64c03e8f3382 GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`9-c0aAr*|t3sisfyU*G1>~da0 z>;J+|;VU&&f=-63EF{|=T=lsjU}U1qP-+tVu7+j4-Npug!HKgPP5fMsWFBMASS0yy cOCtlr$-d5G>mLN<1I=XcboFyt=akR{0K&;ETmS$7 literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtools/textures/testtools_ultimate_pointing_staff.png b/data/games/garage/mods/testtools/textures/testtools_ultimate_pointing_staff.png new file mode 100644 index 0000000000000000000000000000000000000000..e4d80fb4d1c1f92609082c9667103a7b9ec2fc61 GIT binary patch literal 136 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!93?!50ihlx9JOMr-u0Yx-%^)%|^8f$;${!qs zfqcf2AirP+hi5m^fE+DP7sn8e=;QmpL{Qv*oQPxBdD8g70 zs0gasT02Rcp(J1p{K_7K_6AQYppvH!TF1{*`K6071P3I16? O#SEUVelF{r5}E)vW+5#A literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/testtranslations/init.lua b/data/games/garage/mods/testtranslations/init.lua new file mode 100644 index 0000000..a2de998 --- /dev/null +++ b/data/games/garage/mods/testtranslations/init.lua @@ -0,0 +1,26 @@ +local S, NS = core.get_translator("testtranslations") + +local function send_compare(name, text) + core.chat_send_player(name, ("%s | %s | %s"):format( + core.get_translated_string("", text), text, core.get_translated_string("fr", text))) +end + +core.register_chatcommand("testtranslations", { + params = "", + description = "Test translations", + privs = {}, + func = function(name, param) + core.chat_send_player(name, "Please ensure your locale is set to \"fr\"") + core.chat_send_player(name, "Untranslated | Client-side translation | Server-side translation (fr)") + send_compare(name, S("Testing .tr files: untranslated")) + send_compare(name, S("Testing .po files: untranslated")) + send_compare(name, S("Testing .mo files: untranslated")) + send_compare(name, S("Testing fuzzy .po entry: untranslated (expected)")) + send_compare(name, core.translate("translation_po", "Testing .po without context: untranslated")) + send_compare(name, core.translate("translation_mo", "Testing .mo without context: untranslated")) + for i = 0,4 do + send_compare(name, NS("@1: .po singular", "@1: .po plural", i, tostring(i))) + send_compare(name, NS("@1: .mo singular", "@1: .mo plural", i, tostring(i))) + end + end +}) diff --git a/data/games/garage/mods/testtranslations/locale/testtranslations.fr.po b/data/games/garage/mods/testtranslations/locale/testtranslations.fr.po new file mode 100644 index 0000000..2bcc6c7 --- /dev/null +++ b/data/games/garage/mods/testtranslations/locale/testtranslations.fr.po @@ -0,0 +1,9 @@ +# Dummy entry. This is a test to make sure that a parser error is not thrown +# if the following line is msgctxt. +msgctxt "testtranslations" +msgid "Dummy entry" +msgstr "Dummy result" + +# Used for translating the mod title +msgid "Test translations" +msgstr "Test translations (French)" diff --git a/data/games/garage/mods/testtranslations/locale/translation_mo.fr.mo b/data/games/garage/mods/testtranslations/locale/translation_mo.fr.mo new file mode 100644 index 0000000000000000000000000000000000000000..0e7190de975563e0ec746fb84affeacd5313d3ec GIT binary patch literal 494 zcmaKn!A^uQ6h%>SGfUT+bf+xP!PNw0Vq#?N0(WjIbfmGoVq2nqhjHaEx$q186O*~X zFpiqoaB^GvUhlh~d;Y73<%4~226n*>=vD&)@BpUZZKdzf8hn96aKAP5zCaIf{($1^ z--USFV5i&U!a7NJ?6}tKQMyXEjuo1mcycjo$r(;oaVJX8p>jM*P1Zk;;=awIzg66L zxNqh6JAoG zOH2{7*{yVwtKL7%w5ef1!#FlQP1vwaX&xp2Cm(|%_n2zRIF&47N0|{+RBVhLtSjc< OmxEF8!(1 (French plural)" + +#, foo bar fuzzy +msgctxt "testtranslations" +msgid "Testing fuzzy .po entry: untranslated (expected)" +msgstr "Testing fuzzy .po entry: translated (wrong)" + +msgid "Testing .po without context: untranslated" +msgstr "Testing .po without context: translated" diff --git a/data/games/garage/mods/testtranslations/locale/translation_tr.fr.tr b/data/games/garage/mods/testtranslations/locale/translation_tr.fr.tr new file mode 100644 index 0000000..b9ac66a --- /dev/null +++ b/data/games/garage/mods/testtranslations/locale/translation_tr.fr.tr @@ -0,0 +1,2 @@ +# textdomain: testtranslations +Testing .tr files: untranslated=Testing .tr files: translated diff --git a/data/games/garage/mods/testtranslations/mod.conf b/data/games/garage/mods/testtranslations/mod.conf new file mode 100644 index 0000000..1fc09cf --- /dev/null +++ b/data/games/garage/mods/testtranslations/mod.conf @@ -0,0 +1,3 @@ +name = testtranslations +title = Test translations +description = Test mod to test translations. diff --git a/data/games/garage/mods/testtranslations/test_locale/readme.txt b/data/games/garage/mods/testtranslations/test_locale/readme.txt new file mode 100644 index 0000000..7a2ed43 --- /dev/null +++ b/data/games/garage/mods/testtranslations/test_locale/readme.txt @@ -0,0 +1,4 @@ +The translation files in this directory intentionally include errors (which +would be reported when someone starts the devtest game in the de locale). This +allows the unittest to check that the translation file reader also handles +files that include errors. diff --git a/data/games/garage/mods/testtranslations/test_locale/translation_mo.de.mo b/data/games/garage/mods/testtranslations/test_locale/translation_mo.de.mo new file mode 100644 index 0000000000000000000000000000000000000000..ffe05cd7100205ba38f331c44274392b87e821ea GIT binary patch literal 446 zcmZXOF>b;@5Jd+tP#_|NQi52QDO`{e%M}tzK@mYgZIOi_*=uWe9f3s44d4z*OOxBA z;~e3eU0Vtn`RUJ$zGweW*EtcY0eWBxT3`?I`UGw81qR^T&c7%Z{RKRNW`*bp+JknW z6Q~DWKp&t7Xdiln=J(G~d{hH@)q!*Ch^o*$&z~A6Qf8@UTxhv-i%D(7I*UR{#UhO| z8AdeYaq_|6jGLB;(0r?%xplKuB4c{JSxsL!790J}>|hPv1ZFj2!kkvYv(HQ$Fu~k_ k4gKPEJSe%!BK1;" + +msgctxt "testtranslations" +msgid "Testing .mo files: untranslated" +msgstr "Testing .mo files: translated" + +msgid "Testing .mo without context: untranslated" +msgstr "Testing .mo without context: translated" + +msgctxt "testtranslations" +msgid "@1: .mo singular" +msgid_plural "@1: .mo plural" +msgstr[0] "@1: .mo 0 and 1 (French singular)" +msgstr[1] "@1: .mo >1 (French plural)" diff --git a/data/games/garage/mods/tiled/init.lua b/data/games/garage/mods/tiled/init.lua new file mode 100644 index 0000000..51e1fda --- /dev/null +++ b/data/games/garage/mods/tiled/init.lua @@ -0,0 +1,50 @@ +local align_help = "Texture spans over a space of 8×8 nodes" +local align_help_n = "Tiles looks the same for every node" + +core.register_node("tiled:tiled", { + description = "Tiled Node (world-aligned)".."\n"..align_help, + tiles = {{ + name = "tiled_tiled.png", + align_style = "world", + scale = 8, + }}, + groups = {cracky=3}, +}) + +core.register_node("tiled:tiled_rooted", { + description = "Tiled 'plantlike_rooted' Node (world-aligned)".."\n".. + "Base node texture spans over a space of 8×8 nodes".."\n".. + "A plantlike thing grows on top", + paramtype = "light", + drawtype = "plantlike_rooted", + tiles = {{ + name = "tiled_tiled.png", + align_style = "world", + scale = 8, + }}, + special_tiles = {"tiled_tiled_node.png"}, + groups = {cracky=3}, +}) + +core.register_node("tiled:tiled_n", { + description = "Tiled Node (node-aligned)".."\n"..align_help_n, + tiles = {{ + name = "tiled_tiled_node.png", + align_style = "node", + }}, + groups = {cracky=3}, +}) + +stairs.register_stair_and_slab("tiled_n", "tiled:tiled_n", + {cracky=3}, + {{name="tiled_tiled_node.png", align_style="node"}}, + "Tiled Stair (node-aligned)".."\n"..align_help_n, + "Tiled Slab (node-aligned)".."\n"..align_help_n) + +stairs.register_stair_and_slab("tiled", "tiled:tiled", + {cracky=3}, + {{name="tiled_tiled.png", align_style="world", scale=8}}, + "Tiled Stair (world-aligned)".."\n"..align_help, + "Tiled Slab (world-aligned)".."\n"..align_help) + + diff --git a/data/games/garage/mods/tiled/mod.conf b/data/games/garage/mods/tiled/mod.conf new file mode 100644 index 0000000..78b19f9 --- /dev/null +++ b/data/games/garage/mods/tiled/mod.conf @@ -0,0 +1,3 @@ +name = tiled +description = Add nodes with a special texture that spans multiple nodes (aka "world-aligned") +depends = stairs diff --git a/data/games/garage/mods/tiled/textures/tiled_tiled.png b/data/games/garage/mods/tiled/textures/tiled_tiled.png new file mode 100644 index 0000000000000000000000000000000000000000..363a264870a5927f03e7fd4c74e22066cf09d403 GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?I3?vN&YJLDIp#Yx{S0Fue=FBr^&in@gAcx`q zo1Lue3=E9Uo-U3d6^w6ZI_4cR5OMLWW{hgBy&Jcn>n!7{XH0=le#b9Wo2OT&rC6`l zZ6cNLHsgt5!WV;2opN_i8^zf_GHScV^L5|nmC*w6q7#lCOmpgcy{4f~r(qpK6+@EL z1Z{^clEMtO46oS)XZ~Bp+QXI*_b^ZS@`HQn0>RGARiYUOSR1tUGR_qIWKCf(0x~AN zWc$syVfBYEe!b>$A97ah{4Ct?{@`n76$Va*cK#20G9P?ml#6y)%r7Nn^5cNngYZVi zCp-OYCS){l*5_SKI96Sy^ONn5)(Lio6YQT3iVFX`bIs#ZV~v9RnICz-C$qmf?7`w- zH-UeP{f*msvA>yrf;ii5Ed(lVtSMMmdKI;Vst0LkgE Ah5!Hn literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/tiled/textures/tiled_tiled_node.png b/data/games/garage/mods/tiled/textures/tiled_tiled_node.png new file mode 100644 index 0000000000000000000000000000000000000000..cc6902850c541825206a6bf8ac4a3d01b637043a GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfv=>VS)*Z&L*XU?4F00ChJhW`wV z|IeH`^Z!3km|^yUmotIXOivfbkP616gb)_y$qpQAk153Qu`PYbaOy-;L!t)TqEchd zU<3Bm{U5E_#jh`(vUC2!*5du5>{V~0gdZqAjBSzOJI$Mz?!Bn8L(s9EgZ*KpzpkU~ zX+Z;}EPKBN6AJ96xXx5EEzB!#*moJ{-NW^!Q(QwRRQRmId`lMby*k!9m(M7>gTe~DWM4fU=&yL literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/unittests/async_env.lua b/data/games/garage/mods/unittests/async_env.lua new file mode 100644 index 0000000..b00deb3 --- /dev/null +++ b/data/games/garage/mods/unittests/async_env.lua @@ -0,0 +1,209 @@ +-- helper + +core.register_async_dofile(core.get_modpath(core.get_current_modname()) .. + DIR_DELIM .. "inside_async_env.lua") + +local function deepequal(a, b) + if type(a) == "function" then + return type(b) == "function" + elseif type(a) ~= "table" then + return a == b + elseif type(b) ~= "table" then + return false + end + for k, v in pairs(a) do + if not deepequal(v, b[k]) then + return false + end + end + for k, v in pairs(b) do + if not deepequal(a[k], v) then + return false + end + end + return true +end + +-- Object Passing / Serialization + +local test_object = { + name = "stairs:stair_glass", + type = "node", + groups = {oddly_breakable_by_hand = 3, cracky = 3, stair = 1}, + description = "Glass Stair", + sounds = { + dig = {name = "default_glass_footstep", gain = 0.5}, + footstep = {name = "default_glass_footstep", gain = 0.3}, + dug = {name = "default_break_glass", gain = 1} + }, + node_box = { + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0, 0.5}, + {-0.5, 0, 0, 0.5, 0.5, 0.5} + }, + type = "fixed" + }, + tiles = { + {name = "stairs_glass_split.png", backface_culling = true}, + {name = "default_glass.png", backface_culling = true}, + {name = "stairs_glass_stairside.png^[transformFX", backface_culling = true} + }, + on_place = function(itemstack, placer) + return core.is_player(placer) + end, + sunlight_propagates = true, + is_ground_content = false, + pos = vector.new(-1, -2, -3), +} + +local function test_object_passing() + local tmp = core.serialize_roundtrip(test_object) + assert(deepequal(test_object, tmp)) + + local circular_key = {"foo", "bar"} + circular_key[circular_key] = true + tmp = core.serialize_roundtrip(circular_key) + assert(tmp[1] == "foo") + assert(tmp[2] == "bar") + assert(tmp[tmp] == true) + + local circular_value = {"foo"} + circular_value[2] = circular_value + tmp = core.serialize_roundtrip(circular_value) + assert(tmp[1] == "foo") + assert(tmp[2] == tmp) + + -- Two-segment cycle + local cycle_seg_1, cycle_seg_2 = {}, {} + cycle_seg_1[1] = cycle_seg_2 + cycle_seg_2[1] = cycle_seg_1 + tmp = core.serialize_roundtrip(cycle_seg_1) + assert(tmp[1][1] == tmp) + + -- Duplicated value without a cycle + local acyclic_dup_holder = {} + tmp = ItemStack("") + acyclic_dup_holder[tmp] = tmp + tmp = core.serialize_roundtrip(acyclic_dup_holder) + for k, v in pairs(tmp) do + assert(rawequal(k, v)) + end +end +unittests.register("test_object_passing", test_object_passing) + +local function test_userdata_passing(_, pos) + -- basic userdata passing + local obj = table.copy(test_object.tiles[1]) + obj.test = ItemStack("default:cobble 99") + local tmp = core.serialize_roundtrip(obj) + assert(type(tmp.test) == "userdata") + assert(obj.test:to_string() == tmp.test:to_string()) + + -- object can't be passed, should error + obj = core.raycast(pos, pos) + assert(not pcall(core.serialize_roundtrip, obj)) + + -- VManip + local vm = core.get_voxel_manip(pos, pos) + local expect = vm:get_node_at(pos) + local vm2 = core.serialize_roundtrip(vm) + assert(deepequal(vm2:get_node_at(pos), expect)) +end +unittests.register("test_userdata_passing", test_userdata_passing, {map=true}) + +-- Asynchronous jobs + +local function test_handle_async(cb) + -- Basic test including mod name tracking and unittests.async_test() + -- which is defined inside_async_env.lua + local func = function(x) + return core.get_last_run_mod(), _VERSION, unittests[x]() + end + local expect = {core.get_last_run_mod(), _VERSION, true} + + core.handle_async(func, function(...) + if not deepequal(expect, {...}) then + return cb("Values did not equal") + end + if core.get_last_run_mod() ~= expect[1] then + return cb("Mod name not tracked correctly") + end + + -- Test passing of nil arguments and return values + core.handle_async(function(a, b) + return a, b + end, function(a, b) + if b ~= 123 then + return cb("Argument went missing") + end + cb() + end, nil, 123) + end, "async_test") +end +unittests.register("test_handle_async", test_handle_async, {async=true}) + +local function test_userdata_passing2(cb, _, pos) + -- VManip: check transfer into other env + local vm = core.get_voxel_manip(pos, pos) + local expect = vm:get_node_at(pos) + + core.handle_async(function(vm_, pos_) + return vm_:get_node_at(pos_) + end, function(ret) + if not deepequal(expect, ret) then + return cb("Node data mismatch (one-way)") + end + + -- VManip: test a roundtrip + core.handle_async(function(vm_) + return vm_ + end, function(vm2) + if not deepequal(expect, vm2:get_node_at(pos)) then + return cb("Node data mismatch (roundtrip)") + end + cb() + end, vm) + end, vm, pos) +end +unittests.register("test_userdata_passing2", test_userdata_passing2, {map=true, async=true}) + +local function test_portable_metatable_override() + assert(pcall(core.register_portable_metatable, "__builtin:vector", vector.metatable), + "Metatable name aliasing throws an error when it should be allowed") + + assert(not pcall(core.register_portable_metatable, "__builtin:vector", {}), + "Illegal metatable overriding allowed") +end +unittests.register("test_portable_metatable_override", test_portable_metatable_override) + +local function test_portable_metatable_registration(cb) + local custom_metatable = {} + core.register_portable_metatable("unittests:custom_metatable", custom_metatable) + + core.handle_async(function(x) + -- unittests.custom_metatable is registered in inside_async_env.lua + return getmetatable(x) == unittests.custom_metatable, x + end, function(metatable_preserved_async, table_after_roundtrip) + if not metatable_preserved_async then + return cb("Custom metatable not preserved (main -> async)") + end + if getmetatable(table_after_roundtrip) ~= custom_metatable then + return cb("Custom metable not preserved (after roundtrip)") + end + cb() + end, setmetatable({}, custom_metatable)) +end +unittests.register("test_portable_metatable_registration", test_portable_metatable_registration, {async=true}) + +local function test_vector_preserve(cb) + local vec = vector.new(1, 2, 3) + core.handle_async(function(x) + return x[1] + end, function(ret) + if ret ~= vec then -- fails if metatable was not preserved + return cb("Vector value mismatch") + end + cb() + end, {vec}) +end +unittests.register("test_async_vector", test_vector_preserve, {async=true}) diff --git a/data/games/garage/mods/unittests/color.lua b/data/games/garage/mods/unittests/color.lua new file mode 100644 index 0000000..8615444 --- /dev/null +++ b/data/games/garage/mods/unittests/color.lua @@ -0,0 +1,17 @@ +local function assert_colors_equal(c1, c2) + if type(c1) == "table" and type(c2) == "table" then + assert(c1.r == c2.r and c1.g == c2.g and c1.b == c2.b and c1.a == c2.a) + else + assert(c1 == c2) + end +end + +local function test_color_conversion() + assert_colors_equal(core.colorspec_to_table("#fff"), {r = 255, g = 255, b = 255, a = 255}) + assert_colors_equal(core.colorspec_to_table(0xFF00FF00), {r = 0, g = 255, b = 0, a = 255}) + assert_colors_equal(core.colorspec_to_table("#00000000"), {r = 0, g = 0, b = 0, a = 0}) + assert_colors_equal(core.colorspec_to_table("green"), {r = 0, g = 128, b = 0, a = 255}) + assert_colors_equal(core.colorspec_to_table("gren"), nil) +end + +unittests.register("test_color_conversion", test_color_conversion) diff --git a/data/games/garage/mods/unittests/content_ids.lua b/data/games/garage/mods/unittests/content_ids.lua new file mode 100644 index 0000000..d2f1e0c --- /dev/null +++ b/data/games/garage/mods/unittests/content_ids.lua @@ -0,0 +1,37 @@ +core.register_alias("unittests:test_content_ids_alias1", "air") +core.register_alias("unittests:test_content_ids_alias2", "~") + +local function test_content_ids() + assert(core.get_content_id("air") == core.CONTENT_AIR) + assert(core.get_content_id("unittests:test_content_ids_alias1") == core.CONTENT_AIR) + assert(core.get_content_id("unknown") == core.CONTENT_UNKNOWN) + assert(core.get_content_id("ignore") == core.CONTENT_IGNORE) + + assert(core.get_name_from_content_id(core.CONTENT_AIR) == "air") + assert(core.get_name_from_content_id(core.CONTENT_UNKNOWN) == "unknown") + assert(core.get_name_from_content_id(core.CONTENT_IGNORE) == "ignore") + + assert(pcall(core.get_content_id, "~") == false) + assert(pcall(core.get_content_id, "unittests:test_content_ids_alias2") == false) + assert(pcall(core.get_content_id) == false) + assert(core.get_name_from_content_id(0xFFFF) == "unknown") + assert(pcall(core.get_name_from_content_id) == false) +end + +-- Run while mod is loading. +test_content_ids() + +-- Run after mods have loaded. +unittests.register("test_content_ids", test_content_ids) + +-- Run in async environment. +local function test_content_ids_async(cb) + local function func(test_func) + local ok, err = pcall(test_func) + if not ok then + return err + end + end + core.handle_async(func, cb, test_content_ids) +end +unittests.register("test_content_ids_async", test_content_ids_async, {async=true}) diff --git a/data/games/garage/mods/unittests/crafting.lua b/data/games/garage/mods/unittests/crafting.lua new file mode 100644 index 0000000..38b1202 --- /dev/null +++ b/data/games/garage/mods/unittests/crafting.lua @@ -0,0 +1,112 @@ +dofile(core.get_modpath(core.get_current_modname()) .. "/crafting_prepare.lua") + +-- Test core.clear_craft function +local function test_clear_craft() + -- Clearing by output + core.register_craft({ + output = "foo", + recipe = {{"bar"}} + }) + core.register_craft({ + output = "foo 4", + recipe = {{"foo", "bar"}} + }) + assert(#core.get_all_craft_recipes("foo") == 2) + core.clear_craft({output="foo"}) + assert(core.get_all_craft_recipes("foo") == nil) + -- Clearing by input + core.register_craft({ + output = "foo 4", + recipe = {{"foo", "bar"}} + }) + assert(#core.get_all_craft_recipes("foo") == 1) + core.clear_craft({recipe={{"foo", "bar"}}}) + assert(core.get_all_craft_recipes("foo") == nil) +end +unittests.register("test_clear_craft", test_clear_craft) + +-- Test core.get_craft_result function +local function test_get_craft_result() + -- normal + local input = { + method = "normal", + width = 2, + items = {"", "unittests:coal_lump", "", "unittests:stick"} + } + core.log("info", "[unittests] torch crafting input: "..dump(input)) + local output, decremented_input = core.get_craft_result(input) + core.log("info", "[unittests] torch crafting output: "..dump(output)) + core.log("info", "[unittests] torch crafting decremented input: "..dump(decremented_input)) + assert(output.item) + core.log("info", "[unittests] torch crafting output.item:to_table(): "..dump(output.item:to_table())) + assert(output.item:get_name() == "unittests:torch") + assert(output.item:get_count() == 4) + + -- fuel + input = { + method = "fuel", + width = 1, + items = {"unittests:coal_lump"} + } + core.log("info", "[unittests] coal fuel input: "..dump(input)) + output, decremented_input = core.get_craft_result(input) + core.log("info", "[unittests] coal fuel output: "..dump(output)) + core.log("info", "[unittests] coal fuel decremented input: "..dump(decremented_input)) + assert(output.time) + assert(output.time > 0) + + -- cooking + input = { + method = "cooking", + width = 1, + items = {"unittests:iron_lump"} + } + core.log("info", "[unittests] iron lump cooking input: "..dump(output)) + output, decremented_input = core.get_craft_result(input) + core.log("info", "[unittests] iron lump cooking output: "..dump(output)) + core.log("info", "[unittests] iron lump cooking decremented input: "..dump(decremented_input)) + assert(output.time) + assert(output.time > 0) + assert(output.item) + core.log("info", "[unittests] iron lump cooking output.item:to_table(): "..dump(output.item:to_table())) + assert(output.item:get_name() == "unittests:steel_ingot") + assert(output.item:get_count() == 1) + + -- tool repair (repairable) + input = { + method = "normal", + width = 2, + -- Using a wear of 60000 + items = {"unittests:repairable_tool 1 60000", "unittests:repairable_tool 1 60000"} + } + core.log("info", "[unittests] repairable tool crafting input: "..dump(input)) + output, decremented_input = core.get_craft_result(input) + core.log("info", "[unittests] repairable tool crafting output: "..dump(output)) + core.log("info", "[unittests] repairable tool crafting decremented input: "..dump(decremented_input)) + assert(output.item) + core.log("info", "[unittests] repairable tool crafting output.item:to_table(): "..dump(output.item:to_table())) + assert(output.item:get_name() == "unittests:repairable_tool") + -- Test the wear value. + -- See src/craftdef.cpp in Luanti source code for the formula. The formula to calculate + -- the value 51187 is: + -- 65536 - ((65536-60000)+(65536-60000)) + floor(additonal_wear * 65536 + 0.5) = 51187 + -- where additional_wear = 0.05 + assert(output.item:get_wear() == 51187) + assert(output.item:get_count() == 1) + + -- failing tool repair (unrepairable) + input = { + method = "normal", + width = 2, + items = {"unittests:unrepairable_tool 1 60000", "unittests:unrepairable_tool 1 60000"} + } + core.log("info", "[unittests] unrepairable tool crafting input: "..dump(input)) + output, decremented_input = core.get_craft_result(input) + core.log("info", "[unittests] unrepairable tool crafting output: "..dump(output)) + core.log("info", "[unittests] unrepairable tool crafting decremented input: "..dump(decremented_input)) + assert(output.item) + core.log("info", "[unittests] unrepairable tool crafting output.item:to_table(): "..dump(output.item:to_table())) + -- unrepairable tool must not yield any output + assert(output.item:is_empty()) +end +unittests.register("test_get_craft_result", test_get_craft_result) diff --git a/data/games/garage/mods/unittests/crafting_prepare.lua b/data/games/garage/mods/unittests/crafting_prepare.lua new file mode 100644 index 0000000..63ad0a5 --- /dev/null +++ b/data/games/garage/mods/unittests/crafting_prepare.lua @@ -0,0 +1,94 @@ +-- Registering some dummy items and recipes for the crafting tests + +core.register_craftitem("unittests:torch", { + description = "Crafting Test Item: Torch", + inventory_image = "unittests_torch.png", + + groups = { dummy = 1 }, +}) +core.register_craftitem("unittests:coal_lump", { + description = "Crafting Test Item: Coal Lump", + inventory_image = "unittests_coal_lump.png", + + groups = { dummy = 1 }, +}) +core.register_craftitem("unittests:stick", { + description = "Crafting Test Item: Stick", + inventory_image = "unittests_stick.png", + + groups = { dummy = 1 }, +}) +core.register_craftitem("unittests:iron_lump", { + description = "Crafting Test Item: Iron Lump", + inventory_image = "unittests_iron_lump.png", + + groups = { dummy = 1 }, +}) +core.register_craftitem("unittests:steel_ingot", { + description = "Crafting Test Item: Steel Ingot", + inventory_image = "unittests_steel_ingot.png", + + groups = { dummy = 1 }, +}) + +-- Use aliases in recipes for more complete testing + +core.register_alias("unittests:steel_ingot_alias", "unittests:steel_ingot") +core.register_alias("unittests:coal_lump_alias", "unittests:coal_lump") +core.register_alias("unittests:iron_lump_alias", "unittests:iron_lump") + +-- Recipes for tests: Normal crafting, cooking and fuel + +core.register_craft({ + output = 'unittests:torch 4', + recipe = { + {'unittests:coal_lump_alias'}, + {'unittests:stick'}, + } +}) + +core.register_craft({ + type = "cooking", + output = "unittests:steel_ingot_alias", + recipe = "unittests:iron_lump_alias", +}) + +core.register_craft({ + type = "fuel", + recipe = "unittests:coal_lump_alias", + burntime = 40, +}) + +-- Test tool repair +core.register_craft({ + type = "toolrepair", + additional_wear = -0.05, +}) + +-- Test the disable_repair=1 group +core.register_tool("unittests:unrepairable_tool", { + description = "Crafting Test Item: Unrepairable Tool", + inventory_image = "unittests_unrepairable_tool.png", + tool_capabilities = { + groupcaps = { + cracky = { + times = {3, 2, 1}, + } + } + }, + groups = { disable_repair = 1, dummy = 1 } +}) + +core.register_tool("unittests:repairable_tool", { + description = "Crafting Test Item: Repairable Tool", + inventory_image = "unittests_repairable_tool.png", + tool_capabilities = { + groupcaps = { + cracky = { + times = {3, 2, 1}, + } + } + }, + + groups = { dummy = 1 }, +}) diff --git a/data/games/garage/mods/unittests/entity.lua b/data/games/garage/mods/unittests/entity.lua new file mode 100644 index 0000000..af91a2a --- /dev/null +++ b/data/games/garage/mods/unittests/entity.lua @@ -0,0 +1,236 @@ +local log = {} + +local function insert_log(...) + log[#log+1] = string.format(...) +end + +local function objref_str(self, ref) + if ref and ref:is_player() then + return "player" + end + return self.object == ref and "self" or tostring(ref) +end + +core.register_entity("unittests:callbacks", { + initial_properties = { + hp_max = 5, + visual = "upright_sprite", + textures = { "unittests_callback.png" }, + static_save = false, + }, + + on_activate = function(self, staticdata, dtime_s) + self.object:set_armor_groups({test = 100}) + assert(self.object:get_hp() == self.initial_properties.hp_max) + insert_log("on_activate(%d)", #staticdata) + end, + on_deactivate = function(self, removal) + insert_log("on_deactivate(%s)", tostring(removal)) + end, + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + insert_log("on_punch(%s, %.1f, %d)", objref_str(self, puncher), + time_from_last_punch, damage) + end, + on_death = function(self, killer) + assert(self.object:get_hp() == 0) + insert_log("on_death(%s)", objref_str(self, killer)) + end, + on_rightclick = function(self, clicker) + insert_log("on_rightclick(%s)", objref_str(self, clicker)) + end, + on_attach_child = function(self, child) + insert_log("on_attach_child(%s)", objref_str(self, child)) + assert(child:get_attach() == self.object) + local ok = false + for _, obj in ipairs(self.object:get_children()) do + if obj == child then + ok = true + end + end + assert(ok, "Child not found in get_children") + end, + on_detach_child = function(self, child) + insert_log("on_detach_child(%s)", objref_str(self, child)) + assert(child:get_attach() == nil) + local ok = true + for _, obj in ipairs(self.object:get_children()) do + if obj == child then + ok = false + end + end + assert(ok, "Former child found in get_children") + end, + on_detach = function(self, parent) + insert_log("on_detach(%s)", objref_str(self, parent)) + assert(self.object:get_attach() == nil) + local ok = true + for _, obj in ipairs(parent:get_children()) do + if obj == self.object then + ok = false + end + end + assert(ok, "Former child found in get_children") + end, + get_staticdata = function(self) + assert(false) + end, +}) + +-- + +local function check_log(expect) + if #expect ~= #log then + error("Log mismatch: " .. core.write_json(log)) + end + for i, s in ipairs(expect) do + if log[i] ~= s then + error("Log mismatch at " .. i .. ": " .. core.write_json(log)) + end + end + log = {} -- clear it for next time +end + +local function test_entity_lifecycle(_, pos) + log = {} + + -- with binary in staticdata + local obj = core.add_entity(pos, "unittests:callbacks", "abc\000def") + assert(obj and obj:is_valid()) + check_log({"on_activate(7)"}) + + obj:set_hp(0) + check_log({"on_death(nil)", "on_deactivate(true)"}) + + assert(not obj:is_valid()) +end +unittests.register("test_entity_lifecycle", test_entity_lifecycle, {map=true}) + +local function test_entity_interact(_, pos) + log = {} + + local obj = core.add_entity(pos, "unittests:callbacks") + check_log({"on_activate(0)"}) + + -- rightclick + obj:right_click(obj) + check_log({"on_rightclick(self)"}) + + -- useless punch + obj:punch(obj, 0.5, {}) + check_log({"on_punch(self, 0.5, 0)"}) + + -- fatal punch + obj:punch(obj, 1.9, { + full_punch_interval = 1.0, + damage_groups = { test = 10 }, + }) + check_log({ + -- does 10 damage even though we only have 5 hp + "on_punch(self, 1.9, 10)", + "on_death(self)", + "on_deactivate(true)" + }) +end +unittests.register("test_entity_interact", test_entity_interact, {map=true}) + +local function test_entity_attach(player, pos) + log = {} + + local obj = core.add_entity(pos, "unittests:callbacks") + check_log({"on_activate(0)"}) + + -- attach player to entity + player:set_attach(obj) + check_log({"on_attach_child(player)"}) + assert(player:get_attach() == obj) + player:set_detach() + check_log({"on_detach_child(player)"}) + assert(player:get_attach() == nil) + + -- attach entity to player + obj:set_attach(player) + check_log({}) + assert(obj:get_attach() == player) + obj:set_detach() + check_log({"on_detach(player)"}) + assert(obj:get_attach() == nil) + + obj:remove() +end +unittests.register("test_entity_attach", test_entity_attach, {player=true, map=true}) + +--------- + +core.register_entity("unittests:dummy", { + initial_properties = { + hp_max = 1, + visual = "upright_sprite", + textures = { "no_texture.png" }, + static_save = false, + }, +}) + +local function test_entity_raycast(_, pos) + local obj1 = core.add_entity(pos, "unittests:dummy") + local obj2 = core.add_entity(pos:offset(1, 0, 0), "unittests:dummy") + local raycast = core.raycast(pos:offset(-1, 0, 0), pos:offset(2, 0, 0), true, false) + for pt in raycast do + if pt.type == "object" then + assert(pt.ref == obj1) + obj1:remove() + obj2:remove() + obj1 = nil -- object should be hit exactly one + end + end + assert(obj1 == nil) +end +unittests.register("test_entity_raycast", test_entity_raycast, {map=true}) + +local function test_object_iterator(pos, make_iterator) + local obj1 = core.add_entity(pos, "unittests:dummy") + local obj2 = core.add_entity(pos, "unittests:dummy") + assert(obj1 and obj2) + local found = false + -- As soon as we find one of the objects, we remove both, invalidating the other. + for obj in make_iterator() do + assert(obj:is_valid()) + if obj == obj1 or obj == obj2 then + obj1:remove() + obj2:remove() + found = true + end + end + assert(found) +end + +unittests.register("test_objects_inside_radius", function(_, pos) + test_object_iterator(pos, function() + return core.objects_inside_radius(pos, 1) + end) +end, {map=true}) + +unittests.register("test_objects_in_area", function(_, pos) + test_object_iterator(pos, function() + return core.objects_in_area(pos:offset(-1, -1, -1), pos:offset(1, 1, 1)) + end) +end, {map=true}) + +-- Tests that bone rotation euler angles are preserved (see #14992) +local function test_get_bone_rot(_, pos) + local obj = core.add_entity(pos, "unittests:dummy") + for _ = 1, 100 do + local function assert_similar(euler_angles) + local _, rot = obj:get_bone_position("bonename") + assert(euler_angles:distance(rot) < 1e-3) + local override = obj:get_bone_override("bonename") + assert(euler_angles:distance(override.rotation.vec:apply(math.deg)) < 1e-3) + end + local deg = 1e3 * vector.new(math.random(), math.random(), math.random()) + obj:set_bone_position("bonename", vector.zero(), deg) + assert_similar(deg) + local rad = 3 * math.pi * vector.new(math.random(), math.random(), math.random()) + obj:set_bone_override("bonename", {rotation = {vec = rad}}) + assert_similar(rad:apply(math.deg)) + end +end +unittests.register("test_get_bone_rot", test_get_bone_rot, {map=true}) diff --git a/data/games/garage/mods/unittests/get_version.lua b/data/games/garage/mods/unittests/get_version.lua new file mode 100644 index 0000000..7ef7825 --- /dev/null +++ b/data/games/garage/mods/unittests/get_version.lua @@ -0,0 +1,16 @@ + +unittests.register("test_get_version", function() + local version = core.get_version() + assert(type(version) == "table") + assert(type(version.project) == "string") + assert(type(version.string) == "string") + assert(type(version.proto_min) == "number") + assert(type(version.proto_max) == "number") + assert(version.proto_max >= version.proto_min) + assert(type(version.is_dev) == "boolean") + if version.is_dev then + assert(type(version.hash) == "string") + else + assert(version.hash == nil) + end +end) diff --git a/data/games/garage/mods/unittests/init.lua b/data/games/garage/mods/unittests/init.lua new file mode 100644 index 0000000..7243343 --- /dev/null +++ b/data/games/garage/mods/unittests/init.lua @@ -0,0 +1,235 @@ +unittests = {} + +unittests.list = {} + +-- name: Name of the test +-- func: +-- for sync: function(player, pos), should error on failure +-- for async: function(callback, player, pos) +-- MUST call callback() or callback("error msg") in case of error once test is finished +-- this means you cannot use assert() in the test implementation +-- opts: { +-- player = false, -- Does test require a player? +-- map = false, -- Does test require map access? +-- async = false, -- Does the test run asynchronously? (read notes above!) +-- } +function unittests.register(name, func, opts) + local def = table.copy(opts or {}) + def.name = name + def.func = func + table.insert(unittests.list, def) +end + +function unittests.on_finished(all_passed) + -- free to override +end + +-- Calls invoke with a callback as argument +-- Suspends coroutine until that callback is called +-- Return values are passed through +local function await(invoke) + local co = coroutine.running() + assert(co) + local called_early = true + invoke(function(...) + if called_early == true then + called_early = {...} + else + coroutine.resume(co, ...) + co = nil + end + end) + if called_early ~= true then + -- callback was already called before yielding + return unpack(called_early) + end + called_early = nil + return coroutine.yield() +end + +function unittests.run_one(idx, counters, out_callback, player, pos) + local def = unittests.list[idx] + if not def.player then + player = nil + elseif player == nil then + out_callback(false) + return false + end + if not def.map then + pos = nil + elseif pos == nil then + out_callback(false) + return false + end + + local tbegin = core.get_us_time() + local function done(status, err) + local tend = core.get_us_time() + local ms_taken = (tend - tbegin) / 1000 + + if not status then + core.log("error", err) + end + print(string.format("[%s] %s - %dms", + status and "PASS" or "FAIL", def.name, ms_taken)) + counters.time = counters.time + ms_taken + counters.total = counters.total + 1 + if status then + counters.passed = counters.passed + 1 + end + end + + if def.async then + core.log("info", "[unittest] running " .. def.name .. " (async)") + def.func(function(err) + done(err == nil, err) + out_callback(true) + end, player, pos) + else + core.log("info", "[unittest] running " .. def.name) + local status, err = pcall(def.func, player, pos) + done(status, err) + out_callback(true) + end + + return true +end + +local function wait_for_player(callback) + if #core.get_connected_players() > 0 then + return callback(core.get_connected_players()[1]) + end + local first = true + core.register_on_joinplayer(function(player) + if first then + callback(player) + first = false + end + end) +end + +local function wait_for_map(pos, callback) + local function check() + if core.get_node(pos).name ~= "ignore" then + callback() + else + core.after(0, check) + end + end + check() +end + +-- This runs in a coroutine so it uses await() +function unittests.run_all() + local counters = { time = 0, total = 0, passed = 0 } + + -- Run standalone tests first + for idx = 1, #unittests.list do + local def = unittests.list[idx] + def.done = await(function(cb) + unittests.run_one(idx, counters, cb, nil, nil) + end) + end + + -- Wait for a player to join, run tests that require a player + local player = await(wait_for_player) + for idx = 1, #unittests.list do + local def = unittests.list[idx] + if not def.done then + def.done = await(function(cb) + unittests.run_one(idx, counters, cb, player, nil) + end) + end + end + + -- Wait for the world to generate/load, run tests that require map access + local pos = player:get_pos():round():offset(0, 5, 0) + core.forceload_block(pos, true, -1) + await(function(cb) + wait_for_map(pos, cb) + end) + for idx = 1, #unittests.list do + local def = unittests.list[idx] + if not def.done then + def.done = await(function(cb) + unittests.run_one(idx, counters, cb, player, pos) + end) + end + end + + -- Print stats + assert(#unittests.list == counters.total) + print(string.rep("+", 80)) + print(string.format("Devtest Unit Test Results: %s", + counters.total == counters.passed and "PASSED" or "FAILED")) + print(string.format(" %d / %d failed tests.", + counters.total - counters.passed, counters.total)) + print(string.format(" Testing took %dms total.", counters.time)) + print(string.rep("+", 80)) + unittests.on_finished(counters.total == counters.passed) + return counters.total == counters.passed +end + +-------------- + +local modpath = core.get_modpath("unittests") +dofile(modpath .. "/misc.lua") +dofile(modpath .. "/player.lua") +dofile(modpath .. "/crafting.lua") +dofile(modpath .. "/itemdescription.lua") +dofile(modpath .. "/async_env.lua") +dofile(modpath .. "/entity.lua") +dofile(modpath .. "/get_version.lua") +dofile(modpath .. "/itemstack_equals.lua") +dofile(modpath .. "/content_ids.lua") +dofile(modpath .. "/metadata.lua") +dofile(modpath .. "/raycast.lua") +dofile(modpath .. "/inventory.lua") +dofile(modpath .. "/load_time.lua") +dofile(modpath .. "/on_shutdown.lua") +dofile(modpath .. "/color.lua") + +-------------- + +local function send_results(name, ok) + core.chat_send_player(name, + core.colorize(ok and "green" or "red", + (ok and "All devtest unit tests passed." or + "There were devtest unit test failures.") .. + " Check the console for detailed output.")) +end + +if core.settings:get_bool("devtest_unittests_autostart", false) then + local test_results = nil + core.after(0, function() + -- CI adds a mod which sets `unittests.on_finished` + -- to write status information to the filesystem + local old_on_finished = unittests.on_finished + unittests.on_finished = function(ok) + for _, player in ipairs(core.get_connected_players()) do + send_results(player:get_player_name(), ok) + end + test_results = ok + old_on_finished(ok) + end + coroutine.wrap(unittests.run_all)() + end) + core.register_on_joinplayer(function(player) + if test_results == nil then + return -- tests haven't completed yet + end + send_results(player:get_player_name(), test_results) + end) +else + core.register_chatcommand("unittests", { + privs = {basic_privs=true}, + description = "Runs devtest unittests (may modify player or map state)", + func = function(name, param) + unittests.on_finished = function(ok) + send_results(name, ok) + end + coroutine.wrap(unittests.run_all)() + return true, "" + end, + }) +end diff --git a/data/games/garage/mods/unittests/inside_async_env.lua b/data/games/garage/mods/unittests/inside_async_env.lua new file mode 100644 index 0000000..fb61060 --- /dev/null +++ b/data/games/garage/mods/unittests/inside_async_env.lua @@ -0,0 +1,35 @@ +unittests = {} + +core.log("info", "Hello World") + +unittests.custom_metatable = {} +core.register_portable_metatable("unittests:custom_metatable", unittests.custom_metatable) + +local function do_tests() + assert(core == minetest) + -- stuff that should not be here + assert(not core.get_player_by_name) + assert(not core.set_node) + assert(not core.object_refs) + -- stuff that should be here + assert(ItemStack) + local meta = ItemStack():get_meta() + assert(type(meta) == "userdata") + assert(type(meta.set_tool_capabilities) == "function") + assert(core.registered_items[""]) + assert(next(core.registered_nodes) ~= nil) + assert(core.registered_craftitems["unittests:stick"]) + -- alias handling + assert(core.registered_items["unittests:steel_ingot_alias"].name == + "unittests:steel_ingot") + -- fallback to item defaults + assert(core.registered_items["unittests:description_test"].on_place == true) +end + +function unittests.async_test() + local ok, err = pcall(do_tests) + if not ok then + core.log("error", err) + end + return ok +end diff --git a/data/games/garage/mods/unittests/inside_mapgen_env.lua b/data/games/garage/mods/unittests/inside_mapgen_env.lua new file mode 100644 index 0000000..f6f8513 --- /dev/null +++ b/data/games/garage/mods/unittests/inside_mapgen_env.lua @@ -0,0 +1,34 @@ +core.log("info", "Hello World") + +local function do_tests() + assert(core == minetest) + -- stuff that should not be here + assert(not core.get_player_by_name) + assert(not core.object_refs) + -- stuff that should be here + assert(core.register_on_generated) + assert(core.get_node) + assert(core.spawn_tree) + assert(ItemStack) + local meta = ItemStack():get_meta() + assert(type(meta) == "userdata") + assert(type(meta.set_tool_capabilities) == "function") + assert(core.registered_items[""]) + assert(core.save_gen_notify) + -- alias handling + assert(core.registered_items["unittests:steel_ingot_alias"].name == + "unittests:steel_ingot") + -- fallback to item defaults + assert(core.registered_items["unittests:description_test"].on_place == true) +end + +-- first thread to get here runs the tests +if core.ipc_cas("unittests:mg_once", nil, true) then + -- this is checked from the main env + core.ipc_set("unittests:mg", { pcall(do_tests) }) +end + +core.register_on_generated(function(vm, pos1, pos2, blockseed) + local n = tonumber(core.get_mapgen_setting("chunksize")) * 16 - 1 + assert(pos2:subtract(pos1) == vector.new(n, n, n)) +end) diff --git a/data/games/garage/mods/unittests/inventory.lua b/data/games/garage/mods/unittests/inventory.lua new file mode 100644 index 0000000..cffcba4 --- /dev/null +++ b/data/games/garage/mods/unittests/inventory.lua @@ -0,0 +1,73 @@ + +local item_with_meta = ItemStack({name = "air", meta = {test = "abc"}}) + +local test_list = { + ItemStack("air"), + ItemStack(""), + ItemStack(item_with_meta), +} + +local function compare_lists(a, b) + if not a or not b or #a ~= #b then + return false + end + for i=1, #a do + if not ItemStack(a[i]):equals(ItemStack(b[i])) then + return false + end + end + return true +end + +local function test_inventory() + local inv = core.create_detached_inventory("test") + + inv:set_lists({test = {""}}) + assert(inv:get_list("test")) + + assert(inv:get_size("test") == 1) + assert(inv:set_size("test", 3)) + assert(not inv:set_size("test", -1)) + + assert(inv:get_width("test") == 0) + assert(inv:set_width("test", 3)) + assert(not inv:set_width("test", -1)) + + inv:set_stack("test", 1, "air") + inv:set_stack("test", 3, item_with_meta) + assert(not inv:is_empty("test")) + assert(compare_lists(inv:get_list("test"), test_list)) + + assert(inv:add_item("test", "air") == ItemStack()) + assert(inv:add_item("test", item_with_meta) == ItemStack()) + assert(inv:get_stack("test", 1) == ItemStack("air 2")) + + assert(inv:room_for_item("test", "air 99")) + inv:set_stack("test", 2, "air 99") + assert(not inv:room_for_item("test", "air 99")) + inv:set_stack("test", 2, "") + + assert(inv:contains_item("test", "air")) + assert(not inv:contains_item("test", "air 99")) + assert(inv:contains_item("test", item_with_meta, true)) + + -- Items should be removed in reverse and combine with first stack removed + assert(inv:remove_item("test", "air") == item_with_meta) + item_with_meta:set_count(2) + assert(inv:remove_item("test", "air 2") == item_with_meta) + assert(inv:remove_item("test", "air") == ItemStack("air")) + assert(inv:is_empty("test")) + + -- Failure of set_list(s) should not change inventory + local before = inv:get_list("test") + pcall(inv.set_lists, inv, {test = true}) + pcall(inv.set_list, inv, "test", true) + local after = inv:get_list("test") + assert(compare_lists(before, after)) + + local location = inv:get_location() + assert(core.remove_detached_inventory("test")) + assert(not core.get_inventory(location)) +end + +unittests.register("test_inventory", test_inventory) diff --git a/data/games/garage/mods/unittests/itemdescription.lua b/data/games/garage/mods/unittests/itemdescription.lua new file mode 100644 index 0000000..730248d --- /dev/null +++ b/data/games/garage/mods/unittests/itemdescription.lua @@ -0,0 +1,43 @@ +local full_description = "Description Test Item\nFor testing item decription" +core.register_tool("unittests:description_test", { + description = full_description, + inventory_image = "unittests_description_test.png", + groups = { dummy = 1 }, +}) + +core.register_chatcommand("item_description", { + param = "", + description = "Show the short and full description of the wielded item.", + func = function(name) + local player = core.get_player_by_name(name) + local item = player:get_wielded_item() + return true, string.format("short_description: %s\ndescription: %s", + item:get_short_description(), item:get_description()) + end +}) + +local function test_short_desc() + local function get_short_description(item) + return ItemStack(item):get_short_description() + end + + local stack = ItemStack("unittests:description_test") + assert(stack:get_short_description() == "Description Test Item") + assert(get_short_description("unittests:description_test") == "Description Test Item") + assert(core.registered_items["unittests:description_test"].short_description == nil) + assert(stack:get_description() == full_description) + assert(stack:get_description() == core.registered_items["unittests:description_test"].description) + + stack:get_meta():set_string("description", "Hello World") + assert(stack:get_short_description() == "Hello World") + assert(stack:get_description() == "Hello World") + assert(get_short_description(stack) == "Hello World") + assert(get_short_description("unittests:description_test") == "Description Test Item") + + stack:get_meta():set_string("short_description", "Foo Bar") + assert(stack:get_short_description() == "Foo Bar") + assert(stack:get_description() == "Hello World") + + return true +end +unittests.register("test_short_desc", test_short_desc) diff --git a/data/games/garage/mods/unittests/itemstack_equals.lua b/data/games/garage/mods/unittests/itemstack_equals.lua new file mode 100644 index 0000000..561e612 --- /dev/null +++ b/data/games/garage/mods/unittests/itemstack_equals.lua @@ -0,0 +1,74 @@ +local function test_itemstack_equals_non_stack() + local i1 = ItemStack("basenodes:stone") + local i2 = { foo = "bar" } + + assert(not i1:equals(i2)) + assert(i1 ~= i2) + assert(i2 ~= i1) +end + +unittests.register("test_itemstack_equals_non_stack", test_itemstack_equals_non_stack) + +local function test_itemstack_equals_name() + local i1 = ItemStack("basenodes:stone") + local i2 = ItemStack("basenodes:desert_stone") + + assert(not i1:equals(i2)) + assert(i1 ~= i2) +end + +unittests.register("test_itemstack_equals_name", test_itemstack_equals_name) + +local function test_itemstack_equals_count() + local i1 = ItemStack("basenodes:stone") + local i2 = ItemStack("basenodes:stone 2") + + assert(not i1:equals(i2)) + assert(i1 ~= i2) +end + +unittests.register("test_itemstack_equals_count", test_itemstack_equals_count) + +local function test_itemstack_equals_wear() + local i1 = ItemStack("basetools:axe_stone") + local i2 = ItemStack("basetools:axe_stone") + + i2:add_wear(1) + + assert(not i1:equals(i2)) + assert(i1 ~= i2) +end + +unittests.register("test_itemstack_equals_wear", test_itemstack_equals_wear) + +local function test_itemstack_equals_metadata() + local i1 = ItemStack("basenodes:stone") + local i2 = ItemStack("basenodes:stone") + local i3 = ItemStack("basenodes:stone") + + local m1 = i1:get_meta() + local m2 = i2:get_meta() + local m3 = i3:get_meta() + + local keys = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p"} + local values = {} + + for i, key in pairs(keys) do + m1:set_int(key, i) + m3:set_int(key, i) + values[key] = i + end + + m3:set_int("a", 999) + + for key, i in pairs(values) do + m2:set_int(key, i) + end + + assert(i1:equals(i2)) + assert(i1 == i2) + assert(not i1:equals(i3)) + assert(i1 ~= i3) +end + +unittests.register("test_itemstack_equals_metadata", test_itemstack_equals_metadata) diff --git a/data/games/garage/mods/unittests/load_time.lua b/data/games/garage/mods/unittests/load_time.lua new file mode 100644 index 0000000..12f1a38 --- /dev/null +++ b/data/games/garage/mods/unittests/load_time.lua @@ -0,0 +1,13 @@ +-- Test item (un)registration and overriding +do + local itemname = "unittests:test_override_item" + core.register_craftitem(":" .. itemname, {description = "foo"}) + assert(assert(core.registered_items[itemname]).description == "foo") + core.override_item(itemname, {description = "bar"}) + assert(assert(core.registered_items[itemname]).description == "bar") + core.override_item(itemname, {}, {"description"}) + -- description has the empty string as a default + assert(assert(core.registered_items[itemname]).description == "") + core.unregister_item("unittests:test_override_item") + assert(core.registered_items["unittests:test_override_item"] == nil) +end diff --git a/data/games/garage/mods/unittests/metadata.lua b/data/games/garage/mods/unittests/metadata.lua new file mode 100644 index 0000000..bdd51c3 --- /dev/null +++ b/data/games/garage/mods/unittests/metadata.lua @@ -0,0 +1,121 @@ +-- Tests of generic and specific metadata functionality + +local compare_meta = ItemStack("unittests:iron_lump"):get_meta() +compare_meta:from_table({ + fields = { + a = "1", + b = "2", + c = "3", + d = "4", + e = "e", + }, +}) + +local function test_metadata(meta) + meta:from_table({fields = {a = 2, b = "2"}}) + meta:set_string("a", 1) + meta:set_string("c", "3") + meta:set_int("d", 4) + meta:set_string("e", "e") + + meta:set_string("", "!") + meta:set_string("", "") + + assert(meta:equals(compare_meta)) + + local tab = meta:to_table() + assert(tab.fields.a == "1") + assert(tab.fields.b == "2") + assert(tab.fields.c == "3") + assert(tab.fields.d == "4") + assert(tab.fields.e == "e") + + local keys = meta:get_keys() + assert(table.indexof(keys, "a") > 0) + assert(table.indexof(keys, "b") > 0) + assert(table.indexof(keys, "c") > 0) + assert(table.indexof(keys, "d") > 0) + assert(table.indexof(keys, "e") > 0) + assert(#keys == 5) + + assert(not meta:contains("")) + assert(meta:contains("a")) + assert(meta:contains("b")) + assert(meta:contains("c")) + assert(meta:contains("d")) + assert(meta:contains("e")) + + assert(meta:get("") == nil) + assert(meta:get_string("") == "") + assert(meta:get_int("") == 0) + assert(meta:get_float("") == 0.0) + assert(meta:get("a") == "1") + assert(meta:get_string("a") == "1") + assert(meta:get_int("a") == 1) + assert(meta:get_float("a") == 1.0) + assert(meta:get_int("e") == 0) + assert(meta:get_float("e") == 0.0) + + meta:set_float("f", 1.1) + meta:set_string("g", "${f}") + meta:set_string("h", "${g}") + meta:set_string("i", "${h}") + assert(meta:get_float("h") > 1) + assert(meta:get_string("i") == "${f}") + + meta:set_float("j", 1.23456789) + assert(meta:get_float("j") == 1.23456789) + meta:set_float("j", -1 / 0) + assert(meta:get_float("j") == -1 / 0) + meta:set_float("j", 0 / 0) + assert(core.is_nan(meta:get_float("j"))) + + meta:from_table() + assert(next(meta:to_table().fields) == nil) + assert(#meta:get_keys() == 0) + + assert(not meta:equals(compare_meta)) +end + +local function test_metadata_compat(meta) + -- key/value removal using set_string (undocumented, deprecated way) + meta:set_string("key", "value") + assert(meta:get_string("key") == "value") + meta:set_string("key", nil) -- ignore warning + assert(meta:to_table().fields["key"] == nil) + + -- undocumented but supported consequence of Lua's + -- automatic string <--> number cast + meta:set_string("key", 2) + assert(meta:get_string("key") == "2") + + -- from_table with non-string keys (supported) + local values = meta:to_table() + values.fields["new"] = 420 + meta:from_table(values) + assert(meta:get_int("new") == 420) + values.fields["new"] = nil + meta:from_table(values) + assert(meta:get("new") == nil) +end + + +local storage_a = core.get_mod_storage() +local storage_b = core.get_mod_storage() +local function test_mod_storage() + assert(rawequal(storage_a, storage_b)) + test_metadata(storage_a) +end +unittests.register("test_mod_storage", test_mod_storage) + +local function test_item_metadata() + local meta = ItemStack("unittest:coal_lump"):get_meta() + test_metadata(meta) + test_metadata_compat(meta) +end +unittests.register("test_item_metadata", test_item_metadata) + +local function test_node_metadata(player, pos) + test_metadata(core.get_meta(pos)) +end +unittests.register("test_node_metadata", test_node_metadata, {map=true}) diff --git a/data/games/garage/mods/unittests/misc.lua b/data/games/garage/mods/unittests/misc.lua new file mode 100644 index 0000000..d01eed1 --- /dev/null +++ b/data/games/garage/mods/unittests/misc.lua @@ -0,0 +1,332 @@ +core.register_mapgen_script(core.get_modpath(core.get_current_modname()) .. + DIR_DELIM .. "inside_mapgen_env.lua") + +local function test_pseudo_random() + -- We have comprehensive unit tests in C++, this is just to make sure the API code isn't messing up + local gen1 = PseudoRandom(13) + assert(gen1:next() == 22290) + assert(gen1:next() == 13854) + + local gen2 = PseudoRandom(gen1:get_state()) + for n = 0, 16 do + assert(gen1:next() == gen2:next()) + end + + local pr3 = PseudoRandom(-101) + assert(pr3:next(0, 100) == 35) + -- unusual case that is normally disallowed: + assert(pr3:next(10000, 42767) == 12485) +end +unittests.register("test_pseudo_random", test_pseudo_random) + +local function test_pcg_random() + -- We have comprehensive unit tests in C++, this is just to make sure the API code isn't messing up + local gen1 = PcgRandom(55) + + for n = 0, 16 do + gen1:next() + end + + local gen2 = PcgRandom(26) + gen2:set_state(gen1:get_state()) + + for n = 16, 32 do + assert(gen1:next() == gen2:next()) + end +end +unittests.register("test_pcg_random", test_pcg_random) + +local function test_dynamic_media(cb, player) + if core.get_player_information(player:get_player_name()).protocol_version < 40 then + core.log("warning", "test_dynamic_media: Client too old, skipping test.") + return cb() + end + + -- Check that the client acknowledges media transfers + local path = core.get_worldpath() .. "/test_media.obj" + local f = io.open(path, "w") + f:write("# contents don't matter\n") + f:close() + + local call_ok = false + local ok = core.dynamic_add_media({ + filepath = path, + to_player = player:get_player_name(), + }, function(name) + if not call_ok then + return cb("impossible condition") + end + cb() + end) + if not ok then + return cb("dynamic_add_media() returned error") + end + call_ok = true + + -- if the callback isn't called this test will just hang :shrug: +end +unittests.register("test_dynamic_media", test_dynamic_media, {async=true, player=true}) + +local function test_v3f_metatable(player) + assert(vector.check(player:get_pos())) +end +unittests.register("test_v3f_metatable", test_v3f_metatable, {player=true}) + +local function test_v3s16_metatable(player, pos) + local node = core.get_node(pos) + local found_pos = core.find_node_near(pos, 0, node.name, true) + assert(vector.check(found_pos)) +end +unittests.register("test_v3s16_metatable", test_v3s16_metatable, {map=true}) + +local function test_clear_meta(_, pos) + local ref = core.get_meta(pos) + + for way = 1, 3 do + ref:set_string("foo", "bar") + assert(ref:contains("foo")) + + if way == 1 then + ref:from_table({}) + elseif way == 2 then + ref:from_table(nil) + else + ref:set_string("foo", "") + end + + assert(#core.find_nodes_with_meta(pos, pos) == 0, "clearing failed " .. way) + end +end +unittests.register("test_clear_meta", test_clear_meta, {map=true}) + +local on_punch_called, on_place_called +core.register_on_placenode(function() + on_place_called = true +end) +core.register_on_punchnode(function() + on_punch_called = true +end) +local function test_node_callbacks(_, pos) + on_place_called = false + on_punch_called = false + + core.place_node(pos, {name="basenodes:dirt"}) + assert(on_place_called, "on_place not called") + core.punch_node(pos) + assert(on_punch_called, "on_punch not called") + core.remove_node(pos) +end +unittests.register("test_node_callbacks", test_node_callbacks, {map=true}) + +local function test_hashing() + local input = "hello\000world" + assert(core.sha1(input) == "f85b420f1e43ebf88649dfcab302b898d889606c") + assert(core.sha256(input) == "b206899bc103669c8e7b36de29d73f95b46795b508aa87d612b2ce84bfb29df2") +end +unittests.register("test_hashing", test_hashing) + +local function test_compress() + -- This text should be compressible, to make sure the results are... normal + local text = "The\000 icey canoe couldn't move very well on the\128 lake. The\000 ice was too stiff and the icey canoe's paddles simply wouldn't punch through." + local methods = { + "deflate", + "zstd", + -- "noodle", -- for warning alarm test + } + local zstd_magic = string.char(0x28, 0xB5, 0x2F, 0xFD) + for _, method in ipairs(methods) do + local compressed = core.compress(text, method) + assert(core.decompress(compressed, method) == text, "input/output mismatch for compression method " .. method) + local has_zstd_magic = compressed:sub(1, 4) == zstd_magic + if method == "zstd" then + assert(has_zstd_magic, "zstd magic number not in zstd method") + else + assert(not has_zstd_magic, "zstd magic number in method " .. method .. " (which is not zstd)") + end + end +end +unittests.register("test_compress", test_compress) + +local function test_urlencode() + -- checks that API code handles null bytes + assert(core.urlencode("foo\000bar!") == "foo%00bar%21") +end +unittests.register("test_urlencode", test_urlencode) + +local function test_parse_json() + local raw = "{\"how\\u0000weird\":\n\"yes\\u0000really\",\"n\":-1234567891011,\"z\":null}" + do + local data = core.parse_json(raw) + assert(data["how\000weird"] == "yes\000really") + assert(data.n == -1234567891011) + assert(data.z == nil) + end + do + local null = {} + local data = core.parse_json(raw, null) + assert(data.z == null) + end + do + local data, err = core.parse_json('"ceci n\'est pas un json', nil, true) + assert(data == nil) + assert(type(err) == "string") + end +end +unittests.register("test_parse_json", test_parse_json) + +local function test_write_json() + -- deeply nested structures should be preserved + local leaf = 42 + local data = leaf + for i = 1, 1000 do + data = {data} + end + local roundtripped = core.parse_json(core.write_json(data)) + for i = 1, 1000 do + roundtripped = roundtripped[1] + end + assert(roundtripped == 42) +end +unittests.register("test_write_json", test_write_json) + +local function test_game_info() + local info = core.get_game_info() + local game_conf = Settings(info.path .. "/game.conf") + assert(info.id == "devtest") + assert(info.title == game_conf:get("title")) +end +unittests.register("test_game_info", test_game_info) + +local function test_mapgen_edges(cb) + -- Test that the map can extend to the expected edges and no further. + local min_edge, max_edge = core.get_mapgen_edges() + local min_finished = {} + local max_finished = {} + local function finish() + if #min_finished ~= 1 then + return cb("Expected 1 block to emerge around mapgen minimum edge") + end + if min_finished[1] ~= (min_edge / core.MAP_BLOCKSIZE):floor() then + return cb("Expected block within minimum edge to emerge") + end + if #max_finished ~= 1 then + return cb("Expected 1 block to emerge around mapgen maximum edge") + end + if max_finished[1] ~= (max_edge / core.MAP_BLOCKSIZE):floor() then + return cb("Expected block within maximum edge to emerge") + end + return cb() + end + local emerges_left = 2 + local function emerge_block(blockpos, action, blocks_left, finished) + if action ~= core.EMERGE_CANCELLED then + table.insert(finished, blockpos) + end + if blocks_left == 0 then + emerges_left = emerges_left - 1 + if emerges_left == 0 then + return finish() + end + end + end + core.emerge_area(min_edge:subtract(1), min_edge, emerge_block, min_finished) + core.emerge_area(max_edge, max_edge:add(1), emerge_block, max_finished) +end +unittests.register("test_mapgen_edges", test_mapgen_edges, {map=true, async=true}) + +local finish_test_on_mapblocks_changed +core.register_on_mapblocks_changed(function(modified_blocks, modified_block_count) + if finish_test_on_mapblocks_changed then + finish_test_on_mapblocks_changed(modified_blocks, modified_block_count) + finish_test_on_mapblocks_changed = nil + end +end) +local function test_on_mapblocks_changed(cb, player, pos) + local bp1 = (pos / core.MAP_BLOCKSIZE):floor() + local bp2 = bp1:add(1) + for _, bp in ipairs({bp1, bp2}) do + -- Make a modification in the block. + local p = bp * core.MAP_BLOCKSIZE + core.load_area(p) + local meta = core.get_meta(p) + meta:set_int("test_on_mapblocks_changed", meta:get_int("test_on_mapblocks_changed") + 1) + end + finish_test_on_mapblocks_changed = function(modified_blocks, modified_block_count) + if modified_block_count < 2 then + return cb("Expected at least two mapblocks to be recorded as modified") + end + if not modified_blocks[core.hash_node_position(bp1)] or + not modified_blocks[core.hash_node_position(bp2)] then + return cb("The expected mapblocks were not recorded as modified") + end + cb() + end +end +unittests.register("test_on_mapblocks_changed", test_on_mapblocks_changed, {map=true, async=true}) + +local function test_gennotify_api() + local DECO_ID = 123 + local UD_ID = "unittests:dummy" + + -- the engine doesn't check if the id is actually valid, maybe it should + core.set_gen_notify({decoration=true}, {DECO_ID}) + + core.set_gen_notify({custom=true}, nil, {UD_ID}) + + local flags, deco, custom = core.get_gen_notify() + local function ff(flag) + return (" " .. flags .. " "):match("[ ,]" .. flag .. "[ ,]") ~= nil + end + assert(ff("decoration"), "'decoration' flag missing") + assert(ff("custom"), "'custom' flag missing") + assert(table.indexof(deco, DECO_ID) > 0) + assert(table.indexof(custom, UD_ID) > 0) + + core.set_gen_notify({decoration=false, custom=false}) + + flags, deco, custom = core.get_gen_notify() + assert(not ff("decoration") and not ff("custom")) + assert(#deco == 0, "deco ids not empty") + assert(#custom == 0, "custom ids not empty") +end +unittests.register("test_gennotify_api", test_gennotify_api) + +-- <=> inside_mapgen_env.lua +local function test_mapgen_env(cb) + -- emerge threads start delayed so this can take a second + local res = core.ipc_get("unittests:mg") + if res == nil then + return core.after(0, test_mapgen_env, cb) + end + -- handle error status + if res[1] then + cb() + else + cb(res[2]) + end +end +unittests.register("test_mapgen_env", test_mapgen_env, {async=true}) + +local function test_ipc_vector_preserve(cb) + -- the IPC also uses register_portable_metatable + core.ipc_set("unittests:v", vector.new(4, 0, 4)) + local v = core.ipc_get("unittests:v") + assert(type(v) == "table") + assert(vector.check(v)) +end +unittests.register("test_ipc_vector_preserve", test_ipc_vector_preserve) + +local function test_ipc_poll(cb) + core.ipc_set("unittests:flag", nil) + assert(core.ipc_poll("unittests:flag", 1) == false) + + -- Note that unlike the async result callback - which has to wait for the + -- next server step - the IPC is instant + local t0 = core.get_us_time() + core.handle_async(function() + core.ipc_set("unittests:flag", true) + end, function() end) + assert(core.ipc_poll("unittests:flag", 1000) == true, "Wait failed (or slow machine?)") + print("delta: " .. (core.get_us_time() - t0) .. "us") +end +unittests.register("test_ipc_poll", test_ipc_poll) diff --git a/data/games/garage/mods/unittests/mod.conf b/data/games/garage/mods/unittests/mod.conf new file mode 100644 index 0000000..ccff737 --- /dev/null +++ b/data/games/garage/mods/unittests/mod.conf @@ -0,0 +1,4 @@ +name = unittests +description = Adds automated unit tests for the engine +# Also test that it is possible to depend on first_mod +depends = first_mod, basenodes diff --git a/data/games/garage/mods/unittests/on_shutdown.lua b/data/games/garage/mods/unittests/on_shutdown.lua new file mode 100644 index 0000000..6d5d886 --- /dev/null +++ b/data/games/garage/mods/unittests/on_shutdown.lua @@ -0,0 +1,22 @@ +-- Test whether players still exist on shutdown +local players = {} + +core.register_on_joinplayer(function(player) + players[player:get_player_name()] = true +end) + +core.register_on_leaveplayer(function(player) + local name = player:get_player_name(); + assert(players[name], "Unrecorded player join.") + players[name] = nil +end) + +core.register_on_shutdown(function() + for _, player in pairs(core.get_connected_players()) do + local name = player:get_player_name() + assert(players[name], "Unrecorded player join or left too early.") + players[name] = nil + end + + assert(not next(players), "Invalid connected players on shutdown.") +end) diff --git a/data/games/garage/mods/unittests/player.lua b/data/games/garage/mods/unittests/player.lua new file mode 100644 index 0000000..f8945f3 --- /dev/null +++ b/data/games/garage/mods/unittests/player.lua @@ -0,0 +1,206 @@ +-- +-- HP Change Reasons +-- +local expect = nil +core.register_on_player_hpchange(function(player, hp_change, reason) + if expect == nil then + return + end + + for key, value in pairs(reason) do + assert(expect[key] == value) + end + for key, value in pairs(expect) do + assert(reason[key] == value) + end + + expect = nil +end) + +local function run_hpchangereason_tests(player) + local old_hp = player:get_hp() + + player:set_hp(20) + expect = { type = "set_hp", from = "mod" } + player:set_hp(3) + assert(expect == nil) + + expect = { a = 234, type = "set_hp", from = "mod" } + player:set_hp(7, { a= 234 }) + assert(expect == nil) + + expect = { df = 3458973454, type = "fall", from = "mod" } + player:set_hp(10, { type = "fall", df = 3458973454 }) + assert(expect == nil) + + player:set_hp(old_hp) +end +unittests.register("test_hpchangereason", run_hpchangereason_tests, {player=true}) + +-- +-- HP differences +-- + +local expected_diff = nil +local hpchange_counter = 0 +local die_counter = 0 +core.register_on_player_hpchange(function(player, hp_change, reason) + if expected_diff then + assert(hp_change == expected_diff) + hpchange_counter = hpchange_counter + 1 + end +end) +core.register_on_dieplayer(function() + die_counter = die_counter + 1 +end) + +local function hp_diference_test(player, hp_max) + assert(hp_max >= 22) + + local old_hp = player:get_hp() + local old_hp_max = player:get_properties().hp_max + + hpchange_counter = 0 + die_counter = 0 + + expected_diff = nil + player:set_properties({hp_max = hp_max}) + player:set_hp(22) + assert(player:get_hp() == 22) + assert(hpchange_counter == 0) + assert(die_counter == 0) + + -- HP difference is not clamped + expected_diff = -25 + player:set_hp(-3) + -- actual final HP value is clamped to >= 0 + assert(player:get_hp() == 0) + assert(hpchange_counter == 1) + assert(die_counter == 1) + + expected_diff = 22 + player:set_hp(22) + assert(player:get_hp() == 22) + assert(hpchange_counter == 2) + assert(die_counter == 1) + + -- Integer overflow is prevented + -- so result is S32_MIN, not S32_MIN - 22 + expected_diff = -2147483648 + player:set_hp(-2147483648) + -- actual final HP value is clamped to >= 0 + assert(player:get_hp() == 0) + assert(hpchange_counter == 3) + assert(die_counter == 2) + + -- Damage is ignored if player is already dead (hp == 0) + expected_diff = "never equal" + player:set_hp(-11) + assert(player:get_hp() == 0) + -- no on_player_hpchange or on_dieplayer call expected + assert(hpchange_counter == 3) + assert(die_counter == 2) + + expected_diff = 11 + player:set_hp(11) + assert(player:get_hp() == 11) + assert(hpchange_counter == 4) + assert(die_counter == 2) + + -- HP difference is not clamped + expected_diff = 1000000 - 11 + player:set_hp(1000000) + -- actual final HP value is clamped to <= hp_max + assert(player:get_hp() == hp_max) + assert(hpchange_counter == 5) + assert(die_counter == 2) + + -- "Healing" is not ignored when hp == hp_max + expected_diff = 80000 - hp_max + player:set_hp(80000) + assert(player:get_hp() == hp_max) + -- on_player_hpchange_call expected + assert(hpchange_counter == 6) + assert(die_counter == 2) + + expected_diff = nil + player:set_properties({hp_max = old_hp_max}) + player:set_hp(old_hp) + core.close_formspec(player:get_player_name(), "") -- hide death screen +end +local function run_hp_difference_tests(player) + hp_diference_test(player, 22) + hp_diference_test(player, 30) + hp_diference_test(player, 65535) -- U16_MAX +end +unittests.register("test_hp_difference", run_hp_difference_tests, {player=true}) + +-- +-- Player meta +-- +local function run_player_meta_tests(player) + local meta = player:get_meta() + meta:set_string("foo", "bar") + assert(meta:contains("foo")) + assert(meta:get_string("foo") == "bar") + assert(meta:get("foo") == "bar") + + local meta2 = player:get_meta() + assert(meta2:get_string("foo") == "bar") + assert(meta2:get("foo") == "bar") + assert(meta:equals(meta2)) + + meta:set_string("bob", "dillan") + assert(meta:get_string("foo") == "bar") + assert(meta:get_string("bob") == "dillan") + assert(meta:get("bob") == "dillan") + assert(meta2:get_string("foo") == "bar") + assert(meta2:get_string("bob") == "dillan") + assert(meta2:get("bob") == "dillan") + assert(meta:equals(meta2)) + + meta:set_string("foo", "") + assert(not meta:contains("foo")) + assert(meta:get("foo") == nil) + assert(meta:get_string("foo") == "") + assert(meta:equals(meta2)) +end +unittests.register("test_player_meta", run_player_meta_tests, {player=true}) + +-- +-- Player add pos +-- +local function run_player_add_pos_tests(player) + local pos = player:get_pos() + player:add_pos(vector.new(0, 1000, 0)) + local newpos = player:get_pos() + player:add_pos(vector.new(0, -1000, 0)) + local backpos = player:get_pos() + local newdist = vector.distance(pos, newpos) + assert(math.abs(newdist - 1000) <= 1) + assert(vector.distance(pos, backpos) <= 1) +end +unittests.register("test_player_add_pos", run_player_add_pos_tests, {player=true}) + +-- +-- Hotbar selection clamp +-- +local function run_player_hotbar_clamp_tests(player) + local inv = player:get_inventory() + local old_inv_size = inv:get_size("main") + local old_inv_list = inv:get_list("main") -- Avoid accidentally removing item + local old_bar_size = player:hud_get_hotbar_itemcount() + + inv:set_size("main", 5) + + player:hud_set_hotbar_itemcount(2) + assert(player:hud_get_hotbar_itemcount() == 2) + + player:hud_set_hotbar_itemcount(6) + assert(player:hud_get_hotbar_itemcount() == 5) + + inv:set_size("main", old_inv_size) + inv:set_list("main", old_inv_list) + player:hud_set_hotbar_itemcount(old_bar_size) +end +unittests.register("test_player_hotbar_clamp", run_player_hotbar_clamp_tests, {player=true}) diff --git a/data/games/garage/mods/unittests/raycast.lua b/data/games/garage/mods/unittests/raycast.lua new file mode 100644 index 0000000..08d6a11 --- /dev/null +++ b/data/games/garage/mods/unittests/raycast.lua @@ -0,0 +1,36 @@ +local function raycast_with_pointabilities(start_pos, end_pos, pointabilities) + local ray = core.raycast(start_pos, end_pos, nil, nil, pointabilities) + for hit in ray do + if hit.type == "node" then + return hit.under + end + end + return nil +end + +local function test_raycast_pointabilities(player, pos1) + local pos2 = pos1:offset(0, 0, 1) + local pos3 = pos1:offset(0, 0, 2) + + local oldnode1 = core.get_node(pos1) + local oldnode2 = core.get_node(pos2) + local oldnode3 = core.get_node(pos3) + core.swap_node(pos1, {name = "air"}) + core.swap_node(pos2, {name = "testnodes:not_pointable"}) + core.swap_node(pos3, {name = "testnodes:pointable"}) + + local p = nil + assert(raycast_with_pointabilities(pos1, pos3, p) == pos3) + + p = core.registered_items["testtools:blocked_pointing_staff"].pointabilities + assert(raycast_with_pointabilities(pos1, pos3, p) == nil) + + p = core.registered_items["testtools:ultimate_pointing_staff"].pointabilities + assert(raycast_with_pointabilities(pos1, pos3, p) == pos2) + + core.swap_node(pos1, oldnode1) + core.swap_node(pos2, oldnode2) + core.swap_node(pos3, oldnode3) +end + +unittests.register("test_raycast_pointabilities", test_raycast_pointabilities, {map=true}) diff --git a/data/games/garage/mods/unittests/textures/default_dirt.png b/data/games/garage/mods/unittests/textures/default_dirt.png new file mode 100644 index 0000000000000000000000000000000000000000..58670305d007716c3fee12b45e8acf301cbd4c5a GIT binary patch literal 790 zcmV+x1L^#UP)+xj5kBG+jwP?dy=OpTdxIW%S%svYi-AiUwq95neHg?hCz7VnWHWv=)Dt@+7{ zG9yk$tjix{Qdekl_Ycmh6ftmSTdZf+$_P<()8l^eEE301l)&j zPgzWHUtPRR0~_FG^)aeC*V2YeNTaW_wd>dGb*RAH#b}es_^G>U)5gg@K~1JsE{-0v z0A`D8y1L&TY&%$cYrBfdipqnT$G789yi|&^JElE7R3ocRv4*+<>nTzHM=5G!^)%aqz(1wGAfXN%v*Yjt8^_?`gG1 z&);$RzU%0jO?}+_=xVRBAXv!ga z$z&xWeSVb4&(XO?R53R~8Jb?gL!H)|C1iMQ#?79<0v$FGc_eXs-)NrylE3^4-Qh4C z@{|Sc%w?TE+llJ3I7#|;@Tx2&98IsgJB9e|duk4Gx9tuPwp3AEIj^`(<;T;rzBO|k zb>zf#QH)Q*`sE2a9@=S~OL6{o%oB#Wg`}wk66w_9%mFtYMOh=53$us73?bCje;Rml UYvInCO8@`>07*qoM6N<$f@__Gg8%>k literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/unittests/textures/unittests_callback.png b/data/games/garage/mods/unittests/textures/unittests_callback.png new file mode 100644 index 0000000000000000000000000000000000000000..3c80fdc0d3193e66d30e05ba3a20f56b87d0cfc3 GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`DV{ElAr*{UCNZ)d2;gz9J~l7o z`HR%eNg4$Z~kD@`M}$e?%>0mSoA`D)=u_vM%73u1}9UQ?Y*m09s})T@O1TaS?83{ F1OQ5THdg=u literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/unittests/textures/unittests_coal_lump.png b/data/games/garage/mods/unittests/textures/unittests_coal_lump.png new file mode 100644 index 0000000000000000000000000000000000000000..f460d909ef35804cd8d640574bf879646947ef97 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`>7Fi*Ar*{UCNZ)xIPx(6o>8}~ z|K)$ioy9G}DXVj4>Ur?ou3&da_*<84{~+pYZ1X!dN$HG$k8D8!p7frpr>BaF3Q!El z{r?|GGpsc4E&)=kB|(0{AU?yPY_^R+D%sP;F@!@__sl`g1_J??i;lVnn$0#`%clKp-UW7%sGgh%JJ+hH!<|KE|;AIsZ-m`2q w>I1x{h{RlI3Hy7zX_eH`mQ=mjubg(iit7|o%n^Ecp%!GVr>mdKI;Vst0N|xdBLDyZ literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/unittests/textures/unittests_iron_lump.png b/data/games/garage/mods/unittests/textures/unittests_iron_lump.png new file mode 100644 index 0000000000000000000000000000000000000000..22f43e9cce04fe976ec18b3e6836811f2d9803d4 GIT binary patch literal 154 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`iJmTwAr*|t3{C(4|2O`lKATNA zg?U5VC*B2Xx%2!_{pCNbvXfzNl9+Ty&mrSj_s3lft2$!D z1@*3N%En1LybLN)qN~4p-jD%W#^CAd=d#Wzp$Py& C$1{-t literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/unittests/textures/unittests_repairable_tool.png b/data/games/garage/mods/unittests/textures/unittests_repairable_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..46fbbaa74530c32ef3b02fb0e4fdd7f606fb4ef0 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`>7Fi*Ar*{sCpWSkFc5J5{NLey z`{v$OJ)cDntD@p;G~P{M>Hl7R@JxYx$wEF?*U+133tATCOz7U^n14z7#}zidh)zkC z8~4vD9QHDa$o_jM?h%`08Mh=y9b2j$n{CcS$F|S$4_@wLc($A;?aH1!1)!A-p00i_ I>zopr0Ji-*QUCw| literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/unittests/textures/unittests_steel_ingot.png b/data/games/garage/mods/unittests/textures/unittests_steel_ingot.png new file mode 100644 index 0000000000000000000000000000000000000000..6977696a23832867b5c0499997dfcfc0d71777db GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`X`U{QAr*{!`WV>`IPkE1zO_f$ z|MdB7dpF$(^B1~fWNDE8Mvmd|kJ@uJ4 zC~eT_aN+vFc(ZfL+vo*}W#>qgTe~DWM4f D!SOfD literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/unittests/textures/unittests_unrepairable_tool.png b/data/games/garage/mods/unittests/textures/unittests_unrepairable_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..c676213a5de29a6e3c656f29bead261595ed63ca GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`DV{ElAr*{sCo!@eaNuEK{{G+p z%lzAmj&D%X_Lj0u;|+>enR@N_|CP^W3bnf5J#TYOmgJeS=LFBBMQ0SuPx4x9WMt4T zZf5*eF6CojBxP}D`V7X0OB&cDdoDN_-idj{^v(K0*?v2}%Uky6pPdf0kHOQ`&t;uc GLK6T-H8}PF literal 0 HcmV?d00001 diff --git a/data/games/garage/mods/util_commands/init.lua b/data/games/garage/mods/util_commands/init.lua new file mode 100644 index 0000000..8341901 --- /dev/null +++ b/data/games/garage/mods/util_commands/init.lua @@ -0,0 +1,243 @@ +core.register_chatcommand("hotbar", { + params = "", + description = "Set hotbar size", + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local size = tonumber(param) + if not size then + return false, "Missing or incorrect size parameter!" + end + local ok = player:hud_set_hotbar_itemcount(size) + if ok then + return true + else + return false, "Invalid item count!" + end + end, +}) + +core.register_chatcommand("hp", { + params = "", + description = "Set your health", + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local hp = tonumber(param) + if not hp or core.is_nan(hp) or hp < 0 or hp > 65535 then + return false, "Missing or incorrect hp parameter!" + end + player:set_hp(hp) + return true + end, +}) + +local s_infplace = core.settings:get("devtest_infplace") +if s_infplace == "true" then + infplace = true +elseif s_infplace == "false" then + infplace = false +else + infplace = core.is_creative_enabled("") +end + +core.register_chatcommand("infplace", { + params = "", + description = "Toggle infinite node placement", + func = function(name, param) + infplace = not infplace + if infplace then + core.chat_send_all("Infinite node placement enabled!") + core.log("action", "Infinite node placement enabled") + else + core.chat_send_all("Infinite node placement disabled!") + core.log("action", "Infinite node placement disabled") + end + return true + end, +}) + +core.register_chatcommand("detach", { + params = "[]", + description = "Detach all objects nearby", + func = function(name, param) + local radius = tonumber(param) + if type(radius) ~= "number" then + radius = 8 + end + if radius < 1 then + radius = 1 + end + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local objs = core.get_objects_inside_radius(player:get_pos(), radius) + local num = 0 + for o=1, #objs do + if objs[o]:get_attach() then + objs[o]:set_detach() + num = num + 1 + end + end + return true, string.format("%d object(s) detached.", num) + end, +}) + +core.register_chatcommand("use_tool", { + params = "(dig ) | (hit ) []", + description = "Apply tool wear a number of times, as if it were used for digging", + func = function(name, param) + local player = core.get_player_by_name(name) + if not player then + return false, "No player." + end + local mode, group, level, uses = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+) (%d+)") + if not mode then + mode, group, level = string.match(param, "([a-z]+) ([a-z0-9]+) (-?%d+)") + uses = 1 + end + if not mode or not group or not level then + return false + end + if mode ~= "dig" and mode ~= "hit" then + return false + end + local tool = player:get_wielded_item() + local caps = tool:get_tool_capabilities() + if not caps or tool:get_count() == 0 then + return false, "No tool in hand." + end + local actual_uses = 0 + for u=1, uses do + local wear = tool:get_wear() + local dp + if mode == "dig" then + dp = core.get_dig_params({[group]=3, level=level}, caps, wear) + else + dp = core.get_hit_params({[group]=100}, caps, level, wear) + end + tool:add_wear(dp.wear) + actual_uses = actual_uses + 1 + if tool:get_count() == 0 then + break + end + end + player:set_wielded_item(tool) + if tool:get_count() == 0 then + return true, string.format("Tool used %d time(s). ".. + "The tool broke after %d use(s).", uses, actual_uses) + else + local wear = tool:get_wear() + return true, string.format("Tool used %d time(s). ".. + "Final wear=%d", uses, wear) + end + end, +}) + + +-- Unlimited node placement +core.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + if placer and placer:is_player() then + return infplace + end +end) + +-- Don't pick up if the item is already in the inventory +local old_handle_node_drops = core.handle_node_drops +function core.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() or not infplace then + return old_handle_node_drops(pos, drops, digger) + end + local inv = digger:get_inventory() + if inv then + for _, item in ipairs(drops) do + if not inv:contains_item("main", item, true) then + inv:add_item("main", item) + end + end + end +end + +core.register_chatcommand("set_displayed_itemcount", { + params = "(-s \"\" [-c ]) | -a ", + description = "Set the displayed itemcount of the wielded item", + func = function(name, param) + local player = core.get_player_by_name(name) + local item = player:get_wielded_item() + local meta = item:get_meta() + local flag1 = param:sub(1, 2) + if flag1 == "-s" then + if param:sub(3, 4) ~= " \"" then + return false, "Error: Space and string with \"s expected after -s." + end + local se = param:find("\"", 5, true) + if not se then + return false, "Error: String with two \"s expected after -s." + end + local s = param:sub(5, se - 1) + if param:sub(se + 1, se + 4) == " -c " then + s = core.colorize(param:sub(se + 5), s) + end + meta:set_string("count_meta", s) + elseif flag1 == "-a" then + local num = tonumber(param:sub(4)) + if not num then + return false, "Error: Invalid number: "..param:sub(4) + end + meta:set_int("count_alignment", num) + else + return false + end + player:set_wielded_item(item) + return true, "Displayed itemcount set." + end, +}) + +core.register_chatcommand("dump_item", { + params = "", + description = "Prints a dump of the wielded item in table form", + func = function(name, param) + local player = core.get_player_by_name(name) + local item = player:get_wielded_item() + local str = dump(item:to_table()) + print(str) + return true, str + end, +}) + +core.register_chatcommand("dump_itemdef", { + params = "", + description = "Prints a dump of the wielded item's definition in table form", + func = function(name, param) + local player = core.get_player_by_name(name) + local str = dump(player:get_wielded_item():get_definition()) + print(str) + return true, str + end, +}) + +core.register_chatcommand("dump_wear_bar", { + params = "", + description = "Prints a dump of the wielded item's wear bar parameters in table form", + func = function(name, param) + local player = core.get_player_by_name(name) + local item = player:get_wielded_item() + local str = dump(item:get_wear_bar_params()) + print(str) + return true, str + end, +}) + +core.register_chatcommand("set_saturation", { + params = "", + description = "Set the saturation for current player.", + func = function(player_name, param) + local saturation = tonumber(param) + core.get_player_by_name(player_name):set_lighting({saturation = saturation }) + end +}) diff --git a/data/games/garage/mods/util_commands/mod.conf b/data/games/garage/mods/util_commands/mod.conf new file mode 100644 index 0000000..fea6dd3 --- /dev/null +++ b/data/games/garage/mods/util_commands/mod.conf @@ -0,0 +1,2 @@ +name = util_commands +description = Random server commands to make testing easier and more convenient diff --git a/data/games/garage/screenshot.png b/data/games/garage/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..7324883f6c29aafd8e50f3eac6c8515c8e39b866 GIT binary patch literal 133364 zcmV(*K;FNJP)jH zFvdGDF|KXwIJEZRgCBkN^3PzH;&j!tw!4P3wKf^tk2X+uuFc)pZ7|qMGsmK?DP?CW z*S06RzU*Ca0q4u@g&}kA&bRO0eN6!kp@JF$!CNeH+!}*i22lpU+!X?>=T(tp3<3e! z6BUD|Am6YQk!<}V(Mll-D*^&35jZy;`i-?Mk(_`2QIMDmgXmbqdb<18LoiAxsbHw@ z846M^MS2!SDDq9-LIKcPQ<#kbRfU2Af+V7#qK2$7kU5vErKlwUAVo$n3L-^~K>%Rk zemM^7tgHZFEuFse3)`DBEzw$2iXh_2TR$=MOVN^3kERHVFaV$`yFfV$Dk&%;5LyMT zs~NKx>p`Gy7wgrtm(TxVy}GbuC}1211VtqBn71mF5E%_x@hqi?I!D2~evGJw9I676 zHZ?XgLazFLxO-e>1|Ff0tqHbiTk8zuW$jHjuB32X`@&+;_R$;MDj|Uw@MxGpC6(P! zCKE?UqFjm?a@J|LDdZCw9OJOtcEh;6e7Rl^D{A|P^B@2E{I9&5EHAdx1JAwLe~s3g zA+DrEwa%w5*E2^|$vsTx)xrFYRebXP<6mkg6E}wSt2HNyn}~=aYK%EOz2}^ZDY6q{ zh_lEq%0K**zjZRdFCy1B=T)d@v)SFd5Bss(u2Lnbb4s}E86qN0GLY= z)>63ZwxyKmZ2ocl-}=agDzqgJ@XkBGaBye8nay_Fu3n7WbLMR`@XG5%n~U?Wlbe{- z$=E?Bs$7cK&hI#{ zfinU)3prl`8f%lMkxYt-yxmXZ3!-RgRKA`r>fQC00Q; z@Sba9n--gZNa~0{QwWK4SJxw_OUZGFUGPAtu_PiwTY^;pagO51Xw^7$292e3T-`jLzTOuGsIFgrI-cHp@buZ|dS(ya-FLz6mc4a`GXubEHjgpV z!z^AclB=B8YSiJK*WbV0KmT(3zh8XTl`K!5e6ihZRN-iG3c!e_wR7m&xGk&In#jI- z^-@&2-HymO=YkJ6v+o?8hWQ&2`&KEx_x5jm@$}E{?L9i$fAjzS-~OBZ#c|BYJdU!o zP1;--=fRFOwIgqxSw!>C{`>#g@zJA6y8sjbK@b(4Pw!N|>hp^di*xq!)7@mcx9u*S zbJo;j7yB5Ss!`EA0%KN@l8aHxrq~*QvA9HPt2q^xyrHW0mMT+c$%syDz?kCc{qHt?r{U_%@FqVh} zL5+dJNkIU>kmk$+Yz(O~fFKnFwNAz{`O3sGfe4Edf%nEZAOp@}wLn)R7u5pu!={>O zOblvNQ8-T)dvScFN@!3-Rg{PTK?;BZ0NToW-w>Lrns`3}PyqZU^%nBvi+?PfyX^`D zxMX9=Pi5#*)f%*7g65b6SVj|^y>}Y+TDLgBwyInZ=S|o5%;Fspps*mAejGw=Q!LIS zGUimQhdS6HB{JxYiDQ&hhLn5-W1pMas)`ngIpv&&AzC!fpn?E`@zjL+`ts(T#~(a@ z`8310?$5d#?c;iO$13xDHt&Wl2@G5L`qQ)aP%3Nc12-&fm?p_?`7#e{g}s~RsO+xO zv_7swV}m@t|L%B|fS@oNM2$LoJei)>!89eYIUpz^BM29d;p6Xq@A0EItEztI?$5pZ z_K!48d-v{xuHTTSPd@p<{^HKFXHTxW^Na3zsW#i|&Fu-pT1P}FrBcdmR&_njJ|558 zr$0z3#l7~iwl@#mPki>nPcOedJFLF7HD{!V04*J`8-W2Ujxo&-L(amW=AZd@{$m70 z(wqyZT8r=v!GPavUu`ynv%Z}CEIF?Xy38UaDi=UdB_J?)i-g8i*k5aC5QNAf zW5&@{M~sMZmokHrT5A!gX`0!5fA8Rc2&}Qj00I(%Y9>MfAyoiDgp!gW02Bp5ycH;j z!Z%Eu4S!_qGBGy=A6cPSj3cs;J1`y<)K~0lH9q^vKzdQi%HX=>LgbCJTojT1dSMYD5r7tNL8LbtVO>B1r!r#e=%2LoEyFS%R8 zd|r>&)qH<;etC8@Kbb!)$K+0=~)AK|B+G=&P>o%R+fN~KOJK6THI1{QdhR{GWvs%bD((IWMZ8cZj(exsDEDg?;gYDHRoitp^xKn@6K`l3MCn5fmB3uN<>U# zaw=m=c_?VmI}sJozXt5KJs=o`q0dFdSQJ)51Q9^$cD;AD??zBbFN)f`){Pg5Cm2oHhN>6A7TAKnQLa$Eq^SSyd_< zSQDs}oMS8^GLFnz;>Zqdxk^KclyuiAAk}l@$a2YwrKExeM43f{i=^w!E`;DMTdTpV zvtXSf7S*gAl{?`z^ERioaAe+DSBXLzH^%I3E;n^OAG*<0z#CmvPL~Nk9U~q9AA>v+nrI=g*hx^~L1gaCyCUgsD$s0yKqu9$qzKQ_6Yoz^y-b z+if>o6OA>_y0WT^?QXuN*#V6&%b57yo5wGnoS*DHs?GH3;_~j}LkONinI2c0^PNVp z+10M8tJZUaOk)?vGN|ZBAAk4BSD$Y-tDEbq&8yh9lbFWK)vMDV_aX6q{np;%;A;J< zY!s^kL)f35)O9nTEpC4~n@z2?ta8ntT)o_&gdchHpMJId2gmjoK6v;OU#$M*_1Au@ zYKP_ZusCe)RgY8O^?5MjwTi>#?X-DOt*A1;`>+2yIg5fKg0M0dRAFXeoHehp#O9!1 zUyZX9yF1U|Q{sMaau=uT{pyXIi|d?(p{StIRtit|naX^-+mgeS6B=BY_GTQa6u3&& z3{po%EvvM9nOQg2u?j7aAS;UwV-^8c7_Pgz^=U`D^@b!2tKQUTAdH*LgQTLKO&*4# zYJgIo$IVEUDZ3o|n6Cy%I&5-WMi>iLPE||JWMCYUbENPMokKKjd)wLl~QC8uq zGJ=dKh}zVYQW6jVB`C@&rTAbCK`F%;O(_#-Dr^j~maZEKG3La=2zJ-^s!&8?6xj%N zL+W6&9IF!gW!I;u9aDyC3eCJyP@n>+h7ds!M5Q=Ks#;P(+^B4g(HsYb$b6eX2mmS~ zAU2Ijb_IZW04V|jWW9BbMYr8tli8xlF*X|fvo zRO*o$w6(r`{`6OW@%Q%k55NE9PbBGXyDhoQCX2FhzTKbNeGze{Iyl+C(>^|$-&57D z+ocps;q_*{%S(giVD@-JpJ-9ZGFcp7tiRrvPk-jae~oPV{Nqm=td91-wS~*Da97VZ z1!X#EW{2VCBE=237R;~y)Bh4>A2)r;&KZhvG+=cAiGl`)@ofFF5Sh9Tgnk=un6<&Z zqxPLu{>)B*e8~e!qFgvwzg}iHDW+0iLEh19Zj%Vk#!>{yHjNNgnTxEAF<~51zZwqr zj!R~zhI?DaepnNCLm4xqDi0eTP*ZIDWLRx?*E<; zI&*@gvy(m5j0CsHlAKpiWfoCJ1VstXi^QC|armn8n9H@4Wf4PQ6ruDdUUZabMzys|aa_o?4($9|a1Z8!9&cFeJIUbT2vv1S$tl`#fIxFjtlA?3z5 z{WyA}!r2f|0Cy`xC6>K;yW4E*)^)M3g5^}Q00?A`yItYLabPC-rmQkvw}Qj&v-Plz zH?M|Cz5j!Y?{)pKDqD_Zrg48dA3Lh1Fzyl}bT?2~_wJYORVX_oSLy>E*EY=AIy3ZR z(>gaVGkw%=hj-ul>0!Is-`kUDhBzo&BIq_Tm%$aXf zvH$nO$3fEZ$)YBFcrIP`hka`_!=6Wbo~fg7ar#BM5|pNBLlk<4#R$q zAO*JFI`!G0tDNwl*V}bb!sV=WF3p9ez%so@r@HwaF#fhT#B=RDY>dul>N{E zqOr0bp_!SwHQw7XCJ->rraY1XLJ&^F?vtlq|2fJRyMZ}^ZpU4 zaC9sgiBisu_hdlnCG%6&rzjWB{I8#U`NNMt`5{zk7_rrNiw^yI~hG@niGAN-UHi>KY+y}WwXZ{EikfVwAtlY2BpdH(92lMC zjh{`c<8W6^-lcI~?{{5?O2I=xb_B);N5+9vRb>H{%E)A_ZG!;;=dC9Zq&~5wf<-L_ zvTTfqt1JUK=CDj0U>-FD;frrVrrxfEG#Hp|JRDXcNc zZtNXeYd}d*1Prtj?;WXt1yQ5SIe1eNrWB{4?S}!4T4#_n4cydm zNXBhHJZIa}c%@g{Rpn?A8Z@$6^&x;!3EpJY`i)J!JSwgf0Z$$qxp}GtcCu%W=65&C zjdK+`J}`&u(y$dNnnvYjC|h3=s?YQJv?MX=9W|x!>4Vet^|giOx_@rB-mTls&==fD zF`)v2(6$Zk%=TsrI&3y)KX~z1J30G{PyXQj2fuhQyDy_KtJI_PhQz{TeRulK)#?=* zi7T8<7Ny!9`PWj)EgtWO)5J;VEk_m%c z0N7a8-b{A8&5(L;L!XyH4oXU6%-&XR0+O+A8l^Eso=z6KuB#VB+fb1QMkpwwIX!x~ zzkgc#ShH zmiu*tlwvA2Vp@&6tI;LM+nk~uQ?Hppj6;q?PJ-4!Z5=r!C5zy|)fJi$iU?;xBcTmy zvTGVMGiKu5oSK7RgPKqh-*o*Mmam54`F8zBQoe}8*Mv)iwXY(8p=(bz??wfoOyq%{{jkaxJYW?Xko<9WRg&{@}*^)l9V{nl$AhRXfbAOG3IN8iSak5^}_K(y_m$9fvP0*q&yJNNF- z-<{_!rUD^2H*sV%4mqA>0oB%2Rqb7>r%lWmR0+R{iY7(b+^?-Q3JMG!0um!t{=f-B z<*5{{54@tJ4A$$|M-&nPG`FVR^)Q)M!?GVm=54dQ*!Ez-78w+MZtH*P=2M?hiq_yT|h!pxf zmcB2|T=%E#@~X=TjMMqFz3R_`sY4w|6DV;S(T-4BiR>B%?+~VjTpP4Y7qieX18Zlk zE1G~?hrUEeDGFFpI}9;6BLq3-;5=)oYad4;o9l{(aa?br3~XvE18mRMxoGSVYFsQ{ zE3+32Qn2ik$Eu2nQv(fo=G-11P4>8Ir$^&~`MfyeTX_7@_6NCh4<58%yo_g87l2gP zW>}iojT-I#1JW3-&ii&>xSQ=(T{ZPp>(%s|CylK+=CVJXz;p%LLpZ=%6{!6PW zd*L{?n`f)T`RP0Fgd_T~Kl{@^ z__g2s?eBd5PZK8tZZd0pRap;uS?3YC6ieWZ zGg6S$hA`v^i4oMhs%Z^aR0fA8kPkJLTuku6`)cB+Cwq2E^)&b+=jWB$-E`6BT#z8f zQ3V7>gfet5cH39ZoNKv=!{@83wIQA?d>MJQ>u0kdDjdNWG=M|Owex_w-6jQT8@n4u zWgsQzP>l+cKt!}ewez|exAUeUfH7_b3TY0t-F0c&v_ztetflWe=21Z#H@VrYNVm+% zpyeWDS$Igfc%Ev^j3~PA2t9u!muGRApuq5l&Z^D@m|_v|ml3sjBl=J8aU_@3$wZ zaLFvqVa`2`XC@X_(8Y++q|d0&UUP5<($|62CH z{{BbbkJnf9+F9PAChfR?V|cKecZCWVi9?yT_a8lc^U((<*1z2B_=69B?$wj?gQJtH zi{)#t->;_Oum1ASKX~T@1Qupv!8@lU-SwC*hqysPJZxs>=YI9~7|b^v8Xszd_Tl|+b<6JP`3m zZ6D+2dPe}=mSWRZT=PY+w;%`hf13Mx4zAQfS}1uzg0g0tqEPmCBeMKUSIF&PUv z7i&yP*%~lp6c|xh7(nAta^_T^NXa7%*ObRTb(vHw$T)7h0d0kq6;L1t$iSI{afZ}b zNJ0jH3^JJJ&NP+q>)P7syl_8uhY8U)+xoX2a1T&buEiJKKG<`uscc2a%I2 zVfAus_bH`(^|TP7iLIN)vJBv4{wT>!({-snX6ju5MlT%Q{{6B$!>V>bJP-HC%N!5( zAD^1m-FYyps)`|p+JPx#fNb7!i{`CCii}2MMkcvTr2>BL8L~=hAvH}c+6Ooow3TFWJflARPcot4+JUW=i zl!Avea8;Qi`Rt3ENfpv=Ts>drjf^*mr5_8B1It1N32o~_U6T(J4`l?CL15&1YFU90 zrw{A-$*ejI2M=ZivYYzZqB2vm`(b)Ck-&aYH#6s^#s{|>6H5-(l$`Rd5_?+q+doU` z*$}@>@hpxnciR_9ue^m)xTO5)$1lB;cH)gIb=AZn*`RqC=JWbs0&hS5-}UJ8>B*#WGuIj*W) zMud{~7R}A|E0wMKnj;C6RD_6EKTM%yi<1&#GqWmTGpX)e{Cb5RDP1ab?-+nyI13w zN`%Ej?YeSsztCzn_I&u(IE+%Z=HL-AmB{ zzE=^c3Q1DuKuo&4-1*AJUC$yfpS-;P__d3Rm+!p$6N~+Wk3RaVq2Ijq=C_{Td}qCW zX1Dd#^E7>cv5zF?me#_n)w;+h=d3b0SR)Bh$!Wj462}onF((p0Adi01C>I?>~?)qd*`quv50DQ*p8L6)&Lk9 zOR2rfLzx^l#({G*#$t#>OK|o!ouN<>f`T9y5nw|UQ{lqSQH)WfAkp$>4Mby~$C$@d zGK+DcyGUKv6$S&^Hr5#mh8(%J4z~@25L6YYG1b8&Ot5OJ_HJD*8Z)tz!&X5fr<_WR zQQ?-7QnEzCEXsiBEC7N5LigC)l_4->cK!GJ-KU10-z=Y6bU8;XNKQ|WkNbWMKE!dD zOss2+q3YGst5RasG^_Onkd?;$#olt&x6RD#%g??4U#y2`UB5cr|Fxg~)_-=o_u>Ea z5C6+w`I%q)(GTAF<+uK+-~agc$4vo)XRp@Q1@H9wrb{tdN2rh?c^4*A99g}q=F>e_ z2>_Oo2x%MF#`?oOS44xYtI7kz*t4lplD-r^I#`^aukP%(Lr!Vn>D*~HyP*q}9pdQ8 zH{t84CQCN$us3_m+nZeK z1PFeXQ|G%I8Dq+cDdObBx+&+aYv#5-us`_zXKy}uS1{c>JxQqmBG}T8xk%;cgF=s1Y{`> zSxox+I~NW`2x@N#jrpbD_@@MJfh^#i9lKaf9XTYDlrsV-gGd3yoD&GD3W~=&iamqyvl&E>r2WueO)r$>eXGiLXT`5#M>#QNKwGB*A&uev1&3t`S zhdt-^yjXNKauHV{pd!JoLLgB^P-6gq0R&JOk2;s^TpqPvW1^~{XOT))eAG?rC@5>N=0q0uJIlmfoc&l#u@}t zWHgqt>_pX*G3Xns-dBhvrG$otE~lInGFj$?0mxV#xm(Pq*UQdZ+tf{oc{e79F2TTs zg9{2OP^=a2x|^3bZtGX6XXIuwuU}itU!N`Rw{cN)Cftml9)EOx`uy_fdDpDFu-;+M zxeOyCkg^t*?e)03?045as4>ZezH&RI!AdNys-4g*%^0DYVjhdOy1pEDXVkBVtdgNJ zQZ*r9V!^hV4n0FMc3S)d;s)M-=Ude@T)enGxqoD>L8F?;I}~Ol=e$#iB?}@ULQKV0 zG~YWpK3y!Pi*_C)>-pDL#)egYiR{28aV(Zo@3E4caK797*f8h^QKi zg^Ls|k|u{uyxs+Gq)-+yM5UBq9gvWBT#6KdLaK#D;*bDQlntphRt1o>a2~G*H%MOJ zPTtyQ=VcQ6o_V^yxG1G~u)%|*R9DUg>#Z6vt0aEns{>DsL2E=aSyEAF4Ri9Ikf`!5 zrZH4B3|SzPq9b6HrV3*$&Lg6DXB}eXTr~y(xQMqV=VGiV;AA>~`bU2hy{W5EPcSp| z+e8+&qm-Px?QnIun>JJLP-$!rZPl8+BX3E_`M&Rb025r8&}E#zcie`%?^fu%o84{@ zgy?Yg{qxU%{>`5a;pFW*zxT=4e=n<`3K@0i&d)a6VQ{WARg(wJIeUv;>{Mtmug@>H zt4$6;hn#X`0F+Ea?AuA(HWhgu6C0_UNf^sm`!ME=rms!o0+JN8$eMX9)7FTM{jgEt zG>Qd1Jer!l?*8k0O0&yle}4D8dwlc7?2Fy;*=q0ds=X*ihJIvL%|~+I7t%7KA zIoP?Vz~p#5J-OqdS*~_fW$&LnUaz)KzIgWIKlV;rg_I&$EK*WRP3sz4S5{D) z%5urVT-Q#Od|N$uc)zLr81sWicYpYoA1%r(U7Be#VN%>05n(^(Li5SNtEboRe(?Tp z{Lb%H3m;ef_K)BH@Qt7U?E4>`-n%=SEsl>KEavk&r>E0N3?hHpM0L!^X&Bvo)XSKll>=L`UdYGn-(-G0*Shf+jAbIygu8Iwu|U?j+~FqBec z$dS2VfSXaQJ){C`uA*^ce7In2(wR_$KG9JApk>b5EBqB^G zrD#zmgt1T7;utfi5*kFoTMG+7iqQuXQwAt1U{H%>6%pl7Swt>b4ZxVvZj-OSc%}{X zL!#_T8plpx$Rp&Ym6M}ph|63$lyTZlb566$i9kON#9Gy!GhUo^le)J1`R?)CH`|N7 z+0lRhr~loD4?bLN&z`>c!#D2!bX93p>K}ahV!3&qV+N2hv1B;9Q?saoHO|(x-E^_3 zD-l`my6I$Yu=tu{F12kHOR$E}2$rE6a?z9oY%)%*v;7T&rfHas((N{bZHfvGL+1h! z77JDEORx|eL@47p{$Ty;@}0Bg>(Bdl&-pNoW@HvAkb4kO00yEwmaqQ!`ReJqowU-4 zW5c}+=UkS>89zJR+dF9|-Xke8BY?3c*^C5jn&7J{YRaPOhq5IKit4&Pm53%#ZCyBk z-6a4Ls99g-i_7Kx(>tmpenf!V*Kx(<+BakkGNMR~IYj`Lo;mHx^?5gRdA;pfc<9qG z>KYqRG{TwzFg+s926dSU-l1d(+zspABN=L{pBC~@t^-Oj(q;=x#sH8 zYp30HS*!0Dm zs&H#Z0G0&Q*S4Mn(ToU&zz2gQ#sQHODaIgyG8Z7tF*#?@sIm~E^E1_?z=lwS5v3#s zg?izZ=iPRjjG>f;kN_no?$>c~XQCk1l6RyCmQ3N4yAsgp7P^Zi7sRzf=9n@75~=mp z8BsK>It|8CRa*cttA#U1f>-3OpHmmD0Ey#;SInl=d*rX?Ou$ef>vRxHkSD1u)ZARGCqHH zgDuy=Ij{Z5nhe@9Ic6k`3ncz5%N0a^SuJc5d^NBNoX=etqi6W?| z#Lik|nzf+_17cGHg$#bXxHtTUoPHX>G2+WxkfB*qii$Vd4hHvuKr>i{hWUn=bQkMaUhf*0*5kxUSsfv0R(!n_F54@kr z2klL@=l#W`U-OTA@K!ghVv4j2W-l8H!hoY`+mLM6=(L{u#A3;kVIfu4y0Ia)%O~B7 z{;Tdrnpr#c+-(LzS9%`Kwy!=~c?sR+_Ex5;w9mBE&85h?lz!K3c*tdS-IZLPe&;Jm zSV!-IYsJq(-EDY|0W7`$%Rk!G)ns0`lX|(Qe}4=1g6l^4}*KZZa`oRbnr z-)AtABjlVU_if12JAK_o>#{Z0{M!HjpB9V0a(nlhdOtLa&@LKZqq9~ZTQtTYkqC$g z|C93`5vvLpGH3_^7*zcYRQ(N{N52Hv(ONAF#q{ou*fw(pWUvp6`sy0}zK z!PBg*p^EoTk3or}IwQw>%~&uEy;w%ESKIaLj~__2*L9cQdhl~&PSbia^zg@DfB%=? z`E@XI{k8t!#SixvK532vR!Hb5GtZ}WI-sS1r!}KUVdhqs7zyF&*_x?XMeea$3-~Q>f|FhJUnXQWfVRm41?o4oM^27V5 zed+>KtWeD%3XRKzOZ@KdKlP}MH}Php(aH$H+LG8;_TbUt;QqXAec>|PMCmw$3Y_ew zsk^tidG9>F)-CH5-|dDb4zqDM+@{xdGoHQCyybdCYj$NRLU3KjL6FTf&eZ1ZFp!2} z%%}H{msiVb60G?3dONI>X>u9DP1+phdt*xeLTNc}FUNeNv7_zHD))LgZC+h(J!$D> z=rpc3Eo$k;>m8Rqx9;#{|FvKHjeqqQe&?Th^5iK9Xij6y2sC7wPJE8?=%-)b4Wp}Q zQa6VOdy~Buz}Ol@c`=)E+VTkE6R5#nzv)Nu@+dn)x*{0R3ZfiT5 z-}<-yh3Q_^E}TdqgVrGtsTM*MCqvyXbD$D)3eJsj zQ~*Pib4E}_ah6Ai@kaz3LoFN2I z%46S87kknr+t@HM?y&U>JKb~D!qeQ;djV^zf=gpo&|ESR5-I4dprk}bLyf~w&>$hC zm^4ck2IWcP6v0`{Sr9d)Ob$4$t}dQC-fnZSdav&9{H?;pw;9c1~B{??;Iu&WC#5HqXy5lmlR4Dg|;Gxvs0K zqSgOL)my;Haa{e{#nm{pEUg$Vlk8Xy8p2F3UuI@zW@culyf@68m?^dlVwRS7u%Wu} z%V~XdM=UM<)YDT{=RE)C%v6dc$!{G$_-?Cf%K3NS{Mvo{AKJUL|LnC_7kX(gSva)x z$g7vX6R6E(mowTlDoLW?O}_7~$KU?xL-{YBz4QYf1w>pg%S~ehh6Fd^Z4*|jL`19` zee}a0HgfCn)4$?@10OlL_lbS;C-b<65F&8psWG_V&!Vh4@m6t@rCRxbJ>``8d^Q_$ znv6!31%fFI!&ECz87giXpN706;Y}f=*8olGv@tUr6d|^1YR$*x$(g@*wv%t~%u3y+&tu74)i*rlUE!~7!a;Py#qe3=8dqqhjjP~Q{ z2&>2-CF>*+T~*qpbibO;P{Fdkj?l6TNfg0~k)(3EQ_l4|odrLwT~q5QmJEu=CP`S_ zOOKy^;xoVIH(h$|x#Oqqf9~05PCf9zU;Zt>^3nHy95MQ5|KY!V_30lPRSstrMX2`f zo_Cx~Go~BR2!s|yZtHge;A9j^RjS4X)I{;Dp6*h%77>b=fC|U-PSH#nrz>OwtUm@~O3vy|%3>_3 zMZJEiR8{!U+us#kK}CRPKMk-lJGhWCWdVV5sXYM@Ks=eC@F`qys13;bwvZdDN(%wX ziik^x48-;YX=6XI_ZC8ED1486m=IF2$VDu|3B#Ks(Gg)`onp7jvt9BO;%6XlF@U3qht%npkJ&=QC}M8hgS>#7Pzpz`bJZ;do=P zayn{eX@7NXXLMxc(5;;}ws$u@o;$d(S8e}rYwgyijBi;_r(2&3y+~5AAu+ zrM0KG{D1H7IseI*Z`@1{YMF#!tFrOl$0D{KH^#ueBhoZ8?>PR+QL(Kp7-Gid&QHJJ z*}1$vy0$Z2JG^}V{rf+0YTt)1s9dRCf?fMEN3p;fF_U=^X*ap)Aq}l_*R? z5@+YnU3$;KM;R3e1zmZ)%bOiOm*#Ugs$)YGor|-aEk!+)Rb7pmKFP8?o#V-#xdXPa z3CcQgOd*usL;~wbGGtjKT-C_MZk+KWhab52?eBT;^gAAW_xqh^yY=o5|M%xe(0A_K z=8b*rxo2jht#hwFzj5>0&epaohrj9%{Y4%n@A~LxZ@lr`o(B%lmi}UxrjluBXZxaP zIJZqvGSPUmo5ad{MUcjbCMl|F>}|8XQ)Y3hv>xpik>qt_$HOW8_^oIxW2{1FsD z{#a6v+D$KmIG=3q@k9`9oKm$A+*l6+HEjUPqRwc{D5@GmFnkygtZ38P%HY6=d}y2! zf>Sc`wy+u+shF8Y={SmP1JL=jELEi&1x&KmCKhHqt*`?ke)-rO4rF_Ma_@(FNSHnQ zqN<)bRS7{!grHjhMFgNtA(Cr@vshUcM|fDz7$)9$!jntuLmTl3BEn!b93{Z<%RCv zrQZI<-agJmTMy^2pS?3_HbR?htfvl+dInx3sbp4@oXc~QI|wr9TRs|+MH1+GQKI>$k`65t*TDA|0G~ANpAUUp1 zIft_}6@g4P%QT3CZ?pNlw_8zSqY!8&6YKP$Zf|k098=yGd79_7D^^Y|Hsc1ep~iJ$ z#5-9zBg-e|vXx#fw}0iY`?J}6UZT;Zw_e+S@Yt!hJ-YYMq4nV_{r!;&s@&DtAWj6| zxOGz-NRi(E=)3!Ki&atls^9T@?>+stCqMnG@^tmWrE_VHYo$ChiC~+z*XMg^IJwQ3 zt;V$prB`e2wW3Ft%l`OQ1B(`252c1z~&T?ZQVz3faFk|B*nNc z)+?etuIkyQX-3*YrXyGrl87?G1m+=V%)!SJEhPD#JerS^fpk8=r!$T*klARhfd{Z2 zVpNQ3r318_NK@C^xg-*fID`?np)eMrl?H(0%)$PdA>TeR0OnLXjLp2BPRlzH8wWd9 z#Tvu|OcQ63H)vK?O1X&hN-66tg3e)+^)ie+<50}XliU#-M-sswxHF9jdSP!blEGuA zOqlC+ak~mT&=jI-Rzb?agsM_m2N|bhn#~HR>rfv8!!+JJyzk+2m%q1n<>=Lob4OQB zL{dI;{;T_z;xy`EMSl3=cW7t(;Oc2r-nr+{&)?c!-#fqO_Rgyp)?az}$h%EgC(VI> ztzXB86jQUXR(Bh#7GcFkMn(dX&0w^)BI46_VC<+oFKYzxXZh!vzU>2^xlvChVI@p%_tMKVCL-W|Mlk0 z7rMQbxFgnv=YI0~x3|`B96$KzLl1s@@9I&SPSd$Kom-e+IQ&b$>ks|f-}6VhbMsN0 zkfeCwrT_Buv;S+nGre~E>HYf-_wqxB_CIv>;`fSj6mVTPHj*}mIFOGx50LKGX(Al1 ztI}7MiXt-HnB}SLCPEoQ5eaRhoqq7=KIMbs;H6{QXxbJn7$w#?C|<*#5n~v)(Q<@g z1JR-+Dj?W!8tcHJ)S^LvRtGR-LTH`Azrqfdgd_rmkrY^43w``C)rM;0a4?MEBoYK8 z$#Gpf0gG52XK7#vaS{xo3G&b&@$ECC^)DGipn7??EEKHqZR-w}@z!@nQE<@2BiLv~ z2*bn@!XZW|y{Ze0m8yop?$p&CZ-)ez#+SjEI1btxSRk>(!7j zmoyN;5j+=_)s!;S*g`<(6G5GwlHN*pdvh|{o(+~Fh(}kZYFr#sL;!+y+V?tX8}9WK z@i?W$%<2Zkk(4p56|{Edsw+zDFNSxH9y#;Ox&L)=@Su0(_S&tgiMz6E>a8nRFP`R? zx`!W&)5Vm>H+F6uSUNP{+yCOlADlk?9>%yXr#H@@?MVB!%_c94-9a?WnM`A&0wJiA zJs#`#Ppl5^BPqHyw!8{e#o#v08iYnsqDcmrlQVTsmF7RlRT z*#2*$w)2A#zbj+}2h^@DLxcPs0jn&G|LO}L|DFH&)}0rJqjL*$C#)SCeXXwRR8nKsMw1H!*|NB_fA3?eQD6JoA3A*G z@pnD+k%QTuL#N+;|J%=8yZPMZ3op1}&R+VDb#v9Y-9)18;TuY=ZEwA?w)K;$93MLP z*r}5rNu#;F<)v-kP)3xgphrMMBnih+RhX(OvpC1dQSP}Uv$A9qx|dQ!jjrj3e&M5p zA&5)bh7jO?jdR9m%BXj3$`v84Y>PH~0uD0h=&?3$c9&{Fv^B6me*wTZNJlYboux#^ zG4^*`wG5yWxZ4Gq?Hc5oTDi2xXdZe8WHe7IWn`N2UPODq-OD`U5v37^Mo|oKDRM+L zinN^%f=QlJ_%aAb6bukhyv7JV6`)DrEQIDvls3AelySh3gEJem@vVR-Y2q1(0Fa;% zfb^g)tO=Q_QpD4VVInIpcb z!tQKFI5I}e?(A%iXT3p}1txM^I~_9#3r?^OLm02q$qDwJQlqSh!s_1nVKLgfI6tiv zW6@;ua~GytM-M!FXXmvqe)(TtU4O1=*0#2vdgJm}&)xX?!!M@gk(E6wt1_QAwka#M zFj$&Y8@7p*$Mc=MlP>)5wHN9T9{&7W*`?W)Cy!7mHZ~`fLQzC3TQ}_0LGM9^bbr3(St3)5^=M~2zao3xe$h-A!;wUSO08%=r5N)Oow#rBho1PouRQ;gOElah10c;Q(4bEO?Uu;*a#=r%or+OK&S%m zjuDAs*;uoyN*C_3`hXybWkPe?uNFaGS`y1nuJyt}Zta_0T-{nN;&2Ub5!QSZ{F zFZvVjzkK!ER@bF!j76CFVz*4e1!4xWFVJs5!BE8EzdqvAkrEMO0gNNTf@O>{$QVTluvul* z1Y#s(B(#}D*y&LrSyd};C^$?5Fp7kQY#*lrDv^lzG)l^P26rRy99B@;64e%*NWK=t zHAW#63xOw-32r55mLSktQU~5KV=-jX8)bC2Lv=G5RbIrb5x`H$h-jo}#GAroQ9LSZ zF673YT?t*sxZjDkHYzt6TZRiuSwn}rle#G4JQhgQe(E%G*fo|!Ox8Q)wewe3PpshW z-R+&mi`o49`+HWCa7kT%=4QX@)k+^cF;5`$VAEU_waVgH`zE5?qZq4MSxys1RpTIh z%*w{1G|JpoNaN0<`%(YkZ+`CL%TlDktkzd2&HDbugImLYeeCEvoAG6gNtZ}Z+{;(L zefsdBUS~j|>bAC&_?1rjZC_0e&o{M?^KMg5lQj3W35e`mpByFeoz+|S?SJpau;|Hj z?_lNX`mOiueHaCluw+>tyD@sn0lE}jyE6? z7mbcP%!WD`v^VNrS3BtLZH2l#8{ENhixG_Elp&xbcCifdx4B#PQOEUW}O7 z=S*dCOC%el#yJr|(eBY^GogX@S{>s6~#pSFZeL)z~yj4(|Uf zr!smNW`t^E%UPAMcseVEz#;paeBP5CkajwgaJN>V?=;=qCAwN+Ne73XCSndK24&=k0td@Gijq5sI zV!PI*aWX3=l+}Yyy1l!_nW?KfHc{d6!a@N@`Fq(pdU+btc8vrc^T@;aXG&Y=23qd4w##Ku-pPTWpeFAbu~ z))v}?xRa+^nYEo!9;Z>p590vdEZL!;P%#Lk_?vm%c(qee*Mm=eJ6PD zu$}dXw|}r_&#LI}q0_BPciud>@~}tch09+#zW;-rtV`YX$(#omc)*0)i-QMidt)>iMPj;n`;Fb{%MRUt zXR$;W@YX`-a?g=6A87(`h}|myNEnx!jegsH;00 zv%oF3deG16sYlpUQOX%@A@}NoQi_1b zg+-iIbuC0hxNXnVNNekZOHydpBTt-dZMlR7XQh-?sW8=?PzKARYr{&x5deHCyuCBZ za*A9#fh5XEQ&+v7EUK~ARm#NfXcI~_3|FO6%3-gox+$uf3v4Y`RiRA{4(y;gv%0Cg zZ-8-$yR%^>1Y6tMZ3>nP(Xu?cADP53>=%s=IsZybCN3aU^JOE{=+3XEYs7M~KIZt8DdjH=jdE z$}v}qgN5bOi_5G1bdgAbiG=El(#@dHXH^rEtejbdT*PUh1h7oTwW%e~2yJSMkIvuf z?R(pnpny! zx8Lk`jxP1)WqRz~)$HQ(D5t~G!r$G-F*zi{a0q9h znFN`a!if-V?T7x~p(H?C+}R7a7pkt5xGGFh)sp5_)5wIDGvzcUIQ2N}PId;pP8#1+ zn_D~6^SV)-gzj9rxcE!RuSe0b(d54s&9yhro?Fh}d*sl&-tp+KyK(C~QY`J?_hhLq zoxcBfojLOxD1GSE@lWnudhEFu|Hs*U4y0z zMG27wqd}bHjBRJGpe$!VY-0%kTR;qBiL}&TpiF`|yQ&*RC=WczquI2PGO}RHCym!YtpbgN>!y*h zL|QTlxZLW2Q=RTAWAdqU&mY@!?7+h5JL}hX>g|IIha)w6^Tt&oUSHk!xVH*3wl>^e zo!{5%&VA+8FWtNE1gGKPWq(n>DHi*+tvfQGIJ@?~CvU;gE5SO3-S==I&v`A&Ld&_BMm{k7FSpO&JYmA7O9kUS;p6q~(!KKjscwowWf5~8O~(ZnZQGtWTSMNCVW{m84<8T_D-eyjQB5T| z*Gkt_)9KA4>?UI)W3Ox@I5DAwaWT}?3W5u8E@j+nl5pXvk2$tsEQLdW5SUoTWu@{o zEp*|vi)3BRz@8?gV_>|7JVc)JB<8cRzw`2~g_Tqc>#dUQ)}zDAa~mT!x0I0)%(X&@ zv7T85c$1-IyT3nM?gt&3Sb|A9AX;MVW{yR?sRJ!-KB)E{n~Qr?W+aZ}Xf#RY=+4@- z(<5c0C*x{BiJq8XY~gLhI)*7A2Wtb z6WW1XxOz1Ve_$uiPWOMbLt|`$YpV(bf*k_u6^lj`k$6^(%86Q-?@vaxM~<+7U7QHQ zA~Gpzr=IT2A5aCDft>X!ymkGyV~`a>+nd$BM}P6oi5!Py%@M%%VB&C!mnX?915ky_E zax$v0VCB@#bu(?OZ#2Qq5jrcBU{oo`a$agp-~V&(zdI<4pwMVTK|}}Il6KfgFgk$T z3^@z6W2jNWCt)Gt5+bmZyF$4@_6H=sjz4ur;e}IC9fZrs|3ffPOwuIZ-kwD=S-U)%U+kwDSGCbK z)(y>4S=!nI%Yal<1&oSXjYg{1O)&?0n0RQRG{y`kGbSOc?*mayLwK};udSYV?1gh* zdEn?1FI{=%$jV`l>~j~tb9C>D;CyLvkNCU)adzq(uMD5+k>$)$wcEYboA=UBageFhyJ;_ht___+2;GZloaT(sdarNI?85=*H>=-oMstVoYHoKuY2sr;<1e zYoQuBn`x^9ix4pW5fV9+&|6;=VG#mT(+uRx)2EEu3DFX6N&u7LjU7TL0JK8!;8@JN zG=u=yFB~aDyP-urmv&2GQJtr8oN!{1)hHFHmt_v>G|DKGiqG;M9Vl zu$U)r3;eCxUS$DQ3Q}`iEK{x|KT00B|9=(#HqPIEw!T)KNDj-anbq$;^Eb|4`*(SM zWUhC7edFs@`3g(meAaGxbXyKpM-TkWvs&u?FhpSPBjtvvt%z*{^O*n*D`_OTRh zD(a9!0oAomGeRt_3ZG?kJT=G>W1HX|#OK;mxV4B-;9XRMC079fV-g%@BDD5l7Ocmd zf`Q!|$|Yss&eKK{f@Kt(hia;6U{Fb^2#j`#Tsbp{gec-5tW^{v6~(eZBweX4Jv$UB z3%N}_jdMS&n|{BmN|>{icF4e{+Z(lvSZ|&V$0fC*+josK+v8c32of_-^>Sx!yfax? zig$KLgS>~lWfb5JL_<+FkqE%P5uA4XhEi89-9B`3jvy9@<2o$1l zga|0uEDO$z)HKJ;V-<^dHnN=*cVj+nLI~>8?(M_QJUlo?WgJX{5X!SSxKYAZ5khp? zy?&~Hr1#h_z5VC!Tzc{5*8jTaf_t^4<;kh6okn1r?gPbm%XK>qIdnpvO&Fx(3y zBrt|#I#Y=IL7vDY-QAhkP$%#K*-O03=g6!PjXP34Y!BvX*F*kh9MA~`3#9t=7@$s z4dka-S%*&4i4!m)COpae0_;W1Wm&X(ESp~>9fV^;n8{(|6v6c^o!}9gPEk`ib&(U< zAPXtQD97W`4)^ecQZwTLOQ13W!!z^QbZXYNM;ec`G4}aZ<{|*m> z?c3Xn@t#{3o__t@=WAW77U2mb#amaebtKO_aJHAK1d*of>P zhgkrQMEeni+j3SjHPNw*8SPpFh_B@N{Gj6z-q@TXkJ2b^&j~Ih2rg z^rCGL@~FA!P31)zz_}*cR8E6~15lLC5!S`L14~^%q20zXY;Z&+!a)djcU&KW1|otM z0^q{FkW~_qYz|LHjUe%4T5s%*LEParGQKRD-HoAlDyCl2JyJYq+`J&E-L7_DzVf~U zFV-sj>mO`=ZZ>^udEbS5I^QZrZh#-!vVDcP3)!?fzxHY*<*CK|UAtsobM%d?lOOEG zv-yl*WRb<(&-J=aR&)J~F}&QHAN0Gh2u)m|`q1HJ8=68jAa5{{H@KMSr7m!Dfj~85 zIGs*r&BnBF#w>Jm`q5wf=xkO(^Ock>9)qN07J*2HNnk`tn@i@gFb);tGKmsOu!v!A z-ztO+Yaul*STQp~hQKWIq^f3&;KhlWI4Oa)i)Km68e6I;+&E_wtYbXFFd`{Ek1^oPJn8aK>G~1`<(B zL~teW6-6Bu29mnv!7>G@cCocP>GY#c+;#2VbBdKV z*!{XTBhOYD+<3OdW^h38z^>!6QygI=wTMv^A&%kda4w*X-p)VA0Z0Q_f2;+7nQ&i$u{%RCsz5kK zj`&bzJx)09=b6PJVn8Dy3UlWLxbZPU;CPG^1ZxNkjpVSg!Km9wF5bBD@`bO2(T|Rt z`1sSWeD3B;&n8PqBlPwy@}>VKAN#;G z>(rC!oNq?T2p*=<{zEd7o4ebHfM&m&rGP_0dxvG<(*()C~d*Eb~l z`24k#EAM{%lWP}lJhJef$4K|*j(uk3;LB^gD6Yi((pKCW>*x0;2H@Igs{7LYBIxd$7Fmqa? zfHj01YGo7%X2`;PZ!(_6u3Bneo2M80N$dIc91%!{Jk?68+K1@QlJ>yP9e%@ewiS_54>F%%9p!G-%N(0y1pU-)qwR+temvnR054Ym^L+6q>d;@s9%M@bs5at!b~`VtE3e{@zrA>TM~haOKE?W1FNw0;Y2&4YC9moP`x{u*UOx zW(*?|GG^d<%3&-wa>7B8aS$J-ciRm_<}fyISYvkz6r~2;MjS#%fli~m3XDg9JEcF= zuIbTUX@CwNO4>|w3mX|QdY~^J`nkcvdi%y&+RucG;RFMUVZo8}huXt0+`hZ5U(D3! zp4?hq))-L>ta)IcqFicRzxHdF2iK*e_g894O!=;F5pT2Aua(buUiIpwpSfe#59*t*4~xm0O1)1n zy0X82?7P$K)%IXr6sS=v$Eh@@#2mb;$@Db4IYvpWkj)FNJ=>2WW{fplH~}Fa`@zRB zR+QLEAw#S%EZ-4)!Wf(kHH>JaOht`k*<5(Or8O8pjioGP@q(B9Ak7l$AkTG7j=5#Z z2^)u^v`ldnN`mQgnO{;72Z02HxfG}nJP1bv4bucI97@wPwXjBHL?N^R2q)SRidVhR zaY(P9)@r^GMSqZZxNM|6JR2eUg`tLHGXkm9s8JGzWx&XxU=}gIZWIq}v&}$QGKL`s z94>_M#TX-EQ3=g!W&KvSIbJQ-e8x=AifaQ9;96ORy=`=!N^xMOdN6 zo^SBM$QZ+vEs=1|bca|D3f&+{hYBRpb|G2L(lA8ShMHUN^kdf|jcSP-%X`5K)9IEB zX@BR;y@%!xeD3`9R|2ov?a0$J@$BwTT)gybu&X;i@qG&u3-gmFpS!m7(K8?4ci>4u zme0Sp{9=`m3LDw@1HvsgZO*NZ%*?1yBA-Irh;baDRTp6hib|~(3Qwv*;LkdxFu55>JY4%TQ8+BWjC<_wAJp< z!#tIU0AQhkg?2fPqEg_R`=zD9%~+=1Pny1a6EVPeE((p1RjG!l$PiIB@g&Fq z`$1uA2}8*Ttr+`e2Xk`A0VfujC6TYG?>ZzTfKA~&DkbG`CPy7h2}(xUlZHa|AxBJW z~EaLB+{Isq#*gDcCRy3^>(*cY5%C44ceUcf~fHy}>ioxl^_Rc&k)v-tcyLt?#<%-pVWsKO z*@@|W^~R#3r(61Z%_I>I9IxTg$<^(zPt@-Y!||{E)K4xRcy#x%j}d3uuk9T`@71;6 z{GGMmIuU^|9ZTDeqlCfc+OCa(*hcl8OQs5`Or>c9 z{&g%{W0rG)IF*>`Q6P*VaTpD`%u`8Cq>MonV{S|sfom}>lDP0(U_v6Tv8_r$(CKv< zQxnZ_823Q~watw~87zMZ1T>m{cQ_zGjn;ws(kimtcqt81#|DI*Jd$AM&*m(&R63rE!+dEl`Vd+(VUo6BT; zWbPv;79N}*J3K$Wc>2IY^LPDl5tZM&u{1tc9;-|Mp@wro^4Z4z+pEtpR9hIE8f)Hn z`}$yW<(<$iOmvzpHXaDye8Aaz)gDf0RwmIDT=}?r^ANq$-g8;pdIPOIXI;BkTKYNM zzQ~t8aq*=jy@?z>7@%txtZ#iaxOE9F-?ZyBKDVf^UG>Es z0hR*af=L?+1x*T%HGm-4a|+JgghRU<8$!wJ-nBY=$UkyW|$0`Zt$exX~ZF zs(#nu6DN)w-|6l7hyUu`t-<&wp8T}lSuNzQpc1_G-oI;3K6rC@ZkI)X`$@93wRPTi zD~o&X^Str9KlXI6GG9HyYGmS^mID|?*jnhJo$oV77yqhH%Xk`@chAS(gEV8lZ z*=8sr1kuKemTSPGC@jZ8NU==X4vOM5a6?MX-OuEr*;bzCfEgvOaW)oaMi&naCc{Rg z;DzN9$*l24b$zX8gcnp$8%refSeOYLD6S>ain_S7({}^nQp8YHE7eTIqE^*PrGO&p zCAMdzKP<&SRF-jKFFHT`q| z1G%Bp2tesOD^J6`MtS`eXm^k{re7lrW(}$w-Ew#YUIq-^{;Zh zv~S--@!Hvm>0`?q>vI$Hg84VPXZKC*0}_$Wt#{77J!0~MMdZNt!X3PPr#kcuZG30N zQEKC$d)I$WW>)G4rcY$BRczTsyHg&B^8+|g=#t=o;GMUv!H%?zCJ9w4^5Kuk0Xx(| zbJLByQ`+O!N@-M#n4Gj=hI$MXGtRNF6(0FH4V4e)adyYyd5`F7qe3jib-q*X|EqUW zRk8o(+4y7E*`YUB^;x#iQCAbV7{f!cSUPGmDNjn(4$NcVmPs}kz0x@`A<#o1U()xG zgM0b(Os_ea)hmkTDHHv|zr8ts6v_m;5lq`~b^s?9z#E6=4CEZHtikM=1DyaW`Cu*3 z#G7lxwL^<@uWa_m`co$xZ{0Wj^gnp<8qu|VdyfA3KlNu9cklj>|M91&cr6^izg}y; z^V0j*#Vs6W1p)HrFH)&51_Iz5jfE zV;3<4LkpeY}%hQz(h!;p9XuVM*WygHBN^*)DdF4`lz5{T^~~ zR>*ac57g$Zwj4UefH^fUX~m6tg-9iLVEe|ZUYS!0dEj^jGU?V&(fN-*VmvNuSK-lBv&$06XbLX-o? zwoq1xX00+DL_#1Nxs?W$NTvfL|E3OYkHR4^;Bpu;5o0UpwbN>qjzU;Hk2;t@twOUx zaIGk&U`ArLKc3xqwS#P24&8D&$Qd`-Uu^sX1vBrFG&6#s$YeD@rzBSYZl_aI2ZUGmY;tw;ojucsC!5o6 zTzu)s{5@s^S2Hg>^P*r;C6I$GnCL~huWDD>YmXx9ko~2{O9!qMy+!LckGE)hXAfCi zT{?Tb)wF4Rm7-^;{aw74spkGY-SH_DHIIAy7LOmJuAN?s_vRSS`kSkrdXWgn^D1RK z&ePL1yl*o(9rr7n`F@2Te)f$^M|Yd|Cs(%R_l619POH@qd_RE79i8jrXW8OA`E;Sy zcQnt;{jF7ijbOJAGl_oub@thmoxWLYd3d9ViwJBBS48PRHZjkdce1_5=63nikP*hl z>PZ?EMX`HvHoUwX4!RTLpaZyd3+6pj(sLeo^8gJsIjY2)sXSbfcIv94uAN|44|JrZ7cJi(VE7j78=D&J*z5dkk zA02b=9da}zq%XY3Z2iFG*xi5di~mV$fe?+DW5j@tYOM3wmC|GF^cy8>&B70SA-(IF;bgF1vlXjl zjbZWAQ^gaRydw(g7~LA~M!HlD#IAa4EEF|&EfW(loiWG-U1bA60huWK4dhoq*S_(} z;Y(|9vt3zlJ@@9C18R8B0U&$|R|YIGu`^ZLsFxC!YMk%>&c^k1aVvuz1_wj99Koyy zp#^2joEyL0hS&RW{wC~6;cCa)@JsvMsWY8}2lIu+@+3DtGVL0Lmd2JHr$em>7MA5e z*oyq9-Fyi67HqD-gb!N5N(A#C1(<;CS79}Qhj4%J=-`0a($ypFmO_(Z(IpYbiJcy&rtLTzj>JQBwl|>OHewr1I zjkuwa>R~^pzN*(esS6JRF0*>sO9j_j^;=n~W_h;5RqlIUlJ_T@6a9WXRV#%~D1ary zti9fE%#?Vc9M5!?T$9vq0GN(Vuw}d$jdD3DS~=57nG&zpDAUa~ko*H6wJ6jEN^y7t78KlRSiZ;zLuF@1QWw>nYZ^_>f^?w{Hn(#nh1 zFW#~H3_vbl*R^s?G zD_X!5s;-M@rk{HqJ|!7U1UC`L8~r1w6zsdzIr+lUzT53ROfJ5AbI;rF@4Ij_j1)o8 z1t84N$<0~?zL@eBz#`*p=v`A!fOefZNsG) zG6kb$eyWALPg~XIJRO$>r=?RPr&tc z$X8*CLRY}SJAgWX%D{(kYZbBw4zKu~X1L37nmmvEl-UxMnREv4$N80X>o#SJGxJ9i zJ@?Gzf?Uh(=Jl@@7dqRWqpj`V5Kouh{;%rg-+9r|ixcGW-RZIM&o1AnEuCL>hx(3t z|KhvP{d#3K?GKq{J8{ejRhMM(DEq~yg^!g$O{poFh(P0vT|*cZ@~~4GMdpHDV*oI>kzJ_DO>=Pi=*r! zE!=<>1!u7iOD42gf|<*EE*(TXOPFP@Dctmm5R#G+i)x~gLBok4aCf$cHgb^#*hcMc zK8k14TrsIh95L6!!!&knKZ%USu@JmaOi2X5oxm+(sFrQOkR}Bpj_+ekOuy9VF>GrP zGnO03yCuD_LNn7wL11RznZ#to`8P^JBeD~^92hgS#@g)XQBohP^m|FK!!+2o1qJ7f z8wW2KLJ!JwnPf3VUZq^ZmQdP=f9^T<&{}6La4SN|%|T~ZbuwZZ6U7@#Z{4@>nH#rm zbcXNlT09Pd`$6UT3tziq&s}ley|(iD^w>g-)9ah* z#a3^a$*t}fPgi0?9Wuh)Q5OUwv!^*2N_n5&6>on*ja8~QTn~Zn_6KN`E|Exu-d{UX zg0&nDg{JV{9zeo?OQ>3KID`oYPR_#C5Sq=>?TKm}=YUCfi%m|K5@Cc&SQ0ZxWCdF9 z>NcbL@Lc^+Ha0!x=dSjK7YDaX6IVZX_w-Wx-IW4a(6Auy)atuuiUW7%V$99$4c(dz z_7Jw%Ni6WWwDJ(FLS{&N_VmG4nE3OvXAgGw7VyYmkVQ+DdVk|5&)tLA{zHG{Sh84O z$M0>F*}^@G`@cF?(ih*OQ!oG46?=1Rw#t>j2H;gBd43b=)B5ChzWt3$mo6PYe)8_S z?^Q}IE!`YBAx-Mmu3dAk>&?#Ynx9|%0>>(q{a!c1gnNO*jK@HFE|P^IBx=p6jpH=&ea9##lvXBL85wuM zh-G5#or+nG%Ax{Oa9vA@)IkB`xkD@is#1kH`6*6G*zYGcbsTEuoKhMc4aHa!pdO97 zNzk-vVY4uXHUP&EtWFR3EJCnspj-vMWR?mPgJ}L6iZ#Y z* z6QaYY=;(%H<2~LBQaR7B-c$F;f!o(Ed^LKb4=XvW=in1_i?a}z!UotWOhrB0fh&pe z)K9HKpF_3eT$pf1c|j1^CM(X(3w&X{HUSURz>=nYf)(6Z1`ordO&E6|o`L2xynX|Y zIQr_s7y->y(P&nBUD>Dw)BYX(^|ZXc=~!6Som8at;ike{gKSsn(37hf6hUbh=(VXz z!?G6QESNa?e&ddneIMyh-k-LU+*|7puMAOlsJ6y-hV#?ABel1?#_;qJweNIqA$x&5 zSBH&SGMNj`^GDCFR1ith5VUM3G0EM*!bTM`r^YW_sM)m_-+KGD zD?k53;$`ht9M7Bd6-Q=FEmfXc%eJ`RyZ8O`?>Ua!YPBw2yx3~BA9>_a#)_Gl*(aX( zXs_45aN*+W>gp)dHF@BHM{c*Do~k#PQsm6tXSgM2jwz=E{utC6hTvp~43>6WJ4p;# z3@|7G4z;8zEK9RgAR;NTObgjHPU>>t^?FHRu&vyTc7#!=0WxG7BZ+VjV_a}s8LxE# z*k~Y#FBce@3Y6Dv$#<6C$Q+2*hN?xF(atSiqk&=OJ3Bfy^B2F^XF@oI4!Kq(J z(>}!(*dC3CdEinjkeZ-8=lyLF1WvW=3#67;yRPLUjYkSvz158kbvnRW(KN}Z>n0KR z9KTQooME`+lF$+nT+os8E6;ef;%m$#K^7$df|k0q^09>NTwLC;wS$me+T1)ff9P9R zUOYB)pz0lX?aFu7yX^IM-fUEAUPXTCt6#W!Whv{5Ti2H^UpjYfeIwI27~k7ofddDQ z+P3rbGv8WmZ0z#=AXio7>46&S`+EmrublL-QJ|dOv57aU-Rh999dfeu;mmAUlWn+%?8!tt`%`ZPeB1EKKM2(I^`!(p^cWllThY+2TN`M@4&b7K}k zgr%|>V0mu2L7}k^U;u?M`{&^j%#H(c0cN4nhoS_RmtYaHK zQ$3K=Be=WdPFDyQ5R0%J49R93-Htnr+0&nC)yUe;a&7LkJo33KrJ0V7$=VWA@8_kc z)X$rOuT*KHblmYD@M^VqA%Aaw`?9}Pir;?njWKPONp$asy_Sk*EpF<7P6)Yr6T(x$cwvlw(ydl$&I*tg=f=w)@r+B2^AO_orf|P0Gr4>8*7g3w1!!v9N#hL0rN8(TCy9EBr$ZqVU*aIQsnWxbn3`K z$99Hs(cVc9&d(p3-uKSMTLBJ_?4ECy4qUi=Yp1`Z;tGoWVO(^E-A2&JV*HU)e`5dC zBdxfr)Xw~*3~h&m!#GtyEGhS`ZQ)Ed76AfCTF|s%+lR45fEs`cIDn!BS9gr?Wop;d zYCr%P=L&LAk*iz}H`8T_2fM}|MER~X-u7oCi!_xg$da;;(hL!Maj`Vj-|TKXZ&Q9d zU>)65l43Vjs8rp~r@2?@G&CPi-o(!yzjE%b<<(R1)UH-PZhodxTYQJ)t=)SzGy8#YkTN>zGVvwo49zbrG-e84m>B&2m+r*!<=(!TA{!#Z0H7R6b6!G3;Z;WXSMVcYkD7gZ+ zgotr&VN?V#*6RsBNb1K9^7nNTuRs1z09Qic^a6 zB=S8znS#{%*-&=P?PWCPyo0{17^{;=uUT+E^>-C232ae-ZdBtybxF|lg_h#K% zX|v`{tN)s{{R8WV_H`;Xr}1og`?awEO+d20UY$8t!tA^04PsKseWx^G7192&Z8FiD zdpEii!=wWM=1{uZGk;DQSj-gUz5pI=m{aKSd3dJ_dt6wKRdQges9H&$%}!3{Jhd%Y zytZ|%;Cqe$l%QBQN2);tQ$v91Q5{x6o`-9rlCIB{uDdu0X+A`Glo|h^L2MEZQDba* zOuqbG-+k&Mcm96p@O*pGoqX!O8|@5Tt|#v$EAKniG}wvSRw2h{oE0=_%{$`{)y5Cd z-m6{Ry(xC4-PZTNw{k{UR}cTS+rawM(Ym#@sh#QihO1Y` z20QooJ4Y(^1#9Nn=B`&`|Lu#3a-AE4%4>b~_z(X3J+FOnYPsFgyS~_b3E~#wXp$W| zefplYwUyy;zDVzY) z&1yyB#CKiJuteN70&WO=7f5RP=CL!{S;T79kZ003k-)f89O4mMSSIfF zVF4D>a!JNi78lf}g~*uD9Hj3CvS2~U??*#Iyg@q$4M~w;VhgO03v-l49ui zq|-4h#!}hur$d)|)OBrAVj=#aSE%p>0#1Yk@}L z_)r;ilCiO{mkewZZ9%cCv9iII-9f?_vpq~5d+YX~HdX6(`i9Bsnph^+_Y9ZZ#b6r2 z1PB3;HNV>Fx0n=D6Z2Y>hxGjJ>d~)0^DFyzjb+_ItGls&``Yr>rNJQTt>cFue*F38 zpIcvBzjXdan&v`?rKRO&b7Ie)y*F-L$D_hGyd0bB-<=h> z5W_&2I?NTEDVsg;NXb-ArvSPeoEQ>jM4KO}h8HG+{!W5iJRGDbSBq<{`Z%lH4N!;h zT^I^DAB}$OEWmz%3b41}a$wM_&Y zHlBASRW7w=x(MA$n#Ez+B|w1W)v|9{)bWg#tKO(+qh(=!6|+oaMeaIU0~-$~+TEUK zn{iN{GcCdKah4d7>R7Xyv!UyFSzaiSvn<1gDFu1P(=?wL3)3v6$ceMeBM4&F!jr><3KXdg%X1_uhm?wVnfoa z4Z~q-y0RJPd09nO_`}pZ*Kq|Bv6jc-ft~vU_sl@77u; zi|%1>DahJ19UhzSEf$j*;iZ+5tbJpn9dkVsf; zKsSRkcAln3{kOmu)BY zM(>`x+Ptu?#3%Mv?k;3K*muOGtG)2*fW}}kS~ih>3%h2S%nmw;O;6r^WunkR$2F+q{G4W9yo;+by+gFzZNCQ7I#Y*GI0$>4wf?1 zhB_&7k*3M@~I^&@`mWn6Q&fzNA84@R>(y4ozY z4xzDewHOsXM?@W*ivX2U9aZD*#PXQK|)Ns}LfXw$#?a zU7>pNsWZL3bC+zZ52N+exlZy zQy3$gOOb;H1EbF0X${JNCR286_grtT($x6Dmv5wzeBH+{O*@a>dgZb8b2BV`-3h;5 zdGsRn-!@uEwd?gPoOyECzWiU?ryr|EPo4Ng_U*p}q;%iD%K2vb*7tal7nPKM-`Sfd z*9S}5E+W+^`QN^ztJPW%lzP4HtFJ!4y1M+}gO5#4PEStGe6U0Q>aYIH#f$Iu`<+Uq zTB|j4_Yz1_03?|pcRqHHvL!X5WIgP2$!*8BqBNFTr#$Dyh{;WYg5`jPxiDL<&?aU~ zBfr+}nKJuZZe!M1G)oMOif0SV*wa~*>1)T2IQqU?F5ZNu|C&D@aK z;AJ@jB9UUY4)RgLfFUo43>iHXaFO#Qvk;i>hy+patY8KzF6_z4s!;%QD~@HQLWe8? zz?4v=EeWjMi9GC98oo)A0ZTG!s!fx2GBBtPbM!T5X-vE{Qq*x&CTnBiFiMrcikU1K zBq#?auteHYmLith>qZuJjTgn6( z{?qo2U(<3GM$5Q5ormX6|Jly)7r}=z>NG1+D;_U6+HMU?L5MgCOhb#8TIt?adu_Hn z<>8}PTuC4h5DC~n2H*nNV3yIwLKwmMA&lVK(5#iN*u-)GW1!St-`&jjHTJ%~1_)lg z0())v`enGa1Dy?+3eAz+ehc;x$UlDa!og{%RWDpV@{>RN*rm%)Joex_8213+;C}cJ z<=t$+Py8&LIu3vERj@3$qU+y`YQHjYuGEL#jX;~6=-l^7F*KS%%K+PzV=FsO=h9sC zAe#)KR=wsrl>xi={Z)H|ePOD6Zr|kDPWeI0dhyK|camN?-SkL&rFF;QhhXKomsee3 zqp!Cwo_u`f?fYk5tve6E;NzFp@7qpoUAb5*@gw^!&3@0)(+XDHu@?O@~JnGN(={ zPYTzwk~Fo!Q)c!j;v|*E{ED^VuhBt2_QDS_l{WRTlDy7rcnqb&Db$M!%A$P#IwSY{5%KUl8iq>0d6 zmP>ZQIkGhd(pu@4$Ea=D(U3{5M^C!OhHa}2ltF1=T7z_4Bn`RU_B_)_NR!+~PL`W4 z0x>tzLJH*AZjz=s(`lR=x3ace%OzCz;+fd-e~h|ivVWjO3jPL4-W z5(FjNrb@{)O=o9k-+lKTG!m=>jKH~seAs8hMqi+k6koY=>G4O$4j-!AxS4X!KlsN= zNeKKBYyG@ZzXfof#iI(OX5&&0j4z&By6}qtAW~owvNZ8Ym%(mLOw>u13Q8@l(AH+} zc1aeFxNV4GIvOe;n<>TK0xaW@0~jCO>vjOO%)c)%3^^+u(9jaHAxYK$hKw1cISE0?w07{3(K7_47FJ!_8&4f z-DA{S+++161wt@+8BWpCo4(HF?rxqCv0llb^Vkvo~MW^EKLCsLrKX+Vho+0Wsh>U^(aVNAWgHZ zU{VT^P{&DXaaERQ1x z2WeUuRUv@u5GD#EVZ&x#>ewjHIA}H5K|fQuckI~FX0!Q&KllSh!M3)x zUDr#J_|TyvQpykNYJ7Y`DTPNbKQ(fnb6zm!0Knq>TeG{qXMNMTeEI$9DW}&Ly{(^H zU3tH;2ViJUZf*mL@~8-N&^dIwkh!qchbV`12*nm?hxLmE%O~AdOb{|Tzo1$jzJ9Hx zwZU0(n~x2Z)aGWm#|K;hIRh{WW;I~>EW96qKt>w6x3%%^o+%U5lWWGzF~fBLS$K2e z3_bG4{O0#gHwUYCO}=y2;-%@S4To5huCb*N^S#c7IU)6x8`A)=(W2jaY4T@&{Zsdz za-KPNk<3+Jg!<2l$_ z2c4J?j;8f`SrUO%8KEe2DkGdL=u(pxKcOA zy;{A(V$~?yCffi6#g1kAE2&Xq*zCxmS!8R^c0iHI^2kur!#!{pHASt_ctx=64CJKuPN1Li5H&(XW zgATF?*E&jsCe~};URB86+Ui*-l!(Vgtig>2DJF=qywgv+QG_A4G?|+ZYn`iYJ#nmkOpoNTS4gB9z{{qER{La zd1~kw@o8H$*K}@i)|KfSWh3Vv`hL8q|bf0Jweorq(bu zHEr8;q`NeyDaUahyXX6yrGVv(5^TGLN1b7xYp(o~&t*~+ zvQ%4Fl;Lgnj3VJ$y8om-Klz^5E5B@r=1WV2t}LgouC4ZT1_B9Eb0fI zYpHS=`lXQCcFtm(*oBgzkBx>Vi#?#CRiR zd6E=Zc_5I)g~%W&Vre3cY|Ay%+caauadtXGkz1Z;hMyd8=y-W1a-9sft!tNVGsaJy zy5r=@Gappl2RFT|SFdbtZhjy;jN?d3Iob)a?}wvlL?Na6FbMgB_KeoV^MZD3De#u+ z)r(*J(#D?I7Ajz+4TB+c84Pz|@xX6xU;KUD1K==H&cXloOo#Pc)dVxrL5rC9gtW-x z8!c*K&#|xvr-ni8J=HJ;W+A{sSl@v(HRjs;>tHpi*K7*jUuDh@K=|>f zwkit;^K;1G6xK8-8g?*Yl*Ry=i8PQ<^_^Z zeG~rsik4XaVs`OAw?raqM?4s<{n1>S#YsOla3iXseo+c78i3Z!jZvf3x@kIF8o+2V zDizOWa94vKal9w()#INT4(Fjb{m1S;{8z`n@=NCy|Mta?eJ;Mb#_zuy?!Oa!4;JU( z{N+z>ul$vjFMt0_fB28^p9qRKZE^jrtvOLZ+9zY18zq0wufP1(zI_MvC~RZ2A95+> zV~>6O^5qLc6t+!a#HZNYTt9Z_e(l_5dErtrUL7OH9@>SpUGXcLWZFVhc?Q~pI3d7z z>UpkhwW+fn{jY#dxzC=b3N2 z2^&adQrf9aGB!ji%Oc1#W)sVVayu4CyIis@s^b&G2}Sj*7iV2RIX4CS!=r;h6W=U$Bgsbv8k3t zCRn3h(UMBd>gB31LT#B9#?V=*TB$OLwo(E%7HV4q&$9w+%f~=VBpw<(s%!in*tdg} zv8uCsY3bIBFFv29L&mZw>RXoe^wZz|^rt^JHa7m;b5A!KVu$g+6uHseiU{@z+j0@Xs9gp4QqI;QwA4 z?261`7Xm7jSePvPUdR#ZT-vsY>P4y=@Y^LXui<5n_EFKI!I2<`Nia*AYhl_0D<^l} z`xllU{g*cn{zp;Y6)^@GT1lzT3NfgL%QgqtlL;XeoQ` zR0B53e=EEE_Fb*5ryX~!v-5JPa&Y9cSfsno!f5Th7S~S(3!kZ0_PdB67_Et|AaET} zFfmk?~ksww=acxg1Fa*wP$Op#ViphC-yfc2{`Lutnmw zwk;VtZaa!F1)c&XmcV>#dr&RYWGE0K4mBYnaX+#&9iJ;FaRy2a+Ok@$@+@9%bwe-k zY_A{Nv6UpLc0I%Q7EEzGHCOY$7MXUs-8(Zg{lTtS ztyZpFxjZ#BZCR!XCd?|fwzig+mpYyHul&+K>i45crTq5w=R4iYC>spoZI|4vhDZL; zpZM25|6hKrKDiqJ)^ELCpV$MVwQv-6R?LO)e=L&6Udhh~F|zdPW=}{6YINf6Idyf5 z;PmDOu9gw!m|7zYAu4{qZ+%pY;26L=05{<{hjX7j{-y9SukO~=zf6*Jy85jsyAhU+ zMY$PzS!yfJ`|MLeNXxbR_sYLsAV{pA{zI?-^6#FwE!DLs%0yti;ASE}_2i)UuF-@1 zzZM?hfQ>@+zb^*7h(*~i5BdxVUm?IC3rUQ{Mq*=&ywtnTUC&xuNTmEJ(c23fS7-I& z&piLL|LU1{E>03g@)jL*1YTuD%Nxut{E?;NQTHc4_N!iT!xrZeMF01DYc8NrZZ6#>5GHAA_m{jzT83(lx=1PM#Vx2XT;+u@;};s?t)N zWXJ}y-5JO?NE82N)PjRvLIQVbqwQeZ^+r*XW;X9g0bJ)Lheok*N_N4Du}U?UvEva# z_^}kWgy*=`ngtGWsh9Q~lj}gpXFvP751OJczWAb2YG-F-ZfXnXL+zQxn8Uj3Dw?h3M)(T+0m=_mfq+~T37o0pEBc#Mn1 zvFQWN$;B(@{*BRyO~Uvt*ja`Dxonlu*+Np+aWvMMaV_gGxY7iH@QG*t{rL{ zJujlJP$#!VKRLKOx%=(C^Y5Ns>`qiV*`1zsYaqVgs~nZ`jcm|S3R~ev3OGuft1kBX z(LAl)=i{A%Pup&gXXCHbPrLMO-|LslVa`*Gq~pxC)~l{JB}DA`(*VfY8#%jQhtV2d z&$CV5dp~>cpSBjhs{*67uh(?6lSZ5|a|m>8Z8{B#`(-a46nk%7zK?G8j&$@RpS(IZ z_3mop!o@OC!JA8)>$h)|ae&gSx;N0{-UQ$`w$8ZT6mTHd#P>h)cZj-;pa6h&2fp*% zXkIc}2z2=MrCmb~0Zn`9yZb9c^?}`NZeiCEO2Vb38)W3t-nDBXO_S~I&E32A9yomH z)V;@t`r3OdzeBJ~0Tpd~Yi);|e0UKfr$n6*=*eITO|JNeR*$H}Z7L_5_0ilxW2C3XDhgY@ZiFPGB|^cMz#SW7D2Om{ zQ4A2ccFvja8?;QGh^lGi@R%hg*;D~z+O$*!u6h;f;lVH_ng-O>2)KdR$j}d56WheG zP4X-cOK5U@EHAQhy@W@g!HJ4btrAcabWe{{mVxF>`04-bLuBnCulQ4(P?B2Fr zOo_)dQ$`bj-4bng6ECoZ#KQ3O&8{L5i!*K^GwWZvoQGjJ7!23fH&<8JcJE&NV176~ zJ&Q4(oSZy={``T12mjok{|jSNjmos%%D%GHd2_w}hJw{@(ymn&aS?Wt3qc)8$tNeq zFTV7z!r%^|XnXbc(Yv1LY}~5Ur>?&BZvmjU{l8V95U41uY-c0Cyi=5&jPY72$Rf#d z-d}1tL|9li%BWGb+kNIb*dlgb4c@%-ItQ z0t}TWKEcyp&Ef+5KORhfmdR3*f-25w@rr|9h~j-nT*ahUC@3-+4OF%6EL~cJ(XuSx zv=tl5J^BKSR%M?nGd=lGY3H?Q=E*XQ){JP1oQ+RaUE*>r9E^NgMm7;l?`(CZ!mVuv z_Ri!*eaF?+sy=%mqNT}}T-njBjZVqO%`=lf@E3mh+U9f3D0zM5q$$Et&hTfS{A~aQ zqxITZ5E2gTg%1~()l0SelkUaw%eU)A|JJU(nqV&4g|p;V_37h}TNcfd>;uJ&ANcn_ z^iXroz1IHi)#z+0wg@7wl=;nM`|?`WDac1YyWc{HNzv=3BX4ewv^I~uk$edQc_gZc z@%TibK^B>k%pnvZs^ZL~Qkrv#%n`AZ0Uv7y1B0(Mqi;hoB|I+-GKw+Nmi5B_pRvDy z(=5BsG{OJj%O3|vBxf;6CAI~YCEIOoW*lbR-C<^C=4o=bn@w#NW2v~Zk}3G3%ZJZ8 zg%U+L@SUy_8e{CILq_<}~KQcr7UHWf|i_D=(#-jw9zC zLSFX>VPy=lJx>z0ZktYbX_VOjM$$%>Qh5d`Ls)rR)g`47QG_JO>tM0#oipsem>~zf2s_D~|%D!h*d5yfr z%c?rBn)7BgO+{_w?Zw$FFO2TfC_g!=>QXk|aOPy!iI{jBnksms?_9oi>6sTUhQa&ax%Z1V z&wh5*-1ag=8DWA-+XHiFtH(I)CV5$R<_BI{-#Egm4Xe8ke$OBIm;UBo{revs{*xzf z{rP10>1(h2;}75a@8EZG`#zl?3Dc%s*O&K}8!un*%njo>>P_6vvo!UA8izZn5eDy3 z@WE@v_ojnsG+&fl_=GXNre)h$1$95!8U8I*{Zh~W)o5@{`%5_b!PUv%=);fPeYBQ# zIClS#hZ`dP{&FpH^2H>Y%eMF4YVT4JE4h9D#sPXFA4doygvoyYTM|A&p4oVV9sXjq z^}X3|mQq^cwC7!|gGO=81H<#RJee;M@lw&tFPy&7Ut-0>oo~MWqxkF#kL&VOUJrNA zc3*w=qYzz9HV($O?|pSJ4%xi<^6lsUUnQ(+n2f<_*xP~MBiZQormygU?8L3kf9>r%U*Q4=6yzgy{N7PGnXXp%PUg1Ax5;OI z^tuJ)jO7UkPKrSiu~Zvfq%6-O3*M`M@DmBNa``|M1@HQGE(U$q4bp^Q)^rU;BpFcT znRU)O@ZMsid#Sw%-dGXiVj|kojwg{)zFBEcP@ZAyOBjE19n+N z*K0!)+|+t!b248yApqmjs4ixamC&{-SeqnZtW7deuZ@U7h-kIy+SW^FzyT({EG0vn zAmj~eW$yv;I8zM*M|<7%w(&qxoN8q;ao)Q1s?}7hUe2~goZt{FV$q#P$IGtSnWdA- zaNTy}X&!OW8vB#zSZ6*q|nN?*A4 z;%9Gs^WTHtiQwq%n@DLF5F-eJR_?vWi?<(EkI(DY8f~1nu|T9K7UwceBZ6%Rgl>-l zMS_#TC~u4&ZN#}4&e1dmX;>`W?R!ZZ6D>p03050r)ZvAFjht=2b0w1E+QBH@mVp8pac|9=SZH`m=`v;CP2 zQ8fQn+uT>zx3)H6db+5Uc1K4`Ekoa_rc-em^_6>O_raHbcGfW5UWm@~<4-_;DGI&P zD?JFbOLivG7^m%Oxt^5GSMI#@|0?0T@59Cv7Ax4@hTml4n>P&l)$-}$=Cdz|%lgKA zI317s)-a9)jkNa0$-9TISK-zu6Xl^aht2s}r*A8yamp@4VY#+)QV_Lj$V;EOP>At( zoZ6rf0wgI-kT#mdR2pZ3Mc9jU)HS_xMmgEGD&=u+O)l`N>peExv#qo9IpJh6ud@N( z*_iga$%{f+moPLLO%$kZr2^HQlR;JlY{5B7ylw!90f#7te4MD>8i~evYP_K_0t!Vs zD63VHC14R{d6!^!7=1_Hn$1q$|&6;7Hg5>h-OrHMscu#al=s(v20qdp*S^mL zgAf|8j4_Ewkhf7v%9R`x%wiJ>cp!-J0&c za_{Z`6240^0HdC~69Rg8#M3mgS~?G*Hhu4$_mGbu$!%M8S_IeSR4*$;kVhCX#=~eZ z8gCR?R`(U51bN!7yUKntf}gIN6=KgQ^VB!QOSiI5hQ=SvF21zC*)~ws=lAUBjq^{w zu=DU>{B>pbTJdKF=x?5#l{}?&)$i=u{VT6K_ha|p|24*klx4o*$tT`Hw1n?6xE}Ky zpMI%n?yIXmvavbI%R60puTP?aTH7mM9n~V`nBeG`tlw##dF9;GKYF;_`NlVHz40C$ zeGZ4VyNF`FA101)0^nx z7muI2|G+-I_x|1aMPoHs#A3cK<>|5{0suw+K^12~zk4`e0CXL&;qv@Q&ds}zA7Nw# zMA5{NkA3zMrugV|DH|U}%o-_ct&~wx1&f^09w9~|jNEKmKtQVFj3G~~3*Zf+5E`v8 z30nH$C~jJLwph=yQQNh_g}PM=)O_AWsqiisg|st-8sq#VA6jsI-+SwN<9$!JHfBoq zXY2K7m=nabWVI@NK&hBC>%JI77P+R8kxv2z>{uZB^t@J~cfm16AXw}9VzE9uX^SE8 zBt$VYEqG>;x0E7fJtAQcjlA{Ms*X}|bXaNyjMCnBoP_1PERw8m?QdX|5)6SeKw&f( zNM(5nNrJ1Dj^mhwr6|setY`#$)m;T>B;lYKYx6D97QnzP)fHB zyd|q*nDyFtZ@urw(*Yu$q>z#nYo-&1YAWPks&2 zQZ4K||LLh(*wJ(G#TT}oayzr5jNc}-;Q@tdHnXl*cSq&Dhp&J8!Az&`zjm~9bz@`8 z{?f0NgK*|Vzk$Vj$D0dFMqlpi2m0sE7oUvjt=ToQc!)Vn4F2^SPsj0&cm0FA|I?rP zL$~0!XuIDb;d_TK&GnY|dn8(3nLd2`_O|k1I(>Rl21k&vx)1fQ+|M^Ya(Ziix;|HJ zKg&j0+DpZf8q5CP6;Ita0dfOrfTQYKB z3=l_NnI2}UvaF?V1+`sMrDR|`)HJ}dhgptdQuno>T0zD0IgLBfphMh zTb%`zmh-bF&-1>rlhL5lUDYUtS#_=*UI@WP$?|YzqnJAD@?kW;v#M|Z`fFeM^HQ42 zFR3d}yX6U#CGGm+!Cm^*FASb~^^bk)t3NN54iK6i3*w*n8L^8Wd$ISu4?2qD>BX(E z?si_ej7JmYf^X^~iwNOb>L!i)rprfJT}n>kWw~F+&g$%vX2U_1!ajT0ysxE)(D|2|E`rtPUSt zc}wfec<~Zz~bT0eDjlWyhCW3 z<=21r5B+t30N>^QL-^`9fYK+acytUawb`0{kbOX!yF2;(!E)EwK!M6*dUoS|*B9iN zDsGmmCWFQ?m&V+8CNNxgQs!MVthJksA#X#>INoRO_Bn zE+}!{wrwvGCVSs^-Dra|gts>)mijbKEg(Vs#%LVHnej$9zVADc5RSQ0elpDn3dXh! z1NEu4Qg?PVi~@2Vybufkd2jm$x=!~N0F;(ZBsc+5traIBc!v-Gfg~^Ls;$>9FOc!J z?v&udH69D(tYHKir9H8~!KM9uZFImsPUCkTJ$g`|4~RI}o++dzvkW|OBnafUr&Gcb zPhGX>1;Japkuhd>wpGg}&zY9mxgG~M;G0!fSpyJYGK!t^La=mz>$PMQful{M%Bo2= z`vJL#04t?9=adrfJtGkxtSR@#n}`d-X_^uQxUQA9*jYLprY^{3r-Q?z!Jw^8HW}Xk z_9Ki!lG)Gwm_IpU-}q8;dQKNBq@9qRy#MGMe3X)lyQ3E`FK!&>dE%Y1+S%Da8(f#V z7?KtY*(jnYX5~6X!_i>*>o~r%vnSb!w6df=b+YayrVArDmZl+&0l#o z{_pOOUy9(V!TM}j{^DV@>ci*aJN40nHJ@b!J+)N@{caka6VCIfX%yU?evV z?oKA7cKTp1q5BVJlkzHl#)LBX%i*N@Iu-TCQy5Q~EHlnQY6 z>T~hYUE*7{pYP^bE>wey@NiM$f^S^Co?kw0)Y83mdgZiz@bJnn-hJ^m*9i%Ue&X{# z^_z9{!6SI@efY#jpvd5F{2UlB*zodNir(Dp8+&>4>_lIXo$=txN9Sb~NGJ1bcI*9H zs?(bJYFR}j76Zq!5jSL2wHy^BUW(2A$@2;Mvw#zuAuf|s2o0Xb_t z0&jp4GTn@=@z}>&`G8#K`aI3N58ks@R@PHh$taF`)kh+w9#?%YwM3C8L1<^Am{a0| zZ3!gC8pfkwNgCx!OBR9DCh|$A6CpjRRuGe+B?$ZJC;E5n9%azs$ zyU8%_qya&YXEacj+F(({NK_ya{K3wKhCbnG2qa)X&hzPb)M#Us?Helui!m8(6 zduLg_bGRN-cBj^p=GK*ozCYJjHm3_2o+t87+pzuw9w7+q?0tZ!Jznts{aG`nrgwX#?S2@wGaKB#jl)x=KpoWOy9#-z7DH3 zyz&wn?!NHm`PSn_q`giAQbu0eTHScCL6J|=XtbY;ZIMJC&MfoPy1<;eu(3IzU`4b{ zJYILPV8yGW=wM@ZWkBOVKK4TwfFOcHl#oFdG2vqxEA3LjvLf}!cdZsN;v(1{_ew$t z)-|JS2nH#svV_U++QJADLU0BMBPpc{Dis0~?-6U;HXxg3lv2(j;fxExrwm!Zgy<+1 zb*Y_W+IWgV2is{$5TlrC8I^YamW_RUGG`I$`VbdMJ8%8thJf;i-NUyY z*2a&iTvd$HGu4{adB0pWG^5h>ZLh$KR-Wx#yn1?G?Ok2pxP5`JG>h;4tfeCo~l44&{r!k_sCe|QW@0xx{vVzO~bGsyfS|%(4quu6sxS2mbYIX#Rv@%)Dro$nfWPBg@M(=tS6)E$`6}VbDGrg zkf3S7O^~|NvQUr^4oRVxSj{P(%=uD1d9330C$tP55k@D{U}C zQNsG#L<||@vBy?Bg)~O8T$PE49-Wk5T|Rmy83FR=^EF{0B9f-USu&c&kq}*{np$@X zQGyu9mFx)xK@&oV>8SHAAlvmS6C>pOY`aiKBV;Q7UVEN<8wepvN$f?w**YA0t*ymc z`lv``XRC$J$7t2Gy>tST#Yr`q?Ecz!{sIcFRi?amN(ljQ3}bO^lMS=^`C23)co+<` zb=SrtJShrmWcz5r8G#T?)62Cq7L1cEJy|@oL?ip01^}y7ylCW!dJ#*c-gOT{@|o!-0JKZi{fef^yX`I=nEUf^k)@jI>yA zkmZELDFj{DyJJ!U7OXstvkb6Fiugzl%2%t10f2W3cSCyM}_l&JE`AUo!^}=zH@Z+t;KOu$*UXFdQl_cl(KDO zR1+o}xrjr#EQ9Ma7WJidSM5}LfdYVCvBr4LN2&Gjj;Si(04!jeSh~i-ab4v1rPnLQ(Gmw*9SOMC%=As z^+qYa)kd2Md3x~e4?TM;n|x2Ru8!{fl}=eCS&`G#s#YEJN9%k)rN<5q@x$8>yQSFN z*<7xV+c|h7FYdB-4P8)KK4C!_D-O0qp3!9YfIM8&v0k3q)tNLhJ-Fch_@DaLSKqLI z?bmka=3=9W(>-wr9PVmKsly)S@%2jGo5W|MVPeSdy>_h|?)}X-?`6l`wRPCg$kcr^ z9gMn0OUaM=jmJxVDSPwz7ypIxhd(&es)>xmAoUTDv>k`oQJ= z=QpdaZF-f&+yTbGdf8#jgAwGz-#23sugWfp$#|4D?ScXEhGQ_}LD4&;_q8 zofa_!DWdblAwQGm2oE#Ho~~siO>KAf#+~lV zl}w|I1FyQ4F=m`w*9u_--~j^;uC6;O;-k~Ltu#hdM5OBKH*X#P`PaVv+Ts)dWN@F| zx$>di{f|6%p{>;A3%kpCnG{seD9y3u;9)zHT8GC+p=tg5$K5;kWT~rlD|H|!NE0v$ z2+`!?mc(3JtPNf*D}pHrbUe(AGXbD$J@ph2h?KUyLDUmWQ1CRN7z``oKPw7m4cVEEA=vJ{ zLLXM|KYl%v_t~Ea9+7KZFZF8O^9bEL?FteW=f{&- z;gSulT^(Io_QUs2FFt;>^W2s5tCz;7WlPBO6w~Q6fWWiyxT&4sVLG+~vx2K6T7B`G z_Y8hmmW$2J-BrJA`bGqr391_4DBalp-Rt#Rg7e4KMjn3p2S5GZuYdb;V0o|f+3}*R zBtb}dg*vPrt}gzrgUNQb>PnB4>g0472PxX7*2)Tm84m&XoQFv97xw%)pd*` z@4R!4CpbLufahbu2yxy^X;!6-STZQmx^FBPj7grS{)z6`f$gQ44rgFtdvn-n>Ak~& z)TRA_YfpXp`qghfdi3!t2V0Y2@W3e`hMeBV{YXwcLhkAv-vD9R6f@Z(QCeZ3}M{r3BRlMt6DQ5qE_ z7J$s+ycHa>4X#yx?c#-XyNY7mwMs+?dzXrFK;i7>A!j&*K*6L<%T8-`dR88-Rc`}e zCn7Q$^Or7_rNzAx3|SYfv|*Tp;0Xjk0Wn7q_km8vF=M2Ysy9w)lx1-ei`GdWOpz4G zVWS)-jI!IZdLzR(E)T`WUit{PEOIx0^rbIs?!3&egZ~y$dxj}_NlsL;c$BV!H zfN!$ZR}ZNC+u^SgjN1 zrkjPJ10`K;hsSQOgl(E_dxS6x50}}OzO|!k_osg1Ys4Ne6+f+7sSWbXOM^J-Th;b* zAj;7Y;_(N|b%m(|N{!ZOMse7W;$Bg?v2mg60)bmET+TlKp@&7fxc6}9*I%b)|$6!?$kJHMRyIUJldyK>8cuHwPKJ=OWI1;n%bTw}o zNsLjBSrq89lB03a)eU9RwgDs7_oizUVG^*~y|CTZdN^dp`D&#?Aj&!Ke6?(n3=={H zWzh&Hly6Q)CiDzN5l=jry^Uf}40|xxLsNB#dShK%+P?Q$DwJ+0)~YdJv31rcYpn^W zM-(QTMYYg8GK}!msy7m~3JA6aDK1dodT_u1FcBifPMPhE2@sbK@E}RIH)q;vMDQTa zo%e*n-o`LZvR)em!D=0_QQEeZSua(QXK9YxYHf5)JaHZJ;B;ravr0;jY@G5m=WSys z_nYJC>3NAQ-W<;cX*?N5Z`^zMos;8FUb`rG6ne)geRxtK>|}3?nCA)SsZgy|G7O7h z)Aeb>jY0t%X>7vMAn@T)jD(vAV|rP+KEs?FkjRYb^^q-y)F zR~V4iIu^vk>1?VHy-uQQyE8m3=I!dw>g6xl{%<;aP63r|4G2+2%J)}CZ{K5st6`pN z@!s(fUalIBy^+b~iAONFQ0)I*=ub}cbPqN!#oHXS-FT9a$a(m1|Djw?4zojz2FG^R zumd-kC`qJ|91uWoz17Mld3@&(efgWuZx5Frd*R{c#zxaWN5Thae%7qJD2@Q(l$=k- z$?Zkd^(2I-T(6j5T_RuuefoP^0biiYPyl= zcju39FWZxPy>62vf9kVaS_bE!Z5vJsf}%JDWxO&v4xC1$*Q)Ou^6}4KWGpDDB2JN4 zL~EN(v6)UM-Xb7jltrUqff;Y= zzAI%q1Y;bhLKz(=EKgZ*J+|OFW^K?~=cz#8%1VhWJw9G_trI+W>=&zw$27xf)%M2A zA`)e3G}wTxZXr)%k%162PtzzyG;-dAo$aXsl?{qGN*qE2`Q44tbUOAxtTF3()%X2i zA{O%|V#0Wrq?lo^Ww)1PAKiJnX?vp`Mu-sKOUXEXbiOW2JDbE2XHBb}4Xd?6l%)yo zWJ@_C2wUrev4UcZARqEhsWeVZZwBKCp`cnz7*{H!aV$8u$hJyS#6%SL$}}~|-qy7& zvcmLXT;v{HuZ`+}IBK=)YK8iqQJ^exwvS)9mOZ~u_BQD_#c@>CeOnofhy{tJG25HY zp1Hbi6i^q8*V=Vf5*C6FmoM%b-!TqFkues4Xe-_I>ldVz(J-2g3-572c59dn2P4MP zR+dh_b@p)Xx?iE;FBegkMW(Af>ge+3iI1~TLi`BVbAl|x02Jgqw^qX<+AKWc{Db|6 z_U%*G*Ux-Xeq379IXPxUN+av-kma|!!$&kW7iYPh1xu_oC{`NankIv^xMA4;#E$BNu zj-8b#pd{vy@^avB-BM zuwboK)|wEyPIethLB*rTT9ytLTrnAI&rxx5fs=2%V0KR}cMv)k>@bVF#>!5EHJlU92xHJ`nZ!bCKbj>ZkhW7=BiRQM@&51( zf(^k_><2GB<2=D6?q%OKT@vRh%?4@K+nx&?0uh8`g3??_<*@LCVgxA4nDW|4j}bD6 z^-`5{!(-Z*O6n(bc;H4GAVDyEc3z)X>x2#3t~2Hyq4#tbHbw&_rGCWA``xXxhyD@H zy=v<$Dl`l9{B&NH^6KTi$ZdRJ@wp#Z{p7RJg_Cu;?CZ5@E+$*s(F7y>mDM{BDQ;j_^AUrNxu2xpZIc*Ru3NIzx36o%Vu)6 z^7Ubj7{Mx>e$&e1J}qYVk57;%S>kPv2ML!}?tN%0k5e05%J6J7Q`RZjRf|p}+!&Qa zF^`dyJ^9$@E?H}wu@q~bu`DeDgyEPgZM6)tXNib=UwZHiCsos@S>jx8RGkWMDz2Q8 zy$#+2(#pzgkb27isVvSOA1(XZnLw4*g8I((5ohbAW5~1b&PFtpRh_XYDWWW=O|2-2 z1m=Nwf`u}@Lq1P(hXS~4-B;yO#z{tOG#Tc-Z5@P&#~DeTw<6|UF9U;Cc4@|yblSLV z%mfG3c^ATR=>$(F5s#b>-h)R^EYymSKqCUvty~*hE@Z^Am@tFvs+3Bi zRb!WB6L3J(5}sI3nzbz^qF(8{534ML)~H@t5t4STG_tl=ZKun&!?8ogT-n{dxLYXG z0f=6C&X^grr@c_Vy)HraU+=Byp%hmpSgC?Afe}@e;X)X1`nHavk=J@-k`hMSTDPUa zgmZ#v%*x6(GL%h2d7yD@4Yc!q{^iGDw0e6@XemopZcI$G!{oHUr!u*S?x0j~6lx!Wu8<&%93+~Z+zkW zjV~X+`MY+We}^smHZVrgJi#tFYwNa02%ddGUw@&xa3w^M9?r70;&)ER?a_N5eePb{ zqWkA(<9L;4ru3gaJN(;&wEbg0{N^aSTb1^2edQCs^tI?=odnHsz~+8&{N4?{w9O+u zoDyP$lk3suc+r)@U>o|`!R~3*CKm`Jtg94`aaA=01LwrKFdHWxE5f5*Dr+41-p^f_ z49EE}RbE>ayjPt2dabN=*80s!TsG%XBCJLjTb_6kks?jgAH5eoyxN)N?G=#H##YOiUwufF-8Q#Sr%#M0K#bWq`M;IyBg|BB20{T)<|a+ zA(Q~?`W|TnSfk)sLS*X&2OK#Ruu;CPU|p#^6J^^<+Y1&^#FVto;sDB8tva+=^nwb^ zUDvPH^Ht0-ccSfd*GLEe!31xOcY{$3fmr7!bq-&o#-og2w3ezEFhRKq7CF5! z$*anfl*-OTB$CST#3vCu*xl674F=4bFy7p%ADsw+w?F)fjZ%;N!OnO%7)t2?d5rzh z{biCf<2*&&SSwP{zCJ!a8)Xb6U9S4B>%9vh7;k+D9y2o-4^~T)BzQ6$pRY?J-MXym zUe$9gBHXk+;aFF$dhKNW=ybI63hI+{{cu&fho_5-IWYX$$-sH`YV(8N>p%a&@>4IG zXET(@3SvSfWPRJ;m zg@C%wFu?%7G(D9z>ox>zURr zU~9E0il{dIWHfZ%YilD4d6MHucrdc@M#TvF9`y#M7!PITag| ztQaJ1-$4k$BTBus(AIXf>Zcni!F^XZoDkxordG;IjKNzq*^aIDiHPD9fSHK$*?5o* zF=lB*g-5_Sn+@Y4PcY@qxxVYyr>o_>eDru;_kBtWUF*p>t}01j(64*csm?ouXn3rn zQ{FEj%l6v-{1=XH+&VdV>C&b*7y^{*fC(c{zP?ex1s`HARHxY!)tE!tIu$(esvmDA zgyVXporSIslVOetR&6k#>qZkqqb#|1e+>v#mFZd;^Ngb?ikY;%3tp)Z6fM_%oH8kW z*>o;=jJ(s1M`$`ud)*@%oh;Yw+6L#xvs6*TcPHbQuC8m(a~zzF8C@*e5cwh=E>^3) zx8u!7_jXuBfmlSHpzN9JmwF><92GG~D8e*M@@RW=EH!n`c6C!P%A=$8x@#krK<^0i zy36{rb-AoWme^a3e}pz>FRoWo+0LuQ(V|W<-yQQo0Ut6ykR4tB^y448(p*)wUD~pC z?H=FCNTP#%tAGE2K4OTx8o%_VlXrLH*{Pd!g6TJ?nBA|Dt8LFdbIDWx0cGw#J8 zOQi1u4jgmeVH#mZm_rsvs8@g>43$cqf0 z&MV3Z^SG;YAdZ3+oIW~UFUppqLA`Dl3x^^Sz&S@ypyTntIVD$!t|n)1-aa`yeQNoh`b?XzM0Z zF58|(Y-?{)E&@R|6?xV4O{wNfX|c3UY1I!VX(Z5U>A{%skXq%rAiXwOL3MAVSZwSJ zt#N&Ciczs#)>)DV?>nQFHI&e7SSXA8R!G&iT{|hZy$aLeq}NSAo^paM0S(18&IZY{ zHjOt@%YYSP0+aaouu6+m4AOelo*Z?mUVHrs2=Jz5K`>qm#})u(nlY|FFyA6opo z*=l@Jt?sEq8{F0CV3%)pUVfu}>$ZBh$;MB|m#>No6FU4_`}&aOm+|FaD!=&S+aLed z;(dnc{qFR!JWp7xg1y}x?#COyVW10s7-!ux=e(ea;IDpY=k)9-%f(Z{4`j zuDZR8Q7?U*K#O`+BTmt}?gHykP(X*OyL|PzA@S+-}ig27pa&Hv(=)FQCyXVV8jS2@_1c0*4xRrSe>dQC#rL2rwu1U zSrbLrX+;HM2s?|M)?h5cnsA8Y)Z2iVP73C%?`ju(T2(TMS=F})1#c2f&n|KpbLmRZ4A;QHCX9S+{8%6V2C6tz-2U2q zan>8JtJ{mHbVlECE~b2}mY%1n2-=!OSM|$)+4iLY7s3aJhzUqvcAXnx>fz#~!(@-JAdh7m5O#9{ZlV&^u2lLd8Hh z9|*&7B&-caX+gxvN!>T*$`faEd(yAjar8N{2}@8Ru=U2*$y&G>QqqK+)+t^YX@u z|JuFh-aUPeqU$NUbzyS+#&KA7dfDV_*V_kD4rGJkoQ^V)<)l44TsEt|)ln9o9Gynq zOj-VDZ4;e-D0}{?=#mcl$eag&Z9dIN@=SCkK=_T35h)tqVuYu3v@q*EeDKcdkS9Ll zsY8CiQXAaO_OT28VzLDQSJT~boHrjlvo0V&z3-F)AA;1VskG}wo<}P5)&UBrFEwG% zN_F?{bi3URK!X?cHmu)q{Gj&emt6-Bhl-IGs6N z?(ST8aJp>D{_>U0zDn7F*nN3x^3raAfC)2L8%-SqWsp(G8>(EVtVKB3E&wJ#{9;*? zPyOhHBF!4vOs0kR$RW>Z7-p$Q+%xMnS)Q$nDZ>N?Y37;61R_eE@3TS7eby?40jDu9 z2ATEVTEjT*TN%e(_i%dJ01)lkJoSCsr6O$`t$JgX;sP5jwX?%frX`4sB?)a?O)*>5 z4gpT$xOcq^K4!7^fCF_NOWlP)aNwgX$_g%(LCzB=D4|gz5XN=;Hm1x4;1Lf#Smk-f z2D$JdRHg14cY3y}Th-K3wJsQsDXiB$WrQ%+tyFzn*N<0};HHn#aA5RFI@+DD&Bw#JktVP1RQm7e%-;{kmxZG45F3YL;TBjWq7j>AdOt zgbmhpt)wv8Lksh*gd9P9SZ70~gpg z#@w;(BeXt09&KgoQeq5<5E8NRC_(`*7FBoNu3mqbee-z##{A>PJfHEQAR2+VA};eCi1-Wrmv(QYvw{6@Q&>8*ubP3h>d zIqkh1v!TFzND7ANmz(cYzFFIPk8ctn_w?aIc{E_fkQ9dZYggZD4@WE;^P;ltLA;sM zB%_h_uEg#9snY;9X0ein1d1@S_DOC7IM80?Ja}JMiU5r@OuupR;lF-z@JJv01+p1WMpnfNRBKJE`xwtvu zc%(XnsmhX~saq7tx&`YM0%NeH1cIhu91g)d)HR)IyTg<9YAu7p{k$uNtSWm?aJ}d= zgnWucLew0^XD06ldKE9u&)PXlV}jy{^wr_H!wn<@HXEVYCt{XV=2-~cdc4iEslbb${Bd(nS;e@i3wBIx4lFt7^TOPBx1}^x4%DKoc1&h z5e=g}x0Vt?z~S@bRoit6jP`aA4X5K_*UR>v7}EX6-+b-cuOE`r^!}R*XvM+B-Qfh5 zcPKTi4n4ux^ws>d>ArE~e)-|``>Rh_e;uQ(gyN{s*#-iHy$;@e`*v-!EE(slv-j?` z=}a^^!rv#4-TX=mkFRyGNbu@WwPF2tuj$cfk`eysqO?Cgo z%=h@_PhT;K1HQpX~%+lVFG103z{Qbt1>R;#t^kl2p)UL9;+AIb_uf)Me` zRXfhPk#3S~F3P1dVUTe~QNV$vY<1jm%6jF?#k#Ex!GV0>Q+v(|XUKS(80CA{Q_3-- z0by-u-FD|^4X2sw+;EV2Y_xUGLK-q{EEOc!po4Q58><7LNKnjOAdxnHxljO>ak4DS zKp;ZNe9>4ZV@{gZ$)LSe;IYpYb_rYfwcTTrbuBy&xk1(5L<0KQ_d)Yd&9HAvT zz5D*d+l$2;W-O9hcaBsi#v21Fx^XgejehU$1E+ZaNTysfEi3I5TUsZ*$D|*Oli_Te z6Y}t=MX9l+%Xd;52_}5PGi~(gY1MUVxvaIbx^bM6K(x{ZVMGi$eSc|g&R6R`pA~t+ z8KP0aoN-FIG)f7EC?yng=e-5+!E+Y#0Y7|PV@j%JE7Alz+E#uvOgqy`V<8ZvaJlN! zf?4aO2@lWab=MI>q%{bq!;QFnSm9c;1kkZ$=kon;yq-?BZLjj!6C6g9qAqVeespS$ zR%)%C!8y6S3cu^|Wb5S7hey#)LWxLqzDZRTXvD;MeprLhZ=>gDaLybqss16+d3Fti!Xd+YcOM3p0#yXjG6IRDuuuf z$Ad=oIJ1*{sGY&y=TUAv(pClsAz+T9{>0P|;r>_dkq>Fp<4M#1SSOuEjsWs?W~6THRfqR3h8d zP2kL_&|_osjZJJ;)$z%r^FzC~GE|I2jjGq@N+3TXu}c_exVXQIT*o=H9{mRAsmujl ztukY3!qxd%yY9Q-X{i06h>Wq`W~PGn@mY&pun{T&-vwXtxY#~FJdxguG|tB~X2f}r zy;-l71AzlgGv1gMsEufh0IN#JG4|f`2vtpsF|nQA*vSCn^;`z$y(3XVRd8Ab+4-vL zo%eAj5E5;vy>v(Koz{1Jf7q7Cw>nO}Wp^K*1!LoAdU2SMnB`~;PIoox0(LDyoQSQR zPkzsjpxfWE>7*O&c^b3f&fulbn|rT4^RN7GEJ+^y_y3k}&zH)*b6z*Lt4&v)s0p(y zN_~J!7xoDD)*>4b<8%@@MRu^o!bT(xCeh^rzETu41AwKga+>~?`7d6JFVwz|2p_V7 zW7hcg&Hk45dW+9YFbvUMw&|!6oXnr(-rfCp<4$|1gWZp2BbM(*GlALNXYaI1QG$@f zm?7&;aQ5NJ(i)J`96#1iKal_U@##M@9p6@Jhp`Jn9B{tN`7?36#aKdc@BNW61fhM- zfAzfl>09T|ULF<^7PHt+#OA99veZ}T2*U1o+Mdht7T<+LkV*R^{T;^8rx{wAqIk^Ku|iugCq~$2_~9~d4$shH@3Cb z6>07rcoTRe2zF)D%g&A>vbjI(dVO}(4x%DUBOu0G4&0Y(hY9eEA05>;xYb#gPX=d4 z)nGLAUYnp7WgnxoS!)fQ>XekW)7pC3*ZT7Q_PSJy`zH@xTZEN$ZP!_8D3?k;d{ozs z8s`qe=9rj_wb=2{+v#jF8V(bIDF)`E%lmXn#%Vm*+SwH4IYQ?=j#^nrgHG<8o;24V zO#c3L`eAYStAnco3-BHjD>gP}S{qqdr#1ls1y0NGTn>^&#+>j7Q^uSX)<b4uF5O5Fancl~S2j*qTC`>}q#JZ+cD8mO^R;??OE5!{OovsdudXXGZvoy1J`PfP{so%!x^i; z&Zc3Mll06kQ=9}Gw%A5a(l`5?_w?bEj>dFwUmszFci5~T>6DHFggBx-v~SjTC?dZh z;Z8I?h&MQ90PuEwZ)NJ_GXW8QeAtSF&qn#GQ|;QHmt8jGfTNR#>mNLW&lmasHebBo z%Rf1r{GQwQetbCi>+AB85YmT#;QphJWNCo#ub-U%bXotSTbqBrs-C^NIr-pLd^MHS zNn>g3!5Qp;BQ85bNI>3s0tAld=SeIWjZ6n@ki~l; zKS;?Zf8?Tf76~*Oj;zzYQL|hahYesAEXRzYR1`i*S&_t99*t*=1{OuwbDs|ihGS{e zFpD=gCXN6gL;{jpbMCBmRi&!hSnFH0#=g_C^F1-fmn$iy<^pwXql24njGDR6MuKxu zRUJmS?6tEfj#z6Ogj@(X<^qh1xCq`@?2050E({8e8Pd{GLW~R|A%evSP+*=A28bd? z%i5gXJ6=5s!`X#wxb3?6?UO}Yd8Tll`h#tRkmxJ9ou!pSlp(|MIEqh>Pilw9Q38<} zAsS*>V_dft<1t3WZ|^>WpFD9_9$fx=?CeEEFpBaao|xt92hVRG-<-qEl|{<0yWv^r z?SsB-iej%i)-*=FQG3@fAb&zCJb!$=R9*0Vv=hfMnob8XCn(a^+Dzob5!2uX)4^m| zC?5#&7j}lUmX}00WT~NrbQu-I&z;^jmKom9{xf>UYoWdDuC4 zNefY`8o!1V2-=7$K?8mic+1We4aH4jnGeb?m>D-dj_IxrZ%y8nG zWp+Kg^zz2|Iy-oIM~61g@x_Z<*7ezdX3^-a*B@@s@t6)MB9F}J-R|Mj$(2XuLaT?Q%L^D20h(HKEl4qS$IZfVe9wbD#m(+M1OCwKD z*2_iJE6WMfNFs%f-Z^i+ee}FyCq_>w+ZN)FJv#iCHfID-?cCD3cl!Q{5WnZ~(MOWx zd$Q~jXLDnJN%o)oBhSwE28_!~2fNnl(Kv1!y|=efcBM#p!jrD=4|c|*Y^1@92#)T} zF$SrB<)IvF@z8Z!U!2RWDCPOOYK;PiDFNWj8>}G&BQf%Z24I|wHe+(0s^xb}*k$QcAXuQU^}1(W%U4Srg|*1MCx|2F-hb2N16!PPw3N$A7Y zQ;{v{Z1DKo@zix^W!Z>O&1`+X3P-h0%Jc5Q(fRfWlR&)6KDsq%dP8}}V>L-;w;!!U zoafW1x2`NZ*?GoL;I@~RMtm4$<*Ex{jZuQJ+c(afvv+>^=>D%S<&l;&WShcC`lQaJ zq&{xUU37foVGp!DZYRhHMiCuj)*l@oK_%wZYPFU}rz_*V?t2Nok>(LtLg53wtH~=vp==@$brnu=3cdvzj!7Wuatg+F^bUJUH21%!LQZLUs$dG z^mOu5i`6%~-UIv-8&m21TV414!@<(ppYQvRe*PlDsDBb4Hc-5t_W=;*&V!E=fi3YK zv{uM_rJZq>QAPvh+=+-!MzOSdP{jK?yNxaf<79I@?WGy!d}lf#AN;;Or>T*l7>VFW zB^xeCp5}l^*YHkvy_A9su%Rgz`GA|C5J1d1D8dp<5ckL!02gYdU95^Rt3=e+k2b}WxFU6loG&>5EoOvvpsEs%!_zD z9QMJ*B<$~QC-FcbE!XPwcs1M-)|nzH>b4(_vbL$6l@arin>d4-z6*hh7<;d!k}ibP zce~Toq3m&^tJM+$a=z+TxHi@cAMfq&oAo(QAZ8*R0t&cmN5Z8VF;^s%T5Cm~hpzWC7SgGKH8+;Uf=jYbvHj3iS{R`^+t-B{ClsF=I zYnyD0tZ{;6>^pZJWPTGf5zv_ zu&6wP09J@N0UyHZYH_jX#kioUFFj%|+PHsodWOPyG@=rRj3W=)w`WJ)XP&*j{OT8Q zI`GcUf9azSR|)uAPB z)zk#D*<`$2wisod>iWK)jkdf*=j+8&cb+GR9GWwV$dKj)k>`_Z6FN+Be5B8ElHQc} z*RK8zCr7jx(ZNNrn+h)C@QwA2NAmn)vK0{#LfDID{pG&=(X&Upckhvtcz}b#J6mz} z_WHp$AGH9n>YFxq?!kLE9$e_jgs}wUD{(Zpc5ck)hlAhu_~@UU%|4!I|M`6JbR=F* zk{8m1A@r@b{i0Ie_oL7E(jXJ}N@}I2<1NrGOCs$}xt0*{xJX&bdKuyz$rb{#*);B2 z;{)=PwWTae>rmZk-*lQIUadNZtWlbL^s`q2_5@pREEOTR0G?>6t=0(X0ETdC4PfG< z4D*Prm%X>#Xyy@cM%GS`*gZC_!O5Po(vsY$j z%Es67Yw9Bj&Kq`EF6!|pbJCY(hl9i5g7btxE2}6Lyf4D*QRUlhHfw!UzF;pm!{Sj<1`M0Q@p5_`7l!kMI23sqpEF`vWunRg2-NaY=>FWx1Ksi7_Qc9 z!kFMZrD>cAMoHPU2sPW7|u{$hzws(q7xW-7Se!d*2nD4hudSge*x=p0X^_eV^nL9Xgm?U#*8V zdgg5N?^#a2Z;mg^Wafi(aUrPt#7-9M`tCA(Ywj{%a~9S0dg1Y5+dS$4V`HRsgs%sC z>B;+Md35*mzPI#ry*PQ?#*xh&S23Xmp1yV!{8~`#9MTb9g?1z|+zE?}X$ZF}rNaTu5r77pI?DKTitt?_O=eLOz%8>_pRO6t5NBZwP3yRdhVKExV@6@ z(v|OBtZ$y2TY=?tM43;lZ@+tEyyb2MTfa>+iqPEJFLd4S%F<_&7=9;DB-HA2zvqRB zvw(QS!^UL9QPRpzc1^qPu|R!qB9=I8Fmbv!Sw#CPfXAKcg7Xol2wB3BL&T~OG2kRR zK0IG6YEwJ%Lx1=gV-(BD=49jKxD3>64U>o`#s^1iwYGh2rn^E!SkQPh&J6SzqYK*` zlo|?Y#zvj$8K>LRv?#K=?E!g0P+zqe@M_(i9M?u7!o3jA>CPz4JhvLW4_fy|TW4GC zZJsB671B{0Mc&y!G3h!`ii${xh%~l$&Lunv9*_={(SU8+skW8E`;FbgdVhZ0Mm!Nf z(=qcJd5?NyT)@F0oYMKc@dT<>4a%LAOK3%~uI$Qc-YI-6&@1;Q|KQunk00~vi{S@> z5`t_m4Gpbh1JN&;NFOfOhrRD*ue83?r;p0ju^V!5j;4&q&Lc-T^Omwf0(KZ~uqY6~ zDT=2fcQM}^#lx&6LtF>9ViBwLR0e+ktwS=-qBYjk`q;U-?_G80_2v3oEA((t9d*{Z z=_oF16-RWw>PLl0BBrg21Z_G)Fp33Rl>Mcx_>DIoKbY$mUpVlQJ3L$EUd*LMjVxU= z$gA=0Q(Gc^|E$gvvt0PC%|W&kM}2N=C!XFo_|$=z5iyOFMT{~W!`%mSDq>3zD)|w# zPtPtt^`TGbH-3c}X?bdrfvC@HfS!JD2-U=;Q46*3PgzR{^;sB7-ECeF)4g7cF?eFLe2hEn>+7eRv?YJ-FwR zYYC3_`PP(<5TFP8=*|A-(yf1EsfCjD?$sJ2gs)Y)*bzqi)Qd@K@HXfQkDd}F-BSR_ri zI$0bZRZ)~P0Q)#Qy!mbN;UC-yffh7hownJO8>u0HWzGg|mAkkpYe1j5#2*64;MBxacdWUM;a zo)m*b8AKRhk8Lm^81LwMsg(9YP#5Z^UU}Q2p0=%dGHQYYr&KSsDe^30sS7?yk~B(< z)y|TWvcU*p2QSm<1w#Bq$sl){m07O-`37)>T9`=O)pA3RBa;LgVP*DN7w zd64ms&D7JwrN$tKyL6c5;f(2jI*GSjvr`xor;akqLH#q40fs`KvZZe&^+VsUbRk?jvo z@ARo4f&--(W7PI0PgoMMrZ;28DwH^hGv)ZkG&W#!(VO7v!iA&Jt`PV^I|IY=G-btH*1v z;ltOST^}ELOrfveynXkL*1!FI*ZkAdOP{##J-7bw;O(oE|LE!Di^D(L{q(=#|5*kM z0RjMUaPYUEy69hh{qnD8EDAJ48DFn!113rY@@{8;CJGQA=vWb-yjM@@$OeC^7gIJ` zy7Hku8Iq#*-O7~$@m;v*bDDN;O@#csJCH*8{&bv#c+u$7kHVMDjH1qFDhyZdz{tgMhq}9vcvu6!p zhx1{gy-9QCj0ZrDI^!&0yf~{x5igE9CXz;#fN-x|OhsGE*2t!+=4EZHYighzrHuLe z_2S;*ymaK+D;o?%7AGV|&C&pKb?q?5h!W%R>AY%tBSfluZ=~DU92(nq(trz>=1|=@ zxxQRJ%7j;D)ajBr-Kp)(O+YeG5OKa()>YXG3fUlARqG^=3O+bFtpLmIai$b;2stFJ zMi>~zW-yLqP3^%O!i={QCeH?gELAh7Nd}Ts_kEVef%fy;14~m8E-iLK<(o{TN*=2`4_84K7qFF|^qHJ?=kRYBYpJXkjOyW&r z$m1KQ6q2a$gR9y8Coi~!Pp2ayLY(cl=F^W(pH2cxQP)W+mGnL!FxFZg!HeJf)VpsV ze)8HYhu`?(8}sA8fQ|p`v+;+ozubQMV{iTNtN-y2{OZ@fasA!v1n@r`{@MQ+|LZYC z@H@$FX4mH*x%1q6o@wvFIi##A*D8u4i~ZwAwHM)xKfJ`Q@s)V9x%u5{TD;TW{>|+% zDT&jKX!q68%@4kN=b3NG(V~?uAEvi|{&t?=)z|JbCOakC4hZ+7?MbB8&N}CGnnXEK zoB7r-iic6HB~f^C>z&1=YsK(h{chh6DNQhj@ABpUOF}eZ6n=}xTI&#gLH0lV`(IL4 z#sz6=h~q?Xyq2}#M9>6`$04>}Y2C+3VWl4BDWaHQ-*zU6B9Vx`3yZoXjP!Hu8?kzG z+33^bd7Y5~`RHdZNRO3PMb0X}&QsPkz&S?RCTW(XB!D|#wZn+;h>bVWtdc+QGv8VM z`n~hl?svCO^@GLq>Deg?pZJ+?-?_GjqP$v%`EqGA5}c*D7!O8`YA|&evjG{@>wYka zs;8mB$0{ zJ|7T*$z&Ko|ZR9KQDaCJ|(Q?qcW07eBBy!UOks;qdIKt87)S zn!0LjU~zZS4%2PRtt)kCd~fX8+7DuAI$fkZi6|lXY}rMErU`%Jp6W5om$EZ98So;H zP8SV0L^!)R%R1~It;>9r1>NCmSJk8Uy7J`O4_}=<8*g9VaL9Q$La0I z=BR1aV3d|;YX0^6A%;Xht)h1hAD~W_84C{|m}}F>@C3^y!o%IE80JZd5ym9MJaAN> z-MR7u7x$mtoL?31e)ISlCcf3Q7bEf8B@`I{ri2fa`Uf5z{+`kBovvp;w3BZ#V;v_E zWUL*)Wz(G=FP5u100M3Y$LY;)-#~uG z)ScBS*)0gq6Y}Zb{j@cGDtueD35*x3#(U>&h!fg2rF1%q#D|7q^w#>q`;T5Q?;icF zo8*e#{!kcrcr}HQ51aQ+-KD+Rdk^Xx%czLkEFcyrM@AxqeLh71p(?f2RCbmp3_S73 z8?fF|N~rN+y|$g!XD3yWkJQ?1Z9M51y^>l(LSruxVkiI(;G}a=%2h8##G;6b)cPl? zptG||b|w;32i3GPA0*sHoz}(-(&+oXeD@>2c=y@2=GPofkTaGLt9e2g=EFzx#oKLu zSesj=i$T19zLX+mC@5eA2jVIe0E0wP+TlxtG>noT*g_w?u)m3$l`ksgMlp*;e0$Nf zcyQFL?}ZT!Sn67j_Gcc)@X$IZYm+8&>(X92T>EnU@H`+M&hMNo)82^GY3$PBcxQw; zS}q@oK$6iABWR@^B>Z42Syw6qI9po>WZBuXl^hNe6N1N4EtT^j3e-^?l#M7RBA}jO zIJ4Fdc6O6dUOYFx`0>lxC~?*$1q*0=?EaqDt3UC-p8U}pZlewuzRQUhcdMV6GVP6yI-))#-~<{z8D_%~}O1Bw7~VBdp2{5QkjHefsG zUO_KVAn;oti>}>y;r$ohDa~9UY#J(9(#y^U?hM4t@v4?n)~ z;V+f(N!@GIdX@pUV!TSqyFs@up(94*yLVTU-E2z13BDZ@JWjg4J)1Wkhh?b+i&VQJ z!EZft!B5b&PhZb6VVs`r6&s(J-b?-DR=>0s1AM3J|Boa@=)O`9l_m)7QTnw%u&q9~ zb?w>RL@-P&q1ZWtm_vZKHm4rjWFUrFu5E}I9Bgl-(WukC>g%(^@?^1OC}IIKy?^`l zH=DbG*kKyw^V3K9XuBtk@l@4o@*{un`HjiIBAX2g2!IGl1>V~nrfJ?9>ul&MdALxQ z?w!i_4|k5$g$RZUas$~T&=NR?6a}_aFc_G!xl}z`B)J)~;c#Sn#3R6-o}8||LCygX z#3&foVhR)k3QS9hoPXjX^B#jS7Q2v*Iikor2o7Tu8SUek^}W_!S_gtgEE3h)8wYKt zoeS7;0b*lg+^QBMh@u#)OApR2f%x%=eEevcf3uzTE(BEpCLfxlFHg+lnpgm-YuW3=I{UAGTK zmKn{7HO_hnuzE$XOZOa}ffsq)W)jH#x`G6VGy=_{{F%~I!hCIT9iGY-g%{;lX zwfmtNNx)!LHZp`44ExkCKK^_EV*N+I(_VZ~8Osv*osw>r4f!<7Vvs>><8|H%*Tt{yxaoi(S)`<=`;u=AD?UX^+>D=_g!Yw$e{A+%{D zJ1Gr#$^mfW`u?=wC5bPHNNDWU!YM5!-j2#WCN@DNq?TDj09q} z^hs`|VjBZ87-US!Y~vKJ4&M3Oo8#Da%7r)%gZB@OlhxW}$R@LGb$zra2AkQKvTB7) z>+&etkJa3Yh}W%dlpan~VZbBs36aVW2XPwp+O*1G8)QI&v3b)po!gn_lrS{GgXc5D zDVs2aG$HoH{KUEcd;W*T@A+!|!lBOr0Oq&hKl?CT_#PPU!T$?it3U9G^rrVGW#5K? z#=~)=t(95ZcjdZ@MK(&ud|mKw_Rb69< znT&k<Lktt60;9ZaJ_* zK|WE9-<%XSxDZ_5+agP|LELD!s%)ovo@U;lhhM)N9-c}GCucQh$@Oue0&&{SCTMFq zqDc{tqSg5s`Ox-!6Q%+F(M@=>uMM7xr5{@tK zkF#U|glTP#A1?t+HsRLzL?qJa=`2UVli&!l$Z+NhsXOaE0-WYt%HCtYvpric=yCV) z8}m=Ud;Ce)4e!oXVDanJMwh_H|;;>gij7U(VnBc*t z=RmSJ;p!lPS2xoJir$&fp4+Yius%3JbY~I>4h6SIJ#lu4ibPBZ9~-Y|1SCyJ8e`W1 z%dE4(N|bNBO5Szrqck5liVv6by`A{IoAuU3G0Y%No^5Ma*QcFcvX>^}%JksbgZ+zB z$vb_v)S4rQfP$km;%vxCUXZ$Tlm*pWVAv5NJ9~A1xTsnWXk(O_R@J4v`oY~~h$BHx z>figT%YWn-`cJ&8CINm6XW*^B4!{4ugSY-FU;=|(_?-lR_nVJjPZrbS7+Ku5#;cw) z10GWbPwED@y$qu-?ZqfMh4T%VCJ_IQM1|^q3xDZ5@U{W_ZFuu}^fdey@pg3b{M&?r z>J0>h98L#ZJ5;w}QA!#iB1ixf332yV?m)%Ldv8jgw0(H+=roSg=cW@NF~T$Fcwq}u>pch>j|N;@B(U(vJ5P(4js^(| z(e9OD^HSO=RsHBC^W2~qBqCwTwG2BWO_4-rCylilf<}NNj#tfkb7xppmPIrcL>o6> zwucYr2#9mqSy$h#&%Sy5)bpP^I(^_8vo%FAa34d})PTIIgC|}qHQX5uo*j@M{p`hE zO_n}naq_~~-)CBFu9{cBdFQ#WzZc$loSrYTb?E|pyMnKm@InsvdQcu-%Hh=k>|cS8 z{xR6R2H*Y~>_>r*#$TQ$%jd3>NAs6v{@u}DFZFuahw#KvU}3&)<0wHr>1}7V5)7|a zZKYdfq&4ASXI8BnjC_)1-f5tYV7Iq5E%LOnYB((VzNbQPYOh|}VRTsQtLN+8FWvs^ zYwc%`#?W$#xl5NdIP^xP$BND@KO zOXKL-0sioI94Dh1in}dFn0u?Rh#{Jyco49Q$rx~CS^R-v_{curps2EV&BmPPfp2>} z^njSH0IY);+uC~1vZqx4{$#ps*6n1PD>8ciDW0G#8%*d_x`gE~C4*}-7Dvw6WXS5e zD`sN;*s9WHJYLs*o+mk>6ytb6a*U0q-a$ff>wMYkh@nxDVB|5vKu`cb-j9+gCebK~dX+1~{sgM$yjcYX>md6I{#hky`J4(mgh-)i{DGT7AWVpofG|EiuZ;A%x7ukR0{8Ufjg!Y;xU+Hb1EayEw{P7oTb+X6-hg1E z`_=g<;uw>vT&AKpUA7}6mW#Ew3my%lozeD(H@2UdBpF=3dg=7|lydNdHC3yX^~MZF zNu}%2G);M`z42NX*$@%xkTJ?%xV|yoJmS$IB& z%LzPJz$^lepkKo;{wlom7y#hcSMcHLbV!Oj+3v$48~p6ed)M}6={5;);bK-beH7zV z2;5W5Q89_NbcEw<5@W)hHQ6Ytt7f_xlXO;9^?cr*pS0sCTQtr2q8b)ad8klERNrh* zhF^T=#lL#<6YusPdU&1yOC)5NVD4MxDd8O3n(>Urxz`n;gpYQ8e-3h;PA`yT1_Xny zbk}&Vl2nrjC&g$>@E_iHQ?fpqFMj1jp6c|~DSsv{adrNv3u3qx5CjN`J;!E|Mbkll zc-OLLlSMJwa((r%T6Z?QD4LVrt~;+?k)UM3pA!D;8PPp+uVt{ zaniV)_>o}i-lwAo;Sf4)G;{=c?~VBLdip)+78Pzn?PFyJ@B+aE)({-%Ndy#KeZ4K6R9ejs9W|7fu|t%oUHEW5fk zhciqb+lbMcFl7 zmd8%3(Jap+Y?1DaYx^hCQtHxSs=bBS4x+qoRbVzFOtrxaa0=IbQ?_yxPZ>Az8xM|- z73=l!af8C~>FMckI9e_q?qt)h_xm&Y*hFFyB_W=CYAUhroYT-7Dan6%Au3Le78>q$ z5E1xmXYgJF2N4Jior5=P=sjcvF2qj^4De*y=@_QJ4}Rqly!jAZc;f0_1UA5-f~VU> z5wiz_sJk>P0okDQiSWn}OuE*!4Hi5FOu*sJ_I2AE?m8wo0LB;@*#nC(cxO86NC1w(Ij;@k#A|>^ zI~)+fl)G-OF;|^i=nK=NfuJ#qf|z>5n)+}rvS~y%#-pdF1L`}gR)xT+Ko5FEz#&zI zeknT@Y=_ALi7unnTD3?YjgtPOoBEl&9>nAm`_Z!l{Yd)&roa`(iT0!WC4Lxhk@>kX zZ>BHK4!a{i;*tPMKu~A3$_ma9?Ha3k$%r#nQ;Y~DS%!~qbV!9LjtP#yY1`xaw8v4r zU5p=BZ6zm95G^u z&J)qJjs+MdjB&$A&~aM}!vb$zc8L4Yu)T=1AixNLgPM4-5;gYNk9yiBv0 zx=c!d5R}ta8}Nt|_8SC-7Ij~>9boL8c>K;|yzII=r-yR_fG5d#dw+(tV~|gBy0N`G zOa>WWuX+IL*^q9(T1>ZN9-`f?0TtN$K(6cc>owf$;7r4|c;eEh#!tMeEgVXCHirp^ z%0g-3tp@fZxY59kQ@Hh2_!PigL+77_3}+Wsg=)u_3;mW{lRnZ_Ai`E zR(0Cqh+u-%3NZF$5WM!f3%tO9Sui3_J&Qq>SmYFQ&^2ZlBkj-*);vo_s@Zb-R-SL_0vffy!8f&CSv%Bi>3A?$-{q+Qog422GMU8&wm0K^Gp7&X$>vP&_lm6Fb- zL&C?=U>uLK?pJSIg}#Jh^LKby9>V%DoZSQ>;L;}n7&s5kLJ06%#Gbso^<}{sj|mfz zwkAp`qtw{|+)JrpR;E{nx4&|>fo1?OgaUpG1n2_nJ%pq8;MRo?>^$@Gl?T7?&4;gi z>u&lEE0EF7FLj&%K2h@V{klY$7Qh@}R1A-$8#nz~zNXJM&s(37blc?=w-GKEF z$5?p{$fXfiohROL29z`BR3+Oy6BMH)i&byhUZX%y&zIUjRY@1DRbl@28Ak)ICl5{^ zAg8lI)UCTTd2Ah+7NH>L+@W4-`+t0|18L zBf}?&_nQ@zV;Hd~N%*TvxZT0M9@Z8X8VG*!jtkH^crk}NJpjO|hNn`vmcXwq;d%mB z9-Z7Oh9`YH*^R6-1aU%$NN8|Y^@_6)5rX=n>KkLM_c)3OU~8>O5|I_r>J%dWlScnw zQ(pVlGPv#7q|PFa44?&Hdsls983>1a)^1O zf|zg=f)AhE9#TJ@o1t>lvaD;`Eb5GwMAf)oapF`oOc4IiCfyS)Hr+2&q17w~q!VYebQKfazFXK2q z@96dXo5e6T&IN2m;%VTQE^L&2EebIi6kCTbrEa8rg2yog9~P?aFg0jgb}@ zrg#sE6M#lQC3EIJ0JR;xI zzJ2%jLU}NS@o(17uZC~^PvI{ROnxB!O!Rlz_rLE~--#|PR;t^Y;2|#@epuI0oVd!>H++ zX4#H&R?mH}rP9`EY^@d?6XIr@Gw8wPUb7y_EMTyM2?uSfar9(JYO+uGsb+1 zCO-6tvIOt#?mSqmxP^_KL0`%7Cw8`;onZk@-4j9$vQiUmaJ8zL5Ihv*KYRu_f|m<; zHhUtT@^Gt#n=QOv!*^VEuN^nX zO0#qfx&|5n;p^I+RLw@7E<1m3)p1UTX>xPEK6KR4f0hogA zApl?k&S=Hb9AhHV(MC`u3J&5KHVU&C($UhO+b!$yrsf~wq zd3JWxhX5jh(^aXoPgv9}v~tE8nMUmNY+dyYCf;cK+%s4C)F@;1A{;LJ?Ll6uR!g@r zjZWuHqosEa2;RzQXIwAkbec+~X@NFg&YuXG64}?tKK0&%6^QJKY4HHoNAS!K0~XMh z;2r#SyoKd`NJj8mWc}vG;B6opBVASPWSrrEs#1Hcga{ZACCDeFNLpv z0lxYQJpZxpeWm@uv)6v$myRayAPdU&##vbQ98-%1)TgtXRKV6?!)gT^`K)Q#~!}o4C_w?#f6A4kT%j4tqqqB2?wWD;x)2Lv_ zZOsBpM`HLw&aPw*aff`w!32}1Ts9sV!)YKC1Gv`qQCGo(C8DbHp$#T6u>yp-vTk%rmCtbNRHh@!DtJob1o$YZ8U-6j?7Q=-Su8^|*Y-{ulvF^NR60Y+EP0%>cs9$Wm65;%Gv-9!>TJY> zh^w|k7{!^8bu>j(+X_)rXdBDICa&b(Zwb2Y^&oln^o-ZuKH;I&O2wm#aq!%M8OlQ>2H5g&1=#s$wwVBsuFBMPSasbU(x6lpPHB zKf0eyg(q&YZUkj{o-gJd!BMZYw~DhgkBUSHj~rvTYg``1jMH=!t=Eb&z=UEb-aGoG zD52InKv?_Gmbz`ch(oKDbwCN$t#iR?qqS7avewQ!gOsJVmMNot)v8B#S1ZB5#u1@? z<$WN`PosF2Ob2mJcvW}2Z2fRQ+WqKQ40+1a;V?$b^__|c4K~ma_ofS$VQ_iIy|d)i z0(K&JAmJ-L6xU&S41Wg*fFjuB@FN>fI_JgsNk}dTeD)%I{RAE>_}CCQf>RBL>WPFq z(UWXEl<?P!`y-EmHCm)E{o zPOL{x^#L%BQrnz6XGk($H_grE>V6N1@%K;XH%!))k1#KoNNnHWY=XfPk>6AFRu8w@ zXbsu>`nqSM&+fsmJY0DoTj}Vd8{OPc#!F0*aReX)6hB&SRC?4Yragmbj1UPSP%m>4 zkHd=Ub?-6o0bl~QN5KLl0uw*Pado=9WgdKMUSNzR6wdjJI@vF(I}>m@*`9 zmy-|fJqT)!VmcaU*7&;Cahe{UE(MDS!rJIo_2AKDI8)$Pb3lYPO`mL#=2oBc$RWIH zo2K{EI9`-0%Ghk2vQhkjpWJ`yqZ=2Vn)u+Nm;&?8=`811#ATz-&R$%sR}c@t8Hh*l zckthT4kp*&#or5?&;B+8pP)Q_Y3o5M&YyYeTGjUk+hjsEM>7+^+wSVYMwSc$ijl(@z^M>-=Ab;@cKKitzT;{xM+^=%hiGib(WIfBg%$E?wSA(zrD)n6zyw*|)RFZiGY;=dEfv z17m!`BFHv|G(Uua_Ajo1b+7>TuR_KVHk1>ryX3m3fDHEUc$Q#TuI=Of&g%=o`|{^J*l!s z3NE`Q^5p)AO?Pu^-EuA|N*0Sc5^3K`t#oIVk)9FZ7*;KB8{cc?`uU^o8B8*YEcTrz z0-->?2`CEQkYW=84Z)&hjJxxXY;7KU2Eoxd1@D0{TOVmlA$Vnnt4{2N>eC0wS!r(Q z=_KhsGk(0Ct`_=Ct266)Tj8?AYr6%A0%l;^0DuV_hAPD&FUBGnJw41{8QU968+eQm z0;eF^u&juvW`m)%mPEtQ%{fQG`_NZ}064Iy2*`PBf+`UrD9&A9(K&Vcrwo$e zLgDhkt_fx`O6y8RoFL>^xqryz__ic9M*JSZ;mlT6STUZAN_)5CO+bQ+e4NZ9~^Mqd<8B z*lPpchIXku_FdnVWl8>}tMEn*y@%^5+;3omLxkazWBB0UNvx#=1cq$^PoMx}01iV3 zPp3fEKsRA;2J1DfHGKaB?sd>OxZlHbIbeXwJ+X0Xajy2pZ8n^ruVc=e9w;LSEaw(Q z;EWsQg*65_2fg;5f~} zE0k|j#;})!GLlXs=rDxYVC$m;{cL8PAJODyRd>Nq>(KUg;e(_AZPg|ifl8$|TKCRk z=OB)e)>;U9?WGInXKT}WkwqIX<+~ppUHs@w404a{co=uO6$wrS?fVe4Vc0T31S1}N zuls<-w~ns?6F?Yv10sjt&R`GT{%MHEu($`e{x6C zv|ScO;~`CATvPGj@%x*@Et3s+rp1Q&9Sqk=Vc7w3ckx_tRy)l{?y zlR@De^Q1r69D|LBh?P~#d0fD?hDm;%CS z5it=hk5?RXWpH2i-g(nRNAKKoKGnC^SmhZ{jvn7mc!C6Ytti9^?P!t(6RikYL zcxi_vgYhisl~kcmMFft~fEgDdD8PZUlp#oxh)}31Imj|DcoauUS@Mrxd}7P(4xY=N zICG?+u}^{#!xKgvwqt;D}%#euv5Si(=1X}f@zG_J|OUp4>l}`Jxz%3DNDTWom_H}IFi}!ym9`f&W{>* zy%?nfqT0I`F3zm&HPSIf`#bw0@g{IeF+nIv1|ItTjeIyrt&2VQdR>#qj-E+(Um2nZ z4YI6LW-^X2GN;E2K|Hf`y>i}bYaIlxRPVi3R&Q?1MkDpb_nvb^Kzj~UKr(^f4#M#M zF961H<fW!sj_L3NAN{eue0cwKg&Hily|hJ?i9=oM6zQg^wV?qsPS4jCoEn5&LCtBg^Rdn0 zwY1nA5Xz*|DE8h0r9^q=tbTN_B{WFaR;{53TOCZVv7mk3Rc+UF9gA=r(@T37kB`qd z4iweO+dB>l1z2>=2h@Pq-t#&=b0fgZNf+B1gHW zK({wH0+xvJA{t_f0OOeB-OYSF9#x&D1Zge1{=!K(0JXNPuqcX!_@15N(^2`iGPjkT9R`o4x_7Q`@^4ov&q zb8aP$H*h>Aapp`1ln33AzEt%JbB?{TeHEVkrYz`=@CX=t`{-=dOt0UJK zD2kKV13=JMFHf^{Y!QW?~E!U2((m4+U1ZgvdTLsr~5ezcuuhG3U!rhKO{ zNusrErknY6vbk7DNh;F8&c#8LP;@0Nu5M1AnTw4))V9fO;h!jj8Fwn4~ z#AiHt`>ftd#M@;Pz>XRHo~?Lpv*RB6cIm}9h%r?6z3FL;Oc>k1Ab4Og;_0$J9k^yQ zvy8{Tc0%4=bw|>BDo}S4th9g;%MfA6)PM+&a!Pdwh!Y+9rR{12^x2HOI%6o_oQE7E z?`iB2$EJs%Oc2iMg-JK!tl$rAhvGQlu~o(z=LP2d%GHgGbEc$K)&>TcAg3%BY-5_& zUF8FgvTVL=v~=ECgt2q7vnt8?ut-;n&SRYr%30DhN+ZKUvRu?&KPF9bs&n88umq_1 zZ4RO*)-Aug#(3vfpkKk{3dj;3eFN@(fo?oC(JfJ5KVGgVj;X;}LYtK@?B43_@7#EA z;ZKv3`^%tmnpEr63i{~m?C}2aN-9f{W|kOEW`j{)1Rjqb&gZ3YLzu7uOD{xWFQx@0 zf_rMb?^M?(2^W+eA2kenLR@etNod*BamJnYh_NJL1QTs-D}CQ0gaQhv>{z+r%hq#-!<>NjqvZ^~iTPUOI zJdb>5@|anzduw`aX`rj+c_BRC+?u{TnjDN6M^O}cV;pkYV{M(&PAWwOQqClWNLf;M zy|XqEyzh<2zHRl!XySt+*j+r>GFAoR$ul24INjQQ_Q8Y8!ry3NW#DoG0>PULxOE6u z1JF6ZDS!beeoMkJz%D=pkbbwC-hD^u%fO|X?;YvTDeYZ%2D6x zvR5aoQuSH~skCPz%lLcE*`$oNLHB=WBTZ-U^ZzVNuRUp`#V-8CKMC1J{>%^l=u7GM zO#XMIeio}2A`+_Nebq-)6Ho% zN>5ch?wSU*#<#~E4SBqeX0K%VUXtbU)@&nS6A5~HQjbQ0qhRX9W8L>Q1SU8{5d{SK zFeZYmPTH7(G3@Ag)l|L0TEw<%S{{?>AU`^)oV1i0MiBwjDeZ6uIK_B_rnbF?@+>+%8J5Lm{E#p{b#o_Y7-X~Br|WH=l{qIZ7a zaxxQG!0BnnIpuM5zSIcP`N{cUoFF5H*;wkHP>{+R6-?*TQG7Npt+iP$7{S`;D55O( zDxhAuwld^nzw00fVLN{39K{2cCW4}fM!`DZ5tB;M zgnJqmix$aScdA!B$(+_W{N^PMPc2TcEQ4`2P^9PJ5z=cb*MZQ`&x3av_g0p{`vBMl z`iYI~Oof&97YmUKF`&);Re4uuVCpBX3gOxnr94E1QN5QcK%k)m%oqu4;M>`dFv@)S z?0|l77C$|S$5|W;)`rn}TVb^ZZ;>bfA%X<9=P2E_C{aN;Pd~aT2sBQvzHwC2pg%Sh zLljQX*n1b^G0-FgS9eVX-@6;VnG6}@4jdvBXIZqULRVm-1$|QTzU4RKm75h7q5>0#`f@+dwE7^k!JMv*AD4v+b(K(W9b

4%yUDEE|K!g0i|NJd+q22I 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 |6GO9W4VB4JgCbKLjfAXx8c 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 i83Y=qUNv#v{vQDd5?!>&%R(Li0000