From e085542c9a8dd947d8f417ebba0a4eeaf032e9f8 Mon Sep 17 00:00:00 2001 From: Pentium44 Date: Wed, 10 Feb 2021 16:24:23 -0800 Subject: [PATCH] Added areas, and basic_materials as well as tweaks --- functions.php | 1 + index.php | 5 + mods/areas/README.md | 63 ++ mods/areas/chest.lua | 80 ++ mods/areas/command_mgr.lua | 293 ++++++ mods/areas/database_lsqlite.lua | 130 +++ mods/areas/database_raw.lua | 167 ++++ mods/areas/default_settings.lua | 53 ++ mods/areas/doc/mod_api.txt | 108 +++ mods/areas/hud.lua | 91 ++ mods/areas/init.lua | 35 + mods/areas/locale/simple_protection.de.tr | 108 +++ mods/areas/locale/simple_protection.fr.tr | 107 +++ mods/areas/locale/simple_protection.pt.tr | 105 +++ mods/areas/locale/template.txt | 108 +++ mods/areas/misc_functions.lua | 184 ++++ mods/areas/mod.conf | 4 + mods/areas/protection.lua | 148 +++ mods/areas/radar.lua | 128 +++ mods/areas/screenshot.png | Bin 0 -> 101102 bytes .../textures/simple_protection_claim.png | Bin 0 -> 714 bytes .../textures/simple_protection_marker.png | Bin 0 -> 148 bytes .../textures/simple_protection_radar.png | Bin 0 -> 132 bytes .../textures/simple_protection_radar_down.png | Bin 0 -> 143 bytes .../textures/simple_protection_radar_up.png | Bin 0 -> 148 bytes mods/basic_materials/.luacheckrc | 30 + mods/basic_materials/LICENSE | 600 ++++++++++++ .../basic_materials/electrical-electronic.lua | 86 ++ mods/basic_materials/init.lua | 15 + .../locale/basic_materials.de.tr | 33 + .../locale/basic_materials.fr.tr | 33 + .../locale/basic_materials.it.tr | 34 + .../locale/basic_materials.ru.tr | 33 + mods/basic_materials/metals.lua | 300 ++++++ mods/basic_materials/misc.lua | 126 +++ mods/basic_materials/mod.conf | 4 + .../models/basic_materials_chains.obj | 881 ++++++++++++++++++ mods/basic_materials/plastics.lua | 56 ++ .../textures/basic_materials_brass_block.png | Bin 0 -> 272 bytes .../textures/basic_materials_brass_ingot.png | Bin 0 -> 223 bytes .../textures/basic_materials_cement_block.png | Bin 0 -> 243 bytes .../textures/basic_materials_chain_brass.png | Bin 0 -> 344 bytes .../basic_materials_chain_brass_inv.png | Bin 0 -> 1886 bytes .../textures/basic_materials_chain_steel.png | Bin 0 -> 386 bytes .../basic_materials_chain_steel_inv.png | Bin 0 -> 1730 bytes .../basic_materials_chainlink_brass.png | Bin 0 -> 178 bytes .../basic_materials_chainlink_steel.png | Bin 0 -> 175 bytes .../basic_materials_concrete_block.png | Bin 0 -> 252 bytes .../textures/basic_materials_copper_strip.png | Bin 0 -> 326 bytes .../textures/basic_materials_copper_wire.png | Bin 0 -> 306 bytes .../textures/basic_materials_empty_spool.png | Bin 0 -> 214 bytes .../basic_materials_energy_crystal.png | Bin 0 -> 817 bytes .../textures/basic_materials_gear_steel.png | Bin 0 -> 5845 bytes .../textures/basic_materials_gold_wire.png | Bin 0 -> 286 bytes .../basic_materials_heating_element.png | Bin 0 -> 369 bytes .../textures/basic_materials_ic.png | Bin 0 -> 293 bytes .../textures/basic_materials_motor.png | Bin 0 -> 247 bytes .../textures/basic_materials_oil_extract.png | Bin 0 -> 1966 bytes .../textures/basic_materials_padlock.png | Bin 0 -> 215 bytes .../textures/basic_materials_paraffin.png | Bin 0 -> 345 bytes .../basic_materials_plastic_sheet.png | Bin 0 -> 293 bytes .../basic_materials_plastic_strip.png | Bin 0 -> 160 bytes .../textures/basic_materials_silicon.png | Bin 0 -> 769 bytes .../textures/basic_materials_silver_wire.png | Bin 0 -> 251 bytes .../textures/basic_materials_steel_bar.png | Bin 0 -> 311 bytes .../textures/basic_materials_steel_strip.png | Bin 0 -> 326 bytes .../textures/basic_materials_steel_wire.png | Bin 0 -> 284 bytes .../basic_materials_terracotta_base.png | Bin 0 -> 775 bytes .../textures/basic_materials_wet_cement.png | Bin 0 -> 366 bytes version.php | 2 +- 70 files changed, 4150 insertions(+), 1 deletion(-) create mode 100644 mods/areas/README.md create mode 100644 mods/areas/chest.lua create mode 100644 mods/areas/command_mgr.lua create mode 100644 mods/areas/database_lsqlite.lua create mode 100644 mods/areas/database_raw.lua create mode 100644 mods/areas/default_settings.lua create mode 100644 mods/areas/doc/mod_api.txt create mode 100644 mods/areas/hud.lua create mode 100644 mods/areas/init.lua create mode 100644 mods/areas/locale/simple_protection.de.tr create mode 100644 mods/areas/locale/simple_protection.fr.tr create mode 100644 mods/areas/locale/simple_protection.pt.tr create mode 100644 mods/areas/locale/template.txt create mode 100644 mods/areas/misc_functions.lua create mode 100644 mods/areas/mod.conf create mode 100644 mods/areas/protection.lua create mode 100644 mods/areas/radar.lua create mode 100644 mods/areas/screenshot.png create mode 100644 mods/areas/textures/simple_protection_claim.png create mode 100644 mods/areas/textures/simple_protection_marker.png create mode 100644 mods/areas/textures/simple_protection_radar.png create mode 100644 mods/areas/textures/simple_protection_radar_down.png create mode 100644 mods/areas/textures/simple_protection_radar_up.png create mode 100644 mods/basic_materials/.luacheckrc create mode 100644 mods/basic_materials/LICENSE create mode 100644 mods/basic_materials/electrical-electronic.lua create mode 100644 mods/basic_materials/init.lua create mode 100644 mods/basic_materials/locale/basic_materials.de.tr create mode 100644 mods/basic_materials/locale/basic_materials.fr.tr create mode 100644 mods/basic_materials/locale/basic_materials.it.tr create mode 100644 mods/basic_materials/locale/basic_materials.ru.tr create mode 100644 mods/basic_materials/metals.lua create mode 100644 mods/basic_materials/misc.lua create mode 100644 mods/basic_materials/mod.conf create mode 100644 mods/basic_materials/models/basic_materials_chains.obj create mode 100644 mods/basic_materials/plastics.lua create mode 100644 mods/basic_materials/textures/basic_materials_brass_block.png create mode 100644 mods/basic_materials/textures/basic_materials_brass_ingot.png create mode 100644 mods/basic_materials/textures/basic_materials_cement_block.png create mode 100644 mods/basic_materials/textures/basic_materials_chain_brass.png create mode 100644 mods/basic_materials/textures/basic_materials_chain_brass_inv.png create mode 100644 mods/basic_materials/textures/basic_materials_chain_steel.png create mode 100644 mods/basic_materials/textures/basic_materials_chain_steel_inv.png create mode 100644 mods/basic_materials/textures/basic_materials_chainlink_brass.png create mode 100644 mods/basic_materials/textures/basic_materials_chainlink_steel.png create mode 100644 mods/basic_materials/textures/basic_materials_concrete_block.png create mode 100644 mods/basic_materials/textures/basic_materials_copper_strip.png create mode 100644 mods/basic_materials/textures/basic_materials_copper_wire.png create mode 100644 mods/basic_materials/textures/basic_materials_empty_spool.png create mode 100644 mods/basic_materials/textures/basic_materials_energy_crystal.png create mode 100644 mods/basic_materials/textures/basic_materials_gear_steel.png create mode 100644 mods/basic_materials/textures/basic_materials_gold_wire.png create mode 100644 mods/basic_materials/textures/basic_materials_heating_element.png create mode 100644 mods/basic_materials/textures/basic_materials_ic.png create mode 100644 mods/basic_materials/textures/basic_materials_motor.png create mode 100644 mods/basic_materials/textures/basic_materials_oil_extract.png create mode 100644 mods/basic_materials/textures/basic_materials_padlock.png create mode 100644 mods/basic_materials/textures/basic_materials_paraffin.png create mode 100644 mods/basic_materials/textures/basic_materials_plastic_sheet.png create mode 100644 mods/basic_materials/textures/basic_materials_plastic_strip.png create mode 100644 mods/basic_materials/textures/basic_materials_silicon.png create mode 100644 mods/basic_materials/textures/basic_materials_silver_wire.png create mode 100644 mods/basic_materials/textures/basic_materials_steel_bar.png create mode 100644 mods/basic_materials/textures/basic_materials_steel_strip.png create mode 100644 mods/basic_materials/textures/basic_materials_steel_wire.png create mode 100644 mods/basic_materials/textures/basic_materials_terracotta_base.png create mode 100644 mods/basic_materials/textures/basic_materials_wet_cement.png diff --git a/functions.php b/functions.php index ee0f9d51..0f502790 100755 --- a/functions.php +++ b/functions.php @@ -155,6 +155,7 @@ function settingsForm() { Server Desc:
Server Website:
Server MOTD:
+ Default Privs:
Spawnpoint (Format example: '32, 20, -140')

Player Transfer Distance (Value in chunks, 0 = unlimited)

diff --git a/index.php b/index.php index 75a269ec..9bb49735 100755 --- a/index.php +++ b/index.php @@ -304,6 +304,11 @@ else if(isset($_GET['do'])) file_put_contents("mtm_db/worlds/$userid/minetest.conf", "player_transfer_distance = " . $_POST['playertransferdistance'] . "\n", FILE_APPEND); } + // default_privs + if(isset($_POST['defaultprivs']) && $_POST['defaultprivs']!="") { + file_put_contents("mtm_db/worlds/$userid/minetest.conf", "default_privs = " . $_POST['defaultprivs'] . "\n", FILE_APPEND); + } + header("Location: index.php?do=manage"); } else { echo "Shut down server before configuration..."; diff --git a/mods/areas/README.md b/mods/areas/README.md new file mode 100644 index 00000000..2a69ac93 --- /dev/null +++ b/mods/areas/README.md @@ -0,0 +1,63 @@ +simple_protection +================= + +A Minetest area protection mod, based on a fixed claim grid, +like seen in [landrush](https://github.com/Bremaweb/landrush). + +You can claim areas by punching those with a claim stick. + +![Screenshot](https://raw.githubusercontent.com/SmallJoker/simple_protection/master/screenshot.png) + + +License: CC0 + +**Dependencies** +- Minetest 5.0.0+ +- default: Crafting recipes + +**Optional dependencies** +- [areas](https://github.com/ShadowNinja/areas): HUD compatibility + + +Features +-------- + +- Easy, single-click protection +- Fixed claim grid: 16x80x16 by default + - To configure: see `default_settings.lua` header text +- Minimap-like radar to see areas nearby +- Visual area border feedback, as seen in the [protector](https://github.com/tenplus1/protector) mod +- List of claimed areas +- Shared Chest for exchanging items +- Translation support +- Optional setting to require an area before digging + + +Chat command(s) +-------------- + +``` +/area [ ...] + show -> Provides information about the current area + radar -> Displays a minimap-like area overview + share -> Shares the current area with + unshare -> Unshares the current area with + shareall -> Shares all your areas with + unshareall -> Unshares all your areas with + list [] -> Lists all areas (optional ) + unclaim -> Unclaims the current area + delete -> Removes all areas of (requires "server" privilege) +``` + + +About "/area show" +------------------ + +Area status: Not claimable +- Shown when the area can not be claimed +- Happens (by default) in the underground + +Players with access: foo, bar*, leprechaun, *all +- foo, leprechaun: Regular single area share +- bar*: Has access to all areas with the same owner +- *all: Everybody can build and dig in the area diff --git a/mods/areas/chest.lua b/mods/areas/chest.lua new file mode 100644 index 00000000..d295b853 --- /dev/null +++ b/mods/areas/chest.lua @@ -0,0 +1,80 @@ +local S = s_protect.translator + +-- A shared chest for simple_protection but works with other protection mods too + +local function get_item_count(pos, player, count) + local name = player and player:get_player_name() + if not name or minetest.is_protected(pos, name) then + return 0 + end + return count +end + +local tex_mod = "^[colorize:#FF2:50" +minetest.register_node("simple_protection:chest", { + description = S("Shared Chest") .. " " .. S("(by protection)"), + tiles = { + "default_chest_top.png" .. tex_mod, + "default_chest_top.png" .. tex_mod, + "default_chest_side.png" .. tex_mod, + "default_chest_side.png" .. tex_mod, + "default_chest_side.png" .. tex_mod, + "default_chest_lock.png" .. tex_mod + }, + paramtype2 = "facedir", + sounds = default.node_sound_wood_defaults(), + groups = {choppy = 2, oddly_breakable_by_hand = 2}, + + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", S("Shared Chest")) + meta:set_string("formspec", + "size[8,9]" .. + default.gui_bg .. + default.gui_bg_img .. + "list[context;main;0,0.3;8,4;]" .. + "list[current_player;main;0,5;8,4;]" .. + "listring[context;main]" .. + "listring[current_player;main]" + ) + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end, + can_dig = function(pos, player) + return minetest.get_meta(pos):get_inventory():is_empty("main") + end, + on_blast = function() end, + + allow_metadata_inventory_put = function(pos, fl, fi, stack, player) + return get_item_count(pos, player, stack:get_count()) + end, + allow_metadata_inventory_take = function(pos, fl, fi, stack, player) + return get_item_count(pos, player, stack:get_count()) + end, + allow_metadata_inventory_move = function(pos, fl, fi, tl, ti, count, player) + return get_item_count(pos, player, count) + end, + on_metadata_inventory_put = function(pos, fl, fi, stack, player) + minetest.log("action", player:get_player_name() + .. " moves " .. stack:get_name() .. " to shared chest at " + .. minetest.pos_to_string(pos)) + end, + on_metadata_inventory_take = function(pos, fl, fi, stack, player) + minetest.log("action", player:get_player_name() + .. " takes " .. stack:get_name() .. " from shared chest at " + .. minetest.pos_to_string(pos)) + end, + -- on_metadata_inventory_move logging is redundant: Same chest contents +}) + +minetest.register_craft({ + type = "shapeless", + output = "simple_protection:shared_chest", + recipe = { "simple_protection:claim", "default:chest_locked" } +}) + +minetest.register_craft({ + type = "shapeless", + output = "simple_protection:shared_chest", + recipe = { "simple_protection:claim", "default:chest" } +}) \ No newline at end of file diff --git a/mods/areas/command_mgr.lua b/mods/areas/command_mgr.lua new file mode 100644 index 00000000..7df9a70c --- /dev/null +++ b/mods/areas/command_mgr.lua @@ -0,0 +1,293 @@ +local S = s_protect.translator + +local commands = {} + +function s_protect.register_subcommand(name, func) + if commands[name] then + minetest.log("info", "[simple_protection] Overwriting chat command " .. name) + end + + assert(#name:split(" ") == 1, "Invalid name") + assert(type(func) == "function") + + commands[name] = func +end + +minetest.register_chatcommand("area", { + description = S("Manages all of your areas."), + privs = {interact = true}, + func = function(name, param) + if param == "" or param == "help" then + local function chat_send(desc, cmd) + minetest.chat_send_player(name, S(desc) .. ": " + .. minetest.colorize("#0FF", cmd)) + end + local privs = minetest.get_player_privs(name) + minetest.chat_send_player(name, minetest.colorize("#0F0", + "=> " .. S("Available area commands"))) + + chat_send("Information about this area", "/area show") + chat_send("View of surrounding areas", "/area radar") + chat_send("(Un)share one area", "/area (un)share ") + chat_send("(Un)share all areas", "/area (un)shareall ") + if s_protect.area_list or privs.simple_protection then + chat_send("List claimed areas", "/area list []") + end + chat_send("Unclaim this area", "/area unclaim") + if privs.server then + chat_send("Delete all areas of a player", "/area delete ") + end + return + end + + local args = param:split(" ", 2) + local func = commands[args[1]] + if not func then + return false, S("Unknown command parameter: @1. Check '/area' for correct usage.", args[1]) + end + + return func(name, args[2]) + end, +}) + +s_protect.register_subcommand("show", function(name, param) + local player = minetest.get_player_by_name(name) + local player_pos = player:get_pos() + local data = s_protect.get_claim(player_pos) + + minetest.add_entity(s_protect.get_center(player_pos), "simple_protection:marker") + local minp, maxp = s_protect.get_area_bounds(player_pos) + minetest.chat_send_player(name, S("Vertical from Y @1 to @2", + tostring(minp.y), tostring(maxp.y))) + + if not data then + if s_protect.underground_limit and minp.y < s_protect.underground_limit then + return true, S("Area status: @1", S("Not claimable")) + end + return true, S("Area status: @1", S("Unowned (!)")) + end + + minetest.chat_send_player(name, S("Area status: @1", S("Owned by @1", data.owner))) + local text = "" + for i, player in ipairs(data.shared) do + text = text..player..", " + end + local shared = s_protect.share[data.owner] + if shared then + for i, player in ipairs(shared) do + text = text..player.."*, " + end + end + + if text ~= "" then + return true, S("Players with access: @1", text) + end +end) + +local function check_ownership(name) + local player = minetest.get_player_by_name(name) + local data, index = s_protect.get_claim(player:get_pos()) + if not data then + return false, S("This area is not claimed yet.") + end + local priv = minetest.check_player_privs(name, {simple_protection=true}) + if name ~= data.owner and not priv then + return false, S("You do not own this area.") + end + return true, data, index +end + +local function table_erase(t, e) + if not t or not e then + return false + end + local removed = false + for i, v in ipairs(t) do + if v == e then + table.remove(t, i) + removed = true + end + end + return removed +end + +s_protect.register_subcommand("share", function(name, param) + if not param or name == param then + return false, S("No player name given.") + end + if not minetest.builtin_auth_handler.get_auth(param) and param ~= "*all" then + return false, S("Unknown player.") + end + local success, data, index = check_ownership(name) + if not success then + return success, data + end + + if s_protect.is_shared(name, param) then + return true, S("@1 already has access to all your areas.", param) + end + + if s_protect.is_shared(data, param) then + return true, S("@1 already has access to this area.", param) + end + table.insert(data.shared, param) + s_protect.set_claim(data, index) + + if minetest.get_player_by_name(param) then + minetest.chat_send_player(param, S("@1 shared an area with you.", name)) + end + return true, S("@1 has now access to this area.", param) +end) + +s_protect.register_subcommand("unshare", function(name, param) + if not param or name == param or param == "" then + return false, S("No player name given.") + end + local success, data, index = check_ownership(name) + if not success then + return success, data + end + if not s_protect.is_shared(data, param) then + return true, S("That player has no access to this area.") + end + table_erase(data.shared, param) + s_protect.set_claim(data, index) + + if minetest.get_player_by_name(param) then + minetest.chat_send_player(param, S("@1 unshared an area with you.", name)) + end + return true, S("@1 has no longer access to this area.", param) +end) + +s_protect.register_subcommand("shareall", function(name, param) + if not param or name == param or param == "" then + return false, S("No player name given.") + end + if not minetest.builtin_auth_handler.get_auth(param) then + if param == "*all" then + return false, S("You can not share all your areas with everybody.") + end + return false, S("Unknown player.") + end + + if s_protect.is_shared(name, param) then + return true, S("@1 already has now access to all your areas.", param) + end + if not shared then + s_protect.share[name] = {} + end + table.insert(s_protect.share[name], param) + s_protect.save_share_db() + + if minetest.get_player_by_name(param) then + minetest.chat_send_player(param, S("@1 shared all areas with you.", name)) + end + return true, S("@1 has now access to all your areas.", param) +end) + +s_protect.register_subcommand("unshareall", function(name, param) + if not param or name == param or param == "" then + return false, S("No player name given.") + end + local removed = false + local shared = s_protect.share[name] + if table_erase(shared, param) then + removed = true + s_protect.save_share_db() + end + + -- Unshare each single claim + local claims = s_protect.get_player_claims(name) + for index, data in pairs(claims) do + if table_erase(data.shared, param) then + removed = true + end + end + if not removed then + return false, S("@1 does not have access to any of your areas.", param) + end + s_protect.update_claims(claims) + if minetest.get_player_by_name(param) then + minetest.chat_send_player(param, S("@1 unshared all areas with you.", name)) + end + return true, S("@1 has no longer access to your areas.", param) +end) + +s_protect.register_subcommand("unclaim", function(name) + local success, data, index = check_ownership(name) + if not success then + return success, data + end + if s_protect.claim_return and name == data.owner then + local player = minetest.get_player_by_name(name) + local inv = player:get_inventory() + if inv:room_for_item("main", "simple_protection:claim") then + inv:add_item("main", "simple_protection:claim") + end + end + s_protect.set_claim(nil, index) + return true, S("This area is unowned now.") +end) + +s_protect.register_subcommand("delete", function(name, param) + if not param or name == param or param == "" then + return false, S("No player name given.") + end + if not minetest.check_player_privs(name, {server=true}) then + return false, S("Missing privilege: @1", "server") + end + + local removed = {} + if s_protect.share[param] then + s_protect.share[param] = nil + table.insert(removed, S("Globally shared areas")) + s_protect.save_share_db() + end + + -- Delete all claims + local claims, count = s_protect.get_player_claims(param) + for index in pairs(claims) do + claims[index] = false + end + s_protect.update_claims(claims) + + if count > 0 then + table.insert(removed, S("@1 claimed area(s)", tostring(count))) + end + + if #removed == 0 then + return false, S("@1 does not own any claimed areas.", param) + end + return true, S("Removed")..": "..table.concat(removed, ", ") +end) + +s_protect.register_subcommand("list", function(name, param) + local has_sp_priv = minetest.check_player_privs(name, {simple_protection=true}) + if not s_protect.area_list and not has_sp_priv then + return false, S("This command is not available.") + end + if not param or param == "" then + param = name + end + if not has_sp_priv and param ~= name then + return false, S("Missing privilege: @1", "simple_protection") + end + + local list = {} + local width = s_protect.claim_size + local height = s_protect.claim_height + + local claims = s_protect.get_player_claims(param) + for index in pairs(claims) do + -- TODO: Add database-specific function to convert the index to a position + local abs_pos = minetest.string_to_pos(index) + table.insert(list, string.format("%5i,%5i,%5i", + abs_pos.x * width + (width / 2), + abs_pos.y * height - s_protect.start_underground + (height / 2), + abs_pos.z * width + (width / 2) + )) + end + + local text = S("Listing all areas of @1. Amount: @2", param, tostring(#list)) + return true, text.."\n"..table.concat(list, "\n") +end) diff --git a/mods/areas/database_lsqlite.lua b/mods/areas/database_lsqlite.lua new file mode 100644 index 00000000..a7382bb0 --- /dev/null +++ b/mods/areas/database_lsqlite.lua @@ -0,0 +1,130 @@ +--[[ +File: database_raw.lua + +lSQLite database functions: + load_db() + save_share_db() + get_claim(, direct access) + set_claim(data, index) + get_player_claims(player name) + update_claims(claims table) +]] + +local worldpath = minetest.get_worldpath() + +local ie = minetest.request_insecure_environment() +if not ie then + error("Cannot access insecure environment!") +end + +local sql = ie.require("lsqlite3") +-- Remove public table +if sqlite3 then + sqlite3 = nil +end + +local db = sql.open(worldpath .. "/s_protect.sqlite3") + +local function sql_exec(q) + if db:exec(q) ~= sql.OK then + minetest.log("info", "[simple_protection] lSQLite: " .. db:errmsg()) + end +end + +local function sql_row(q) + q = q .. " LIMIT 1;" + for row in db:nrows(q) do + return row + end +end + +sql_exec([[ +CREATE TABLE IF NOT EXISTS claims ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + x INTEGER, + y INTEGER, + z INTEGER, + owner TEXT, + shared TEXT, + data TEXT +); +CREATE TABLE IF NOT EXISTS shares ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + owner TEXT, + shared TEXT, + data TEXT +); +]]) + +function s_protect.load_db() end +function s_protect.load_shareall() end +function s_protect.save_share_db() end + +function s_protect.set_claim(cpos, claim) + local id, row = s_protect.get_claim(cpos) + + if not claim then + if not id then + -- Claim never existed + return + end + + -- Remove claim + sql_exec( + ("DELETE FROM claims WHERE id = %i LIMIT 1;"):format(id) + ) + end + + if id then + local vals = {} + for k, v in pairs(claim) do + if row[k] ~= v and type(v) == "string" then + vals[#vals + 1] = ("%s = `%s`"):format(k, v) + end + end + if #vals == 0 then + return + end + sql_exec( + ("UPDATE claims SET %s WHERE id = %i LIMIT 1;") + :format(table.concat(vals, ","), id) + ) + else + sql_exec( + ("INSERT INTO claims VALUES (%i, %i, %i, %s, %s, %s);") + :format(pos.x, pos.y, pos.z, claim.owner, + claim.shared or "", claim.data or "") + ) + end +end + +function s_protect.get_claim(cpos) + local q + if type(pos) == "number" then + -- Direct index + q = "id = " .. cpos + else + q = ("x = %i AND y = %i AND z = %z"):format(cpos.x, cpos.y, cpos.z) + end + local row = sql_row("SELECT id, owner, shared, data FROM claims WHERE " .. q) + if not row then + return + end + + local id = row.id + row.id = nil + return id, row +end + +function s_protect.get_player_claims(owner) + local q = ("SELECT * FROM claims WHERE owner = %s;"):format(owner) + local vals = {} + for row in db:nrows(q) do + vals[#vals + 1] = row + end + return vals +end + +function s_protect.update_claims(updated) + error("Inefficient. To be removed.") +end diff --git a/mods/areas/database_raw.lua b/mods/areas/database_raw.lua new file mode 100644 index 00000000..26308168 --- /dev/null +++ b/mods/areas/database_raw.lua @@ -0,0 +1,167 @@ +--[[ +File: database_raw.lua + +Raw text format database functions: + load_db() + save_share_db() + get_claim(, direct access) + set_claim(data, index) + get_player_claims(player name) + update_claims(claims table) +]] + +local claim_data = {} +local claim_db = { time = os.time(), dirty = false } +local share_db = { time = os.time(), dirty = false } + +function s_protect.load_db() + -- Don't forget the "parties" + s_protect.load_shareall() + + local file = io.open(s_protect.file, "r") + if not file then + return + end + for line in file:lines() do + local data = line:split(" ") + if #data >= 2 then + -- Line format: pos, owner, shared_player, shared_player2, .. + local _shared = {} + for index = 3, #data do + if data[index] ~= "" then + table.insert(_shared, data[index]) + end + end + claim_data[data[1]] = {owner=data[2], shared=_shared} + end + end + io.close(file) + minetest.log("action", "[simple_protection] Loaded claim data") +end + +function s_protect.load_shareall() + local file = io.open(s_protect.sharefile, "r") + if not file then + return + end + for line in file:lines() do + if line ~= "" then + local data = line:split(" ") + -- Line format: owner, shared_player, shared_player2, .. + local _shared = {} + if #data > 1 then + for index = 2, #data do + if data[index] ~= "" then + table.insert(_shared, data[index]) + end + end + s_protect.share[data[1]] = _shared + end + end + end + io.close(file) + minetest.log("action", "[simple_protection] Loaded shared claims") +end + +local function delay(db_info, func) + local dtime = os.time() - db_info.time + if dtime < 6 then + -- Excessive save requests. Delay them. + if not db_info.dirty then + minetest.after(6 - dtime, func) + end + db_info.dirty = true + return true + end + db_info.time = os.time() + db_info.dirty = false +end + +local function save_claims() + if delay(claim_db, save_claims) then + return + end + + local contents = {} + for pos, data in pairs(claim_data) do + if data.owner and data.owner ~= "" then + contents[#contents + 1] = + pos .. " ".. data.owner .. " " .. + table.concat(data.shared, " ") + end + end + minetest.safe_file_write(s_protect.file, table.concat(contents, "\n")) +end + +function s_protect.save_share_db() + if delay(share_db, s_protect.save_share_db) then + return + end + + -- Save globally shared areas + local contents = {} + for name, players in pairs(s_protect.share) do + if #players > 0 then + contents[#contents + 1] = name .. " " .. + table.concat(players, " ") + end + end + minetest.safe_file_write(s_protect.sharefile, table.concat(contents, "\n")) +end + +-- Speed up the function access +local get_location = s_protect.get_location +function s_protect.get_claim(pos, direct_access) + if direct_access then + return claim_data[pos], pos + end + local pos = get_location(pos) + local index = pos.x..","..pos.y..","..pos.z + return claim_data[index], index +end + +function s_protect.set_claim(data, index) + claim_data[index] = data + save_claims() +end + +function s_protect.get_player_claims(owner) + local count = 0 + local claims = {} + for index, data in pairs(claim_data) do + if data.owner == owner then + claims[index] = data + count = count + 1 + end + end + return claims, count +end + +function s_protect.update_claims(updated) + for index, data in pairs(updated) do + if not data then + claim_data[index] = nil + else + claim_data[index] = data + end + end + save_claims() +end + +local function table_contains(t, to_find) + for i, v in pairs(t) do + if v == to_find then + return true + end + end + return false +end +function s_protect.is_shared(id, player_name) + if type(id) == "table" and id.shared then + -- by area + return table_contains(id.shared, player_name) + end + assert(type(id) == "string", "is_shared(): Either ClaimData or string expected") + -- by owner + return table_contains(s_protect.share[id] or {}, player_name) +end \ No newline at end of file diff --git a/mods/areas/default_settings.lua b/mods/areas/default_settings.lua new file mode 100644 index 00000000..b950c93b --- /dev/null +++ b/mods/areas/default_settings.lua @@ -0,0 +1,53 @@ +--[[ + SETTINGS FILE + +simple_protection/default_settings.lua + Contains the default settings for freshly created worlds. + Please do not modify in order to not get any configuration-related errors + after updating all other files but this + +[world_path]/s_protect.conf + Contains the per-world specific settings. + You may modify this one but pay attention, as some settings may cause + unwanted side effects when claims were made. +]] + + +-- Width and length of claims in nodes +-- !! Distorts the claim locations along the X and Z axis !! +-- Type: Integer, positive, even number +s_protect.claim_size = 16 + +-- Height of claims in nodes +-- !! Distorts the claim locations along the Y axis !! +-- Type: Integer, positive +s_protect.claim_height = 150 + +-- Defines the Y offset where the 0th claim should start in the underground +-- Example of claim (0,0,0): Ymin = -(50) = -50, Ymax = 150 - (50) - 1 = 99 +-- Type: Integer +s_protect.start_underground = 50 + +-- Only allows claiming above this Y value +-- To disable this limit, set the value to 'nil' +-- Type: Integer or nil +s_protect.underground_limit = -300 + +-- Returns the claim stick when unclaiming the area +-- Type: Boolean +s_protect.claim_return = true + +-- Players will need to claim the area (or have access to it) to dig +-- Digging will be still allowed in the underground, +-- as defined by the setting 's_protect.underground_limit' +-- Type: Boolean +s_protect.claim_to_dig = false + +-- Allows players to list their areas using '/area list' +-- Type: Boolean +s_protect.area_list = true + +-- Limits the amount of claims per player +-- Doubled limit for players with the 'simple_protection' privilege +-- Type: Integer +s_protect.max_claims = 200 diff --git a/mods/areas/doc/mod_api.txt b/mods/areas/doc/mod_api.txt new file mode 100644 index 00000000..78cd25a3 --- /dev/null +++ b/mods/areas/doc/mod_api.txt @@ -0,0 +1,108 @@ +# simple_protection API + +This file provides information about the API of simple_protection for the use in +custom mods. The API might change slightly when the development goes on, so avoid +using internal tables or functions which are not documented here. + +### Table of contents + +* Types: Custom tables or values +* Helper functions: General purpose functions +* Protection management: Claim-specific API functions +* Callbacks: Registrable callbacks + +### Notation + +* `function_name(arg1, arg2, ...)` -> `returned data type` + * Function description + + +## Types + +* `ClaimData` -> `table` +``` + { + owner = "foobar", -- string, owner of the area + shared = { "covfefe", "leprechaun" }, + -- ^ table, list of players who explicitly have access to this area + } +``` +* `ClaimIndex` -> `?` + * This might be any value, depending on the database backend. + * Can be obtained with `get_claim` and is used for `set_claim` + + +## Helper functions + +These functions are grouped so that they make sense and then sorted alphabetically. + +* `s_protect.can_access(pos, player_name)` -> `boolean` + * Returns whether the player may modify the given position + * `pos`: Position as a `vector` + * `player_name`: Is a `string` for the player to check + * `nil`: Always returns `false` + * `""`: Returns `true`. Warning: `get_player_name()` returns this value on + objects which are not players, such as Lua entities. +* `s_protect.get_area_bounds(pos)` -> `vector, vector` + * Returns the minimal node position (1st value) and maximal node position + (2nd value) of the current claim. The coordinate values are inside the claim. + * `pos`: Position as a `vector` +* `s_protect.get_center(pos)` -> `vector` + * Returns the center node position of the current claim near to `pos.y`. + * `pos`: Position as a `vector` +* `s_protect.get_location(pos)` -> `vector` + * Returns the location of the given claim (whole numbers) in claim-coordinates + * `pos`: Position as a `vector` + * This function is only helpful to iterate through multiple claims. +* `s_protect.load_config()` + * Causes simple_protection to (initialize and) reload the configuration. + + +## Protection management + +* `s_protect.get_claim(pos)` -> `ClaimData, ClaimIndex` + * Returns the area information or `nil` when no area was found at the given + position. + * `pos`: Position as a `vector` +* `s_protect.get_player_claims(owner)` -> `table, count` + * Returns a table of claims which the player owns, whereas `ClaimIndex` is the + key and `ClaimData` the value of the resulting table. The second argument + describes how many entries the table has (i.e. how many claims). + * `owner`: Player name as `string` +* `s_protect.set_claim(data, index)` + * Updates the area data for the given index. It will be saved automatically. + * `data`: Area information as `ClaimData` + * `index`: `ClaimIndex` provided by `get_claim` +* `s_protect.update_claims(update_table)` + * Updates multiple areas according to the supplied table + * `update_table`: `table` of areas to update, whereas the key is `ClaimIndex` + and the value `ClaimData`. Set the value to `nil` to remove the claim. +* `s_protect.is_shared(id, player_name)` -> `boolean` + * Returns whether the owner shared an area (or multiple) with `player_name` + * `id`: Can be either `ClaimData` or the owner name as `string`: + * Type `ClaimData`: Checks whether `player_name` is contained in + the given area's share list. + * Type `string`: Checks whether all areas of the given owner are + shared with `player_name` + * `player_name`: `string`, the player to check + + +## Callbacks + +* `s_protect.registered_on_access(func)` + * Override or extend access to a certain claim. Depending on the returned + value of the registered function. + * `func`: `function(pos, player_name, owner_name)` called in `s_protect.can_access`. + * Is only called on protected areas. Use settings to control unclaimed areas. + * Must return a boolean or `nil` + * `pos`: `vector` position of the interaction + * `player_name`: `string` name of the interacting player + * `owner_name`: `string` name of the claim owner (player) + * If `func() -> false`: Access is denied instantly regardless of shared areas. + * If `func() -> true`: Access is granted if no other callback returns `false`. + * If `func() -> nil`: Normal protection handling +* `s_protect.register_subcommand(name, func)` + * Registers a new subcommand for `/area`; throws errors on failure + * `name`: `string` name of the new command + * `func`: `function` to call when the command is executed + * See "Chat command definition" in the Minetest core Lua API. diff --git a/mods/areas/hud.lua b/mods/areas/hud.lua new file mode 100644 index 00000000..7a478672 --- /dev/null +++ b/mods/areas/hud.lua @@ -0,0 +1,91 @@ +--[[ +File: hud.lua + +areas HUD overlap compatibility +HUD display and refreshing +]] + + +local S = s_protect.translator + +s_protect.player_huds = {} + +local hud_time = 0 +local prefix = "" +local align_x = 1 +local pos_x = 0.02 + +-- If areas is installed: Move the HUD to th opposite side +if minetest.get_modpath("areas") then + prefix = "Simple Protection:\n" + align_x = -1 + pos_x = 0.95 +end + +local function generate_hud(player, current_owner, has_access) + -- green if access + local color = 0xFFFFFF + if has_access then + color = 0x00CC00 + end + s_protect.player_huds[player:get_player_name()] = { + hud_id = player:hud_add({ + hud_elem_type = "text", + name = "area_hud", + number = color, + position = {x=pos_x, y=0.98}, + text = prefix + .. S("Area owner: @1", current_owner), + scale = {x=100, y=25}, + alignment = {x=align_x, y=-1}, + }), + owner = current_owner, + had_access = has_access + } +end + +minetest.register_globalstep(function(dtime) + hud_time = hud_time + dtime + if hud_time < 2.9 then + return + end + hud_time = 0 + + local is_shared = s_protect.is_shared + for _, player in ipairs(minetest.get_connected_players()) do + local player_name = player:get_player_name() + + local current_owner = "" + local data = s_protect.get_claim(player:get_pos()) + if data then + current_owner = data.owner + end + + local has_access = (current_owner == player_name) + if not has_access and data then + -- Check if this area is shared with this player + has_access = is_shared(data, player_name) + end + if not has_access then + -- Check if all areas are shared with this player + has_access = is_shared(current_owner, player_name) + end + local changed = true + + local hud_table = s_protect.player_huds[player_name] + if hud_table and hud_table.owner == current_owner + and hud_table.had_access == has_access then + -- still the same hud + changed = false + end + + if changed and hud_table then + player:hud_remove(hud_table.hud_id) + s_protect.player_huds[player_name] = nil + end + + if changed and current_owner ~= "" then + generate_hud(player, current_owner, has_access) + end + end +end) diff --git a/mods/areas/init.lua b/mods/areas/init.lua new file mode 100644 index 00000000..8632958c --- /dev/null +++ b/mods/areas/init.lua @@ -0,0 +1,35 @@ +-- simple_protection initialization + +if not minetest.get_translator then + error("[simple_protection] Your Minetest version is no longer supported." + .. " (version < 5.0.0)") +end + + +local world_path = minetest.get_worldpath() +s_protect = {} +s_protect.translator = minetest.get_translator("simple_protection") +s_protect.share = {} +s_protect.mod_path = minetest.get_modpath("simple_protection") +s_protect.conf = world_path.."/s_protect.conf" +s_protect.file = world_path.."/s_protect.data" +s_protect.sharefile = world_path.."/s_protect_share.data" + +minetest.register_privilege("simple_protection", + s_protect.translator("Allows to modify and delete protected areas")) + +-- Load helper functions and configuration +dofile(s_protect.mod_path.."/misc_functions.lua") +s_protect.load_config() + +-- Load database functions +dofile(s_protect.mod_path.."/command_mgr.lua") +dofile(s_protect.mod_path.."/database_raw.lua") +-- Spread the load a bit +minetest.after(0.5, s_protect.load_db) + +-- General things to make this mod friendlier +dofile(s_protect.mod_path.."/protection.lua") +dofile(s_protect.mod_path.."/hud.lua") +dofile(s_protect.mod_path.."/radar.lua") +dofile(s_protect.mod_path.."/chest.lua") diff --git a/mods/areas/locale/simple_protection.de.tr b/mods/areas/locale/simple_protection.de.tr new file mode 100644 index 00000000..07def45d --- /dev/null +++ b/mods/areas/locale/simple_protection.de.tr @@ -0,0 +1,108 @@ +# textdomain: simple_protection +# Translated by: Krock/SmallJoker + + +# Privilege description +Allows to modify and delete protected areas=Erlaubt das Abändern und Entfernen von geschützten Gebieten + +#### AREA COMMAND #### + +# Command description +Manages all of your areas.=Verwaltet alle deine geschützten Gebiete + +# /area +Available area commands=Verfügbare 'area' Befehle +Information about this area=Informationen über dieses Gebiet +View of surrounding areas=Übersicht von allen Gebieten +(Un)share one area=Zugriffs-Berechtigung eines Gebietes hinzufügen/entfernen +(Un)share all areas=Zugriffs-Berechtigung für alle Gebiete hinzufügen/entfernen +List claimed areas=Geschützte Gebiete auflisten +Delete all areas of a player=Alle Gebiete eines Spielers löschen +Unclaim this area=Den Schutz für dieses Gebiet aufheben + +# Errors of /area +Unknown command parameter: @1. Check '/area' for correct usage.=Unbekannter Befehls-Parameter: @1. Siehe '/area' für die korrekte Anwendung. +No player name given.=Kein Spielernahme gegeben. +Unknown player.=Unbekannter Spieler. +This area is not claimed yet.=Dieses Gebiet ist noch nicht geschützt. +You do not own this area.=Du besitzt dieses Gebiet nicht. + +# /area show +Vertical from Y @1 to @2=Senkrecht von Y @1 bis @2 +Area status: @1=Gebiets-Status: @1 +Not claimable=Nicht schützbar +Unowned (!)=Nicht geschützt (!) +Owned by @1=Von @1 geschützt +Players with access: @1=Spieler mit Zugriff: @1 + +# /area radar +North @1=Nord @1 +East @1=Ost @1 +South @1=Süd @1 +West @1=West @1 +Your position=Deine Position +Your area=Dein Gebiet +Area claimed\nNo access for you=Gebiet geschützt\nKeine Berechtigung +Access for everybody=Zugriff für jeden +One area unit (@1m) up/down\n-> no claims on this Y level=Ein Gebiet (@1m) ober-/unterhalb +square \= 1 area \= @1x@2x@3 nodes (X,Y,Z)=1 Quadrat \= 1 Gebiet \= @1x@2x@3 Blöcke (X,Y,Z) + +# /area share +@1 already has access to all your areas.=@1 hat bereits Zugriff auf alle deine Gebiete. +@1 already has access to this area.=@1 hat bereits Zugriff auf dieses Gebiet. +@1 shared an area with you.=Du hast jetzt Zugriff auf ein Gebiet von @1. +@1 has now access to this area.=@1 kann jetzt dieses Gebiet abändern. + +# /area unshare +That player has no access to this area.=Dieser Spieler hat keinen Zugriff auf dieses Gebiet. +@1 unshared an area with you.=Du hast nun keinen Zugriff auf ein Gebiet von @1 mehr. +@1 has no longer access to this area.=@1 kann jetzt dieses Gebiet nicht mehr abändern. + +# /area shareall +You can not share all your areas with everybody.=Du kannst nicht alle Gebiete mit jedem teilen. +@1 already has now access to all your areas.=@1 hat bereits Zugriff auf alle deine Gebiete +@1 shared all areas with you.=@1 hat dir Zufriff auf alle die Gebiete erlaubt. +@1 has now access to all your areas.=@1 kann jetzt alle deine Gebiete abändern. + +# /area unshareall +@1 does not have access to any of your areas.=@1 hat keinen Zugriff auf deine Gebiete. +@1 unshared all areas with you.=@1 hat dir den Zugriff auf die Gebiete verwehrt. +@1 has no longer access to your areas.=@1 kann keines deiner Gebiete mehr abändern. + +# /area unclaim +This area is unowned now.=Dieses Gebiet ist nun nicht mehr geschützt. + +# /area delete +Missing privilege: @1=Fehlendes Privileg: @1 +Removed=Entfernt +Globally shared areas=Globale Gebietszugiffe +@1 claimed area(s)=@1 geschützte(s) Gebiet(e) +@1 does not own any claimed areas.=@1 besitzt keine geschützten Gebiete. + +# /area list [name] +This command is not available.=Dieser Befehl ist nicht verfügbar. +Listing all areas of @1. Amount: @2=Auslistung der Gebiete von @1. Anzahl: @2 + + +#### Protection #### + +# Item place information +Area owned by: @1=Gebiet geschützt durch: @1 +# Hud text +Area owner: @1=Gebiets-Besitzer: @1 + +# Item: Claim stick +Claim Stick=Gebietsschutz +#(click to protect)=(kicken zum schützen) +This area is already protected by an other protection mod.=Dieses Gebiet ist bereits durch eine andere Mod geschützt. +You can not claim areas below @1.=Du kannst keine Gebiete unterhalb von @1 schützen. +This area is already owned by: @1=@1 besitzt dieses Gebiet bereits. +Congratulations! You now own this area.=Glückwunsch! Du besitzt dieses Gebiet jetzt. +You can not claim any further areas: Limit (@1) reached.=Du kannst keine weiteren Gebiete schützen lassen: Limit (@1) erreicht. +Please claim this area to modify it.=Bitte schütze das Gebiet um dieses abändern zu können. + + +#### Shared Chest #### + +Shared Chest=Geteilte Truhe +(by protection)=(durch Gebietsschutz) diff --git a/mods/areas/locale/simple_protection.fr.tr b/mods/areas/locale/simple_protection.fr.tr new file mode 100644 index 00000000..e2164096 --- /dev/null +++ b/mods/areas/locale/simple_protection.fr.tr @@ -0,0 +1,107 @@ +# textdomain: simple_protection +# Translated by: d-stephane + + +# Privilege description +Allows to modify and delete protected areas=Permet de modifier et supprimer des zones protégées + +#### AREA COMMAND #### + +# Command description +Manages all of your areas.=Gestion de toutes vos zones. + +# /area +Available area commands=Commandes de zone disponibles +Information about this area=Informations sur cette zone +(Un)share one area=Partager (ou pas) une zone +(Un)share all areas=Partager (ou pas) toutes les zones +List claimed areas=Liste des zones revendiquées +Delete all areas of a player=Supprimer toutes les zones d'un joueur +Unclaim this area=Libérer cette zone + +# Errors of /area +Unknown command parameter: @1. Check '/area' for correct usage.=Paramètre de commande inconnu : @1. Tappez '/area' pour voir les paramètres possible. +No player name given.=Aucun nom de joueur donné. +Unknown player.=Joueur inconnu. +This area is not claimed yet.=Cette zone n'est pas encore revendiquée. +You do not own this area.=Vous ne possédez pas cette zone. + +# /area show +Vertical from Y @1 to @2=Verticale de Y @1 à @2 +Area status: @1=Statut de la zone : @1 +Not claimable=Non revendiquable +Unowned (!)=Pas de propriétaire (!) +Owned by @1=Possédée par @1 +Players with access: @1=Joueurs avec accès : @1 + +# /area radar +North @1=Nord @1 +East @1=Est @1 +South @1=Sud @1 +West @1=Ouest @1 +Your position=Votre position +Your area=Votre zone +Area claimed\nNo access for you=Zone revendiquée\nNon accessible pour vous +Access for everybody=Accès pour tout le monde +One area unit (@1m) up/down\n-> no claims on this Y level=Une unité de zone (@1m) haut/bas\n-> Rien de revendiqué à ce niveau Y +square \= 1 area \= @1x@2x@3 nodes (X,Y,Z)=carré \= 1 zone \= @1x@2x@3 blocs (X,Y,Z) + +# /area share +@1 already has access to all your areas.=@1 a déjà accès à toutes vos zones. +@1 already has access to this area.=@1 a déjà accès à cette zone. +@1 shared an area with you.=@1 a partagé une zone avec vous. +@1 has now access to this area.=@1 a maintenant accès à cette zone. + +# /area unshare +That player has no access to this area.=Ce joueur n'a pas accès à cette zone. +@1 unshared an area with you.=@1 a enlevé le partage de la zone avec vous. +@1 has no longer access to this area.=@1 n'a plus accès à cette zone. + +# /area shareall +You can not share all your areas with everybody.=Vous ne pouvez pas partager toutes vos zones avec tout le monde. +@1 already has now access to all your areas.=@1 a déjà accès à toutes vos zones. +@1 shared all areas with you.=@1 a partagé toutes les zones avec vous. +@1 has now access to all your areas.=@1 a maintenant accès à toutes vos zones. + +# /area unshareall +@1 does not have access to any of your areas.=@1 n'a accès à aucune de vos zones. +@1 unshared all areas with you.=@1 a enlevé le partage de toutes les zones avec vous. +@1 has no longer access to your areas.=@1 n'a plus accès à vos zones. + +# /area unclaim +This area is unowned now.=Cette zone n'est plus revendiquée. + +# /area delete +Missing privilege: @1=Privilège manquant : @1 +Removed=Supprimé +Globally shared areas=Zones partagées globalement +@1 claimed area(s)=@1 a revendiqué des zones +@1 does not own any claimed areas.=@1 ne possède aucune zone revendiquée. + +# /area list [name] +This command is not available.=Cette commande n'est pas disponible. +Listing all areas of @1. Amount: @2=Liste de tous les zones de @1. Total : @2 + + +#### Protection #### + +# Item place information +Area owned by: @1=Zone appartenant à : @1 +# Hud text +Area owner: @1=Propriétaire de la zone : @1 + +# Item: Claim stick +Claim Stick=Bâton de protection +(click to protect)=(cliquez pour protéger) +This area is already protected by an other protection mod.=Cette zone est déjà protégée par un autre mod de protection. +You can not claim areas below @1.=Vous ne pouvez pas revendiquer les zones ci-dessous @1. +This area is already owned by: @1=Cette zone est déjà détenue par : @1. +Congratulations! You now own this area.=Félicitations ! Vous possédez maintenant cette zone. +You can not claim any further areas: Limit (@1) reached.=Vous ne pouvez pas revendiquer d'autres zones : La limite de @1 a été atteinte. +Please claim this area to modify it.=Veuillez revendiquer cette zone pour la modifier. + + +#### Shared Chest #### + +Shared Chest=Coffre partagé +(by protection)=(par protection) diff --git a/mods/areas/locale/simple_protection.pt.tr b/mods/areas/locale/simple_protection.pt.tr new file mode 100644 index 00000000..a6e0c3c8 --- /dev/null +++ b/mods/areas/locale/simple_protection.pt.tr @@ -0,0 +1,105 @@ +# textdomain: simple_protection +# Translated by: BrunoMine + + +# Privilege description +Allows to modify and delete protected areas=Permitir modificar e deletar areas protegidas + +#### AREA COMMAND #### + +# Command description +Manages all of your areas.=Gerencia todas as suas areas. + +# /area +Available area commands=Comandos disponiveis +Information about this area=Dados sobre essa area +(Un)share one area=(Des)compartilha uma area +(Un)share all areas=(Des)compartilha todas areas +#List claimed areas = +#Delete all areas of a player = +Unclaim this area=Desfazer-se dessa area + +# Errors of /area +Unknown command parameter: @1. Check '/area' for correct usage.=Parametro de comando desconhecido: @1. Use '/area' para o uso correto. +No player name given.=Nenhum nome de jogador dado. +Unknown player.=Jogador desconhecido. +This area is not claimed yet.=Essa area nao foi reivindicada ainda. +You do not own this area.=Voce nao pode possuir essa area. + +# /area show +Vertical from Y @1 to @2=Vertical em Y @1 a @2 +Area status: @1=Status da area: @1 +Not claimable=Nao reivindicada +Unowned (!)=Sem dono (!) +Owned by @1=Reivindicada por @1 +Players with access: @1=Jogadores com acesso: @1 + +# /area radar +#North @1 = +#East @1 = +#South @1 = +#West @1 = +#Your position = +#Your area = +#Area claimed\nNo access for you = +#Access for everybody = + +# /area share +@1 already has access to all your areas.=@1 ja possui acesso a todas suas areas. +@1 already has access to this area.=@1 ja possui acesso a essa area. +@1 shared an area with you.=@1 compartilhou uma area contigo. +@1 has now access to this area.=@1 agora tem acesso nessa area. + +# /area unshare +That player has no access to this area.=Esse jogador nao tem acesso a essa area. +@1 unshared an area with you.=@1 descompartilhou uma area contigo. +@1 has no longer access to this area.=@1 deixou de ter acesso a essa area. + +# /area shareall +You can not share all your areas with everybody.=Nao podes compartilhar todas as suas areas com todos. +@1 already has now access to all your areas.=@1 ja possui agora acesso a todas suas areas. +@1 shared all areas with you.=@1 compartilhou todas as areas contigo. +@1 has now access to all your areas.=@1 agora tem acesso a todas suas areas. + +# /area unshareall +@1 does not have access to any of your areas.=@1 nao tem acesso a nenhuma de suas areas. +@1 unshared all areas with you.=@1 descompartilhou todas areas contigo. +@1 has no longer access to your areas.=@1 deixou de ter acesso a todas suas areas. + +# /area unclaim +This area is unowned now.=Essa area deixou de ser reivindicada agora. + +# /area delete +Missing privilege: @1=Perderam o privilegio: @1 +Removed=Removido +Globally shared areas=Areas compartilhadas globalmente +@1 claimed area(s)=@1 area(s) reivindicada(s) +@1 does not own any claimed areas.=@1 nao possui nenhuma area reivindicada. + +# /area list [name] +#This command is not available. = +#Listing all areas of @1. Amount: @2 = + + +#### Protection #### + +# Item place information +Area owned by: @1=Area possuida por: @1 +# Hud text +Area owner: @1=Area de: @1 + +# Item: Claim stick +Claim Stick=Graveto Reivindicador +#(click to protect) = +This area is already protected by an other protection mod.=Essa area ja foi protegida por um outro mod protetor. +You can not claim areas below @1.=Nao podes reivindicar areas abaixo @1. +This area is already owned by: @1=Essa area ja foi reivindicada por: @1. +Congratulations! You now own this area.=Parabens! Agora reivindicaste essa area. +#You can not claim any further areas: Limit (@1) reached. = +#Please claim this area to modify it. = + + +#### Shared Chest #### + +#Shared Chest = +#(by protection) = diff --git a/mods/areas/locale/template.txt b/mods/areas/locale/template.txt new file mode 100644 index 00000000..bf589766 --- /dev/null +++ b/mods/areas/locale/template.txt @@ -0,0 +1,108 @@ +# textdomain: simple_protection +# Translated by: YOURNAME + + +# Privilege description +Allows to modify and delete protected areas= + +#### AREA COMMAND #### + +# Command description +Manages all of your areas.= + +# /area +Available area commands= +Information about this area= +View of surrounding areas= +(Un)share one area= +(Un)share all areas= +List claimed areas= +Delete all areas of a player= +Unclaim this area= + +# Errors of /area +Unknown command parameter: @1. Check '/area' for correct usage.= +No player name given.= +Unknown player.= +This area is not claimed yet.= +You do not own this area.= + +# /area show +Vertical from Y @1 to @2= +Area status: @1= +Not claimable= +Unowned (!)= +Owned by @1= +Players with access: @1= + +# /area radar +North @1= +East @1= +South @1= +West @1= +Your position= +Your area= +Area claimed\nNo access for you= +Access for everybody= +One area unit (@1m) up/down\n-> no claims on this Y level= +square \= 1 area \= @1x@2x@3 nodes (X,Y,Z)= + +# /area share +@1 already has access to all your areas.= +@1 already has access to this area.= +@1 shared an area with you.= +@1 has now access to this area.= + +# /area unshare +That player has no access to this area.= +@1 unshared an area with you.= +@1 has no longer access to this area.= + +# /area shareall +You can not share all your areas with everybody.= +@1 already has now access to all your areas.= +@1 shared all areas with you.= +@1 has now access to all your areas.= + +# /area unshareall +@1 does not have access to any of your areas.= +@1 unshared all areas with you.= +@1 has no longer access to your areas.= + +# /area unclaim +This area is unowned now.= + +# /area delete +Missing privilege: @1= +Removed= +Globally shared areas= +@1 claimed area(s)= +@1 does not own any claimed areas.= + +# /area list [name] +This command is not available.= +Listing all areas of @1. Amount: @2= + + +#### Protection #### + +# Item place information +Area owned by: @1= +# Hud text +Area owner: @1= + +# Item: Claim stick +Claim Stick= +(click to protect)= +This area is already protected by an other protection mod.= +You can not claim areas below @1.= +This area is already owned by: @1= +Congratulations! You now own this area.= +You can not claim any further areas: Limit (@1) reached.= +Please claim this area to modify it.= + + +#### Shared Chest #### + +Shared Chest= +(by protection)= diff --git a/mods/areas/misc_functions.lua b/mods/areas/misc_functions.lua new file mode 100644 index 00000000..4dcdca70 --- /dev/null +++ b/mods/areas/misc_functions.lua @@ -0,0 +1,184 @@ +--[[ +File: functions.lua + +Protection helper functions +Configuration loading +]] + +-- Helper functions + +-- Cache for performance +local get_player_privs = minetest.get_player_privs +local registered_on_access = {} + +s_protect.can_access = function(pos, player_name) + if not player_name then + return false + end + -- Allow access for pipeworks and unidentified mods + if player_name == ":pipeworks" + or player_name == "" then + return true + end + + -- Admin power, handle privileges + local privs = get_player_privs(player_name) + if privs.simple_protection or privs.protection_bypass then + return true + end + + -- Data of current area + local data = s_protect.get_claim(pos) + + -- Area is not claimed + if not data then + -- Allow digging when claiming is not forced + if not s_protect.claim_to_dig then + return true + end + + -- Must claim everywhere? Disallow everywhere. + if not s_protect.underground_limit then + return false + end + -- Is it in claimable area? Yes? Disallow. + if pos.y >= s_protect.underground_limit then + return false + end + return true + end + if player_name == data.owner then + return true + end + + -- Complicated-looking return value handling: + -- false: Forbid access instantly + -- true: Access granted if none returns false + -- nil: Do nothing + local override_access = false + for i = 1, #registered_on_access do + local ret = registered_on_access[i]( + vector.new(pos), player_name, data.owner) + + if ret == false then + return false + end + if ret == true then + override_access = true + end + end + if override_access then + return true + end + + -- Owner shared the area with the player + if s_protect.is_shared(data.owner, player_name) then + return true + end + -- Globally shared area + if s_protect.is_shared(data, player_name) then + return true + end + if s_protect.is_shared(data, "*all") then + return true + end + return false +end + +s_protect.register_on_access = function(func) + registered_on_access[#registered_on_access + 1] = func +end + +s_protect.get_location = function(pos_) + local pos = vector.round(pos_) + return vector.floor({ + x = pos.x / s_protect.claim_size, + y = (pos.y + s_protect.start_underground) / s_protect.claim_height, + z = pos.z / s_protect.claim_size + }) +end + +local get_location = s_protect.get_location +s_protect.get_area_bounds = function(pos_) + local cs = s_protect.claim_size + local cy = s_protect.claim_height + + local p = get_location(pos_) + + local minp = { + x = p.x * cs, + y = p.y * cy - s_protect.start_underground, + z = p.z * cs + } + local maxp = { + x = minp.x + cs - 1, + y = minp.y + cy - 1, + z = minp.z + cs - 1 + } + + return minp, maxp +end + +s_protect.get_center = function(pos1) + local size = s_protect.claim_size + local pos = { + x = pos1.x / size, + y = pos1.y + 1.5, + z = pos1.z / size + } + pos = vector.floor(pos) + -- Get the middle of the area + pos.x = pos.x * size + (size / 2) + pos.z = pos.z * size + (size / 2) + return pos +end + +s_protect.load_config = function() + -- Load defaults + dofile(s_protect.mod_path.."/default_settings.lua") + local file = io.open(s_protect.conf, "r") + if not file then + -- Duplicate configuration file on first time + local src = io.open(s_protect.mod_path.."/default_settings.lua", "r") + file = io.open(s_protect.conf, "w") + + while true do + local block = src:read(128) -- 128B at once + if not block then + io.close(src) + io.close(file) + break + end + file:write(block) + end + return + end + + io.close(file) + + -- Load existing config + simple_protection = {} + dofile(s_protect.conf) + + -- Backwards compatibility + for k, v in pairs(simple_protection) do + s_protect[k] = v + end + simple_protection = nil + + -- Sanity check individual settings + assert((s_protect.claim_size % 2) == 0 and s_protect.claim_size >= 4, + "claim_size must be even and >= 4") + assert(s_protect.claim_height >= 4, "claim_height must be >= 4") + + if s_protect.claim_heigh then + minetest.log("warning", "[simple_protection] " + .. "Deprecated setting: claim_heigh") + s_protect.claim_height = s_protect.claim_heigh + end + if s_protect.underground_claim then + minetest.log("warning", "[simple_protection] " + .. "Deprecated setting: underground_claim") + s_protect.underground_limit = nil + end +end diff --git a/mods/areas/mod.conf b/mods/areas/mod.conf new file mode 100644 index 00000000..153a2a33 --- /dev/null +++ b/mods/areas/mod.conf @@ -0,0 +1,4 @@ +name = simple_protection +description = Easy to use fixed-grid quadratic area protection mod with graphical area "minimap" +depends = default +optional_depends = areas diff --git a/mods/areas/protection.lua b/mods/areas/protection.lua new file mode 100644 index 00000000..fc57233e --- /dev/null +++ b/mods/areas/protection.lua @@ -0,0 +1,148 @@ +--[[ +File: protection.lua + +Protection callback handler +Node placement checks +Claim Stick item definition +]] + +local S = s_protect.translator + +local function notify_player(pos, player_name) + local data = s_protect.get_claim(pos) + if not data and s_protect.claim_to_dig then + minetest.chat_send_player(player_name, S("Please claim this area to modify it.")) + elseif not data then + -- Access restricted by another protection mod. Not my job. + return + else + minetest.chat_send_player(player_name, S("Area owned by: @1", data.owner)) + end +end + +s_protect.old_is_protected = minetest.is_protected +minetest.is_protected = function(pos, player_name) + if s_protect.can_access(pos, player_name) then + return s_protect.old_is_protected(pos, player_name) + end + return true +end + +local old_item_place = minetest.item_place +minetest.item_place = function(itemstack, placer, pointed_thing) + local player_name = placer and placer:get_player_name() or "" + + if s_protect.can_access(pointed_thing.above, player_name) + or not minetest.registered_nodes[itemstack:get_name()] then + return old_item_place(itemstack, placer, pointed_thing) + end + + notify_player(pointed_thing.above, player_name) + return itemstack +end + +minetest.register_on_protection_violation(notify_player) + + +minetest.register_craftitem("simple_protection:claim", { + description = S("Claim Stick") .. " " .. S("(click to protect)"), + inventory_image = "simple_protection_claim.png", + stack_max = 10, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "node" then + return + end + local player_name = user:get_player_name() + local pos = pointed_thing.under + if s_protect.old_is_protected(pos, player_name) then + minetest.chat_send_player(player_name, + S("This area is already protected by an other protection mod.")) + return + end + if s_protect.underground_limit then + local minp, maxp = s_protect.get_area_bounds(pos) + if minp.y < s_protect.underground_limit then + minetest.chat_send_player(player_name, + S("You can not claim areas below @1.", + s_protect.underground_limit .. "m")) + return + end + end + local data, index = s_protect.get_claim(pos) + if data then + minetest.chat_send_player(player_name, + S("This area is already owned by: @1", data.owner)) + return + end + -- Count number of claims for this user + local claims_max = s_protect.max_claims + + if minetest.check_player_privs(player_name, {simple_protection=true}) then + claims_max = claims_max * 2 + end + + local claims, count = s_protect.get_player_claims(player_name) + if count >= claims_max then + minetest.chat_send_player(player_name, + S("You can not claim any further areas: Limit (@1) reached.", + tostring(claims_max))) + return + end + + itemstack:take_item(1) + s_protect.update_claims({ + [index] = {owner=player_name, shared={}} + }) + + minetest.add_entity(s_protect.get_center(pos), "simple_protection:marker") + minetest.chat_send_player(player_name, S("Congratulations! You now own this area.")) + return itemstack + end, +}) +minetest.register_alias("simple_protection:claim_stick", "simple_protection:claim") +minetest.register_alias("claim_stick", "simple_protection:claim") + +minetest.register_craft({ + output = "simple_protection:claim", + recipe = { + {"default:copper_ingot", "default:steel_ingot", "default:copper_ingot"}, + {"default:steel_ingot", "default:stonebrick", "default:steel_ingot"}, + {"default:copper_ingot", "default:steel_ingot", "default:copper_ingot"}, + } +}) + +minetest.register_entity("simple_protection:marker",{ + initial_properties = { + hp_max = 1, + visual = "wielditem", + visual_size = {x=1.0/1.5,y=1.0/1.5}, + physical = false, + textures = {"simple_protection:mark"}, + }, + on_activate = function(self, staticdata, dtime_s) + minetest.after(10, function() + self.object:remove() + end) + end, +}) + +-- hacky - I'm not a regular node! +local size = s_protect.claim_size / 2 +minetest.register_node("simple_protection:mark", { + tiles = {"simple_protection_marker.png"}, + groups = {dig_immediate=3, not_in_creative_inventory=1}, + drop = "", + use_texture_alpha = true, + walkable = false, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- sides + {-size-.5, -size-.5, -size-.5, -size-.5, size+.5, size-.5}, + {-size-.5, -size-.5, size-.5, size-.5, size+.5, size-.5}, + { size-.5, -size-.5, -size-.5, size-.5, size+.5, size-.5}, + {-size-.5, -size-.5, -size-.5, size-.5, size+.5, -size-.5}, + }, + }, +}) diff --git a/mods/areas/radar.lua b/mods/areas/radar.lua new file mode 100644 index 00000000..b916764e --- /dev/null +++ b/mods/areas/radar.lua @@ -0,0 +1,128 @@ +-- /area radar +local S = s_protect.translator +local data_cache + +local function colorize_area(name, force) + if force == "unclaimed" or not force and + not data_cache then + -- Area not claimed + return "[colorize:#FFF:50" + end + if force == "owner" or not force and + data_cache.owner == name then + return "[colorize:#0F0:180" + end + local is_shared = s_protect.is_shared + if force == "shared" or not force and ( + is_shared(data_cache, name) + or is_shared(data_cache.owner, name)) then + return "[colorize:#0F0:80" + end + if force == "*all" or not force and + is_shared(data_cache, "*all") then + return "[colorize:#00F:180" + end + -- Claimed but not shared + return "[colorize:#000:180" +end + +local function combine_escape(str) + return str:gsub("%^%[", "\\%^\\%["):gsub(":", "\\:") +end + +s_protect.register_subcommand("radar", function(name) + local player = minetest.get_player_by_name(name) + local player_pos = player:get_pos() + local pos = s_protect.get_location(player_pos) + local map_w = 15 - 1 + local map_wh = map_w / 2 + local img_w = 20 + + local get_single = s_protect.get_claim + local function getter(x, ymod, z) + data_cache = get_single(x .."," .. (pos.y + ymod) .. "," .. z, true) + return data_cache + end + + local parts = "" + for z = 0, map_w do + for x = 0, map_w do + local ax = pos.x + x - map_wh + local az = pos.z + z - map_wh + local img = "simple_protection_radar.png" + + if getter(ax, 0, az) then + -- Using default "img" value + elseif getter(ax, -1, az) then + -- Check for claim below first + img = "simple_protection_radar_down.png" + elseif getter(ax, 1, az) then + -- Last, check upper area + img = "simple_protection_radar_up.png" + end + parts = parts .. string.format(":%i,%i=%s", + x * img_w, (map_w - z) * img_w, + combine_escape(img .. "^" .. colorize_area(name))) + -- Somewhat dirty hack for [combine. Escape everything + -- to get the whole text passed into TextureSource::generateImage() + end + end + + -- Player's position marker (8x8 px) + local pp_x = player_pos.x / s_protect.claim_size + local pp_z = player_pos.z / s_protect.claim_size + -- Get relative position to the map, add map center offset, center image + pp_x = math.floor((pp_x - pos.x + map_wh) * img_w + 0.5) - 4 + pp_z = math.floor((pos.z - pp_z + map_wh + 1) * img_w + 0.5) - 4 + local marker_str = string.format(":%i,%i=%s", pp_x, pp_z, + combine_escape("object_marker_red.png^[resize:8x8")) + + -- Rotation calculation + local dir_label = S("North @1", "(Z+)") + local dir_mod = "" + local look_angle = player.get_look_horizontal and player:get_look_horizontal() + if not look_angle then + look_angle = player:get_look_yaw() - math.pi / 2 + end + look_angle = look_angle * 180 / math.pi + + if look_angle >= 45 and look_angle < 135 then + dir_label = S("West @1", "(X-)") + dir_mod = "^[transformR270" + elseif look_angle >= 135 and look_angle < 225 then + dir_label = S("South @1", "(Z-)") + dir_mod = "^[transformR180" + elseif look_angle >= 225 and look_angle < 315 then + dir_label = S("East @1", "(X+)") + dir_mod = "^[transformR90" + end + + minetest.show_formspec(name, "covfefe", + "size[10.5,7]" .. + "button_exit[9.5,0;1,1;exit;X]" .. + "label[2,0;"..dir_label.."]" .. + "image[0,0.5;7,7;" .. + minetest.formspec_escape("[combine:300x300" + .. parts .. marker_str) + .. dir_mod .. "]" .. + "label[0,6.8;1 " .. S("square = 1 area = @1x@2x@3 nodes (X,Y,Z)", + s_protect.claim_size, + s_protect.claim_height, + s_protect.claim_size) .. "]" .. + "image[6.25,1.25;0.5,0.5;object_marker_red.png]" .. + "label[7,1.25;" .. S("Your position") .. "]" .. + "image[6,2;1,1;simple_protection_radar.png^" + .. colorize_area(nil, "owner") .. "]" .. + "label[7,2.25;" .. S("Your area") .. "]" .. + "image[6,3;1,1;simple_protection_radar.png^" + .. colorize_area(nil, "other") .. "]" .. + "label[7,3;" .. S("Area claimed\nNo access for you") .. "]" .. + "image[6,4;1,1;simple_protection_radar.png^" + .. colorize_area(nil, "*all") .. "]" .. + "label[7,4.25;" .. S("Access for everybody") .. "]" .. + "image[6,5;1,1;simple_protection_radar_down.png]" .. + "image[7,5;1,1;simple_protection_radar_up.png]" .. + "label[6,6;" .. S("One area unit (@1m) up/down\n-> no claims on this Y level", + s_protect.claim_height) .. "]" + ) +end) diff --git a/mods/areas/screenshot.png b/mods/areas/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..f2885ecc14033ff3baec5e23c179c7b30e9b8df8 GIT binary patch literal 101102 zcmV)xK$E|TP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBU!{ZLF)MF0Q*NMV8yG6x?~30+(;A1phT2LNY@w>wZ8Ym65PAq6Bd zLe9?1G&&1DP$y|$IIFO>wvRLuoC-Wd3~OsMSYr`THYhi28;W{%YLGxUK}{VX5=3Mu zS7I)ba4IV*8bCM_nZNEfKp|gmHaRG-B7FF8g> zS1K4t2}m|6BOw+gVhoJA_*g|Y=j-vQmX2a%F)=C~IxQj@90f5$8A($ROlvQAVmc%$ z6iIL*2EYSpb30>?Ej~0UFEt!;a(PHA8E<<@SZXhQqd;SFKw*I%F(n*2l@>uj6ppTO z6@Uw5Q9*ZfJyBaNV`OKUeM*q7T0BT2KSd}^Uoa~;MjH;1wGpO&QAk5E zAzMj1Fg717Ga5onC{bKDSY1Nm5=(K`cOM9&md? zYIr>=FbGv}H#18ZMo}+CX&_NOFY)yGG+rM>Q7TblEMQwcPi7cRSunD|)htjKe2%9z zDj*kY`8)ss010qNS#tmY5b6K`5b6Pf(+ZdX0f$aWL_t(|+SI*WXd`F3E?SwJzz{70 z3l?Ge!ap&sAi^M{>L7W0lY%8D7jr~!M2GDj_OMt-^b%saJ8R1qr)q`-lW{jn`Xboa zJt`6!*+m(tFLYY7&0#L~h0BPQ^1fIJXU;JpU1^O|lMHi{?JhOC@GxROU;U{{s*kd^FA+?ur8G6#p~9@z{US@!=K&j&VIKz4|(0eD>oe`d=4wno2a%I6dCyHEcoI{f1vxGBIH^f=8vr!nDu34w($FW~>8VL>?L zT@L^Bg1r5{L!&^LaJ-#_2kr*`_`!q2Kse<6jRN7YPh%(ueLkg7W@HK=9EHxHAoO~_ z(*mK-_c8zoy}l8?Ahe<72OSHlKDcxLGW41HPxFZPHw=U$Jx~ZkNR65C(L@ z7XZSMj|~IDgug{j1V3ZLLFnZgJ)=E85Dt6j;1dsdGebc*ECvY;!oVkI8s0ddlTJ`$ zfN=DinGOhjo+>d4g#&rS5D+GUq#Rz?{qF1u!clL=7lfk%;V>W!5+a5Mp$|a91d1a; zm>3U)!LS?5h7ZIqfk4>*upuDya+M=MIONWW(WWIB2opi9XPDiKZjfY_&3!{jSa#vP2tA+ zCqqvBSRnLFoJSWl$gg-eqe1A3Lw!Lw(s%ox-e4dc8Sn-!r-sRusR_LC1Q~Nch`sXh zvu7_n+6V%|^*?xmaQ&4;;#KmGCkQ`WH=g_B7s<^Jp9M)qf`gDUUOut@!Mo%*c^jh& zghN0WsAiq$_W@zDq#${65Dbp`f{z8lz-7N_7((a0Us-=;W8;%ge;wpYF#tm2Uh97& z0C?_QuXjyRZ*iCeUwIYy#-rY%-di_c^p|f_)U$`r zy-V))kQl93^(QhAZ9c@j?ZrWwQD?xX(&=6iebA$d;yk=DD!pJKlJ-}D0;cpGoL z{p^Le^qY*gogjCn{`JN6XAg-bUVr;T56JnXCxamLH?c!tHafBj1j0n{RC)Z6a1^eZ z&9L5hWG4H{`fr}se|`Ix8{M}b;VgdK-S`+7c;Vp(pTB+OH;MJP|MdBDSN`^!zpei% zL2Q{5gdcxm9RAyL&pi)+`0U{aA2^=kFVFt;o4@_C2f~djFTJ(?!Se}nw<~`Ils<5P z@Z;_WZ@-YRZu=02KgJ7u_=5AjeR$=A#Fh0A60cl&&U%-IB_uEZwtfKb>M!emqW8w28hs^3d}g41~eL`%xeq*`}KU2!ln5%}9ir8VHTc zqi4_Q_j>ON`RAG8Wr2bBo_$WvHbD5n=kRv;|CK+z+YdthMB}jG4+)+VulAneL-Lf= z^M80|z1DlruKe}6gmJg^=iMOugnIXtDoT(?`^&za)R!E9=I4J6Zo6hWo{L zAHMRr`4Ucd{5d&*C;IRi0)uy-*Kac4Htzfvz!_%rc^sl%_|Q8O3fVXbl9vb0F^7OK zSUx#PNEon~r(c#5k;XLA5*G;HHoV27kBQq`|Fw=FAo9@*0H*;$oZ?sD#nxYZz8{1? z`Sfl5unEE|&kB)@w#MJuVUU~SpE6+ds)AQy_I6?R>Ie;g+^um>guNZ&4@wRmkK3dl= z&*9LO^*2I-kQ&~T7{d7(2ZR9=;HiX!p(@JyB@$^irfdk|EI0JWKYaUh7lHuF9te@V z{OR+z2SE6T^+%s8J!dOM$f+p`CT~;iHFt{a_vcz1ssJ)el07`rDtbJR~n?zdr&(e94}B?zz9=FWGn@6bOCu z6JHP}g3*0~P#J=98A5|FL?QUXy)kv^*(3e&uRQxap&KppY{IqmKnPRx{JYNx+9=!E z;^!}k^?cR?q45;dh65q^k$BezA<#q&p5v81bc4{k?cFy%e)|&j;-`kgwU54H90jU} zf-v#!U!Q$|m($4yyz7*An?@Qt@NHemZ+Sx-1Xm@v`|@=DKMe3v|t6NCxtUA(&f0x9ko`NiN-C(aYr z%bOs4<1M_?v@l8*r){R}4Fe)jB@D=$8eW51+6dHdO? zFBvi6r_Zju@q&K%A$i=Z`cv2l`N_vuuDtlKI<{OO?4sa8(Dex(_L2jH?~zwE-$mlt zOR&=G?-_sHz|jrkT^fIl_3|bNfAaCO^@q=YuDgHo{tOT%UVQgb>APxirclwSfu1*}<9J|W7 zAbjPo4_~Q}M^XXDSp3N0=xtMvI>d4nUs?55iyt>d<+~sPFwWyfI@G zXhIRKJyG@2OUDy1`iH*%srcj3B-fxUzMvo+%J26rs)Yxkr>U46gaMt;G`w+O#Z zK%*PSA;mxsOnq@25`>AsAPnNR!h+BX;bEwxQvjiRHegH;QlUoQ!^h7T214EXRq-R5 zC>kw03xrMMx8>zVSP-&uB`g^%BnSgNH5CqpBZ&Y*0+XTOp*%~39w78XT>uaU z?;!+CiWhB(ejO2OpiBpac_z^};q}i0h zIM-NgC(O4iL~1hX9z(z1i9{HSkQf$bB}S#ifkEgwgAxFQ<5jH#ajB;W!eB9_*QswV zgIG-@dT(st3>lfG`ng5I-=T zW<+&*BBnnTsJZ3|tB67GC&|d08%RqckvIK8=#?6OQSkcf#xRA6aZI6aQ7NoH9#VQ6 z1wwy@jPs3!2I1&0Ll{dKs6{emZyZ>80j=YWjmC1LvGL}c8$hADu~dwN@T_#t5C$ps zg+gIC5Drm&2@k?ywV2`kyTJ^E3Jt=c`A|p@jxY)r0K%{x6lx8)+rTAqe7pf50)t3Q zn!!Ps%?d*)jXp`lwEeNihdTuj`c{O8(_b8N3yIJm3@ny85`@7#(-cF(F}rvawcG&e z0Kz!_S&l>+fMY18b%CZwG?s@{i>K|66G2kIQ9DYxfg~Ne(0U#X3m7}PjwkWhfX2NsaZcGq{ z=-*A0mjp{w#s^_TR@LPQV!}`C%l5XfH~!-vclY-8uV0^k+G^<-^kP&`3_`z7@kBwP zuT=<~nfT*kn9`eH(P%Od2Fp+;1!2hc$k?0|9d->G{~#b_+2-ETl7D?>b$54nW@e_m zxcKG#t`0(Tw8SDOP8o&XO_+&-Lf`W=2?)JwF&-cskt7EI;YgxSSP%|tt4#{RfGGIn zlY_=)qd|i?qc*qL7BKk!reAJ+^XAQcV36m_JfG})F-Fra2!xb(&1D+?c$ z96osoAl&V{&&nRA8vlC>ot3hg58x4hW~aTr7+s-1D@A^ZTr-?!P%x zR*#PxGgjpgUAr`}CnyoM9m!SzLQbeD3gzEMDZ&+N(J;NcNlc;t&65R%BhKh|0>VIa ziJ&0#31YrC5awE55IBh+4<1w%u(?3@Z#0_`nr@WVP{EO9!QT+V6Eo2wnVO=$Yk%zb zVNDto`nuuJAWQ@V;RsUe1RxCDI|-%Q-*;;@z-eo_F~}#8<(_cfpo%E5Y$Q@3bpK|g zR07W$w3=+z7lc|gDltry8MA{t6@NUMLPv#^?jITpP8Ec{&oUthClc`w210Xcj{H*{ zeP(A)sFRbEl{Bx^1w~280?WzrW6x97AWZ9+&h^LtD$Qmin{Dpw_?}vZkt8y-!Z^uu z-Aq$c5N_d~Ohi9tAIy>W05 zj!28g0%2f#KSdA{E2tNU2MwXu*>02EA}?1eS-D>SN>N!>i2HcsY*uN4X}zp7t?`3^ zFqQJfpeAWBghxk-gy%RIMR|8>zaxJfz)>dxI=A5s)kH85CK8F!wV6;L3_?kpJ_t<= z5)dYOme8<@zMnQ*D9A!Ao6Q#5Z6(IhB|)fpo{}}4X$?w4BytSaKZvfXy0(@Y77<2| z7^xqG!>!(T=Z{BGW~fn{UIM1Y{!8tLmaHcL;ppHnNKJmCyhM_!qS!ki9TBrAioO8Y zNgZbep-?F(1x}6&biC$Mav`%O=%Yk*y8rSrXkB2t9v}M_su|=YBq$^#*I$gY`JMVs zg2ItC>al`CUq?L9Kk>_pLxV6xh7uNpVOsQFXNVDpgK#IC-PtK90$gp46}sGGMUXvF z@+L8YsLw>ew3hKBqO$qr2?_X&&mC9VmL8=LJ)d~ zgOh;J+mTEP!cg9LREVgFqJ|4lD0ylp2$f0+HjtHTH6hDp3!ETCy$vB5`E1BwT4(c! z1)Hk+=JK(Bq599~=L?&gn|JPP<#Np4>J*l4dq=h39SD8NQr{B@gT;m+S|{N^7?8}M z-!6*86l$=9RZkFR6*{FT9GkBQDM82<=$cQIhq5$0a0BqeH4axm_s{z`OaA=+!op8G z(azJSy9~41njQ!f!}=i83<`sGNL3(FrsxSmIiEk~@^M8L+Ond^ zsm{WJHwb|`b(t`&Gw70-OzUES@h?>GYT8ZalJ+FJzYjQ$xA}cc(ew-T$3raOq#*Qc zoD9pjFA#*|wUNC;LQzMdSgclyMUUDwRf|`klOQ~<6xxDPQ8If6cPMXGjZU<-nbyrF zgPt(sPvTlBOVXmIb;}I;fXSI@Y<>?`JnXyi0)oPk1;VL-FbJu2x*!~mV3mHz(r`IZ-NuwAItx^h;I$5o}orZ|4) zUGns}v-C*)gu2hir&?ELwo)=zV}JG)N@&u2cL ztv#+4N{1}S3-V&Q4j_5LBNi_omr$s7QyZihBQTP{Fj}<8u%O^*8qXA&DD^`EVZdhH zNZGUiP2-SaNEZge#I#g{Ck_cQAlK=fFYM0m{(k@Z?bhzRSGy#eUCd@VS;@%VxGa|{ zZ8rwv6+y^kct7rRl=Nc2Q(%BRmSyD_Q;d?1aS(t_fI|1}ll$Y5E^6$|WJC>msvsN{ zGkh-~-0keG&d>j9e;*UUiA%BQp8Yv+YE+d5tp>y{7LAmyaOskdAw=+p2@()xv=qY}s`YdlZ2lw3 zzj){ZQcx6*0m32n!Y;03N->ej)P<`_|t ziZM~_7E2;0m*lU!g1^{KKC5I=x2YjYq~j?zomTxY2)m~p9U&D#O_0UiIoQD?Mxv-- zF!VsubWGvUTPHPz!`RCg2g0F2=l2alzw;P8B;KYgSWcE$;m)CN|htw zOQ4~KT=m>5_5%fB-^Yx9EuubO0Zo6fe8&{apfi-TQk2uQ6r1vzl8X^eO*p z{9*}fYI>&7?~VhvhVjQkpJ?ECC=dqLp&3Blu*uIcKsdC# zIRb=3Kj2YuP)q?+A3XgmII4rAN^D)ziggK&xKt8FPAGX|3zQlz4|z+PZf9$PkmoO5 zDpUR-ymPR%wF!;j?M~;TUvy9#-#))aQPVbs0q!(6=obQkaBjH8bsS6tlxZCq8`|Wk zkTdWX4npUjAIy(D8axZ_9T4@iI!Brvtn8&YhC}Seh$Wd5MU|FI-kchxR(kCv0zf7! zq`T!yU7rT=0hFol+_|H(r?=3KL23K|?U_w#`XCH|!r`~iO#nj5+Y^PFbqX-tN;Dn8$oEs0DG&eo12}^(_K`?!M}Nb^ZcBmzJF6V+&#MvjSIrQ zBNq)qODcS6X=4NWXu&}kyf7OQgm1m^#v5<-J=@tCThU3q)3k&0=ytWb-D&ORyt;S*smi=`tQ|8P!^G+N`PDlezld-iE#qBnC3+JN zx<23O%rBrtI8RaEk0~4%gnpm5SLreY2;IL<4#IEEXVM|)0O7#P`r7L0fY3hr-g_T< z7(%g@A|z>pBR!b-9xy*=Hkm(bAkjRo}E^ zg;`nD7NG|GBzp7a-v0c;?(PZoeSt8%KMnvwkMlSd2;FhOq#$f=Z1e}a0Ro08gYc72 z{_@FB`aWc^1$C0NjPf!l(tCrTsWQ<`?axw6>s0StpWpkv7bcEss5O6ad@PWeb-}h;4V_(-T!Vt`1th|31X{*K8b&@pUNM|wwAly5u9;`C+#ozBs zVAR~k=#gjjxh55(az#oO`DmNYEJBWd#v43GV9#{fBT1IJQa!4oMaXg)a3H83s3{B- z6pjbNK{$j0p+|=5iczfxEj5~r9{>n{etxib@YA1fZvOfF{eBScK3x+YvoXSv78IKG zz}GzRwO^bm7o$%Atr@RYoEBpwO)nC{$3_d;F7MYZp~0Rmg2FG*#Ud1El**dSacZGJ zQPV)-R8o`a`Qy+a^l-!hKsbO_*Aq2xb?E{@=o*5Xt?GvcZ=iBpcfb(bBrMg1{p;?J z7;Hh7t<{nSKb0M)K8#b$p!duhsqUxq4hDsDhs=JkF>d_#)I( zk<8sytAbFkdv$oh1dK+%_`>B=%ZkkNDkhUv9@PJCyAhhkBn~5x5oxOV1xU-v=C!|<` z1w&Ba!4T|E0OS&#;_LA*6byPi<_FCj=q?D|oWpT3RQZen5x&TDK?USIp;aoO%g571 zCaDXuRy|dcqrN;DV3osG*rqbzhQkK(v-PaIyX%0=p9hk!!P3L!ZK*@pNTu()+1yKsYxg5Ng`2sLjrbBS2UJKa0?_T%TK<<}p`P{z6T|RB;1= zo2@xW_%x8c^oakCz^DN?KP8o-OgWikInTvlM@Ngilqt|Ow2(-gn0)-0V~+eV*oCkX zt<>_R!$TzxFlLXB2-YOYHBByQMQ9npsu82+{(ON6SrplrqH?Ne>#|xGz|YnkWQ8Q}q2Iv zu=?=$Z|&lR9g<+0Tm{B_PgcgSAm~Q#_HGLmRw_L6-*8S=GLY5IYE?Z+T zcv8UKpqNyv$p{KZrNVO;=#M9%SBGPB`C7!$5VNoO-_Ls546bHGZ6XlDieANkZV*Dd z4Ir!*an$9Gby2tMG5A@)Q$Gj=krR~+rsnuT5Q0tv%|U^S71}f^Hy+*?1ZeO9&(F6{ zKO)UQkfJ?twVBK1I@q3_yS54S>Fw70zxaiZdLaR!j1squUQ30{!$Xn*(s7R;=aun5 zIF>0K(;r_f2m|)*hUdtxhh78-p_oN1VRa7bMXoLfk0-=4`l+;N5gus-OG zRY5WJ-qsXB@q!Il`0o>m8c=F}etv#HNYP$6=-dI_X6v<=UfMlB|LIRV(9c{2D19&p z1VXQ{LKGPw3IYuBMVdaOO)b~#g_y$c${z>fwSFfcJnXvs=r|zM!^x}oN342-un#KR z2M4TjNbuzTaBpFp!?0zi9}TK)@ibvFv~?;&Ddn|Ec60N60>aM0L2m2(I(S{)qJ*7J zC%3?Udc68~f7fbtI=fGIcU!*9X?@}ewMYD4OEPQt51d3b!x$ixr(p`G>5s<@3aQcO zI{=w$LJ(HRu!PQ&f4)Va)p3ntoaeT;H}8Oz?B>SjFtCx!$wCVHfqfpevxjL80wWzn z12tply~Rwqx6I+HM+~=lzMcEyAOF3Bhi^RvudB1?g@T3M&iwrTOUK7IpWM9p1Z=_m zz1`KPei$Tj3``WG@Tfn+7&0nRs43=+SJ&FqcVY@d6b>)iA72azmAN?wPImQ%M|Czt z8Ix>N?>vP~X|=YT=4qj|&}vop?&NZ=$gH)xx^TTJC~A!Dm&)30ZFM#mR(JRIug^d2 z2cgPB?=2aJ-W!p7>+CTe7LGi4cMlKWf7$^E_dG$kvhrl{$&)XR7Z(>VUAi>0LbRuM zcYQ#J3eJ&s2<+iXNoq@9F-*R|1c72DbJ+p|$b^ApAnEq!u%oOUZJ1=JnT;GeZnvl+e3WNfHndVi^ie zOH#pTa@T4S^#d@47aJ4~rL|5AgzDVf{>_z}y_&T&hemHG5aQurA*{frIR0wzk;~=s zla-a(CoW>LepJcESVE0)eSXOqV>xWPo+PY>{+h9njV;=8Z!;@{XIFnPc{H=Qm?Es` z6)y}dmdlIDBo;4r7t5Cn5YEiZ_!>eK62TUW>+|pU5BZ67RFjS@Gx>u9AvIx87%n{y z2||)Ph@K!6=TuH%-5}ILfsj*FwNe)a*4ZNyIZoh3%%;z}^IRNd#kQzH!Kja~AkrB zkot^n{&dYuJtbinIm^gqY1}z^^+WW>lLUouoOt;PEMri|y3qRJYqrv3NT&?}I_Y$)4E;b#p|Tu zLS2w4oC`ba8HUa^5t}P`-_8$&XrkF5ocr*N_udn&=2uNg0`tb>IxE6R#SR*Y1g$oqz2syxrivMRfq#Y~$JV+yGJfiBv28n7C+R#OC)Ru%9X z25eO^8C5g|Qe5B-CNnX`OL4!D%quKgsOX$%tUs>sK9uTmIjg4AB~?|FcwDfXA@IdI zBNiT*P#zeqh+R*`8dJ22?$IbUq{8M4%^8Y>f4r_9|d}MMX*SDp6j|nSOqbr6srj;_@aF<kU z5gc-y!qv-Nb+CvWmGs?qL_Ldd?|8L-g;K3hp=lwjbD|ZcQuncWES5eAGFvZ|)C%6E zD$o#TjYj~}SxdzQ5Ju@fE(7$nR5_!jV(Qr$ zt`B%hsi?s;VYgis1nPpKcp!#T>(Hqt6H*2zT9&&RPoT&$R^$lXG{?tcu{z5lU&(a+ zxm}cm(G~-Q5;Zp+6ow^OPXt10+8_*AoiV!==hf|;)uP(!oa6dSR#rd@s9D=08ruiE zsQd0Z-+^Al?!CwR_Xj~(B>$-7a3h4}+**ADIkTW?CTp0s7-W1w(3NP&fd>POiFe-I8lTM`L%jV}Y=sw)b)i zwunZjwYysN0AVlnK#vZMxy=J-m`A$8lx_t%Fu)p>c||yc(osLh zdixAm)?o`YuI>&Ddm?Am7=5=L2!Z*0#RD>3y3kE!9}7q|+Bzq?TlNMa5T|Ky$VZ15 zni62;q(vs>FAuDb_?howdLX2}OMg68W-=`hYA7JHqL~7~H_BYfiU|d^P*0uM?h4Hd zKII0X-bv|!aDRX0<_YP*Ic!*~T7{BYuI293EnJ87MF+XnT5!u1ZJ_{77h;)gr55Wm zWx(sT+`&1KOC?IF1Ej6<`=_8sTszQmOs7@zT+69;Sy_?gLkOk|3bd-Z4IicSWK`k= ziR&IIQHdqg>{N1?L^VlSB(q}@4YK9)yEcX66=|lF9-DmEVIahsY82_rlo0e~xgN6v zs4SOC+fb0#PIxh?4S=xs7Wbb#!8(zdCr-V#B%uS$0-Pr^F51ef-a#hR1$VDkg@kzu z#UZ7j^s&0C=tq;iVcQ2=Ul&%uSs=vn-g>l zbJM*+bpk>RjeOHfIKVuWWwhW}&RGc-Ztu@Nabu7oUVr6@-b;2JzrByeuKAsOEH0Fk zOg{+i#bJ<29RT4Sh=%-`X!^oqFL zV5+@3AxhVJ&DkG>nCes%QLf95cn$qyGVv+Pu2h$2>!}o)V|BsZ5H8Q;ONDYRE_8+d zHFK-;`;4(T>`4y%t^wQ}>_WJ5_x4YTr0<^hLhS>S;!1Xb649lDPRkP^2owNR$T9tS zYk??L9~es2ei$T^0H)o|-MMoxE(oV>3MUB)r#tv=T+i*Ix-tktQaG`yc^YR|3lSO$ z@WWQPB+6M+_= z`uVvxuv(j2TX!~zWqp5vko^Jc-K|w$Lr9`q!=e({ZUx%%IVDp#p+6p_CpmQxrUvei z!#DiEG%1^ok~MY4<6`qjM6gt7MOf>V`1G1}?;U1KSW2U4g`TaevwSy;S~to(tQaS~ z;%``Ip%*F}Ahp2S3S7OfjTVpDx_Fvr8=NJR!H4C6igK%rxZtiZ9VxO%HKEHn(4KumY10kF{5{n*LL5V2> z&1SFKM^dRWpT+o_Yifz~ivQ*Kop(6f1w$65DTAd=68(36d*M6@yX0dVg0rHL$lXQAsecG`DMAWZa zxoQuDb+shd6?fxgb+^}LjVTJ$5gfxyDL$3S3dBA-&0neXFYi2hhv;3o!b82htWzA^ zH5qqLSp@Sy)=DLmkV|WvFo;1d#*1A+Vh9&YRqKN%^hD>!>IB&&U*`E_a?zW(nw&`{ z37eMaf|bkNO9X`beq?`Yw>Jp@*shez!9X~6?`}*!*XZNJj)h|Q`+-pK10naoxV|Fs z;)(^rC)L%3UCo*?fgyxOuIz4{%=bVDBPqktZJxVqPQ|c~PD()f|9Iz}N8K*x<_rjW zUs)`Q=q9_dpdnf3WDO)OE#5!uc`UdG-Fc~~N`g>KMWZs0h1wn>mi45d^JA4dNHGwB zqXlp7LY?Q!h!w!<(;RP#f++hi;@;m&aM~^@k<(+1#t`lrvN0IKh#Zu{bDNU3=SaNee2q6bpz(9a3 z5WOUAa4Ozo_oq&e#Zty}Ity9LHl59S6IZ!Zy^fiySeIp?gQF&s_y+oMZHOdD-2x~P zROiz{K}b!5v~Y3S{S##-gP|e#O2+Bt&c!pacP9gcCQK?)wg*C0BHBZicTFy)x@f96 zYSyCo&Oe^m2b63z*3r(LP2g%3t-ESf<{Za5_fL(E#(}FgSJxYDI>Djp_Mrm!uh>n8 zl@T5wtPl|-MTil-q(i1Sa5jlx98@a{_%6utECjvQ`tE>(DNkgz4-ZR-Uh&Low=0xN z;8=i@t@?rx-zo#lFrBO($PVIU0*3XdyG-hjrvt*_EfZW9Xwxa?^iryh8(L-Aw3Swn zn+v)ymgP9{OVI{lI@87Qg^dDwjTPm0{zq@)T$_^wG)`_hPN}Bt3Z-h5l^u1s*=m(E zkYOY{?kf(`B2Rd&09$B3ujf~waQmM#|1X3m7Q$+984}+>|VUUXP5P0ndcD+-Q3LeWJ2M!8- zkAxfdq~_X!8Jgwnde;5zbA)#0`IKX^yxC_X?GqlQW+PXyzU$>wisMtx#!3A@IY0>J zok~oudhdqxapwI75#e2oJw@GG^H7Q750c(DrZp%Oh`MOX9nIN{w4W;FpmjLcz3j*t<% z>Y+D?4r34phB&$asZN#*Orc&Wq>RY`6Sia&pcD#(7jFv34GKMKK7n{NLkRw=8PV`J z>n4K~B*I+BJh7z0XN`zewX-Upwm=9((yR?hXcAo&A1k71GJ7C|^VW3jOBV=bEF5N? zoIhQn8m;0dPn@&A)rB1Cw(X+N*0(kXJ4_Y`8=*s*Vtpzz2nN{{O5`%jXUZ&79SrPZ z$DnHwdbUnoWh)gg5O#GTVIt$oNxHTST)Q`j>UD?-E2u=Fp1@%&hE5^9s+-9kLtsdj z<+1)7cBW_w$MwgfK{#DWF86iW99CjWqPcwL=FMuIH$ek8QfSZG$pgt9?8vT~Ww|p8 zE?V^}_Ga2pJFY;p4gb?Wc%nP#2BA1Bi7vrQ9fX2}uCen(qa=5dTv=QM*K53#-haB|Jv!<*|Y}l9D0kd+bfXB120sfY8N+h#^EhN$r-DhmMT`kC*Q2agq66yl zPL*>}2car~u;|J@$|%UOvI&Nr&1qZ&2p zGQKICsy_~v6i*X`eXmgxEY{2{_6l143Di=Ag83n?=7?I%bsGn0jM$YIqOx`1Xp}r6 z#)#M=2MG0wU(w+mOQo2=DvBhTLcy3UskV5OkW81kqxVm!t_z;l%zpkX^hOaYF0h z4gF$VUs~#zIWTB6^ZODZeITrZfIwacvNVqRU!T+rs%~AhE70TP#ByJ{aC29eirarmwvS;# zaG-dXDWF_JMg%YzRbN9v+vD^sEHIeCA{=+PeBP*7V>3Fv* zudUIv$GOhs7zQ=U%|9~-AoFjZGTWVxyy1f;51c;Jf$3~5=!}0JIf@BFCY`oQL@0Tq zb$vu#yeS-m&oy-r4kL46L!twOO%sG%^`u+163a7_2aM^GGi&OXn8#9IUqY<&nEB@I zMj6V~Y>(-pf(XFwJ2c*q#V%m5&RKNEaNN~Si?lwRa6@K^%h{RWZpQ79og^`=6F#h$ z`%26BZb%M82^K;x~WA2^}!i~8N z2M9G2gl85^@QI4sn^u_`DS{Q1X{xN51;MVpf>ohw2<3Xl>pjBThsKuuc2`b13w>;w zJ9qBuMISc^`E;5)EAznYUU*GYuZnv9jI+>d4mTds~A~1*whD9^a&MY=GX;b zfDq#)_pNXQ&}0t6ZTa*yg<)6=7p+(wn!<47-qMW?D^6@~uuUCAf`la0{Ob0aclSlx zY=KTywY3mLE~TlqG0L2AF`9)(i?y8~%!;atRHWzWR#s+C_Q*7b!{re%>Q2W6OiJf4 zoWX)r-SX)iSp95?D@7q5_t^a*lN6f6TP&?%^VmR^fgN~QfYNKGHE_9STp;z)74lw% zm)pCfRTteo(&n`lJwLhbLm9k&j*%6B&=^qBCsdG`|NPweH0>ED1D@y9xLZCa5aha; zpm3bQcMEupxyy4+^EwP+vuS~_Yx$3k)x0C$=}ik64pyp&nsl$*!JnzJ(3@vRvqTp> z5-`yO1+E?>Qq?MlAkh&e8e-IB?AU2!&JQ-LRk%1(ZFYVtHSR0);W#=j_G@KIWpEh4 zD(o6cas5R+G=~+1OE;T{AR|B?j>gjTaF%t70kg&_YesSuz5Sp^*{(=q^x6=;jDdy=x?QGR~#`KCORQez3SFUZ&f#| zcXBOwHg|z9hDIEc;WCoxKG-mTC12OXOhMnL*xx4x1EUmE;ylusNF*K^JcZ0rmT0Rw zxe0Y1#pxLwJOKuiMd^g`qpi;G=E&R>kzm&cRP+gz>sz`Z+|%J{e53zJ@VU?zI0d*& z1B4SRWKLNZuBn%2HXhA&nj1a4cB-E(bl~|D!oxIh@&uE=*4VE>+PA!@Grd4weS4*D z>kp9x__VUtg9%3L5JIMTf^nG$0n2U>4oFllRBuxgPGO%kF^QHz#pmidN+CJV8TA`V7s#F=HqtM84@t3}&=dv?3ddw~4Fw@COAXt` zql~v?b>A#_DV360e_>SsYCx60f<#RIS`_z=6NJ|>KDK4i39#Vf%O|Ye*i#TMn=EnEwiP$dsfMsd^|~$d?J{0zA`IXG6}N2nE}lZ z-fnK~?wy}MZS~GVc~Q2-q)!$Q<_V?yPBX=EVp{0U+La_iFsZY4KYvzqnzpM@A?jAi zFwyJI&q{B@?Hz3E3!L0(Nk=5iiT&GoeU)9`=bwRMAs18Y&1R&zyxdHC5Eb;ENYrAk z@+|9V^iWs?Lk7BrdD)l&P{;r^7_AtaGUrpslvF*5$rEE=#7wW*XxPY6UApgY&1X<1 z4HdR)?8)D{XO{?dEA}D%iw}ao1;UfE zyB0_)(N{&$!K-GfX|gEWDIpH7KI*$N2~KCPauOP_Jo+FmERZ(bInnpnL}%DtBRN1# zgp_(}sakx1itvS$ktJl+8G^!QMD_{^kp~~?tU)kWWfUSkdvh3libLL7faE)w3t;s@ zl>Yb=#Zi4s%Iy4DQ+>LPbj_iDuck0iv1eQm&UvRW_AgkaZh~;7F&p{a0~3TIXMk|~ z?5xF^Eq(M@z!yxkZA*w8DY_LbGVqG&pNTRI+Glb#K z%&`${D6ClG322aTY2Nf`^xBCkl81LQQg1@8Dsa{6Z0D)N62dNC6}KG`ToFPxM2*@3 zLZXwdPp*99YJ>svfDa)f?ZbfnTzGO9f$ zAZ$b)d!!{$Z7Y(6+eKmsB?cj+=agL>n(T1J`8;-K)4HxYrc?Y<+ITjLEg9{$85 zUP))iqs>eyK@MFV3>Opz*8us42M^3RYj!SK1_9>VSBsoE-r6ra$ zK@=F0-qDpb-2MG zg8ZV@8pE7>xH{qaOjroAH|G`t*78YW=PcQ(!D9X1K@Dkr;^UOyH{)O)q8bKnR`v zwn9dPW3KkDzQ9QUmqE<1woJl|fK_(c{!w9lqqZ(Kh^%Be;#H|`F-(uSdXy@A8bUaO z+F_km@?U)gL7aRR!zs1??E$@r5c7M+Czdrqh~d&&ur}TJYd!<@U&ia!1(Sma1VZET z&kr7#SIzV!W%of)r&e#89TVQ=?>1#QYeiaU>!Pb`7H6`G%=MTD*RF{NIZd=1!y+jL zis^k)ogj2q2MCFA%;l``(*PlcH}xrZCk8P|RV@~T%Fd2LyP~gbR<3`A<#-@*W$8X@ zPxi5k-Jti;P~B-BbVzPI7!sb6NhUA_jrvT7X|+5x-mnCX=d(L}I-g3>ic%9WoZ@Q; z5mg#Uu2cxcA5|T?U@L4Z(=~+`DAPJOymCD`~)bMKLv3Mc(R| zP$F6;RZ>2*Fi_p>kPy$RFLn^{S+y9Va}Ez~$6O*uDl)6NJ#qCQXoI z492;ODmbrkfv#zEvC-(O$Y2m!Ci@g;PDm%sO*LqG;N z;d^ts@exb3>DVwJp`|VUmTGM@R5kI5S^c-lFS|1uN--7)F>C_r^vgB~HBLZvFw;X1 zr|8>d>pfWZ=8JVI4QkFgmz+7`#%r~dd|cn@+hUim2$(h11Wj^sV)Vju!^*pYn1h)2;||svd_StRN`#17V(~ zO+(m@#g2~+CWqyWEqn$?;j{#+0}tH=tq%?h3jMpsmNR29j{cI#!y{heU@HgWl^}~| zN}9Gf1|(51K_(VN)mBYSc6Q;Wp}J7KX*W*zZU=d&Z5XL4%M)%(uQsOW+hv_1)V4S} z%%e^;#FCSot0hbd(3p(N$6Y5JR)`g{*jw0aO3VNV?{Ux>PL)yGNe-%REH8s(5Sf{2 zqPvU2wa#tSeKrQ8^p?!^bFY&D``As@%VqcrxvW&y3WZE1#`&ejSUq6^?igPn3w`E~ zonRmwOPX*Ze>}c8;ehcRMqw~L7sLp~A_1W_PY2b2`@Qgs z?&COC>9B>EP>e+S(vn7FX(Pk3sWPFr76ubiG#`=29`iM<$%f_h)A(KN=?E4x5Z+3WJpg$7z-H zfzTjtnjl=tl2e+6kux=oP@OS+@_mt{tfJU4GelJGG;<8D=o|#8$N-@g+dzd&1p(oz zxPNn{(~Ii2?=|#`4UeUzr46CroSFoSK~@pI363J*B47Qzv}(LiwR3&G&8Zn7?oI*X z!kPf#bVekM1otP4nVF4rH=Rj)(p#xWt-!cxVPwgniYg_Hh0Bc?p!n zSO#nyyk~*V#%S6Pgjv0>Nxmzv;g%k9KEFmroGF^)Y9m5DDlpGKq%P}Rz;aG#5C)t% zHp%R|EilC^g{nQ{7OSWR2q98!$sipV{*ZJx3_wT@MM5&sBsqRj>nYKy3R;o8@rpeV zE)ftSEOa)3K2Q7ybS)!;OUr|fvEbf$qno&sMjIywTR3lTRMD3vrEX9Iojw~9aNvgVd@19X8UuvJ+r)Hp!F=0j@^!n} zto|VjWA3(_RJ)&=rdV(&HkS!Pvovw9`OZ84XkIVGfw=poEmKSoqHkiNutAz_rgbAw zg>sB$yJO5X$@U~18Yf&Tv)BV6X5jZPo35>AFP1hoHkN2X=~=x}9fRwsRNYnd1(6wJ zbDXBQOTpNkqjanJT1~4_r9)&a7#}((Nb1Ww=9e~B%4cVbgk!xnz(a`aL?TMF*3|i} za*Yv9cQ7LC1>W%iHZz2jXjcw#z5Qy8dO7uX+< zBSdop_Na*=PZJ0?{*$d<`JV;b?4k6k#4HeU25uYo?4;s=tSQ#Zx>mrqR$%M)j7dz9 z`Cffc(P!X=%eH9}1Y@eSNkF(pv%Tz7A1{W6pX%(B$%ZVA*3;lL0Nak`A@L%Li$zt<^9;+KUgNN@JMULMvgHp`Zo3D%>pH zYi?9GmdJsPCBi(l|AbY-^90XdF1anC4noZ}?pf#3hk_2mc(K?AyPvzfaS?9%+5uBz zu$p^-q`#JGE(<~=pC^4}xj7g!;w!aA*s2hDMZY|q)fLn|Q6dy-&>)0_2{zJ#^AIbQ z6omz;Qc+Ar;6fp9(}ci$$Y$5#RB#YZu>5_hiq+K6{@@U5jmu^d5Z<#uC}Pyk8h6jO z3CR+s&m_y}hR;r4DA=zh^PAg30kC6%uqw)G)mWcxfpC5m<42Z}ERY#^y5~#DixV5z z>s8pCYtk_!Q_jvoVYHizgwQ2wu8c!XsVvm$0K$~!<`?XPv46dRhFoMB)0E5-bISa- zqcJoiM+b6aea<98QtBFJo_1IdL)a!+HDOGEb6~2fduPFjW$SS$5q7g^-vEM0Rod+o zzRGzc@!$*Da@i)pktusRRMI+zKlUedjq8ucmE;=8iNuH_Dt{2i-Sk z48|gnFpQvK2^EsV7!Nu@?Zxc-qCPFM*{W4kGaDx>tzElQg8549fwfpSItVW-0O6AT zKDV~?W$(8rLuZIw9FZ1nZj8`e1wbVRw=HEQvDhb1vrM8p6rCemon|E0>(*!(k5fEy zW4%ICLM)lzY4+ZvqtLvgXVp7MY|!)7iL0I%Ny(T`kPFbkVoFM#>6*@IHmc)Pgm*XlVmGkD=RdPmo=El8d z*7%&306^q08?@=TWek~^aZysdBr2BhGScAPU82G@^Lnp7n9aswbUtf;?HjXKFE^VG z5Q5i5h+Vx$+;^&9!V(&*bKEM_EGLwc#>xP9O{U40@%Jq^3AR@I>&!)_uY#v&xLXuh zWE#smp2CDM?K%XJ|m-(GuL92|^^sMrM4&F6t4LB>j#X zR+mhvs8(BKQRGyso$Qi=JGVecV{u}|P8e=9stw|fDMty15W6}~)xdqunx?E*&9x;( zm&H^0v?>}a1NuM+0MbcRoghYy+*A(q1o?B)ey8Zm5YsD^RgTw@C zNM0EUf#8p96vC_C&_TF#@16;TN6AwxMWih9%&dNnzFktx&{5d16q5i)tRWV_?>8%M zn%+1uaiEgMiJjW&8ksbxhwUsaunrJ5`awwc!tL+h?169|>XQOQFw?@ujBLqDipmcGFZA#lA+fzPy}_3=DIEAqb{Hz7`=Z=4M1Ui!g;uKH4B~R6WYgdB~{~ z)^U)l%|m@ELAqL z2D9G`XbAt_4%c)kIF)nM2Ulnlta7tgqbAPS!J#509C>ZuIjjV!O}?APcqDJL2~SU* zbQ<66$E#YrqmGfZV^MpOBl1pAgM-Hy|V)a z*-F0TOI*b=Jw?f+xWjUp%V7FTQI(iEOeg5$C5TF_$__S32y9Qe8#m5{Glk(u3n5Hl zNF5r=gYV!Q9J)aGz&c%z$&jZB!pC>INwd1FFJDj~->(RbCBX_D%@ZoH8}P1HOn&p^2vNcT2nFYq6ZVoNyDZTjcl^arJhut6M1!(r z_-Qu?3zf*ST!|==!m<$Sr|y%1_QMJpdY6utBZJcAh$|Szl|nOgszz7`AY;YaP*q2n z#XBv5d^Nz=ML3wr0EcKlTI<14d{3wKpwZ0vq5Xh$5;g`&$~+EN-`_`%1Hw^x%J8E> zZA3&bp}+3RF@GBR_`e)TeWI0a=Jj&5GtgONV^&$=`z;7VWgRNicnVfKsUWcbis@y z+6or?LP8jDBpcbraih`4nTZym=mAyq$ng%-YM`pt1e28= zh8mwjIDtQ&R4h208j|(%$JHPI2$BotZ{OZ~Y2~o&Itk((%?$4ZVJoNGsx)k1Q;#4G z5Jr-!xn2kN=~Y$sZ^sWYoeQ4v>De`#UzL>|ZQy^#+~%ROfy)d)15$Gb_1ru6$?=*cqR3n~Z3h7Dkfv zp2+1!v$14aPJ*Av?_wpvBFpsl=Inn72gABbGgKTCWwdNX*N{G@ zM(=&m68jJ`B*Y~qvYb|XM78KqIbg;yIS2!|=MnyRG@Z+@SYx|o>Br)1(F9@cUW1so zROi$dE4ptJ3Pp%;=(g|PvK*}P<&AY@cVC`swM7IoS09CnlNGJOcs*D&hH%e7Rb zc^v6iIwEt#WLZY!hA~py|EfGzcoOXy{EHo)8g$`2-dbEKaN>g zcv;i%VMZ}#c)*yOIR0&Q)!+leO_za37OHfP)VPZo`{G3GtzfMFfW<+ap8)AmFm|=i zH$VrW_G9-6Z`oqNpa@p2iU;OVwS1ACaFjMtKzOuLOmC?HyIno7V22jp%{ z5!)gT7-oB0)2`(p++a?={`YIwtW_s1;;TW=-bE?Vu6ILuNy$hT3Bu8}!H9nOR=<$X z$7i@831b&87>}b>xxi|ey5RngQ5QK%YM%*z{Zop8IJe_f+ zBJAxML~C6Mcn>RjTo~Hav`tb8G6R+0B9S-T42+{W(A~=I^^7wF3^k3q5EPEC+8Aq; zOaP*Ial^cfdf}lIY7f6GI*6>)J!3T(YJ0bCnQOHH!joIK%*k5a8KdIzvT*>$>vgzM zkGM$Cpw{nppxu-u<)21@jBVRgRh0CkRuq5YnqusgA`8#gaw+UJ3U-F zy{VMVYGN(M2(DMgZsHkwM?o88fJ^wY?p*<_Q!FSZVuMF_$xac5Tpv91==`Ng83hy;75SorytQKFkdqJwpJ=yeA*q5dmS2||x^jS}Vt@Q}^s7=x}HwY=BdLtWm z0d7iI&KhO%E_4tH8d8zmInFQlbx6osFXCV!Y^2$~_3N*R)KPITElJB!tw@#`OGN!c zl031YfD(ur3y9VR+rRGEE#3!L9fSwg)G|?ZxMnpTt!a9sF$e!G7nP_9Q8;wFgy*9o zk-sMwVxaEb({H_e*>K2aG37E94unHzj>Wl`?-?{|n}|hLW1osv#vta12n@cc*6awu z*g}cd+5V{b`Pi{&l(^vQ*3`1G)5LB;nm@_5CuaK^HL)oS zQW`Ws_U%30`k9Bx0Ue0An77|BY+|r>ok#XN_?5U%lmKs_k3g0-ZCEHo(6?!>)uuE( zP(d%^+|H35t05?Z40WUYrvAk?>HMd?LY=Ti8YkwOZP5&Ls%h3vNLokd(s`s|pQ_lm zO}%HW706tHUjPV|_Wr)3i9Fi|o3vf1^sI%Xm0YJC?TC^jWDdDl|HLs7KL-YH zdFR5?DK>06o@pCyx`-oDNjo~yh+w+M$p%MD#cT+sJS~}O#Rr2-v^=j5E$^BbB&rUU zr{3QFx$$*3HtXD)WTR6MhP4^$SyFDlV?NmA?nfNo%cj{a)%%whnmrI=qWvI8iC5!RhlJWc?>u#BuHe(#UtOI~njo~gpVwQs zv!#?F=RstF$57;+*Wv5)gt|AC;VO zz!6FJSnSG#)`c?-T%pM7QokwqgW zBtN`5#5^6Bh(a(~w_O0ywcxk!I2zSk$4Rp}Pga`z$};f!VjbeBt>t6EH#!AtdN?0x z;BM}+%f}jUG&c;pobcrh<1sb}eKO$yoI-K{lXI|Sy}thH{6^DCbhnJ)PPTqKfk*Vi}ZTZ=sm&Pna5W^xiXC0|7AvPXq?#2|MYb88!PpD*$8|fPOTk98@81a z?qR~D*|ZJF<5EeK_39u*!18@WhO1Y#Qms-Y(VZ(HR-;-RnypxBO>8S!@g+0Mn%feR z2;-WuJ`OOv-*=8~-O^*lyLXQy5`DO1U%)CB64~y99AW+<#!dkI8SJI*T1k=U3@6m%H0QjwK8Lg)T@JtXQYw-*U z0~1@x&j)pYaACCvLbQMzebtuD%>r$eDg;h-I$UZ#xwyD!7p8Xvi+PAOnU?TxW|3qf z^ttS!0#a5Z7iT_7yxUdr8>ZPyTq8?2n2p({eU1gWErL~GXfEU-0qq?0fR@~BG4}Fj zZo>oz8$Bx0j1+fl=GK~hY3lp-dP7LO_3tHS;G^%~$N%n15^>nu9{zM7?LA@&7*)~8 zHuo%Ks#P{$@o~mv-;={el9eWSD&UGv6RK1K~&D;9ta-Ma&+`Pp^nZ{0ON zhb^45oNf<<8wULJf4}_}KRiH4QKLD9?lkEE25p`^nYnF&@WxVON#7gDpIBP^FkE?B zbL*aQD>n^$m`uuD-e_)eVzZVNO%SR=$zt}S5C1bTMFfnxdkx}}ecDpdut1TfmAFQl zOP2{fQR?wvHbt66qTDOXI6)Yljgeu}yLTPWeE06x%(k>G9VzZ1r>F~uo2J5>v0}6D z&E3_*MFK?<9Nzuf!|IVD4gB=iz1!}h&W7Z#a6VaF|&OA>E&uOPoX7ZEb%ZpIRkbU@@NSXx}5yYZNwx5hoq{Z6CD(?+2%VqWaB z^JUu%+DFX0m?aq#eHI9WR$6%9_NteKGn@qM>wHeRy)O6I32vm8h&e1uDlVG+h%sjz!!&2J)D zW!PMfG8>|};qa{zR^c&+4iGXV{1??DG;l>}c9l#tI|X}RmR@E)gB6o*^-=q)3`Pwi zQl!X0l$EU5`_)aevvz&ZOcO7?eQK;K?JtW``eHHZ=;-u5(L%;rlT+!)3^VRa+FiX1 zLnc#wKv>C}h7h{nJD^q{9}CvD1E?U8wNLc0I!nlD6TR&G_Yq6t$^e`r8l)~;g=o7v zXr(L$2z9e(9O+p@+d2jVp*N8RBN2l7|NRFOf>!&tB(UkarR`_Qpb?o-6NH$HGiiMs zYb<`3Fx1wtqHQ#l1$$3I=4U_KO_>_4r5a9&LL}le%dbXzjRS(U$Z7N2Wg|a1Jr#Ql zz|&oAejn|%o;boEZ+q8p59@hH z(Psu`o3?DXGe;|xEJOj2;r`$MVgIpJ2NBLt@aNnH1Z`wnG>_~iA~MfC8-p=7QL>62 zo6hmdfBL6?`kC}I!%2T8eSJ$i_4vH*+OgpBjmWn*1|_18PNSqw677L7sO~f2seyS&`3zgaU0yjP2uptcOZ*MUvBTe{%`-*Q|Q<{>tKDC8-z4rHk;8HF^RFf zS~mwyApKU{JT-YBWQFW))2Vm<4h)ggYIXbnH9RDurc;XzAKkXD5hXdRA^=}}FS2ZZ zUGJkisGmYTC?n}^k4XUHAcq>VYnF3=fB*Mp6TglKxTJ0yvg!#T*cM6-y0%UZKpRTPwj$+dsfFaO!R5D@A!O!s>rH0(i) zZU576|B0gR{Lj<>X`l^8iLu) zW(I3?E*$55CVj$VOA`V#Jsf0CZxM)`xe#%mxK1Kka|C5zH&}R;{$G^6e{7RynlAim z)FZWYs8;evHA`CslBia*f+nMAP7H&1#RQ#vO{1=IvYK=pz#GtZ*5tyW|1=aVdnBYieZ4NuEij~DG@D-%p_ko`lEocNp@w3 zTdm9AU&fEUPy!RWH8~T5wDrkW3H|IdcIb9|W0IK4ki|c}s7fz(CW)TUp>;9q zDAaip$>8KRI;~3ji%$Ed6NI#I1jlTN(*Y;-5|%fOx!5Gk1C-{bi7bX7+sN5k_u+s+6Qxv_+_p9Vq+4o!x4^0BK$ zTRmE!N%Y=i?59!>g+c*R1wyMjBM~jFp*`xfJ-6*0KGp7-H$B$&c2jI%s*= zYBtYb#d{jNb}S)iYv~Sk*^sFq%dinngY6zYd5$`*wqIb=S$dB}i8#8ku~nn+*1FXW zVYjUK(J@gNYO2IrIfn30S@#9-ePM ze%!`kq~6~*Y;-b9dDVS4jqg)l*MuWICPFZCpm59u^w#DL42VwkN^9(=m2T8f{SK#9G zXdkO{)sIgZqnM^s%yOTdCQC9TS)H@JJ{IeEatrne|5^}M zrzWpj4;4XT-R7G>p#+`Fme!03*DXOP{*ghTFo@#0q+N7?@V`K8ef+p`=uo-*XwC#- z>R{RXqaTf@62A|cdtpqjIXWpHis78)An4j;YOc+|$kp(HuZK3%^7+KbN)!r5HX2+#Zn@j63SE5D2!Vp-KAspdJm`)B=+50NoUDiF4tAPkYhf1YP6A1FHpp}^I|s+p}`IoeRv*-nH@ z9oyw5n1pS$j)c^M!U)%mKkKdG zy-aTvC{~09m}KnJjcxZhTJ-V`lS(}hB4BL9kX^YE$K2c(UtnBBjxDl}ft2xr!eFV? z1DfpgagSf0wk?>2LLG#bvMnv&079-F6W&}RTL9vA@$GE;T=HgH0%E2r5_DDfIDlES zI>sV%ksvIJA|aW@YEofc5Y}76lvh~Yj4cLV0FE z>ICCU+0J_o-0tlbYwQ8_8pMb2&dv>KwPuhIsCsRpbjN1UN`BP^m!?^@=)G23#8#y- zQD|MX@XAFVemVl-ccfR>Pn6^T(;NT#dh~tm>$10TeEdI53t9O6$fzV7C@ePlPM@yy z5%9$IpE`~c{NR8Cg#L!1@y`X7Fou~u(n_@zNk~y$C6c{i(J4Wddes~;IWP$Uf{eL3 z;oKRUbEBf1e#6Ek=&QIv83b=|Thlvd1KYfu&H+MLDi9TzEaLzOl(gV{vu0rg`{Sr^ zoMXw=YBZhTSaBi8jQ#0UEk&>%f0w?%laspMa9Cf*M!xlRFyGdNhVll1P$!CmYM_(~ z22Xy~+SX2=D)M-OzT2W!q^fcwDMN%W&c_C%06L)NH>)Qc~`lY6t zP?htEB*VOGYHF(DE~8**NK=cdmOi)*5>W^=vsw#nc4c4s`e!3wY>1ldB>F#Cvw8bAS0E&Z(2&ORzC~T z3p}E8u|TW70`)+66!BtbC%6!{P@o6>xlWy?lsiyZ_jn`-*YAzs?f5fSWJIgCZlReh z^zw2&Hug43ILX%5_MYC_0-U2;%$`;O$pJ!{>#nLSc+3&>sm_Q5q4+6VaA<;1JhR9~ zy1u<#3JUm63aGYv_c-jKt&I@;5rKlY;HO-A^%Bh#ezOGK%7^ftTDz=6Q zB{`7P&^OLG?A9<=IbcN`X^~G))3PN>Yjah`4UkGgzjt^Vo4l$FU)4DdU`}M3Vnt*w zR7{?(#UO=?oodWj@S;29yYJAU;^EF@Qa#9j8HA}oLD)-)LA@o3_%Q6?w-E*ny%kGl zb=!8Rr;xW)&uy7>F6@~WP{n-CoY;yEZ7pZ{IDtZ2k|KL2oT8Zd^0!EGnHa>M z!E}0HV8v!h^6`TN!Wa}N{>7}|%m9Q`WLXRi)d!(+%VM@u(-a6#9}<>OslNdw^NTV7 z95$I(^7Ed4i?&Q0FyG7nxKJ4rt8&V)9G1;mINphkaaOsz{|mFThlyOO`NZsPwJ>%$ zV3ou1q#)m7hcPewa)R(UDbs8n$1R`oHabeYyuL!cjRr7QH0NZIWMBZyb1!U;Cx5q{EEV_saU{jNQ zQcmo0IPO>{($eb;s~}ACK^E393=_9doeU#V92UaA$J^OMW9J=WMS5Od5>bmms&C^Z zdV4!*tJrXMt58qo-w->;gK)7qlZQ^Ch$T{3GI{?pWd_^pIFvGVDMzyR%{SkCUR&k|h2cf-Rr!M!6LFw0 z8C;m0JigUF42g&Ksu-^qyKT2f_!s(L?d`PhItzJzw9nAGfXK%Ob#h}~DMmZRhRMni zAF%!wiJ)i?E9nL{daSu=(Sb_t6z9j-34k(UZ&G)M)p>pH?%n79{hQg;5`?ZXJGG%$ z)Q4;hISvo)QQxXPR8&t+&mw!s{DfwLjfcwT#uJR0Etpym+R_lsx@3WHN!4G>e#7kj z`v)IAvYzHSd8p#coAOW~WL?|v79JrUZ$qI39Zi$SS0QPT94Ps^vSxnLnUvpsRho&= zKE0^5&(2%kc)(6O%rTy=mB!Aw?Vi#CDSw4&IU68S*yVt|N?{bB9qGmJ@K!2ly3Y?j z3kHd<;yF>hJ2u(c)64RytS(c>NOWRixVRuVOEiR?gdiQ_7@y2s+Jbkc4ppf8Y?A6^0gk5|6 zrkxuT5R^VwviD67y=qG>)ME&Q7Kg@VI`5(yx-+{f4iMVX5bKf&$lbf)kQs!(w@DJs z-oRAHp+l0A|Lq|BsT@ZU53+D*dSb}*V?BgKN%KZ?R?AN3O6?}iJ`)V8FTXs?7cg!N z`a;=ayu`c@%8>myLHoMw=N|i9VdWAX4Rud6Epuo=NY{QPS9N=CIM>?}Y%gqSS9%u~ zk{>Lz54Yrcor}8Z{d@^Uqt8BD*rw)%r%>HvuCwo0u&p>}nPzhSaDCMUw~oLzP*8}= zkRUPSHYs&h4o?>g!RSZidHPRcW+5vr%^J!C`kx= zO~0)II!%Ibuj0}PX=b}bfKWlv3BpsS?0HBP2>B*}knf}ZlNB6-a2Y=Y z1Wx=HKo|(Bhsn+G{11%bM6WhHulT^f{1Y9TEgd8m)Mqjb`RojgiG*w6}` zjoG^;E;B1uk{>+zNe-IyK*UgrNt>-fVHF;$bCgpc+2wQA0%HDrA zoNX~dh(kOR$ApJ^M`^pSY?A~axGFPBe^!3h{-CaE5_|UC$p)cKNBdmIO|9wE&Cz_U z9QV}jV@M894`XL*cFUHfHnhF8G1JJ|055YuNH^@m@B*Zfg6&^gv%nZm^=wty zI)r~Mt?egvC~aqpDXrM;5-ARzrJ zO2@h0pnbdgHrlfH=32KF$of%>0eqC41HbLLVQe-G^g^U4tZUzJ08I-EZft4M0jxl+ za0J7fGnNH#^92Z*ZACdtFH6}yWx*l^!dgxx!ZbNgqc-Rn`)$rx$4--=E{&p1Gm$~a zK-~Lu5EiXMiU6T`)vd>D+%4gBEh4pRuZ_h}wCXv;V))(rjIS}1L^y_f!8oA{Dt9Sz z5NN|-wNX5VqxQ}ZKm0JB3#)j@>?Xv=524aG@f|^^bw8F5llQ7xj{2$LJ+sIsa-V*x z=9sA@_Q0#NI<#`fclO*#1pZTf9h4)xH#0Nxc;>_&E3s&&<}SufbHVJwa4-wMYKzLY zQ)ok=qNuFjXYH*mj+su3tZjL)Ono?5J!cm#blOsHy@ZYI!`s-voeV<){mU9CA(x>g zisXXv2hk&PmJdYEf^3K;MC|N*+ffqIu9D6HIXs~ao6$?EXh0cCFxVs4z@u_wo2$8N z2Owc^uVcd0ZxpR|+nB`9*qF^e)?Cx7OW3OUrx*|NuJ_;nyT22+TJw6)Q<90e==q(p zmjP=dz}?4=-4vEEz0Y=E`omc4Nm8ua30b%c+QUL|&-~BF?RiQcY2+NKD@yKePX-&;}V{5BcOO#4C)mVTw6`$Zj}yJn$^7TcY`gvga#uKseny9OJ7Y1|A}eRWi)wMj_9 zwq>(!vv+JuKVSuaz1MCC4JF7(YXsbW!?5AZ1e+6fR$lDrus8@@ie&wxPd~N&ERiE% zFL5a%#1~kWDT4lzP$Y$I1yH!@Nod`K~ zK}g!J7N$rY)+`s=3?b+>mM)4t1>VcqvHhUP5iMswDM3Ix)-7S?#GYoS3XZ8cWUFmr za;8<>N4TP&gZ&fPFW*gIna!e$U(OD}np}AIG8w)!s)K3UolJ9& z5)m#DOl8%kCGBLnOlgVF_YEM_LQPCyiA_y?8wk7R_mJE_Kq%*?LZnY0Ge2V{SL;Av za6us>fo;@xf&x9+)RqOp?cj+-^2&m(v>ddR_6qF~!ET+++Us*YTVJAO2g5~1CfAOY z%E??$PVaF>Qzf)|JCa%OU6Q6?e~?%&$?(ELjW;H8)o`wrGL{qI=IdA5weNVi-S)Yx z+JShk8yZ*3{ko&9Xn~MSVO2xSO{)iBV9{~G^NksZDXZ+E1wwY7v$Fz(V^kVeS*<{$ zWCkkuYJ30g?_}v^tY}Vx!XWY`Fsn6d5=FdR{Z!ais7~)5OfT6jp{dN>KhxZ4?Q50! z$)iV41K}sCD-0A9lk=NFIEw91kZAbb?+5^MK#aeHU}%H%6^qL~bBd8e%VQQ23+f$! zwwG$jb*gypEvwAedg8=gPtt}m8u1jwrxx9l$ik)0I+R%9Ooxy6E_8IX_7)Jz1+ZPy z)8nmPN2e!Hr||@#QWMk-d*LJ89;jWPjf5qfKO^3{;b%{dN5Gk4^O5G*N(6V~Cmr-bS zlBEQ&;J-3$;qMr`d@C8e2v-MPN@Zl%E<}S$n!zQEZe3Go9?NUjmR44tx9&5Wts7;~ zJ*6`Y{Nk2kB|H^`BW;4Q0(niE`1uwP&hH`C`uD#NG+}LfrA#0HqLUUTPQ@KnA55mQ z;LKPRWUNk-1kav8U?I?Bo3`jllosxIdaysj-Dv*Ymun8KNamI-h0Gt|E0->aFB7d<~w(U zI}WB2LHsd4<~_zj*vM&~WDa(1c)`X_AzFV{_XGlACiEHElH1O0Mc)o))pMt<*FLs8 zb;${|OcpGGLYVi3)d~P-v%}kV>zcz8COKn4h2}VZq#g)|J)U>oX>O*WEaHJv)I!U= z1qd^wf?nRgKW2{I`FzaM4PAyT!;z3(>(gB_p2B0bYLBec347@G(*?WuhecHYq6|TW zF{4G7jSpk?@D!HJ%8iZbz#!bE2s8qR2n5BGAT+#qu?B=SHZi>d2G{eVkAnEn0%0G< zi_6VrtvQ&mG3UR&di5zFoD}M;8V^+jC-2Gw100XK4=GL;&8B?nn;4a(uD|&k0wH>} z48ot(1>v2IJLL_Xa@DsI!A{GfVf$I@&%yyjuNe~?S zau&XQVLRaP(muzkri~PKHD>Q36V24_gz)s<8OGZ6g={#iCY}PGmfqtF3!s4=Z#Rs3 zmNR(b#JO``8Z?b9R*oFWLp2W56iTU3_xYwYh!amORunrtKLNiKI!UUpal0a{?nq^{ zr!-+GDx|Ipt+lWz(75b#oHlNaYJ^Bq^`@S;XUtKRkza4BsOX-F4C#D>seFu#WHYg&~lBmmOC3U%Tnb(mL2wL?Sw7O_x^ z{;Bfm@BZR1{^EDv|K%^|wZHl0_rL$U-~H~>KUIMc%vc3N5D7i*Qa`@i3BA*dv~+;* zEw`?E3b1QdRBMc9HfBp@2l8yb7KS}Fo9yuf@8leOe6JqEjJ!I#&2#VrsW!K8Y}L*e z=tFI>7mHA^o+PCOJ30aZM1>2(U$$aEr2a}LBrW~@7XcRdr6(IcQ`O;s1`fVV@30tgOlrzPatnU=?R2$@awX0L=Z9AjEr{*Yw zH;-}UP_nr`jGI$+8ymkT5UQl&Z|kGb0m8(#x_Y)-JJg*te|mjF`_q}156QFsqhETd zKr>C86SCyAE&%}eb-qK5ctNRfSq(sq?44QYge`eMm{`Zvh1Z*iz zS+b*$>MXcha*0_dwnCwy8@@cMoEVYHkSjnua#hzw6U}MUf>;I>yqf}NAKS1C1uL{f zImlBgW$F>OdbR@R&h`J{F`oAHX}n71tFKO1h}|nnR85zku>CU)VPD_v+n9YE9d)e9 z5<;*TnDy&1iu|5#3k_O`CS>O*@YID4UF`p}Tr;9Y8@FL>teSq9H}=Y!^R5Y1+gWvr zaAAf;R;I^XEM*O7!T~b~35Nv2VzG+5S_Q&%df7tZGJ|l9%;QJayvew?G7fUrxc9#T z!tEXtgol!k&ZbNdj$Q}ah9r_Izxy<9RxEz0I)D760)Y&|%Y7JRFI!2wjN?lW9=xR+ zLGv6WvZ+M5nZE0BAA@SuT;~=Tu=(p^&j-GjH~Q(%^Ar zf*7E+i)0*%fBXl9Ueyr6t!zEz-<-SVi2whW7x@((AO%Gbtn%#qg zYr6;W-`diW?T)_1MOtDK{O%x3C35O1Zhs^39UeT;4NLh0HO=5T$Y52Du%?JF+Gh_5Ar@DfDb0EewK$zOAUkS# z5M$u|IZgNPhlZSNziMl9H`vot2nGSgo}NT5S4(Ed)Y>P%zTME!F@gyMh%U^~TC2u0 zCJ0ZDj|-8haRm4k73+7ie%c%7%NJf;Sqn`VV%V(nc7Z-F(5_|#DR_-UuPd(AB1!`u%;~^Ll=)t z;#zueX=%y)lFBeB_}xI53j{mi#x~^DUvzab2oL$RmmgIox?UDtz|nOSbeg~aeRf9Q z1i}pxFobTAX$c|WCLQF12SJ<3$wHvvTzSzfaD;ByK{&6^Qt{Tvq-+gh=S(tIKtd9v z8S8WMQ&n>48%|86+S;-`fm{!Y+>@vpr2=)%KSD{jBV1e16Nv^$zG7Y2$l=5H?#<2d zQXGvH?jAojmCj^`>g36M{^UvNnJ-^9?|?+@6VkzkNOFd(oi_UPL|KOsyd0{bblKQ6 zoPp@dMB3(%MG0Cxj&qQ1mkHd6C7Ldpc|hT+eB7NocTN!sUBYY%gILqAvuZU+i_?Q< zB7(d``sKm&Aezb&g+6oo;wh%EDl=&h{F)DWwegd#zZ^xd-F;~4*$#D$G!!GY#AyQa~TP;M`OyYnb=Ap3FN2VjWhLCu%JjiORChmzTs${*lRD*X73kY zT!%1!>}OLG&L3Y~+;2~T=4K$=KoUp+u&cJW3-#hLl41`~nM7J!Hz={Fb9xe!9YTHh z-aRqlN&*lgj~~xCR#jAJ!?9O3uTDxZitpAl&pZ?2#b*3|GDJJdJOzaDcrB;PPU!-h z5GhW^WD%?U!(Pwa3O^LC*oA=+H#}S@jYpA97iU+kl@Ud?qa!s5 z*XN`#sgQYsZYz`xzo-g`xUYlXCmQ|OZ49Zf)wq$#RHN|8lX!f}(PMGg z!%oW{W=ziWe zbM-3irzo{;Pea+`mL=e-ji2-K{4w^QQO-MCf*h-T$=FDV+6mh%NS$N?AxXwezCHK2 z+8YCe_o=@@AQaDV)yoo>$Z4DFIDbP_=rBi2R@;-XqC@B~v<6yQTHwnCr54=pTb_my z0m5_R%wC|)dS0&y!n_?_(0U5#I{bl3n}+g^YH2)v`g9x~92h+5s|Dd0X>C^onkesA zAS@ywj!>a_EEK|hak)H9&{aj?r<^%wA?44DFTVKVkN_d!L)c0NVMI1cI8A}g!~-3L zYU|ywxl1p>=@J;z%WKDM_*7uTtK%(z7@={(j#u~AfDnr&@>GLj2tNOO6$lSK8huou z4`cMu(Dm*K0^$6`=*0O^&_V!0evI_&|7JT(5UM)hEs$A9SRuL+^)6bUE-HuyruNtt zgl92SWOd?DYTn@a7BApUJXj zTS>J*w84get?uqetGi5Zy-Pdg@vNRQc@82)E-Db#t5So*wZv#kFD);xtqty8uKK84 zE|^3%f_OX2WNZnB`DzfpnWrigLlAtNrGY9CzT7?Zh%%GWAsW|16YtUd%iX|?@g%0n z$9xkA)qsIJFsZk#OQ-c!#a1TKMTO*8& zop{|=736*O)i`wcqsW>ko;1+V&m8#B>_QD^@4%Ye~=NOrXKl)nYs? zXK+}U5&t~3h=Ks1lk3>Bu@~$R3fK-sfsAVG&d6n0nq0Dk$W>_ zwE@CcocXaiu5`51s#>#twQYnBL-OiADX$(;Me1GJ-;g_B;4H*fv?fW!<6IOG0(bJ} zix)-N(2)yQfpE<#5H5pdy(}!@O<)j{CoW3OsZ3rJRyne^ygMQ}7h0qWgdYyFBVHL; zp)eE1km=eAgr5&}zf4gy#-v6ksQNlIrx(OD`oF8pxzTULVkU2Ze7<8|LRvyo)9L>8yn5dwIFPZ*yvkQ{)n$$eiGZ|&@8kU z78MQb2Q*HnaTO;bf<{@E-gRpAqG%h7i11?F8BeQFO@7lxmx0~l0u5a9@*2kp6naK9 zx%&~JVKK6{MrJYn5qW<_SOwTtI20UMS{vl&Bx2a}E0FhETT&o=G<02nu>0k1Owf;h zUXCJI5%q?rfRGtVy6Tw)^|!b&QgT1{#+&A;*?wt#=G-5c0C0K{tu_mUMj+c>a?{4q z)RrfhLpj8zn7%}bsUO1Bq#K_$_h-QQdi)Aq-*NG9HO@woFe8>bgj#Fe%m2QV`Rl76?hzuqfY2mr3ny@aCVVay{o5+wV9K_>`%Ouy@rL+chRuvqlPU}cmj4RdA8E?+q8 z5hxU@gDy2t7g-fW8Qewp+dx=c)vB2?&VC)0scoikS+z|D2VJhg!N{_RGVyPus8&Pb zMUg9~m*@o)2+8{nP%Oyh9zb&7`RAYKejpI3KseMrbf_CenxW9=-AL_5yJ!)%uo)rw zke@iX|8B>Cg}an+BYzNA-uy(p<)0MVwi{+fMDRWyjardfDd^U*^dp#6^HDAKJcBcp zXa%W;bfA65_32>1sEX8R)Dz?8$R1l1hYZZZhNB~MHC+jx&rF;1`LbN&qf71zjRrK& z)PoH6n&Xcgfo>OxGHW~t5SsJO5V9p{O=xSv5N<$doAy%F4=|y8t-myh|0ffkIbuU1 zMr^cDNIJ0r+x)vGM$`#}YR9L`uuUmzozfiQ!HI;P#UrzFs)X`g=^8~*rbjawvq(dV zCT*c^(^y?vA)i@?&L!eLdOOR=xH&_i>clkc&No@Wm@8%1w71 z>-HTYZMmV)&xXohf9-pp2Akx4uS~fK3QiCzy=FOJ0nhf9zUcae^mq;S?)FnI!g$udq?QI#GS_3n~m|8_Sr@cd?ZeIiKrKpc;dY(4D zXHqvNjcw2N+}sQ;mufu9yF6||pB>{0(8aOl-{si4tb`D>49Cbj!okGYSTYbM$Oh3? zA#FR+Kyd+tF9Lop2BC|19H-c#(haA2dNi_z9#=gOs*7a4R=7$ns)B;H0N0CR4F!FJ zaJ?{tyD1f6-XaIDxFZeZFX6pg?wIP?{0GmOwjjvXP=W9y<;v79KJ)0t*I!S(kHMz0 zyiZ1lP7vzKt@_=2NS6TR-q{BxoAhp$9M!*t6P_&MHq*$J-4aM8|6Sw)DLrUo?iXws zGtmd`5nFY?R-boGvk9K<0;Lv{#G`kf=c(!w?|b<0Vca}IRp}_3!g_eQf+Y}|(Idiu z;ROCo256D298EDRMi3T(j#8nWByLi?@b;E-ABzKo&}m4eGP=>RotPoI4rIWOHZ&YQ zd<%;Yve^Kw{V~PdM0t=iP5LvoOFMGJC5zFrTLSncQk_AUm|bEJDr)wN5lV$Ulo5BX zt^$OLlY@T=lBZBHbUkglP7}3hYL%=ki3~+is{ypMYiVg0_pH;qcHN8|)5Kmm7gq{p z<79AbEG2pFIk_|Nhz6l9+3fAdHIMyc2|e zMTaXr*z=Ylma>~54EOx{?oZ$Nw?a0M^rTW2ne?TQB%jXCa$b-L+w31W_(55OL8j8t zaO>XDdy@{E7B#SX$9xS0K+HYRX@b0(6X1m5?R@^>!y`xHl(J%mDORUbRu6>w6*8HU z+yD(5Ok5=cfp(J=ra&l_HMdx13GKx~^-iGb5oY=USm4RTB!`HTl4;wKqYxvR#CO7E zQAgC|r%Up;B-kkSLfX;UNnj(wWLR~MkuCuR^R7Mqk^v-mJly{S2uT^9P1$(a0AW$NV`kxi z`9;%G^m>1$KYx}N&Ys2pJ`03hL!WVgx>K*klm|5D19TmFu2pwj3^NP+Z%7({rjIj zCoJIh6^ld_(m&SCvM_}E%eDfU2c|8&EkT<^rUEUIM7FBQp~vv`rm>7n7#ioPFh85S zdLSO1I+~U{c~a7=kQU31#gQX7Kqjh_GURmxi^O}lYO5rA%WfM;TYB3U7SK~pDn%wG zECxL}Qq~++`Vm{S#q67A?4aM8^|%w&)p0j$XgFLj!hT473I0ojlMyRb?(cW*^(2H5 zyh_BImP?@kL4zP%%4}^3!$_qWk3b)RkeV5Et+Nx%85;=e43(JWne@t%G{2%dTomnL z*@AI_UpTl7>8_h%qy;8=_wL=r;t^5BK9!UW781e9tdeL&BCw#IQcUEKnBuL|(+zGH5~y+{F$rZOvs4lI=>QDf zChJwO5US25wsA(iQEYYx<#e&a?0bzFE67Qxf>OsgH8l|kp{(HbqK0^;6f@9#6XdIs zh~sj(7KBj=t8Ig^{eZwAlr?iu)-<8^LBOdlRwKHZeG1bb`5kp{^cD=m7u5o7H3W~2 zAJ3DhjtS>O0)(q_=d>IyiNwd|=k*@|gvD&hCk6cl-IXevax*$E)|qv84tZJxg~-|< zO5cJ`h8p4E8YRcOWL;1bbs02Mc!cHHF+ux=N2bu>=CR_~O=|M(lXeh)$$$AD>WiRc zk^hBgBx~Ah-eUjRe%V;A3qo1K)-F>wG{a+^=KgK>o;`gAYSms{ANQ8cCf&AQ@7(UA zGcAcDw$@15D{7uD`!sJ2{RO>Ss&ewg<`;|Bo>2@2 z$B_rr*`_!Z%a=iWK#MyT*B8fieFBzI*WY0fQj&A7RN|VZnh_(1)_#Jv2?1hQHV-`< z+xxCkubb|44iy-yPn$Oh2t|+<>__lh;=ybbH=1$!M~)sH5g-&f`7l@gR?YGsTTWTp z`GIIA#|&LWj#MzDaFIhvttJMn0U^}~2Lx4G_<6u>kRZIg?2=2s$sdcLkli$DghjG~ zmTFjf5Uj78KqEl7w7i!7b5&Z*ApGbOSMdoW}#?zUCriWe6E$9gbl=f4I zXNqF_8FV=+&XIDbZ~Mc!xpQa~69~)L4d8UXU?NV|p8eBaupXwEffeGqc4bPNdcxFg zH}T3cK)>K-dz3TAI;kwJ_@QBXR@Ss3&pAulYbhV^+$pp^jHiIGC%_tAB+{iz5HdG_ za}(feWPN>IVbBE(id+D9Y-yrIY>HjGT>c+02xUf6j6AMXB9Ts?h$QQz!qp-mC=a4Q z$PShnw8gZGF&9C8vRim{YSTryRz$B0nl&D@Dps(VFyv{g<(o)xFq!w~s-%Sf{qSEu z{Ltq+d9qi5@R_6i2RFVEgd5``yL^R2T6AXx&w${95%;Q4-t6AFb+x)3t>AdvqR2b} z`Ezlx8HzeYg+l+zGa0all7&DIyrgb4@gxy(@30OJH5pDVO!aZZZhmWjx7KiLuD`#r zadEMKrr$oWY2IIROZl;v;@)@O;rb1W(BRDq{-6GZmz8N_35RJ;LKg)Jhmk^}|8P;g0xf}$w6 zL}-ZX1VSE5U6$66z(`8ktIJDkYfJm~4Wv)0qKrK@93XL}e+`AEO%QsL=MQdt69~aZ zf|pw)2ET0uo*22!!xZibncIydNQ^l>be~2pQg}^g9WU>9@R#iF9q8`?s&qhbc*3n6JDHGCTVzk|Wr$jCil9pB)TO^c_ zprbUor|l)k3liB1EsKT*>PF1evICKXgPUy`#C0M)fO?n z2YOmt$q*9b727V3I~G&q>`Mcn%L(ZUwu0E(z#w$HS681tg=|BhU;`)=s*GfHHK_?Q zH6Y@dak-4GEnJ}xag0kgWR6D4pUeV0J-kl&e)i(U#eCD9JDp$%2oQF4b$1^-R?A$F zCURwk4c-d9KAwUWIEj%d5*8VB$$1wl3#E5S3giIYKM0RJh|GB`4LC00KQfajT<=b= ztzARw<K(LbFLyp#Si}ef`F=c z3=p=59+EMy=}ZfYMy)>Zkt2(eLV%3bhvB5Czkctc=l=cs&*;w>K1*J~XJkT8M4dw} z_G&a3fS6Wt|LRwV8#sNyrt4(*y-v(*)=~t~5k_~Wrw6-sL>%{0L&H7TOwa)FOO3M# zjrnSOk2%7xOKH=qE3dDr=EhgBK|vKUoIf9|-*Ty05ETzIpSe z6NGm312L|Z=LtkB${tb?8uwjGD+>@M@8(wIZ2{u z_XSR7XDxSJdTY;H^KMxm37KSfYFy}jI-sP-F?l+dKGYa26)1v5$5b{ij;njCet z_!IWQ83G|fsB^kLLIRUGyN3@Smfh%H$P0VGDyW_GZ0o^HQ!2T=ok~HcFc|20sjXxC zD8}4p&SB8t@dj(q@W23%%3x{*X?;ja9qEF!a0RWoR%!5P*VM2bgkagUd}e|WkA$y| zMEw3&U*((xtg*~$T@)HuN_8?84hhN34HMWB5utLFlRXvFKr+w-2Ib%r69+YoXbkr+ z`rwP10O4I=7==yU-2mYo4~)vtp^>TfrG|6 zM^V$J?I^geDK6l<@4osfijcY!h0N_?Q8?XKg}|%;VbN6SV$%c%N!%@6zbFsIf8}{g z7iTK;3LHGVi0AP69*RVn;)K^;du?d>Sl7*C2n!ViaabdC7hD5NyF@$+^9KxGTZ=G> zYb|1D$wXlM$nTCxxkL#+x+Q&Wb#-8c^|N7DX=e2K0pj(q$Qre+R(*M`lGJ`3i`m?z=ZuE&!O{N2uN>Mkq4!iZnbNz2uV{W=ijSD2~4&C3WCs2XJ zvAwxq;(K4}40dG?A1?5maYJ+S+vm_)?lb)@vXmpF2aft3G`UI^2%Dj^ ztBDdLrl{a#wc31Hi}t-;-e?8{^bytTJDIoZyij6ugPYJGxlnP2G7@Tb8Rc{R)ids3 zy|f0WZI-Ikf$v6VP=_!RNM?a6iBxSJk@IE@B55a>hzzEAq%JLrHDvD6ln4(JTLFz?PKfa}NmEsucYJfkOdy0o z92hvZwzh9KSUGEhR%-HRu2ui*hj|~HJtqibp(jsbQEB@mB~0%x%|9SoeoEg={6C|I z4`0%>O~~$Vo|!?LtP(9RTF!-%3HnL{g!oV;2(OnHV?Ub!hXr&$cCt3}cEs$iDnj_r;D zlxMc*I}$*kU;zssf>*&p)72{;a+~`pM42Spt}7Jk4I2|MA%@hcO|lRY z4RlJbE|F;cv}l_cFIG*)2159};bD}q!3zwKQ_Nwl=!t2KR=YyiC{$ERTkMcw1r;$D{4@X!D6vb_|o3WX%n zpXk^qZ(!0X7#%+9n21} z?BnHXf=ntk9PY&qis@<8VgkSFaEnEWR9EznOHI_%t_-x$wF?z^YAD_e?v>u`uNVj z-`T!N7|av%pOZ2^bS^`N9*9ACD(ksMB3-Ujb{HTGboG4F?#{`M^lLaJk*s)dD zpo^;I%c9bbZyVBM*ERI?FgSkE3P=+-&S5&v0YdmOEE03O z`}NH2&CS_&5&+5K!Qkd?YO)+{SijZSh}m=Omwm@3!-D$1PTUZHFsG+F^tSTbW=F&h zLX;UfUnawZIpb2foN=lISD;9kpHd-Zi3IylaVuS>U7K#K9Cg>#PXG#f@7&4i(5()K z|JPyl7=KCM?%{29^*~4obAlapR^}cJbCUjIWZZ}${q9b~rm;1=V3yj+`+AUnZ+-bC z#e~^jTH}2jd;AVG6`MlfF1(@%;STC06P_USwf@rK!@p`n{PTo{kjo^}Af~-W<}jHj zK$xPxvT}T+L-3ci%d7JD;eIiRdf5gf|=QwkjH@|+ibAJEN@$8!~goCL? ztoAG`SCn~%{MX_Clud&|!Gx9gZD zk0GKIA!S_mvo$M~^0WnsW!?CMY&fM<3zQ$|Eq;8hZ~@~Snq$gN->!?nPK=TydG$%V z$gB$ul&cs#&f*pvXq!Ox!h+v#4LltWwzhtN_45mi-_Jh7t^mrw2}DnX>b@ydNhn-@ ziH^z1mpqM)7y#|3LHK5XaD--`+A#jv1LSsIVGtIxvaU1ilC5OAa#6At_y!=2tR8k& zQDO1WC}$^kdU{4i)~zmO>}>b{bcEPwsX}K~g!7B>kI+b2ef3=wyEW~3N#dg9m<%DS z9`Q01nG920m=;-aQ50(ESA&sU;*BY+)Fq|__ocyNwtWRUSS&bs2*v*}hA?w_h?P!`o?gJTyarAY47#HF3I943@!ImLRE6I@oG9`G6 z%Hn;kkvSR+(4sOrMYBYmT5*&K2Czw1)!RYWXmjy3g%#vL!7FEpfFM&YW=8V}5`Al{l z>2zSZF>e5k5E>;H+a(50!G@t|-!?0*1VA#df`X#YEN%`hwdiOtQ;#YCd- za0)Xi!TqwUL7`Wgl2{O9|#p0iF6YPR|p%eLLzJt$`FZ|+=O z5wc%|!U16f$7p_uIa_qKIDiXFF1sScF7nlBTIIv5Sm+5>xRZPhF8P}*;YX@OGmXMp z5}|b=nN5U2RzQT}r5q&`y5S?bav44TinssSXU_wK2cO*xCK4D)d8aY?N??97+1?SH zgvwU)=}Nf*J9mZ*A#tqQ{YLw|u8|_I4O$p0E|*V_m!~wT=I4;=YiT*5HqL9EDU9<@ zw#}8_o_Tx&1Vbv!kaUOam6YVP%r?raG9U zt}+H*!d3zB#EC%8fFbl-!d=$Sc(VL0VE7tFZ}#|cLXIU~lSEG>qwkqaI0!$7J39C`>qsE(FdHS}J;(ALog~+v;Wc4@|qKc_78nv0Ge5d3h_=4L?Rb<-n_YUV1QjJ2n}O`A}E5w zRk1e@UYndPh%#eoF%TUg_(cZBSV1vO4x4DN7Y7C~Knj2C0HF%?(m>~6dO(3tJJA9h z_F{E5+)_4+FXRRj2rIPL5-W4iOznFx|7`!WWC;&`G1Hu)k(AB8e=N*Cn|vpc*u0*g z9SnzO8p+N<>PmNGIY|!e_<1>IXU-uXJvw<5LF8lahO9|Dw8yormfQ!PVUZi457y!F zK(P1T9947N2JK2>Eg90o;eLszCr(|ubO{L#g%44o>8mF*Mj+7JTdp%?XBf>o)w;75 zi3eNZbsAN*$f=#3=&Tr8N5)+bgxK`12U=T)+3Xt_UWYMECT+`1lVO@Z5&L6h>rMIO zv3DatAwmUwqdKej-k3pV6k_wFA&N3g%&EjPI=-%)9QQX1KYS5y$AqW_LhhQhv>-)k zyFPUAHndbW`};Sa{f~Fv={>u7T{BCDafexiM$sB~=!yppL@r#ou)KO~mB@mq$++y| zOEgowM%z<_7|1pD!ULu@$n&nHhJ>T%|?Lm9dC27KiGfpx0`cw=T8SW!_PjO zOcf4$COaDL&5@lGo>JCQbfLb6y~bDgb!e=Zg2)-Ap>@(xlO9Iv-{biVXB0UmtV{cL z+pX=RBh1mJ)eoe;kayGIF$qq)v0^nYxoo_+SUvzG(}-w&O=;V_HOtKp`d#RI#6!XNMCFU>X1 zJD8@BzD9I}wAfmfmiv`O|9C9Ixd~~>LbFLM!eC*L&Q5@EWnkaF^m1JgJ_n7jrKLdy zLe}6cwC9G~!^xKRaIQTVJj%O{%j2;a&7>iU!ywvk{%~oX7Tqp3f4w=gdH&$s+`;YJ z2lqqw1JnjI!~(ZE+9tb3ga|6Qe)B<61I*ATbfsl>GMRv6+WtLXr(B2T zS1*7l>`IOo#7<6vU>JIaV?rV9<|l=GxlS{N0DIAGOdx4CP(8Ojm)A2sK3>Ng(|a@Y zMz`MIOvS&H=FjB}*)zf4xIybFP=-zR)>f9WbRb~k3#f(@qoH>JCp;B)yPeb>q9A|wJlj!~Pod*vd#97+TzxEnHc=pmSegUx!T&Y*M*}3z;^05OKe!R5$<5g;o z(3fasfbh692H9$g{szZ(QWAnFFv3z1V?~q603cEdO$D4K1|brd6`G^3Zwa4EFCW8` zDiBKTFK7X@XUQZ63c+N6b{&@=Z-D9kgl0tYq;&2D2%qh$U@oe${ObI{^PAE0@1)?5 zvsZ36CKJ9ye`0df*F`mDgl?sIn&1(ia{%-0yuuIF^ktU!9(2LNs5G<9#fr4|!rD-P!*>nqG2~EB`K`J(EBw92)Sl7ZGo_n&eHkCrgxgo@)7+72sK`tKgNWeg~H_n z=>rFLuI~IXsDMlsTvbK#G?(3B>UOeLKd~)A0UL^43Q(AFOenWv*;-$vM_R;VSM0W6d|&x+0082o<=qk z6QfDTdq2ZK8wd!!3CpIu3FQ*-Zjp8J*I1jTg3KSgul;ntF1%8gh$^)v)Ak z>v{#x;?+qguo*?oX6r#vcyS{=>KzuMz?L@#Ks*Y?RHMYi6Ks(mO^FsH8Kpqgx{9#m zzmEZeuYd1*aK_)$2#lO3M-&LD0q&PjEXgPK(7!F3xvIB^1P$qN&CNQhp6eVtP~WHI z(F5eS%er%=Diw>Sr%lV;fAHYOZ*iL9A{sm!%b$JiwZ)3`$DrS*muw(Rr!O2h@a~1x zrPV=ewU63qOH=k^5tnerluM5>amE!{VZt}vu|(Dnm7{BjK|sY>A{m-}>7}|LgriPt zlDPox7h=TS`xu5G$lnbkIYG%cj5Z2{Q!t!~O!;Ie7V^da3hu5v`fS(1gXa(a_WZ%0 zpFj942+N5i=gObFGFzB0T)#i6i|!gY|Ay3GOSYC$vz@7AN{*EWvndONXGGN|h8$u6 z0;xtew;fJiageyCKG#K{spsWpOrsRnQDlwF4RJoPuf0Z@iz+7$t?$|+Au&BNMJzUa? zJ9g|q5Q!wzL?I(kw+L$LOQu=C%F>!M{cXK*9V&-3|LHOJAI8CzsdG^xT=%q_QVvIq!L~@namMnd0G>9);IDnz73rj+uQx4%jFC=k_ zt0r}oXba%?OPm6kW4qRbO7Xy*r6tx#O5eG2jp+W@mP`<;yqMN^r88v-|V{{9qj`O&-c&#{I~thR<8WXKc+Uj zCnnsZ#HP_{U07+JM0v}Y?+&_qX0b8JAYy|qErlUHGIUNc^mH1%zbQ2AhcoCsT)AS4 z+Nr&yXs%)w9@`0x%n|*@B26dd^SJv6CPG3riy4Tx=_Srr#srhduIY3m(7ga~K##wA z^=jWZE!YusT&m9m3K=6C=pB}6wYfTv=(8D-Txa~)Iu8kJt^^YZQEaIJAwl4K--8w0 z@xvX$81j`JaL7A3H`!xKoEf~VTa#5M=BM!}jR~ym2$d6ceH~JAZZ`~JM=}B2lS%i` z!(tiIaA3gAL4LgJgJJ4qn-UP`H#dK4=EaxJUg`r3FU5QzEaT&~?)Y=fq!bnh*c1+2 z__5%|a1KIAGLvi6;!!Tth+TY?`0o-vd5mVDR;J z1i`^&(-P7Fc2Aje*6da;(Ayqv@1;)4boSP*Igu&Hnh1p5hw`ISQ&-=*Ix_R~-`vLN zX0bnkT>0SKC+AOluqRLN;M7*Hv!Fox<-Brgi$RF5{81=e zBEWk*)7+Pjp%fi1czUn&*sWPC_K-AJZ``w4 zHNsm{=sbhR$fEsh?uZITa{+y*@3{M>P~35=^dL$^hYAbEfG1s@Ra2_P)oN^l%+MOg ztnj~Kf=s3-Q8V3#yTA83;cv$niJ8M5u96|#v4gG4fdhL?hinK!I>9c(JRv?Pbd@y2 z#2m;D_u7mGR8DyprN)m-utpvoqoj38r!SQ^&Rx3X z<8b;z2rjHVKOpv%Xaj54E)<179@x3GW(l}c-H*6hMb)Mgu6G}YgsaF$*eAQlJmU5{ z#q{or7bV`_tOr7uC=!Z+L1||K)&3bJ&~My?>&(z z69^wgqZrzX{pJtP%>4YdN@b&YbaUq1=K0E8*TJ6Kk4C4ux`;IhM3m-d7pE{`+^ECW zp}Z2Dot>l;PUSsahv;u|mQHKwmU|Lny3HFieLV9XTZ9~-T~p)SBBnkbK14y0M7J=F z8DlP&0dg?wzJUesM94hU?2z!Gy3}`{*F_+PguIu(Bv(iHY2C2*h9wM<$>6=@4MVs` z)s1%BGFR5WF-nvr=#7Ab%2)Ks$zW}@MGt7miFdFWBzyS7AmC>Z3TgC-KzLWpduI4k z(RsOw!F)BmzmnV1+X)_Rn>1vePJUR3*XVjlmQA}~ArQg~O?6F7Omua9Ky9k_5{;N8`oJI9vSq}dZ&E7f_U>19q&oc`1L|_AZ_(JWomF1VfMv;* zPzajppLB;pUN4_8a58UJC{*RTxJ(7w6&SUu)%*5cy$ zM4$JacMx}pxsXBc!SWF0%3WRe4|*%3 zu}_$p-v#lGlHcov*a8we1ZMLfY3m-GF3~arRU2)UOsPOjn^Hh;>zL$kMw;!b%tX@ba(FC4WSPseg?h{ zGOaetE&j`ToR%}{DkE9c-_fUv}+)J@tZ(6K<;W3o%KF10)Nmi(KXUT_`tSc8 zQa4RqH~uM~|M+8a*Lek@sqP^n-B3c@U$wo7b*wp);qTlN)Ed9&bGrrV6jdQAJUm_= z``^imbM@T-Card$zm^aIJB81SOEUQL`s*kXzDpO_Jp+W~uoMV|Rn8frhK`~Fn>3xc zJ6Mg^gn)PAN#0)0VKrl&jUfMYU&&a6^`svHH>+!uK-kjWPV%GS(flZBG-~3TPrsEz zikT+Ud1XnO(6F1Bt*ZwBK>%^!#}_F5prsK+p;%Gn8cvT{Hj@XSxNjUGxpoX2h&7H} znYnmzpbCTzEW-K1?gIEX@wd9^L$*Q~dpYw37H>|)5G?Ey%{l~HV*z``c%2*GyF%FyWf^XEsAD?geTk9MCKg+T)(lOeV-EH zld)I+@B0t$$6{Z9{ZIb{rbQ@(g}L4T_>cee5Mx~b^iNolrv2byCv1Mh)>ME58nOBIP z`{C*id2nv>dtuD@pp~PXa+DMZ@hW|N$im!^@IGJQ|S%sPIWwB}T^_b}B!pr~$SA?wK!VP3*Z%#dY2*%X1_E6% z9t5H8Of>rcbN2o*ZQp6OFzQXEs?4;yN^Ui!VNwBetuTTmBeaR%4AZX|()Fwdbw#~* zoiJeKntgMTVy=d=YrCUS)ls3K{xM_X+E6Axi~|ZH>&`TusI!2{*Dc7sthnBA6*P?- z$3<+FD1_ihX4ik9_nhbRwSgq#~AudcXn8~afTmKYS->rzmxPq@- z5s5-6_xL9}ur?Txo&8?#wQJX`7K;|3b$}qGKIc$mR}ZCDjIb)1Vd-u+=1({U^kidLLW_RzgPO@C?6+hNTr4TOQ5!T= zF|PQm9YqlGf#N0kD_p`;T3Rz_(AS-*3oRHcr|Mh6Za3(!PX0FjrnY>!PE5=OO> z9k~k`Tf8lsfp{!baqGV$7$4#??$^Y2O?+Ui?!qxU5)6_fWU0GeTkCX=xH7BD_RUTF z+|Ev}fzWAd6QJK0!9y+l!4K{W_PPro)WkNd@K#WzZBx~{AkDN{iCZpCr)fOy1`IaG zAa7_QB?OafrNuyl|A5@SAX+iiP~!o=oy&rGAIMHNW{0w-=4+9iZdbB(Q&d!8U?!#{ zKmxzl~x0Pn-Z{FLQ&CJVPhU2L!T-pRJoxbTJSqEQdyagzyoqQ>*+eFef`w^pU6$2AhAUZEDZ z=ZmvyNklsW_JO@S$f&t<2LkKgBM2QSGN1nK%%=ufUAPb4pMCEg35Y{k6xEDC?mm9K z$6U_)&HT%~v!8!j`Zx-AgAjt84t(B@GIqxW1w*X;Vmo07hUA0xR^C>z1#fna-HVbo zV5t@&fYz-m1mV8dZ`?S1p2}AzrpicdaQKn*ziuT65k3}NA07|7ts={BtCF#^nmg-b zgIOmZIa5I-o#iFx68g4Wl|e|OW=S+_)(P0o+xz?9c<2qI*TjC!;nU;eqoZ&j4Dw?~ zxnURtViJc|lJAxTkBw!eD2p)SudVrZYS~HdJdVL0bkcSjpE5GHDAClhSE)kYGgk0B zuuEsNi;GZ;CDr>>25eE=BZ`Pea^6CrNH@ifXiN5f`e(e#KcxmHf5xM@fWrItjiXo& zRVp&%TA0;(Ruu}-mvGDc+9=H zO$}B@#Rg>gqhRtJvMN!sc#(5ueQ_=4 zs}iYoI6N_d^_pBk4EqsRa^<1<$1EmSps_3cjf%%k;taKqtlo3o+im52%-SnOa!(0U znzCwkR;+1#QWjmVRcm7-SRO5Fvs#Pqj}B;achKr?5T@Z>8fQ=w?u0_lJj)-NCam>G zMG*2Ccz-W1gQ_0VPc0ziY1?R=(#RuW3m*(-R{X9)Db&<1A=E-sVYuQ@<8a-?nrJ$E zR^ZwR^A$j-DN+d{%&Z*pCKH{;Trfg)%iI)gNM&W006_py9vv)&?_qh^w`YFHtZL5c z-kUX~3VREY?)XRj5I4YY{{>s)y>#gBML=<@xwNTtK^EE-L1^sg#An0TWq>e7cOMEI zSDX}8t)y%g+OZcDAmk<$l)(jr7xUiA9EUPBQ{Hos3H1jF!o=JA2#3*8)Fk|f++eU} zUE>Lhd);v=aUE+z4}F2CB6|)8F`JWsD}c?f*)g^F6)5cH!cBls4FD7)4MI9l;G>aF zs1NvZVE*67EHuHSm!>9)t>N!GRI$N$YJdxgriEvR|C zC28DOa(F&KG0e^m7m1vN8HyiT@kSEs-8S3ucE;!KV;wgQ-|oXWS5YCLD0vnoh0X9& zMAWlSeI)qN_Y#E!;a-AJ2X54`4xxHk6iQ>Vb{z#&dTI5x zDyfkm3=sQx!mx|)1X)d;brGwgRn*$>o~xyEP~A_>A}0praA9WV(xoNrFr>C~tM{rD z24~*ta68bKSsnWwC)|#8NA-#Q`yHu6!$(e!GAktS<4y;%a+O)N_cf{++povin(!rO zS_tU@^3iz1wYAAfEndF7X`|Hoee-7tS)g0juHf$N9n7!pRyVBP1DPZ2ufBsG#7}mUIos$9WQqy-A$lckyQc2^7^{?$ zZTBe{YRi2C;+=|;y+Y2Ey!RAQhy(d=6$-&#o8;t0PB8n4xVqZuYDU6?m4z;j|NQ<* z{Hsvk{da{;stS<8(fas?x)M8N)q5ESIB{kR1cPj$>txYNztQ}l()#!&m3WiPbZkME zU!&f@6%4NK5{_c@#&_77y!`S>2niV1KPTZ^?K8#!%&nsDy`y--cixjlXRz0MAj95E z8z2hdN3aRRWJBoG+@m05yjQHIOd)Otn*R<~LV#Qi3c*oWd~?ep6_os?R)y#HAX z1plClnkZT3>XQoY7*3}L2wmU600V!C-o~|_Nn&_&Qzg}HKL(w>*kSAQZ}-S+q<4}@ z;?JmMS%tx%7GRWTVFfvUcCO5JrQH2-Nw4lGx+cu`25HjgjPF@q1)-(>v%THw9G1y& z93Xtw^enLR`3t&wjZvzyhY#bFHEwqZUpzB8Nn<*$d6`eFcR!h&^!u~wnARBe4=Isu z@QfyHTWqQMap2;jON~FsLP|DN>odu>$S5`u0qLbjHM9pY%06HC^DP(HD_8E6F`1))Uw8Ey{K15zFdVz(u1c@F z{MXSFyco1vK^Z&pC)PXN0HMcw>Wotxm%z8JSVj_6D~E`#cFrz2pj4fP@z#0^tA6*QgN*8~~(qEWeu7XAqA z2%&=+^k9i}#kdM~D{e+EgT&mkGDOx3Q{bX-CJQ_Rh4NNX-$1-GKrM6j?Ag0GYDCh; zi(S;O3%O9>b_zS3Sqd?D!qc4xHLftJ{{FhGUf_N>qwa_{f8DwSN$9@zu{`6lEUkAH8b_n1w zj(z^Z3t*r-h^;cfYcBT4osfZ<3$5_hp#U0_x|=m%0b?}J z4fu#q604Dk@A1ef162if4BsGhiCuzMO;ZS8;1}bRpX@?Q7xl?GIP`maak^10h&M$6 z)V8|}ZCPep?zPoQm#KT+kBU-hRJ)!XAl!M^MAS70ordWj3BxX*t|ohUvO!w?tn?#$ z0qJL17L9{Zm%7MkJ41_LTOpU8wOT*HQ=%uCtSn5h*~TblQOd5? zs1yx=JKhMy5b3)zB03M~==|=T9HUB`TTr!V4!~ zd%0cmw*Ma?38!Wyk>MT8Ody|mPvVL9e)?bj0?7RNJM`Ei0^;+}UzlxeXRA>bE2}}r zgVf+{5Xy$Kb|8)#TENj5)wRcJrXZ*`K!`H+2K!vs7lYR=7PrGvjXiLQt_shA15M-O zACF_(*Pzqonw+NQYQ%>Co3^S;sDopnk3%E_0mC=n1QUp@=;$_1j0AJh%?aq#>lpWE zo|y1@nZMQ<#^1B@W`F;)-AA%$J(G0ua!&N$Vl6y ze>bFD({u-9``nFbPSv=HC|7$sew>n#MEV3sK$!pyvcb?{m3 zscy%8RjQtnOPj)++~f3}t%&jes>g^cRg4DCB`A@u!MlN;Mm)g+CgXTcEwsn9b1$5G z?X{N$gzrh_0&an`wA7KR{`7u~_dgkph`K3=89z2zBw*If$|XbGloCmDFPIqKS+M&@Sf-Q zynf!h@8Eea1B4?hE|)jr2wJYAJpnO;r)>k4hFYvHHw*$-ySgBc9Ui_hOlHN|3(lsk z3ahY_Klw=}18&iY8)5h8@ifUm?43T=)O7mvxP*UTNnOt6nwT&rU@foy>@((GN+v$H zYhuAG=h;{>Oz1-Kd74RAh^~na2z-fO+wiVD)-7n`4;=&F4Hz0iLy^pmRo(dcZRFKMMcHA{yXtTxjj4)YP+AgAW!gN;gIRK& zf}{RCJPfjfxQ7jbR`-IZv62SqdEaX zUDOR(oc5-qRo;j)fwSG(+|gzE%wu>y#A0}(8Z8^sV&~4Cd+p_OMB!d~Ki@MBW&Xm9 zMD5l?7ztm4yW$IFkg!f6e1xqIsYh5!c;zgeDuNJ&5l1YF*#a8!R?Lfy^O!VIjRN7z z)HHNp@d?dOD3DXgG{hYdSHV^uu1#(_pbWur$aWKCE4_@I5%NlvBGIX&s0_Sy3Q z;h=L+$UwyfHjSg5VfaTLeFyA+6B7w!l7EJCB^-VqnfRv|zb992>=-6;Z-B-IxRAp? zI&Mr;f*hyd;<&wmm^OMO4IMgk>ljXOF3~9&-4-?VuqKk71bjx8?QW_}(U?pY`RE;d z;|^{bKfWApr7$-`V}ssxkc|%+_W+0Lwvqxp0~8ht9+5>9s>>VzR~yv}J#L}RHEs78 zct8)xi@|2)UH|H;)0wfbWfA3;)In7|rK8qWiZU_)sH_aewU&B$;Fwp)=f}QxPcYvT zJj>vQ2NdG~gt1voi)nLeay@nK<#X7N1Qa618V$*u5^hPa^6A2qEEIsnzEd$aAH9%h z{~XyP(#n$E<5jLy6x#*}S#Np!oLd0qW=p|`&&3MI@e~O~wkiN2Ht*mUZU|UMhE-5x zFu68v2MEufPrrU17lCjj5kYha%u$W^{MMnyjQieCER&AD zzJsqjQtp;c@715(uRYb3a@E_t50?+!y46)Nib^DuN-%?q$#j5~FbW+oIuCMziV9@- z2dM5rcuB*ln>TSQeEPSto&OCv&tPwsN@ z6m~8sy-jyfe`u1HS~DrqTY7DWBgh1)`g-1;>vdHy{a56T@riM5z{ETN;I@l8TaV$L z=S*1z$%S)*!E@(egMY6O$i;Lnm5FHVG~*H<7R1&>Vs^IqBT~!K%g%DvvB3X-x(Grp zfJcGEhz2;UVSFpI7iL%(Yi5feM4!yp;)aS$O~z`L36WC*`&@abVQApU09V*8V{ohq_`!?L8q>FsLIM*{l3_wc^nwpovr=F7I zGRs%c_RNN)TWJWj$1tdw3MS;JsA*84am;7#TA|#4)hihnqFUsKamsI`0>&kJQCjnO zoZO|~uOYzrA$0MQg`sUOx2>+8rMx2$XlomFYC#aSQ6~FzcSBl&^Vm>PjKx?A&%JW4 zl^`TNLnBjhvuF(8ZM?1%DPdR^(At`KVYc+6k7fmgr34B+E2LKnAVdrZ+TJpyTP#yq zaWgn)2{|$`vjzy!sdvx~KcgPhHlS~6XUB{eYrr4EmJ&F8#_!*E@Z`BGujltYU&U(} ze$J>d5ijhljp6>)GjG5B{KMQ`{*I8}dW7@3CS4_B~H9l<1>%p~Uk;EhxL*SKBN%nlj6 z4YG7mD}m6aRAHEcY05_Wcs{>{d@4k*dYX_-N9BmDFF{Zc-$+7O?S+JX04E27GI_xg z;TctMUE^8-dA1!=ZTX28RD;@~SF{_T?2jS#5=nM#5ESL|wY^TR56!s%!uv(~?kQF9 zo;pyt^%bVQrhVT=-##1`%~?}$IvUMn%0XdOLgkvqIF%ncu05maN8^T&WXdE`S$!;KGO-Z8qQ!pC zc?sn+DjJc?dhlo>9I?cQ%L1mR7>)grAh1-;jIlKWkZdh|`so>p#b!|YP~+4fj;gVa zIqr*}A)AN??vMrur)tVLCMGsTOi>2Xh{J5^4p|Ospe^(V_MLI&pei_bCFhG?;fxex zIV2=tKSbf@41r4_Wf!aVj&s;+JL8iJFCkKoWmJpNZ- z^;Y?P1N>&$axI^YN$x@?I*;mVL|AwkX?S4#%ZY~*6DtgaZb2k@T_@wnJF#B#6eoGi z7G%~FV)fE&eAs`dM@qoMG!tce?<=IljeDRRq}>8B zfn))Lg%jIobanL#5p-3GpetHl&N7=Zsmyq3iIXgX>WXNR!&dHm+WRJN}c?AdJKvgY+3VWiXv>5JespApKOv8uaQxm5q3@dlISp||aoEISUuzIq5s`}Z|f)ih~RHG>FLf6xj8w;}@707ct@!eCGY zT~KsIm=WO5yNbR5PW`e{2cs_I!{JqEuShT6!xY&o30(=8x_n<%+?MOY2}3w*3UGCR zNqQyy62H!%NhnTK?6L0db1%R0%Kg_~JEvwR(v3_>K{OY3`8-`}{)^7e&p$6MO&E2M zm2g%xG#!9!an? z$&9dzMno5)c1OoYMv}?5-Wtgl)ZBhF+1li{`BlX)8Qi0cZ@RPHW8I}Mzx>Mm`>&ll zcakbW;bodo5%)HksmMhnZ1dAk|Ms^?$8P4VS2&qj7Q|AKM58-l2LhBqJ2SVyzL>+e z7>gRIm=4IsYETnvNCy_A)nueQ$lA0MwiJ8eIL0**K*T$vR6_Fl$42_o0xtZVa+Jd4 zUw!q}-@VFe7#hAA*>kYpvky@_kT-ZdZy(;u4`G{p9*Iytd+x&znVZxf83Lb^xOUB( zTESU);}C-ivH3ck4%*C}brYYR^4>(iOXTx#OH(*?Egb1bZS*jQ*;|J^Xk;~ghQq$%B*)OYAP9I)$o3M$FTNeM`Rbi13RindiyE91Ti6molLh@DSKmJ_MM;yOAK&L+SKwp6064;TPa9qHttn&5i9aKXJ9S zWuj5MixJVqx39&U<$WX0tb9H;`IK3hf`*uz$t{Ka2kBITFTZyGKCXr*PbQ4bQYeOC zYCh$Jq_c^aq~D?{HaBxPBEJxGI4dz+z~TaYc`*?!Qo$vmNHfe>LR;L;B;(zB@q4l`UL0!Bl-Quin*ZxpfBn0^{?)HveHA@Q~1$`K@A;j1Q>94w7)Qy7}5`1R)pgakZ4{kl$H&hlVDJ$VTh;QKD3I2BkHqf*@u} z1xK?}#sl2o!or-WxIqAd`vXw}aN)cyTjGdMa=D65C#)ZX`2;f+5ZF*Q;4eGG3Wd5z zn=;zti=uh`fc7TkZyFi-)vJH~>Z^bKt6%;4SJ=6D{@vk&XU@O<{GK!3!N|WJZi4^r zsAPB9uiAgJfmA4vdj0(p5%)PF;;;mpL4{beiFoWbZcNt0)okU$2*S~bCUmx6qWkrL z8XTTL9yALdL~>izR;(;Wi!p&w%4daHiVRc29Hz)L<&`cB72d>^e7NZeg^&XG#5FVW zfm8T$JU4EX{HgeO41`IsN-5^hg~^_#Ith&S)>M;{-L`Eso0`2?UN$szpy2$}3UcYf zRS@qE6yh~~1y)+u*W@hjHmYK_NM;)##0-!jjARM#Mn-50hinM19sy#K>Yac=y02{D zax&4GIiraaLJ(4ZIwj)}1_U$Jfz|=Oydd*7hR(#K<3NR*lglFL zm>D4qmx`4z)+!IAyVgvp8rVJ~yy24MLx8l#-_ii^y$|qATVA#yG}HAe9{}O6epOX< z@cDN`2VZ|4Abfjh5E7ebK3qM@)Fk94U43x$8GGoOccrO5VID(7Ty?4mG3`f?RSv%7 z7;Zb8n_Pma2I2co0}g4;WY;S4(lq@*R%EA@BZlbwnaE7Da7+d6+(g9-pCNtn!NdTj~Mx^?vgbOuLkYPTu1P~Tft#dUr z- zTy=l=v-BhyjGv7pi&l8ZP-RAKwT<1%b`X+?=#4#Mqn+=E%YnoKABwj*U5>V^_nAA*Eg& z#k7VQsw1Z6{wQbi z)#U+ax(YjEh7#T}OfH5nx){dD84G93-pw^_4_pGT)Kl+?#{ZtmQD z8hc72DUVh%6esHb11N;;pr@p#U?503O$J>Pmz9m(yTiL6s_5SiV&GgDYA&`LgjQVW zX*vJ83mu8B#0}l*9NsbBGs>hi(3BNI1%4JRjbDhCoa|VW1)@lY7{t&<46tv3^K@cY zS#-LBGrj=s50cPTN2J?t4-kaiCPTwW#Nn=(VRsYP<3;|+kV9m%PJ-}cVeN9$JF#|v za4#=`6lPC-2Z^v@X-Hy(*#c$IY?2AY1&Uvga?{>U;S7#zK_Qe|3((O5n!Fv(@i;C+ zD_jI2L^YyvXq{ElW@re>@^E}2gbm(!u6=4|0Zu5~4ypJJtU5A&C!T~Gpb((*syKiC zuma)h$-KW0tMYuXBhSwty$TyfX!Pn;WIY~=P$^e~UAn$)&g{ny>d0_Y)_~qF5aPxE{Mdv30mDGxvSPp-*hZM1 zJhFS?HxU*o*$KjIR@v*+D2|A#G#M6lV^kvbQl@SO0)2f&#zoiVUBLT+_=D!adbbHW zTA$s%XaETvZ+;L;Nw~3HF5g=tBiOj$FZWkez=-Gz;P9S&U!^1ALxpY+4ytRaYJ!=_ zjgRe&3JT-Yc$y47gz_@ub^iBGo}4PZUvM~m#4#HQ7wZ%+&lL7UTW>h|7j z%7(cpdnJO5;e-cS&?(2(mtRgy0E9A1X>nUHOX=j8`P#KqJ&5dt?aGzt{OI^-JdH3g zy`mzW*0IF6#0ZkCOQgKs#5VRGdFhELg!#orvQ7kp+oWN<(Pqv*3c_t;uR>VircXc$ z^cuBo&wHU1?yP{CZ^sy!z@6p@M9B&RpG4qw4dH9~N^CmlNe0_6E(GMTZUF=gA_4Xs z#;_URa#*u-nLw~wg(LBJ%@uNB4K~~)`fS^#%x-ugkUbp;H_fW)4!4m_%35F!wMgT6M(bV(N8Z34D%06U3VKNbK# zCzc5t8k0N{7q477d>A0~v02V#f-Z-{ufmb8;ZyjW6x$%>$54++b8Vc!tN04Cnt)KL zzLM&>(3d%hw)kHtLMg4SU6$c6^)fhQ`yr4>)y*oR+F%Ot;?qwHC}(+no59U+LE2?h zMhI9z*5Lj)M^`BMXj)MKEu%Z`pr(Pt6qd_Yim(?@J!`;L6Rw2d9L)%q1I_-Q{mvh8<8*w4_3b3FRw{A5b z8X9Uk(%pnKYV3nY=)Oxsiic*`{fO7Bs&#f%U@na`R1FvEZcIPTy4mB+n!`=k>iZ|$ z?z#)7G>b)cYa*J&n5DddVah2EQ=rcYg^-LM)tyy3v@LNlRv{lTls+CpU+gWxM=W`y z{(Vy^^yOv3d|NpPiXuc!gOla4qqb8exE=kbN7+``3|hKS?)WAdN#sTlh2+pA zMe-tjGX6XdS`0aHn`n^JIcUcQff0W%blvQWfkXHj{TbVyk3aqx3Pc2_*(N8MAcEpu zE!jxdB%zOTMt#t}&BPe3aW`5S7a1q);=qr{6_sXL7v7H)TKAzw`pj?jK*(yK#n$oY+$SR;M3`~_LYIp}bx1;h1`SHnMoHT<9ltl@}n;P9Ey#=e8M&Yin* z9vfe9Q}oe7oJ?XF5%x)zlf&11A8XoaT^nc8sea2mq~#`6ibo^Ds6hn>r%nE}$zN{s zA4fp()ikcs-Pz$44I8*3{hsdXh{+6@gvX6Z%CKe`o&YTj-@Q9*vB)fCD|G>#iPsw) z90YliPHTC{MX-IL&2B>WB~GWd^wnd>$k{OJ_q)3vfBGgAs->f}u`E{Y2oVWBDb-b(_6`EA(iS3wXu;olt0po%Hi9Uw;MS+<8)MyFq3rmZ$X!6r8(Fx@%Eq2R zAA%801GvBW!7AoL`83);;1C=xhQM3i70ru!f$_7$>PggP-R>5Avxcn=?&@j_I0#(6 zo2#oMoo4goB>GtPMak%35}i?RTiRs8&&g+lqzL4~MGfl!ziiR%`V-VSRDYzjH5 zb^}&PMI~9->NEbXi1rU0#y}%Q=v~iy~yWk|F2=&`OQC@&mVXI2~@OCn}bA>Rb5c4Py)N(9jWwxh2x6 zxxfE?pwO}2;10Vjb@gv>=_P2NNXiTY6Z;|;2L74(c~oS4q`?jJMp4|~Lm{<#_D4VZ z(f=(7nF+RQd2%oqd^~HeziuZ8i^QLyj8T0s^K&#quF6+qCxL;%Af|Gz5&FLX!oD?J z8+{y%$OadwgBglj*_v<-5a#oE8u#L108>0{eE~9XeF0}>K-Z&zkx{PI%g+1qnkl4Zd5!k! zS#!jsQ8F0BB&C0G@$$sAtjVD*E>>IITU(}ZKhC*C;*B?OL6Z7PA`?s|)|=y&G&q>; z+EDo%IRk@_p>W6Ji714NW&FS{#O0q5cnA)DXC>UF5;R&69bepmO%d#*?tXsvheA;6Uak00 zwv(Yps_5#vTDC;JLTPC=L0HxyHPGN@gvDVf(!x}`SerWLD5)W6+3?QFxlK__jdD4m zlx;UA5Ds>aBgk|>89F*M5U96rMnFe|hnM#`0y z&PmMJ?e@Wn(SEq#5aou_F$xdn2qbXPX_wQbRoM|;J$m%$*sWWkTve!xHZ@70Q4Aad z(fhPGvtrvu@vQ8=qQ;q3*{mHmc(WJ9aHSsGVjx>_U%sp*+>6Me!@=C2GKK5IS_-Y2 z=M6jKaU>?W76wL2{+$P&2A=G$XN%W{Q=PC2U<6++N7GO2KgTT=#K z2Yw_K6^ni(?z-*JMpjgee{t;CQSOjC`XQ9bL4XjWTq$_fST+7|72Ojh-0yJ*9Vm4|$;g!j2_y*K>akgEEW(u^;`&`-eY#_Sql) z=l=w)(>~><54oKZoQ@e|00?;vQtiMlBE?H}D4-29Ngtk0w(1o8o3y}TbvqrzjI%@t zab|f0rgLX)dJJI*W9j1+2htS?P>>K06^M=|1|SUDurj9{KNqJq$iY9X4^9kUE6|=m zxX|EsdlQ=Va<_)e8*4+u3Wm?Agl5LuW8<{PGm5^5lpaoB?!F5mTQJ~HZw}P*=L$ww zt@ik45Iz}&secy$Wk8z0goq}r=-wu2b_ui^x0NyR9;SN~3Xo zd=DYW0PX53-rL@b!yl?|C#0WXGutJ|60Qv=eP@05J#~tM#q7 zR{8uBQP(CjK|s_D%4CL<63~HJ%`gQ3{Axs<>?yx@R>QI07G31-tWc=xxS;*bTZiml zJxHg2^GsmVQS0xz%4lIU!9IWx;GUjtFT+8rG+m{!QborAfS8!nw5p6Qs%a?Z2U6*@ zLjzKxv|FTc3VK4!MG&U`{vZBO%C;CF{N*oy_q+f7t#7gEZgnq+QL2pjnk07SRMfFF z((OPvQ(j3MCX*QCxu#)3GAC%?gaK}-VzAelZfoN;4duNY0uT7~(#OX_qjt&uz~#}e zGCWoph~CpvZp$QXP8*UUr@QkMGYxhlGE?fthIweH!40n2VZE$r>yF@hJnOM!y(TUj zWK`0_hxo7`Z>V`bha7>xBAS#wCaiJTiYA?u-+b{r{u(Gg8HA5u@bO*BMle=!KhI8q z*0w$iY&A{nQN6Gf$50j~{mV?XLjZ(PLfx#E+0{vaP{K=!3Tq*(xq24g%Fy88@#DvN zoYdwva7DyHV0T9SZ@rcA1J-~bMP1z*VrlB?cmp&k!d#DLh3(F1MMhAgF9nu>TJ$5U z%gccFF*`!TUpe&3r9(~Jkhi>i7WW*N>t}X0smo6XdaB>x6c$g6vNDRfh(p9)FG<%j z#o7n>$!2ZjdZ5vbE#QF0E9OWda-&lX2P?BvMLi)T3axXUoqvudg>BBR5+^)v;S>N10$N;(7(f@)qz zAh@<}T3^pbESBtWlb+yK#8aoXwhmxGx3N*>?Cq5?e=kS|bm)yV+B)L?(uXoXWk1gG7pIbd(wL z?l^0J(BYtDVW|@#nBThd^Pm6S-+9md0U*RXBGTsPe_vBGC#)gnB~wdF?MpQ5EpQzV zwGb$|V9(`d_`OD?L$@$U>;3n`R7i&rQ#j5%q@2?q?ZateTpY*7MhE+GcZ@JWLHbTc zcw|O`JyFDDB3u}Ql(ew}C(bxch?YikSKZ?wtMyO5>`da@+FqL7Tg+>*#~>vHxSm@T75V-+W*KnM?JM>-ha0 zGdPOx%&Ga>9bgT2K_C&)tFycU&anw;ovo294>q-|k2MnB-r8COA%-Zw{VhnYZ+)xg z=Rg1ZzgL@3RIbv`|DJs{M=-5i#JJQx)xiufFgMU*Lk`i75_@rhS3^9ao2M>71Kpp3 z4T%yfnm5Ns?RiF7I&p8rUBl;!j*UfaOak_*00oA4j7Oa(P9R1GyyG-zW-|D=*-hh` zgK?gQ%_cc_nwekraSd@d-TMChi;JdV-J(OxYz|vYoajx!7!Wz2Y4D@dzLfjwtHHsl zLFn&jYWMeX86#&Ot0lgF2ZT>TVdpN$iJfZK=`4)~OG{Nn@pR5AftDywqeVYlK%uZt zwa#cgdV1E35uQ4W*9vjex=ouzw~~>8p5(S7x5DqAkB}+EujkrA^YgvEV5?CUog2B0 zjjpaiT2mH0lnt(C^VTX)BsCLDh7C?x%`Q#_*O>xbMMbm z41NI#L}a$Z47Fc1bT_L}-h?>p8l$26tW?@?O3yN|0`g zhRhI8WCgsedAR$?kuLg|Dk@;2Loy;~2wcCD!9=XY=5P&+=6sKWaGNIl8W2uQ?1UVC zphtGgxJ*h1D&i_b%4Jewl=x!-9{^!_AzpA&P`BpTVLH*IpH?8Ol+njoCdz8X;8vDG zNp>0sHPb5*PrxCZi=nGs5DmIqZ{d;m1(N0dD5BH-n%<)8OauYzr&YuSgnYK7aeZ_~ z@wSL!^p7Ht!6cr5RZxRnZ@&2^Y+EliAw6Jg%3-%J-{$4Fh-9t{mqG^^7+~<1 zoy-9N2&;C1aAv`>AVG1+%4DQ03;;1k$pPeL9O;Qf5u?J{i|rTvL0f0tXYZe?$7bz% z=y74*gylUn?(EG=?!syzcY)y_Q2!x8A;AQi14Ba<8@5J)Qr zwGDjJ9C)m+V;*O5TXb~E!K^py)-?;%A83&i$XkGB8;OZSTK54-`v8fH+&KE1eJCb4 z>NC;h5}fspph@3Z3h~mP{#_9M=g!XEAcWF3zOyM&jjpcW9*wH)6|8~yvS|p}IYGwo zuN)8KjMXG)3;(k6LW^Rw)7|RhRrXmd$)xgua%q}?5VykgC>I%2eRUgw6FHi|!Gn%g zgmSlU`$j10V)@*&$4_;3j`BENd-xDvG4GJ^(^+MwkQ<~Eqvnjum2{4h$mY|3)t{+2 z_U0?EKxHxnE8&qX&sfA`_Q6G-srV4H6Z?m~y@3a{wXRjW{dWu+ne;*BgM%F53P}HF zvKE$6K<6S0L@Cv8RUC~>e{q(=cUQ(ZR>%!!B~QHoLbn_I;Jfes0Ta2IM?omROPu;0 zsA|9yE`i&gotfhNZq67jGxQUu_Qj~JG8rgOg<+jbbhcE(y=hq9c|s0;HHg3#Y|``F zuuv8T90mbP=7Nz$y@6^t%E3l1D-OyV|r^cY0W4UN_udQ==_JF%><2?CI)lq3TO&}N>oQ1hIkm>VeE26DGQS@ zpyYTXpp7hpJ0$+`=x*S2$Nh05#0w;nmU(}~iL4o>08~Lfpmp*#ABg~jL*@sA1w~E(Yb4>FF*Sg72OE@D1{E); zL}9!%)#?khA*vyt1DU=8=Nv30FmFDj<^6!lU7*MV5xC1p7{o7_*O{PjVHgYxKq%27 zJX-uw%5Xq72LqXOTAUA{z427BMst@J7d33E;1u3!9d=tZ0ujCQk!#ng6V;?*;Hkh6 z?+AAA;QI*Cf*e;ENnxq7;J%?swJJ>1|e3cO#3sU zJZOU^@``{^S`lAH+2Pu7E3nzf%fJaDeG(o;5O%MvtqOFl{|(gxg3bM=y!ex zvSPIlD<|#Px#5QfVX5N|9qTwKW293}_{RMO|oq!{@twZU01d0C`nd2MB9A2K=i=-Es zpN1bVG&4cR{N>BwbN4rh`WKxF0NCxeSRgDs;sHCff^sxG9Pw1c+q~tu(bNPO9unRL z=M`8Lbd?A;3IzV?-}v}?5PtWYKnOoMxL-R)ImN@+htaDzpRROgY~?;fW?kG!;uM)_ zCi9lgMW&bnGxR1XbCaL^h0*ZHpm8ck;zfE1TN8JdDk8S6bPkyI#z%)g-X9|j6Z z6*`@W(c!!}?-XI7AIic^L0LFYJD!pj()33Z-Y#gu29Z|s#qEI+xB_s21f`!Xrz-$` zbq);lmdm?5}b{HVM(31PGq5|H@pULp#!wn8kGQRJ;&mBR}1kg0F zgGi48H3PTVa@QTf*3LC%0LlV`kHAy6#w3+yj{C=D{j*gv4y~;~;o`4<{Wu6`rj`n( zC)t*~gbOGKDA3E|!x8OJhb7$^?!flvpYz#j`@?l#Hb;tcGHL#qT8!y_>uR$#mu0KqB&0b$l% zS&%(Id;}0KV>@K>tkKW(@x8d)=aUF?9#sAkwboJ4uiV%nMkqsBXhZR}Y9>Qkh$Es; z1FCJ6>ajXnk!IkxvIXD*nWZa$WBUw4Hjx`Zu3@-oCF?Pn`Y%);#X(LN`Bx7fq<{09 zXDk-#Bfj%KEqD1$5&-tY#4&lN3@0P(Z!`SWQ8rt6)F_QL8e~|VAgAK#Kfu3F1-I`3gJgBsg{S4$d?HG_Z&EO!`_|d z;t7bEqX?qvgD4R-1{~iyX2s?H7lFkW8yfVu+v38)3M)lO767v!qG?R@G#Z;%Oxg+@ zdMk7-C$@k>xKg11~IgS)psvt=GOd$AB5AoOAx+162wMsh?MV0d!WZu7bOk`{kv zf|fhyl|8(B;$4x>ITO2s8Wp>PJh+*TJBp)*h5_YohLb!l%z>3@ib|OFvLFBWZ~o?Q z77BsEJlD{#GyqWTMGz{YX2;TQLJ-2%CG;jFgknpr)Lk#gSP)|w?!d;5q{^ga1dHwb z`Kr+fjB|;tFKKySLFhDc7mgfx=@!C2U>ydDf8jIlm)EZ0yq-WL7xMn`)Ac59K=q2n z6IG!3@-oh&91M}A8NZ_;*l_*2!>zyApu3^)#~wZ1VIpN?9TM|MDuTumaj&VYsb5>k z!mP|LcI(ig8(P=+X|l^Aqwzffg!0n){|E>fkC@mao19Hq!&b-OLYux?2_4GvvJaXe zwHg+M4DG7#c7+j%MPXKc!=?AYK^oxu7gA}YuZBH6yKTDL+`MuHB&jfolamlG@ETdn zunr!N*s15Lg4ln<`7wlrkgeq?vi5Tq)$}wzS61|`rfj3dGMVhg$BoM12^g%D9kvaTwMV*#O&T3uQL zb&4BZbc4k*)w&*wRdt|l(WYe+Pn3p+>+9>*thGUNTiuI`L9!ai$F?{^(7Q5>&rBah1hRP#%L|n4 z^`=zQRwQ9QaNsnxgwnYBc9p_^`Il`Jesd{o5e(8ymB0`eKSfhqu`?Lhm|WSu%}D?V z3z%I_lssHOJ#{I_g}^vB}jF^YafzkIsMpwb$N)-fVHvWwB)X zCpsUZh@e?RQ4A|*A#KbrmzCLZ#n6%#K36U=^KSO21DXe z80QWF8`p*+;e@w8JX}9~#5;rlOpoWL#~enK5rhYc6tXHj;X3@W-%}4@HET?uMys6W z0u;>i!11}4@ijIytmAotV;E<$dtHl@BF0x9G~sO%hlUUcX;P-%>{dLIMMX>v4{J?; z<;uzdN#`)883qV{@PmKh<3Cyo2||q+e1CM5JC_+WSrXOb$;mhg=1dQ|2dnTvnUY|M z#AJ;CIC=cMtO)yEgscEh59F=lZFq@PezxoQL#@<8l6wHjvT~X%w^fSO1Xo~PX9AO} z4Of7o+2j*1Ng4FW*kP{OMcvwqZ7r0yf)EmmRZffNm5Yi~JRgVweUr+>OrIf5l+#<+ zae7C=Xd@kDfM+-9pk!Zp`PoA--;UXevDv1I(1WW-=PyI+FVgRQCDrSuqp=g|bBbAM-Ai$dxThji~*nB(KXTgLsJN^W|U6%r$`h#o-NhexY^$ zRLuQoCHx=Kov2qRVw`!d;0))MI$FzWN=w`QN#FH8_-?rWdUM(iJq?U=FdK(L;|UL{ zAqK_6U~S+N0gZhi+Z+Ec1En z;fcDVKwHCptJUIgG`L;ZVCJw>9Y@|;yLxP#8%@N*$ecY;G+NVee^yV`WwTADy1JE> zgl7lY3=IB29@`*%q!j+$V-H)ZMQCbZ5Vd|j>auFVY&NPxts{1k?!Ia0lLO5CpHwZg ze`Gq^24)hML>`Rr+37ai{zgVN;WP2Gw%`eq1O}1kCRtqA+KfWA39HF6RyPNT7q?qL z7{^+vc`=*#3ysCy8|aSh_HnL{wjZaul`j+?8F$nM%bl** zrn_>`(vEOJrVA>FcC@kRkdc9T2mQm6a-g(IR2+SDvzV~$0HF#D{>4AyVYR|o4-igG zH7raC2xA8R7B+H5-K{5C6$b2+#=@YRKyQ_amo zM~2P)39koZlKwC2PK760kZy@`AE~?08Ge{DgD>=^>Lvg}1nOxZY;FvH!EqiZQVi3? z^8}|cYW3p&{rJgP9qQu0f6<-OXdb~WT{9W!7?|?KF%8VFT)3czHSOjb(0dfg=1>8F zyHQvK;g5dw-yVA;vo4&rxc>6z4_P2@dNNfQliV#OdKSDT0HAZIe= zK|77W@uV?`4x6L`K8AU>Ng-rzHYNu10HM?F^RKVFoTC=E{qy>M{F^c2hm_X3n)E}F zyy>@<&0J#KIfrXtr9}b@g0O?85EMdkDKiELQ7m_Xu(hTX%a~?oL4sHXgg2iI!X*q| zB-pEL2_tG)PjE9Vy~tH?+<(pVs$g&=m-hS0{bG5?&84DgIDEwG?f3NeBM50Fg1`1gK zfFg5$a8b-7r>|bcFhGY2+bi?1L^Umy)o4^qsZ`S&DjC63=#9SygvKcEaS;ADha=0J zh$Q@c-syl1s?<%i#8{7)k>Em7EoaH*RkC6gmM;bZ(I`Mj_Qlv?CuWlkdY#sQCDPQD zV$4J*%ySb1G`M4?@q55Y{Q(|Kp~F?vCmY`p&S_vUlS$vbaa6PhRSJYuw+bM0B9_2} z28{=nO|X`t8(&4KokVnVZ*Nd(6S2=5R182kSc{~9c-JTkDacCfs@42dnq&fUgyZZl zdJDAld~U-6rH(J}z?21-Lb#pc*RmVXPuQarF;c}Aj$yzZdm`y#hIT=mb4ag3 z9|0kK1#ZgXo0BeXd^}-hmb};7WCj5m`Osaqq-=NPqG_g}w$-Qvi<=(cj7s55G@4D8>JIjA#d;obgryD9oHk z4}ahukA(1r5pE+OOi%!`3xq`!{_uy}^W-O>@GNA2S_w!xp0=_=FR50E-edKmQ!{{Q zA-!>RZEe1=A0@~Z8fk6It0RUk#*h$>&;`RYm0lw*u1D}(KspFC9ke@*VD2W%rI@7>+&V{FJ`pZqrdww?dzuBls#Ru;<)IZhV6pTBs9jPMr%`5DiXB2Ae)7fk9ld zYm4HQ0F9pS|T9O%tix*(FsFXnwoi>0EPZl~;I zZg9hn!QbkJGv~K6-TYFA!VUC()YVX9h_OZu!)AP_w^~#)PF2ub!I)2wMq4 zRVsIY@Gp08Hto#q;vzEqM-dHmI%QPQe6L4szZTv8vswZ&5_G=S*D$BNls{Jka?r!127j!%J@4tT8 zVp#`M=(4zjI58{`z+p9!dt|_E;f(ZZA?gbMUE@zJLP?4S(y(5Vs_SWnYks^G{-+=E z@%%OlpHK=( zrcpRtfx;~Hto%u=fehcHuQoP{LKeh18<$F1r3*)5W*%RUU36U)2o$k4;z$)+fZNS8 zd{vI{-feS%ABV7o8xL?(-{TKf_1q1)m3={5+LBzO1@6caJB zg+SyTkmL-|q_{fZVscewV0smfCHm&(=da`|aC@mrhblZCa{>o5GU0IchMTMFwmdg6 z(_2Y-t~De3&77(ZYu()C!3MWF3st(7#rb^W02DD+$GZDPfY8d$I0$|Q=?<1CcvXlP zpo+hJ+eV631zq9Ey#+07oiRA8ZXO;c{=#AWw$ix^g#Y}X`1s*A3cs!tX7x2$D7@h)D&`jc7EI6LjPKoJI69#P}u?7%2zHatUQdNSZLvH(AQ14{+lqWI#%UzmOAZ+ibxx=Bx%o4@^Fu%uIUwrXJ zf(am;C22TQra;K*7z{cVrg++6Wd4g^NDahWUcYXwX}7vuJ3uHA?Cog1YcRUw7M>1j zyO89nfAGCOeqd~F?_*KKG#~8!=_^PJwENQ`I%T2K1*^P;sJE3vpPS8}rxM6M_asvF zpm99SwW;P|DPs&(PGm1so3g1U4f*FFb*$@d>pGt#E|)vlU_l&Hz+wS&hzd!*ChvF7 zU-2n^#)PqQ+E`x5pFA?`hmp!!f*DQ87G|9W2>)3LISXENT+YMIMZ@Q^Lum62~JqL}Hzz#2TLp7iVa!Ny;!7U1!^k3+29jauwy(03X{z z5zg64p@&omu^;nAe2_sDPA56YAaq^$TJUyzAod|s-ize9TFGz6*f3K*>c)iHv2Obq z$M0sPX`=2S){#PqXr#Jgw3+3=5 zeg_&SK1tA?G%PwC7Rv~v3~t^KGi~J=+x*9dt=q^MV)~Sx)qz2_JSEJ~EZG9nyc2@| z{2wlbGAPCm)i*!NS((#U*m~?&@tItVH=;J(rEl^_&)s^<%j_lYab|q)9#2KmH>gQG7kM!HaWG128x);C>`uAo)Mru} zYh8TpD1pFW<32ppg%orj1+rAgo>e5JA(4gMiIYEE>IQwp_~ynY4)HaNlW8}YWckcw zYAcHY?$$+o{`Cf%4U5XKg87X^s@s(8yY#XT(g~XkPr!Lkj|GfIVn;WDQW#q(?BNEU z1cXyY1B@T+OhbdKeQtf-y#s`J=Y|GHO^st}?x*lM!Rd*0^$-+t<02H>R7}iL1R~G-eEHsuLEivl3PXd(hgQ%eN3az!m0(DJB(Z|EP@W<4 z@O;{)$0bg!+SD9po7>%8mo;6(U^s%s-i}FtaD9CdPYlcc{Q)<`GXo?0*CD03;{qWrR#dF7= zIq8z&qAi3yMG7HLeJP+wIBhJJPl$V9Mo|gw_}2TN-ogwK*J2acuWnOi-=&}x zGegqeK0i2b%UIuE{^g?}Tq=!iFM}5l#uf@-yBXu2Vhm;**7sYV0K)aylzXX6c|2nx zTBzYUOkv_2G&?n1dQ#S2gN;=B#f#s&i1b3kHs^3bmo*ZNrn}OiTm?)JP#=Lc3?;5L zLnvf!@^Js*FzD*$aGmFnH=P$ZZnu#@Q(bM+s*(QT4&zDUYH+!(Utf2x=kqv#E&KC> z_&ti|7$wqC&O@bqHQ-k1%Z!$a%Yp|U&vglt*20#%o|!c(-w49H>apEBmq=7KepH2h zi>tIAq|?}7S40~S;i5Br&0wjEfk=uPT=d1+qHA3mXB!nxK1;~n0K1wIrw-eR(^<(M z^S0;CCUp_F$_yJ@cD4YaIv0(D5pBikCMB^R|4L&BR8A33WBL5$WoT(8Pp3>KgPru>J*R z^eD*8qeqT0SlxM3R1O^%~E46>W4Kt zmvE=#2gWd;*n^8e6tcje)q3X48KRJz7@?8Hr#L%^Rcssxa!QPmAik6yfS3O&9>NxN zMa0uUBHaCKXK-9|^cbwfKdfG>&!~YmrZo^Zjz-bjk2!aPP`Z@%nx)xRLJJ^#S`rzi zelcqt$2VtV&`B9D-&A}J24uK>q0TH!1zT${tY$o64F%cEy5TBDM$#ZI?#^7z96eSu z^4$a<)DFkf#fzIr4R%52*fuD!!RWr6IVy$H2p_a}g@%U0Ln{#bp&>D27ZQl9Ny2r>`l6UjxFDsOvI{v@0Zq1<2$1>;{Ixd8P6e-E83G7dkJb!;&Wjh>u-!>#t9*Bq z`$n25u?9`E!C7&dAdIiA5l+kZ{%)oz-yb-L~v7P zf@c+YxDhWc9Q9~;?kk!;Sis?z80%0`xzvQ8s6ygMq z69M5A*=u<6rVOJKL0Hq!pkB0E6$nodgi|=AL5M8P;CGONGvpfExrf^bI+T5(HKKIw zm?2TDcf^?1#hW4Gx+FE2;aH$*2Awb$+idv|G*!2%LZ`>gaM2txLl3>>X==h6nt`{X zYNvvVHHA7=m+jIZthYq5fSH|?W-vy0hPWMW$huG$@%%v8O&*3inz;$VwjH@=)Bda} zJ&N9@q`DfjUnq9|?@D1wK&?V9-t_oUZ3lL(1Q;Cb#s8o>dnBU4De3|Au}YGqR)2wG zGwlSS!C&|FkULaoVIyC_@5T;oX>7%Ihm%tiwJYvsF6Fxuoqv^L3US-aXVwI}%W6tP z6e1=v8TX-pQKp^A5QH+@(c=LLWamp(NaaivOc**ZtVR~_DhvX;)_Z5poIR_Wdf@h~ z_3+`wMyrz>H{qeOnF>mq%GD_94UWOL#>U{_yAlojuN^29Q|QvH^vRMUw;;(41_&2A z%65U!+S`T8wqqS2q^}K4iQCOpwe8%R!YCUwC$jJfR85DR&SmYIfRN)nrggCzuJzC~ zx4O#6%qaV>ji}QHRXI)%l>b||nvSTOp$Bu3=B?!c+>zqS>H}$~7MIfuAPo0!t>X;F zmjb`Vew1g&i4z1Ni(;?=7nDs_U7JIKNCyTQeVMkX)~0r$Yrg4hHWWI7Ri7)>H%l=0 zRUrK5U5{@nh0Z+TvW>0(ueJAqZTd|2J)=|3Rp+7|B+6>GP(&4Ht_2k-RIGqOC{9GA z^hC5OcqKy;vWuhbFcA8uz>lLG;%sz zlNdH2R68>XY*m3FHfM~J!|9`~y4%FBem!cLZVQC0kxkSyDIFOWK{|nOe4Lr9a?hqqOzrO8%oM?7N9D<2xOVV79D2efkkcANE{;5I?N1 zr!O}=$6z*bQwmwdGgM4Z=mfBKQ0=j4s9ZB-$aP86Tp6{iAztkZp7kSHI`3cX$cN2M zEI$m-db^ep{ZZ>#&+HT)wFx@W@Ca@MwOQ|*rwfXGh<4M&#s%()ZKuTzZ z2z4%j}-{hZpPX1xzObh zI{5k{VF!e4lv@jl1}KCKnbMjXLR4@e9?_dfK=|nN>D`2|0@DwQ>T3`l53XesX~ob0 zHHUA~uCY&h*DA@I8nGlw4A4Rz%>_g+}ndSTtVbQAt;W>`W>xolWVjZ=$j%h+x#!K`Q9%>*^hjj>e#got~d#OmQ> zUIo32Ivk{7?L^H=xGj8^zP^*9#fFRjgeFU4a2VT{y&-&NXacz=J6qlBtFr{tp>zT> zkxU510YzMEP~uXnqjesyL8)ZDw0-JL7qM8+Upu{C>%vWoc@AAvw*a(?>2$~a5d7$K0H2QLy5FZ@U6W00Zk%Dg(C7T)=>hCh2%H zP|Fw&9Yk#*L^;`r849&(FP$HQR0A%w%$XDQR*z^pX$HkQ{f`jvOm zlP9tuD=82d3B(f9qC&<|$6DCo^>0tBIZ%2FW${yS?VNNUS4(tIUOue$gi>(7uy6o( z`hWLGg-Ay@sk;SG)hQv6zm0hYBzTkr1U&&{suNd$*$^i)+`^s%Yz_?w(^lEFK)7If z31F_C?dJ-P@3H5LrlSkonTC`J!DX(;8bUs>2s0r*DNKyoAw+{5%<7;jSTi(2)yxW! zW*D+TSZzUA9X*Xb7@D6BzV=!*C&^LieJ#ZuZ@L)WDIkpaeRxu&pLX|4ZqF& zvc$D=)_3uu5!do;kHNv*9GXARD+F0w&0Gq)KS#S-Db0$(E_;+2p-#I{#o=O+;wtnQ zmD=3v5pE{3rd@`)U5TD_{YoK1_8yF4y{M`80I%W#z#*@h9oyYN{LiDloy zWvQ%S>QOzeXm0T`0%kZmdK?fQLN<^2yg&b$PTgn+MI;M>`s@KdkOzuQH10*uDq}pm^l-atI(%3|tZ**sB}Ont2m>FO;BBHLw|Q zMRSPux3=a|?^l}DN}~1qHd84CS7sEm4tIoDRFNDEdvyeITe^=`P>aF1mfK3VyIP{! zIW{0meZNlUxelQ4^uV5&)X2I*sy79d#r#O(Q~2Nkb|WlzM5P%aS>JmQa7OS>uTE)18;cp%H zRbgB6aiU2wD+wOgxg@9^Mrh!c+{!qAMbfKUKJ?}d<<*hMXt#J$;3lr#lH%d25N1{# z&x9ITj&VBCBJN=!H^ULtbE--P6VpW3rz-zNmRM0JVq&;)eOUIX(*!ilSEKEeb>J-! z`uJEjPUE3kXJ-y4%dR761c%Bjo`FVE|pdfUsI} zb7#S#n%&T(GIDcZh!PLT%&>*Dg0iq&pbwXDN)9$QT-Q`olNW3NC+z4SSjFY}J5r&A0L`&3vvE{Q)P$O3y1B1?siuF;W{wV!1= zwVrOsMuz9-7a{^79@xSnAk-grU@@;xL=qZ8-(@K}i~>SGi^<&XZX`A$W}s_Os35F) zxOweB_@5Co%ekBh;X*~d&nUOo-7SkM+*oT-a ztWe5dB883jRyift)S%B9;q%BHCb2Kwl#{%V}$wi?tJuUtiHar_50Etz8Fmf z!)#$hN(K6?P2!M(9U-n8ksudYkUhs#xFdZGX7e&b6^mR7Q8 zG~6(aGso$K>KmX>6(NkM7QY-23WeVdc)j>18$x6#!Cv&$R{>$Q%!GkA-oSw|%B9L! ztu?|%ff~pT4~iKh=f6S9zskRq;3S017!Hc(4uWvD;bE)Dts`|@`Bvw7QjJO_p7@l6=6 z#!C0iEvqr-L9h`Qrpyj_><628Pro7;J&PuUiaXw)oo`iEHji7ld6aK2kR{nfvPF-e zC9mU0Y!gW{kU|SQxIu2S3V#Y9)Ehu`aCa-|LWz2`?A2F! zU`z-JBuWHsmwjHwWc22milG{IHA9l?5X>8C!#zl$Oe$X=f<5gB-fgtQGdm-0C)gQ6 zr(rDxt|{`W0+dTQ*}xmq7V>`qDSs3f;t<(4`GqgmA;vnA+E%&kct}!(p0;{?6#4P^ z+*cr<4iwn##wM})wjAX|cOI{Q`D()!Uu%QtUpJyKlMtfTDh%ZYoWvs|w;qv%C}?@! zdIp6#GBlrDbwap!;6M%tcRtO&F%XcXyX7^jTb<+}$L&V{yEMRu-O_w4QLW)gi+iM9 z!z#=`bczKyLempDS@l2v|3 zW%CYjXICQOhJ+Lc56amF7vs4(+Qg`VPQ0^eJ)}}mzEU%zRVb!Q#R}!Q1j2N>t4+)W zM7)dYl9G}^)vLz|VcS_PLk4MWtr#Cxd6{eoBM~TywEg2hil)NjK}i&T`W>24c_?0f z`%zQh$XOiCeh_{8!Gn`0Pr6QS+z+G>cO0UuA!;D*pvQ!=tOGOx;1OLEM=&U?!3&_R zUf*WX#D*m(9itBMR2cx%*5^`%Y5(-L@_(8~sdWlE{`6#|DWeWa@Vl3ff7ehjcHA33QwsfSV%Wi@2WMJsCEWa@{1j&v z$fI0!XCr9Nf=fUM!?JxgvY@dznHerqqxj409F2sObB1#<$_s`^g+cMSc0XBIFoRl8 zlXSqBNUpPuAuar60}GULU=zIL^16wIvsJeYE?6Iq`uwLr>F`0%7x!nqvkMtoQRR2NL_2GwruxaDQc9CJd z(}#GM=ft23#sD;uA42ogNCgUFsnmWGC%u&8q&k<|z4=ZB#SBL(aL7l4+5yHdoC+!O zUq>1L`fz{9x7acdTee021~Fws3zxV%p~-y)Qhyg;fs)y|3<%4#xKmiwN>~so3NhWs`;j+# z9KV+Q&Z6+U@2aBdS@{C503WXsBtubKQ*!=%*$2_>8#ito99Xlly`3IT%s|(`Rt&iq zsIXI+a8S9>_A#oDV%x{}8B!0MIVrmTdGiB4Y?}X~1aIPlw;ynqaPaKG>guT|ZN|#V z#(axs9{O%I>>B^<{c(8sK!zPkHU|*M9Yh&6MS|T}0$F7GR`!YAOUq4#kjeptmRR-F zwk*~Dygih0g6!SX>}0jFl9i;H_=ha&$XE`MnO6x*h#_GH%lVmDxsJ{fxrEH`F=0Rj z4~`{rd6)`gtcAs#CM^Oiwz-9S44V*A4yURg400zZAoFMjB7Q5-gNMnv#H*_n+thmP z(iMvqgrW{18pLt0R@Fv)Z9=F@)XJzIq9KIqMLB78rEDlf5>t{;nR1tt6G47zzRsz!xC zSfTuu2_cJV2H-XUCAvP^*g}DvC`N&LChj{qTBraI5Si|u-|5@IA(9Un4yV301+X(AitiYg4&34_zZpyY&AE4pgAL&MX71K~mj96&Ig z27-`NMv^gtl#D>ga>o9CGMFr1&`~MgXKhTfdo){Ehb7e*DE~x7;xUet;2*pv9 z5W10C#0&`Ec$_a|S4d-9l;Mc`6KiXLp)!*QN8uE)>CA5%8YnT{coc#@w-DQE=MfyS z09AZ8E}~s(ntN2t&nHio-L6JOO$$mJF2LJv;^pJ{Q`a6Gfz!ru??bAvGh+kkc}UtL zmPNUFKuOfRm6O8droxY=rrw9Eya}Na?Vq#RyXQT<%1Sh}^Y6)mP+gr`3SZ78EPE&A z{^@qlY88e$bppaH^K~+(TuUg#P+u?UvO~yq{Tc)|cTHaV8|gIB5VB`LAVe!0w2{wm z-+r==tuY(hKZvgQ-~(i$SFC6^-QP#J9uHBM5cLVHC#+c87Y^&HBCL6MEjQ`9a}%2y zh`{#IZs!m^R0g?OLa|S+92!<5`f>DsBKzCJ$f@U||lG z+MY2LewC4+nV4V=EQg|M%RV(cHVDxthymiWr$V7konT2AX;H{HSwT4K(iuKiiJ`+F z0X?jb+v=@!GKZPUlU$ypll`(zqpt8kVO;k}1p;JH%8ON@gJgF4nO2-Nie=fww1$mL z39}becY{jR>_zDtFw;tElc&ni7|0Mp90)216LJJ88(x(8=x7;z0Qw-M&V*3vYC-5V zn1$|gKzN=jGBViF*V(!?{vf$x#eN(E0X&4`YxeKQ%DR2kszGbqW z-H9G!IDm&Jp?{nvW82T8y&H32`^Hr(ut_-Sdh|Iex+Z&kU8v(i@jpLbj~{pL8h^Za z3jpU(gsk7 z2AKvf$=S;>olF2>t^MpoyL-Arvs#9M6oyS524!-W6a=N+(?Adqp4L5|Rw|DO!UpST zTtUb+6``EUNqU;X$?9s!?8vW}omJJc(g(^$(CwoNLXS%o%}UiQ*HbivdYlllNKj0F zra@;dPo+hnz?9H*4qyB0Sv1~DyfP@FM#@^r8(s`>?d~Z`kTLb!{-wS#~GzW zzWXjJ5JtzT4YeONi)#>#T>oGrARMZ|iygeFVqVqqE(sSDg#DSBK>hJkeS!;~TG!B! zXJ{o~7X?C)*haxMR_{YMF%3c@5k+4-P+r-mk~P2lCHn`xgl#?yQZ$~?b!8ral8|v zuYtgE-w_C>k0Y3k(Vi$c%!+7t?jz&e5dJ2QM%9=FAy1;roPL;qYX2u^f=7=Qn4t-N z_kD;vH#8ts=sYx;P^DZFis+D1E0n0LwR_P(kWF@?!vGk0a+i>BMRbg`l93>&^*GKd zJtGn2P|e4fKVq?R4Iz)}k{ZIOtn#!Sk5B7jMGSdHHiEJhlnu#9sz~=|S<=XIr_Xn5 zt0^?(d89@#Erknim<({%Ltnmva9AzJx``?+5T4h6uJlnw*^dId8DY9E3LDWTG#-q; z@x~j$;QYJqZUl6wm5qQw1z|LB5%?i1Z-cP!ujCXXQ#JTL)OZ$h2Yw&ic@khozieP&J5>4^g$VLhTGct~(7&6YvJH)ic>}4uA z5DRwgY~2IdMNg|EZRi;LHMzWmCE$wx3gbW0wu@ub6(rtDeQ;0(*F9X7i zbaIpGK2G~v%ggm@jKR$rXE0n*E|GB!p&AeBbkX*9#=orGR!L{6+-BXZ?COT)MT%Oc zhVbG=zWUo5LfQZE#}G>? z8=g^^2T^W_;}sMk;!!wb;c1HatgzW{=;l9gI>dqU`+xX@^3?%_`xsX+tmx`GeIPy= zsOnyjL`BlDx;s5Txqr>ZjrHi;L*rf`*2AK((J}0H<6l1B>3w{B?4KV7E_Z(V>EkU7 zW;=K6$S+EG>@{3jhjmL#g+Kgo1QQ`*kuSfbpx67HtKl3m3TI(m$q!Xj6r?4fdxuub z#7^6K+=_FSxj7?4qvB)wt}6;gmkfmW<>OskP?r}6v$3wk+)IZ$ig5Y1VX%}TK6PNZztN4 zJ^Fk{L&#Ot&6?RJ)|w&Ap?qxZu(!rz7|!q z0-=WxvO^xr@yN}JwL>*bD-Iwq8Dx$dsT($PkJGas(`9O0#z2iI>_rCwn z{~UP#^2?hxZP~JK+v8iEU*J3@kpbazt;a{;%>$p{-(rtBkvGBk1e?P3ErB@qV7eC{cy7>Gy%E-WM@j8);K z$iavp3?*Tdq*mI>CW|%<0A@3mlswVGBa8sUL=(fWG#Vfbir=q+3?Bw{N67-e##E+|2qdww4UsS-ZJU zL1>t>Bn=2D35w)4{Ae-O4#;613K6C52HjEcXFepYQi!8jT5}0i2%l~F?D!|!CXUeE ziId^BZCkgN!g=J$6JLj)`7~ay{^@FX6~+B4RzOtsiQh}3>F5FYCQxt*A=j?6<2)Fj zIREe=Y$(U7s*b$8@65h^|K}H@BH8bG(W!8sic5ZrMB)3??5AKlBur4W7%v=FMXNAL z8-);CK>^xEP$+IfxOeZ>hCFI9$-0ZVq;OJysUugm(IlFb41=hF$VHb!5k-w+Fab3f zCC4DiWNChQB}lfT$2J2Txi0F@gNS(5T+nRb&xp+_2{ z=CGw>docz(j1vj7Jsy}vFUro2uUXyMV~0?Tte8QJY6!*gBBU)Z@HxADnaRz!ku&cQ z2vNE5F4CSZ)|auiOr=;}HyB)42!*f?ulirEf6%^vfB(v%{rfipLJU#=2a1PKzrds9 z&70$jK~>m+c~~HvCWMK(5hN1VQkG$D4a*uJLRT|D?U5nvyF5tqZ&YWqtRd|3MviRx zY~rJ*+xEc(@W?){dQV~c5bVnDh)s$P8<#G>?i~#iLUxb(QDEa`?H0sJNj@a;UzUN6I0h@1;FprrG?!^I$F059*Vw0+_Um3~Deo6Trix!A6Jl@@s^-qPpiTnonm?2WDo=NZ6|~ueu&`fB+pF-*=sz)q&3>>2Dl{S zA6*WoD%=PmJ_AXYij3yc@P}s{GJuwN)N^r12r>7~OjzUh4579GbvNi!K}HAf@N^{o z$BB>jy#F195&+;PSTi+jxeC(a{sy>@94;^?9U2Ka+DE%{=>w?AGU4#?CDd?h^kKj*o zw!obzXqkgms4qx%L=-(9W31k#DZILOFJvY1hD{3R=1#ZR(u8jArD7UFIUQ5sEOW^U zy)_1dNIR>=CM%gt^W%Wwe~c2qf}`4(g2Q0Yn-=0wCq@L(5N}R!tWY3>A!%=Ss}2HW z=?n-}Xd&iNY*l4M!L1$Jp^W{Xf{;HYHRDw}xK+)3vk~3R$0EJUx;b!?-@GoRK+{z$ z%T2SYLciwd>ox{KVf&io==D|S&u^@b?#J0NEqG`c+NXSFsf4t4Kx!;?r7tM-5W=KD zn2^Ld%>yWwgc~3pH^3TKRMlWp$i7kR4@c-|ftI`qoFBW;4Z64uK4aYbUp;bW-`JTw z-@$E+cHOW>^dnGKy(8LhaUoK;zL4Fca213!<_fg*Jbt{3PN=(f`6#B3V)JeAy4(55 zC$Lv)Ys-KzJ58Mf!Y$Bt#{{@#%U-I7K+>zB;iLYRmO!-!Iu|shrz<^5=63nH_w&wI zO-}ZdO510w0ThmnU_^4@-1cjk3?FE4~6Y|e9a;Pm-*?m(vL z(*+?tbV3?wzOWNQSNnEAxE&A%A}nCINlz$t*WF|Zmq0i;q99bIz5=1!31K=-4}qGs z9?wb&xvr%$1LjZkD<5KOO2uX*ez?O#g&I%jBI)`0O`G66hUFL*$ej~kZX4TnwY6wR zkY<*rTTuAL`Wn=)Bcg0_p~eAcR2|sqrr{;H0>|P^SpU0!_bH4h`5x_?sH&1cVm^jY z!jSBLeh5J!9m%i`Z`ty66EoF2cQ&w+B~Xpao2-iGVH#n=2s%%0DKUXJ;ba$8lCW)z z9Yvx!&thp#`)zyd6v`zwRgqLG*?54}A!Qga$4|q zwG+vpYI1HfAWX>VozcJ|8En`fzuyRxaHY^U*i>$mn4WTyG^OQ(;Ek5_22h55K zg#9Li3k$-am`P$#xGt^?TfM4v#YYGuboORM8=nhX5QZ1*5V}@`N3Y|=q`f3f2-##z z`6SMW6;jM@eFLHwNC{-x`$ZfN*xFG;|<;9K{OJs z({!gLg>7Ryao~35_@=9^4cl5fufhPTVZ#O}pZVilIH69kHlD zSjq!bRDoQw?7L!zq%Diw{`WHoU)1Z);i!eyPR%Hm-7#ya?f|dvwS5H6) z@p?sWp^3^7(vPL({!6$MLhylfc7VNTwJZ|Xr?*ip=%ieupuP!l3`~AxEcsl&9 z+6wbv&{AX+2vxe-U=RZkzWZT&NfRMV4~Z=l+>+Td&z#{PD}5D&y5w9SbeRweh5h~X ziuWMHNbRH{lw_~Ou5bj7-F++R?8A;zHabuV_jG7+vLn#8bLV$s6IYLKYZz-CgV6+J zg=vCJ*Z4{LEt;;Mk)|Yjm?0k&iTLs{2~JKn!}ssnpLSi-m+sR-i6la2@rD^;$qP+| z6FRCpr2J?@JM zpr$Z^`CQin=#j9NOAEp|rO(Enlq)uMiGYT%PQ}dgtz&U1v5B+AMj~H%ax$orFk&Mn z5K`y7#xY!(U3IYidxq1qBcRF{CI| zQ*@QUr_La45b~49sjzm02Q7?;8I3?q2}KU<)`LHNUxj*~aTpL<{Q1wJGdABju?0qn zG%%r@_1F(Pk$&5;qo^nr`_rFJw-l(>kw8;5+I!X~*JEi+c3+F~P@G1nfN+;_oeRf5 z`Un+p$$+Qe*%0QK3SnLQ10)SQw`mB`<_JOPusD$L7L_qVOP1#}`XI4$Wy8X}XpZF< zQMMb2;MeOAR5i}q4d%YHguGd{Ag)U>PdUs=cTlboF z>~ygw1%;n7K1MXLQZX0`g^Z2Df`$+Ukz9Ce5CX$HwKcSs!coZxj4TduH5Pd}kz~?u zwDw5u4~JUjC;#}zsi~_p>mK_Oo4PL>8Zb3(*Z^nH{Ih2ZkeN$EJ``Eh6H7(mOw;b$; zhC5rb(4mUOPUVd9@_zTbMTm|el+06&b#rsJYC^|=yM$B~=tQ!aN!AcH84OAux!PQ& zdE-T0{6GYyEP!MF=-5=0%D9VCE$g=0_zFcAgpF|229aq36pjxYiVfpB#UTue=*+BJ zLs&&=MfYetu9sZiJu>a5^M!k^jXjR!zyhBTTk`a2 zhd%m!T_1Yb7(^;(f4FVUnpF{`K4HPWvhUNH%`0h|+&82dRDBPUVFiT(p;Qe^GgjIt zWJCKZq}8F&fZQQYPS#fNBw92&vBvA`fn94`S$+3xVIUrY3E9~3GY#qo6NphDx_|um zx8Lr#Uz#5)C}jC{n=C;v77jK2B~S&Y!*Wpgcr+Ni)_l!&mB+g&7F*55bFsw^p}pUI z$(HxMJ0P40mh`~N0w)ZFM{u-M66(lXmPL^=3QwY&WX{K?Hr#ybcNiTVjpcc&^xd<> zsI5&bs_H70Cu1U6GRc}jy`!5mPBS!}dV0NR7C$J>O6HRNlTVM|;!(Q%K2ZryG#vmru5PFjQw9ND4=|?`r!EwbQ z#>o-QV7KnRkrEmgLt+gfHWJ$JMJPnpdM%TSXbqqahCJl(OQv=kLFh4Y~}E1XoB7qYU|hzjZhqwkJ>v0{GyvHihbIxp2> z;?GMjy$&y}yU@93&m)t;ys}u(=X9Uas`D%7Kzwq1)4r*z zQ=3|!Vm91*p)`n^*V8TGd9f9SG)r9_-eG@R;Day5$4BSibwKEYsmE*`dg>!f$Hhyl zaZPo49zC)kEGr8l{&->u+xR19XJ8XkmkCw%zt|!aS`ZE|K_PqJW|>D;iR1^WfXiYK z7@3QCS}E=iKOmaCNo$DIsl~Q334hBJC8vZ=kUef*N)9IR;k?2UD7ShoWb{pGKpA$m2%Z_2q+8Si0d1gX4D0CsC zo&o12`c38;QmCmvo53?zVY4%_X=a}pX;}!Dm@1nN#0Myh)TPH`tlQ|;`dzg^ zIA_(E!gW_VB3^O6mCh2r}jI0?;;|iK%01v0ijzMoK}ELyVc7IdliJ<41T65 z5iOnaO_WKyeED)rQ%Eg+KC2x;uN?eZ3|bT#S%XLb#*Kc=y8Og%#1UBu`)`nk)>JLm(&oVjD0!;?S!n$)UX$E@*cDTl_;Gq_LEX3DZ*^I0io!1A=xbqCQIfBVG|)#k@&noNG)N- zpwd-$D@kV_+B zJESX+HjCHa`U>-W(xvtcJwmOE^>{OM1B!rHRP)aA5ITHX7K7d@)4Ix7-kET%7=1{SVl3hu8zTu`h142oAP%@XXOVZF)*ARLXgjH^LmC29Ej@a!a!zijC zg!%J~mJk#pjn&_82=SN<8Wbjz7KPKcfg~o<1<39Mc#c^wEnos+on~-)+JG=&Lg*F< zMchds)Mo*Vl5ujvVg|&<8p3#-Z^U@^MaqY`N9U%in?T{y<5#C9&NOVB=zO~M+f=IS zK&-_FjbLTAS;s!1I`P`HD4c!y49zs}U@}sd)iX$t+VX#dG(fqe4$D8vMG__G!Rb^3_w1$Jh>GT{;<2>*WjeD!) z3p+orPmpdDr+DQ3-I(zms4oF%;VTY3XD;)KCQgv)p9Oq<^AR&7q2m(R{h`gWU z<9tJLmSJHm2zKiuTJ>0#N~!Pt`ZObK$iyYp73FkMqAt;OLoSXv1+iAvnsG`sPU*%G z!X|EGGa-}>fH^~H_eyGLdfiS4jTuZcxMGETB*-B3BNc;@xQ)W9DvQFTeK;7z!1gma zPfZ>Lq3%R9I>Dq7hs7&CyfUqE#}}^|l+Hv0!jYPre;&Ar(n8eMT+%m|u)`{ueUW;g znAG9B+OT8d>E5SkfjToau?2PWd$x?B%Im0T1fQiwFk3ZDt4-tg)FvOawm!bKA=uvj zD65?Hxgh-93E`$MJ3BM_>5x7Lg9RZhGxnPw3Wb2M_E`+N-E0@>SMQSMLoql`1Tku@ z`=U}WYK#COG!X=S^8a2MLGiNaJ(b!xsemFW46@KrwJiyRXNAGDf}rTeQC^i0awe=* z_1}uZDnjUy->dSM2@PSSO1zH@f{eYKV$kbdv0}U2P6lz-E)1sQaf`w#+i);wUyswe z)hY>Jicmx`s9F&%230qh&vTj(iZET6FFvdp6xV1O(I{F|pcFfZ;+oBC^^LTSD^X|p z&Y?b_1^Eq~6Fc{g?b+12Y3h?Lohb79VQLCzC>{CG2v#ymtdm#nU+^i^x!~I5&K)~$ z-P*pYefy*TKOoGzkhqX>ODXo-1qFqLP6qQH{_b}Iq10}f%}qHOB!p1Sk)w=&;zJM| zA6F>{N0U_48kAtgRSO%XD+{N^W*%v)Izy|_rCKKxZr`pcWTfTg1&zk7;b5@Jz1U146X77f?(ywx?l? zzQ~=MHht3CIq}_Z(S3>Xns2p=QV1Hs47)t#{P4@0#0t_{_~y0V+P;0w_M)G%9)F(5 zY-TUZ)L1Ajy}*Xj!orN(C10IatE@{jgPB3H@mBFt`2AM#etO(uaD2Sh1lhqL+#B41 zDtqY)%XoOACJa)nP%9dlg$cTuGoYJNLZVw}C>O@gS`b3M5N%Qr{%uhZ*0QiHZAh1B z2ty&G+>sC_6ogiqxk*#g-!HADlJ#65Fl6q=tMPyOXOoyt2 z4-Bc0KhM1Vp#wt2V7C@E$Y4+?6a>+MrqqZm1jlPlkR1pDJ6+gsRmA&QH7a{`Mk2Zo z%4I>QY(ZtkXErtDIcp7`${Q3)T0E@FF5FbrNDQZ8=xL)6?gMrRJtl-{gF$6MDkrz> zu^*KKlttMBrX37MA`S*^A-0V|+YFvo5bCCEQ(-YTgmcnZfnk({SP{@8SqcT)SfetW1AQ|-T;kYXn8>+ zI3zOHEX|wcv3{){8?Qq5=j7ELc`pQ^P*~>iJzEIJzJITc$ zmyI@klA#o_^h#_nC=lv7&s=>M<^%JN(iJp6cvaS-q{LDyw5Gx)t($3{N(Jl;ih$;v zd8KU-x(OklK;44Kn};zWZK0znR0UKnL(!{A+bFBd6BryFU6jR`4O_Yf&@2RuI2p8W zEj5L92Gjkj+$>>0C=!cHK{%%%%w|v;W$!?VU_^uRG2M0|0k!*Z)%8z%BRH)_;r{&S zb;^vQpAtuqNDEF({PB-__ihayAiTyjHLHb2?(91y~=`9dy%|N2NePi^OhHG`5v&c&cWC)OrE(VN2XGApE86 z!gSZEo*OCLA4Rfx^2rmZYWXJ@A?iB0WlQI_u16yz8~K?c4vdYG)1#pS2;ZcUN_wB+#jElnvWc)SBgj6I+)4yjo)~Xq{u^o(R=J z#sl@%2b4l9AT${Cgu^xnjZ;#Y3U%d*JTP=XnzPe31QDlsGANWXniqg@7O>4NnDso8 zlQbce4gjpwXn)cSrqeEyfAh?ig*4$sXgt?ge;t0%brMI1*SRMtcI))JbWL~ybR5FTlT zKFnvG?{C>Ob!6&HX(=>5m93W3G#;He7z{fQB!%&LNA=xw=zt1* z`8G>!vsFoLwE9h(5T;ViY7`X}-M@do`5XtlwQv~K)m2)0?p$SMr9ha*7pdmT=5>`a zQZgFv-o0B{dG1_u^WD3L4S^{)JpE|PSf^-tSuGjiHv5Oa7N*{LFFF<8 znyXL1%Fz}Mm&H7}An0bK44M#bPkZo1GcM=4brypH zVZI$gsa|nh*r1)l{APn84Pm2`!NZ505E4T*4+d=%+L%5k4C?!?7|jJCF_hO^sUYlW z?rBt?(4c;n!^=SES-;>-Ru^sEs-CwfRfG>tX(|6Ed|kR>!@6}i$-_DBg^7vxKl-E- zG6`dQ>;i!HebC8uPa9qoLhR_~UVE*+-l}NLbK^F5-U|#usCzdBK`H|$wOWdEu!32q z@dQCYsAfdfN?;C`vmp`=l9&n|S>4b9bx)mK^NW0NS{O7b+WyZ z02<}HqP=hheY)<#g)>m|egBiGPxg)3ExZzT2(Mnq-RhZpJ+3cj1z~x;+k<&<_ikID z0fjwB8J8N{wk-uAO1X>%PQ~D?p0eiVG8qJgMkbl{F;O`?;qJ}JpeutxR}@pB<9sW$ zND2%6I=7}6R3g>}glP*xOeY3}jimx!QA)1bIU9rt1z}}nu&C(n-7bScf$*FOVY8~X z$b=AA%3v@*|E>cVL&4xiW3qN2l%>l(LiJ$CHWsdekNZteVGYTNt!_DvnxXDJqV ztSJ!;uG!kKOuuo~ELhK;5_s9V;TBb9EywWI@FfZ+3o=QAbm5W^KFKq>*abl)PwlF+ z?R-rJQ8S=owQy9`;0uCYCxSKz^#TkHQK8T}+~QQIBwTG-jesy{99o5$+98CE7KFV1 zrKQ}aWkHCSgS}Pr-AW>5Y{G)UbA+(;Txlt{hU?ZT2u~L|A(Z*TV9=Nf6@>V{GRL@K zV=$%6S}X{I84xxaEESE8CbA*Sp5zP&yY=IO%RvZrR`|{agNN}qY}j!4u>3LW)Mllz zaUJM8hOrk*^0tW|o^GR*mufN3gb)-q?%cRs(|b0ByYpZ#4_~!1n5FF2#r@TA?MZnG z3bKw&8XA^_Fi#-lo=|C13xsuba~Tj?XJw-8p^9?bz@WVu(iGowwnMsb0Jdl`h+h#Z zIKVZyP$Qi-M67S6wUaFd(~F?1hnLa3I2e4BD@_RHCJkY;g3t&B$iumFcd@Yogr$J6 zOF?*AL739NPktdOG#Iq)3A>ks(6&Y^bC%$!co+{pe3%#>6AIU@qpUfsMj9qO7KILZ=rxUvt3G^@sSr-e)#5K- zUtIMJuYEFs2Q|TXfUW%&h?Q>n_|$L!JsRHL6`Ko zJ4&Y(W2Im)Zq1-Fr`}Te2z^LuL72(`VWkmEY6uewLW4ngVJZl@xpzPaDPxIv8!Md< zmYNKvjOe)gIU$T@K$t~gqgs!*iwyxDuMjNF9d8&Ac6Z~i$T?ZsAiVeS$H-|!N`s|` zF&iG{hmSkKM(jN#me&koT-f$e>-&F%Qjy1mFyXQ94)=F;wYR?zga;p0)48m?{1N@- zckAulJXDuLi}e{0?mTtsRN~=M5I)TF=rp~Cu+C)Aq|jn8VPjD0mF*3=HV7SQ+$g8Q zn5}Y(Q(>X*X)=Y>bzy|g7eVVyAjG0#uAS=g348yu42489_k@6uGmOb#N<&y`gRrYv z7(C6XqS1s{14+^O=st4@BeXUgU6z9*tR?Lr0#EA_2Gvvv>xXv zdwFE{VJW&>F&GYwj$Xfx_}D?=&WC{T;lt%jx0UX*fuO}8DXgorGe`=PP6TaI%&uG= zxnM847(cLRKVA(l7Lb{CgXO%?iSVKv>#kCgy~} zbIrIC20P8o%2!|s2%DQNvKm#F=28%@vq7j1h=R|e5cgEqUPBms287*&Fl!<-7IEXo zV|2i~G~3nH6GXO%Z&s=7CN>~jh`*w=5fI8ab_|jb`yiWT8VcJWB!z44Z(L)vyBqX9 zGgn!`E+t!7uza!Y~OwOe6r}vJf&~t;G@?49-!z-(_b| zPu|{T+HsQ^3=+clfmp1`I@97*2nG!Zb9S~^5EfYwp1WJr-2Be}swi|osAfH((8$p6 zS~(#U3RPfYhp@D?)Sh+0P#u9wLug^BAxzom)5Fdnep9oWeoP31&63*84I%Wn0ipHD zTM9xh$AIwOJvII22UDeLKT)*qej|KCN@X!7h7@EU8Zw)KEIli^rop3t@Vs*&UKYae zZL;$ys_o?;v2XLybuW@N;qa|n^>P2AMVKED@{d1tYUw?pG53g9Lg5zLN8akZq zxUMDIam}O*r@{j}JpkQ+jKmh;}dAp^pD z%uuFc$mf?zbc_Qg{z*n$a_<1g!UEpL3$HW8jWHRnmh9xesp!_V`~6)-1*28DKAR@QFV8zG$tX4V@M!nValH5D4Q z0#F|+T^>UGDFUHAG!_WK;5%1-_V<7P_m%o)1)-6S>#|77gs@9_tYoI2xtYpfFsOPo z^OvA-osGh!AuMt-nBSdHDVm^yuyP3qxo``FvC3ya2=u7xf9PYi@8b{d-&cQ0R`5 zKo6IK@YE~+j{%`4QrDD=K{s=;b_U~d8-zIuJ+oWFK_MWVjK$KniWT36&d|Yw%RqQb zAWYd4G(0d71~Gb4=j;$Jm=mEvp`BiJy}OjjN;ZT&_6bxLOVug7JcR3>1!0kc!F<(S z0tjs@w{r?KZW0EUfUwK@+w$+-Ltk>=rHXqdg@h2PfmAT4669(YB!nvmAiinSUQ5_0 zYzee;NBGV=ORvW-<%AIIMWe66UY@5X_2ma|-%jqPe_RO8<{HA`8#iv8dc`w`CHWK% ziE}ad%03gqB^Z>R%~~6RaaG1ueM*2VqeLgv3zg zE^VuE#-o~@5N0vR7pfnXpO2V#uwvzq4uOebP*SDA9#F_~3%wTOe?x04)_N?#7Ms9i z0zNnG?I%xWH#j|WDlD(7+x_aRu$LDI>kl5h{Tkxs`g%Ins`c3O@ZpUcue{=6hQ{N0 zC1(xIE9H5X6>x3_L7}v?IT#cQooyG%r8~mY>9&J16?5i8d_=nG7;mGp=h74GnA*1`P=7><|+1!-_ovLJ6~%h0t~=tsv~y z5E_$U)`R5M2M?Bp&^#!rDa?b|gp+V~!dlGiB-LnPrt4=O1X7_qp5N3PJ$~fuz@WTfW z5Rvd3cILi@A=+#8^&Z~H3GkGH(Cf)TA(PmSnNTFIaxv(ZN*_TmZo74IOBSw(~Q`tV^BLXF^8U!BVV;Sv;{v*MDjwww^&?dq~qXh5jX zqf6}&cG)0Q$9>O&&^(nkAWS_Q!lTNsDi?%K1_@z#`Jv7FROFaS3YMmDg2GcgGdL!N z&`Pw;Go;2BYgStWDu;Ns+DY=*(yHZXFQ&|kE!Uw6-laT=-?_ffx5i3#1cB@>`4Xjj}1cJJUHUE);l9A76_q&x8^+EX`dfLgThrC z#a#ZR`tBfCV_FZQjk6r>uJA88b!zc6__G*vPG$F(f zZr;>a(heahq*66>{e{36UXM2lh5DOEj}9KBZaLl%X!a)S7e_}=-4Op08-q3qPcm@E zdYuVjBpX7H4Z@6DvsJ2Gxg`lSg-_H}s3jwxITdOM^@T7Pv|SQ~kU&@x39zW&0 zuGQ^s9<2&Sai6^TBeU38?vt2oGnc~d`Vf}M01BFOF(E&W*@Aw z7|gpZ6jBF~+Sj5pBb3FnWM#z(e*dXc3c|6HJddreLQ&|>1)(PggW60iTaO@1ksuAv z;DarTPxAA37z{=iITap{pFaIO5E^l@eRcY$zx{82`=10tY*}*_i0Y|OFMp-V|MBQi z+;}u55IX64P6)ef3=%@P+&>G#(hLYwsbv@}8dnfz|3w-?eyPv6O$bx>4C0KWp=4-G z2yNHR-eu4F2NaPuiC%hc2y-8n=-I4wl?7p$Kqx&&v$I<4=mwVC?4DIn$f%in!iOAr zrd5QdaD8qD9qo6XTo5`7xY8Ml1Ywy9pXBf8)C@wcu;4<`%)g#K?MzwETzMvhcV$!9 z^M5^A_dosJ|8duZ@Z2-9G^IAQn(vcBCtbFp|11c*93vCLvr9o}?I;Oh)COTHqsGVf zz`N>A=00}GVH8?KObChLv14`)4RO6I zVeo9~nGlxdcSju%rgA~3f{_=2kV4=olR`Be>UCMuC=51R3Y2)WObVqE45Lnt>|T5- zv@OP>+W*M+1pXz9+P~x#CI}zi%DK!*+UBA9_o33P7QxeDW5~<>#Z2*gwGL;e#F7(X z=4i?i#SjYTi(>a>D%4sb^96vg^>jS_EC}rzLK}p*X#eAXy75d1bD_m#hco0zEdya! z*OC+pgG)hZPcoKfLYQkwwn6Aw_D|70&Pp1>`i=L@t>H1fLDWPV5UQN7N#UhKhaj@_ z@y7;zFASkm5U#8~7JE`Z>2EO_iXWajb!v&tmYM|B$Wuy^_6)kB@I>!>#Xow!o;lGw z(A!LuQ}t0A0Qnm?=4 zUKsQqwtnTYd-iDL*fCwxDt}QngqHx}B^!m`ILC9W$4+e{q^M)aQk(srq-@E!liNWJ zVxAS0I4LZC@5h;Mz((&c9yb@C`0>r&)wR9fH2-GiEBOt@tABh6ti4m*;p(0FG5t>O zE)eu`@9K!F_r%YC>^<>lX7w-fQ}4{YRYeA`6#r|_H}B2Qy!7*#)jzIVy*eE2UH$ml z>fY4PXWrb?dt%qM-ql~@0Y9$pO$dZvUBmO7DE>FUZ!Z4LuZnxW`c3cZD>J=s{_2zo zp(@&c^56dbDK5v;( z8VZBn!!`<2#%ip4OVm)m(}GY@2=7K1<5pbyhky7uD?RhRN?-w)w`|p1<^KVZSfAiIq)x~ek{ME0{Ss5FF zu;6e1>C}xyR<5<_NaP8kIZa~^x}&T*o*dG18Z(`1!sQqFZl13UOvz8J6C?cdiAMZ_47Ap{_33L1go;r_qYG_s~b|v1?y2WPpAZu zDl45Odd~-;LE$;|9w-RAx|XIewG4zkJq`+kO73kL2u1eEg0Rxo;VDBg*wfQvFj!Pn zB@n8QgC$pT&)gc`Qz%lk#$#Bjn-FfM$2>f2S5~aNbZIFFvnXtDHyJy>W=)2kM|mJ% z_ZRywo@Wd~=m&%ei$WWN!^Lvx-%=3v%A53?nbmJy>(vlm6A072@2$S#oB46(@oNgg zt`oiT77;?LWTrp<<9o%cHH7!yD&Bdbw<`?@gQsWSe6M%w*88cHhVYwT%zSfYX7yKm zp8r_PC4%;+yK;U2h^*tSy+`DT)s04Wp3gKS1 z8C9`^n^$Jb!7bBdXU=}B_McyqA?QJ^{LKEP<>$hO{zXEVFr;zp3|^Ue3Gc@0)xRJc zSBkH3v0mL<`8cj2EWU<_WF{3l(OdlTeDCVw)FVLH1PB2v2-El9DfWr(-^@4j{q|9K zr8s})8_ayc`(G9B{km8|cyQ*;w~9AhJ##B6v|pLIhM916Z}X1{JkRfouN434?r%UP z&+0UU)&h0w?_~672)pcEM#0LAs_JYAn{xyvxgcDQ!sQ_B>9JE7G$1qu!2rl1!gKzQJ_^aGuNfv}F z%uMzE^BXh#OD;sCFT|k7(;u$}gl4_Bok6U|jdNrTTeaH6zZ9?j#lKuxeWLiK-6zy? zjKJj4uZvHl5El0a!|%+j4g$h7A;cE(*REfmP!L|3`C0|XS9b447=qbx=B40PK=_xL z_ul@xxHq_a=FJVgt9@6$KJoLJ_x|PU-qp>R46zIRn$Pq5pUu4YtLDn$)mN^(^j`DK zn|CwPf9F(uZ$cQeK^U|kTp}>ZJQe;45T>33!k#P$gU^O=dK%i9If|-H29?~0g0RDc zP-A%bu)^@KjTFs2iMTC?5C!4p!HU7bl`C)FJftD~%A{}Esn9SYX-8K|2873*s?^T| zA?ilU1;VVgcsNx2UJwTvU(dWX^9|BTzgS&7vwHY3wuDIBbnxDihzWM2qs8xarFYMK z<%?-}+;f-oNtZrj~k+`C#J%4_I=eYKmfeCUp zCpZ)SN6dcBsW8_aEQF5gZv#VtutOIvY6=e@HYhYB69YoSAcPFA9T*(!gS&SP8j=SbQ{hX`V=kN5 z-rl~yJrly?FU+9FQ}Q63Cr8EA0Vji@P^y4_*mKRpmCUTWuQgX*t6hktdOCsvp(~xA z3X1S==_HC1QvRqb2x%a17fvBNx`G{%NRZ31j*k21@y6%JTN+zJMMv|u?pU{N+gLF5 z-s-Nfwv%+HujE5}>`$j5;ZVm#%0hrVuS_;Cf{#PHA$_rvU zjyE)PhG*WawH&fSoS%Q+`@j9Fa+y;D2ZZFQ(uj|-b+62X5cgDn>Ny968O!T4AXF6o zXPdU$b3mxWSsR3_)mh0vTsjm}RC!mV75HH8+0r5O;)OVtpr?7N9E*mrYq0KrM- zdb}is8>?b5lDA@2E(jZb3WK09&y&UAutu<(6y{)1EPFE$v_t4x3PPdKe;^+ae*NBw z6R!oKAQJNXcCL%UkUy-I&8D$xAkDv#jInb zR}5#55@Se%A>WnPU(dQzB5T->F~d#vq1^#%Glw$Ca?`Q7);c5ALtcUPt*PbSVGQp= zrcNoJ`OxM8XfNDZYt1z39igZEz{tSJ$f3RwQ25sKPKCHeRlB$tuUbV0GyF>eKZ!vU z)nx4lha(1pmgA(8LFHWTWH1`dKrlCi1;$i3w&!YxXenVT+yJka&Z;6G84S>WTtWEz z-@hn?W}t6C=w5CtWI?!QIS6&D^>ae#U@#ocWDpc)G8k42y2lA&Z3cvyy8ou5fWaUP z_!NcHPIbP4J9ldMj~E5mDLhm&P*DLuR}PIJLe6<;oNGM>h1dwLX>TWlRg;qrU!3Sq zW6+bA&0xf0&_b-~ZD&4_H!b9kVJh6y*;%Dzkphb{ zLNDTD;)Kv65Y9at!i7u**Q|LagQV~UA(THe3&KDqgW<4(kS1gnggLu@Oa>z`m^C2O zQhU?W8Tx#8)~+2`YlBcxh*fw1Il_UJ1Ly>;xar6fE_Y%#FpEJugrjO?G6)KP3WVWjFenZP0wF0RgiChdvK3rx zu`nhL3gZTa3PP7nB$5;|W#T1@pA;j-aCOu0*XxM({hOoo|A+PqD6&VaF3LQFR-en-fyK+%R z7K94Jz_JjA!-?mC(C~&-43a{>UsE`3LMU~{6tu!EFz>cOs2Ajlp^=dh1)*ni&Y3VX zLpVK3|H-`gn$s;U?N6S>x9_*A8GP_{&;Mx*dj3EC!@+sCXh!J(0000N2bPDNB8 zb~7$DE-^7j^FlWO00B5qOjJbx00960|K+DZ<*`7xmQlZ)S>d!i;<-=evO(sxLFcwY z=(t1ZyF=`_M<{g%Dt8GidkQUj3@&>OE`1Cyd=4*u4KIQWFntd&e-1E%4KaQYF@O&- zgbp%)5i)=gGJy~>g%2`@4>E}jGlCH_iVie}5;TVqG>Z>4h!Qo75H*kvHi;89iV`-F z4>pnyH;NQDjuJPH6E~6&HI; zIhYYSnGrdg5IT_+I+hbUni4yf6g!#|JDn0dlNUUg6+D|1Je(6eoD@8s6Fr$0J)9Li zpA*`{{H^{{@v|%C;$Ke z=t)FDR5;6HU>GKV5mShnmy3rTj{=solw@u;+zObY;u2DmIdLlpjEId+PvXF-z}Lq) zEHXZk8JB`Udm}T+@EBHHzVNj+HqcfUV#4K3M=uKx4QUaa;o$D0XP_@Hi!-2nOGKk z?f@4f0~rZfoarId%}!lIo*!p|33PEbP?ML%nWEgibb;;{#F^y0{f*7UB&2YsNk2;` wQ(+-IiPqduQ9uZ9s@74J!<+1J0BU6`0C>V4f@c#(t^fc407*qoM6N<$f@I|nBLDyZ literal 0 HcmV?d00001 diff --git a/mods/areas/textures/simple_protection_marker.png b/mods/areas/textures/simple_protection_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..950609c8226f5b2f91d6a765cd74fb5f26ed0755 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^Od!m`0wizjKe`@Bv7|ftIx;Y9?C1WI$O`0h7I;J! zGcfS&2Vq7F)?gK&pj3%#L`iUdT1k0gQ7S_~VrE{6o}X)oLYc9ish**s`)4O}peg}R n7sn8e>&Xc(ex5(T;9|?b|C(8xXO2WOP>#XV)z4*}Q$iB}f@mc) literal 0 HcmV?d00001 diff --git a/mods/areas/textures/simple_protection_radar.png b/mods/areas/textures/simple_protection_radar.png new file mode 100644 index 0000000000000000000000000000000000000000..75bbbe1a1cca664644250224ed4377122ff67c75 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAj3?#R^_xk}U&H|6fVg?3oVGw3ym^DWND9B#o z>Fdh=keydRQi=J1?lGVcTYyi9YePfB|NsA=U+Y~16cO}vaSY*zPX6)#KO^&20|5qx X&yr@lEal|F*7-Wl|@_9Lrq#@ h#sihkDrZLqhU+Z0TdQwe@&hVj@O1TaS?83{1OVWhB^m$# literal 0 HcmV?d00001 diff --git a/mods/areas/textures/simple_protection_radar_up.png b/mods/areas/textures/simple_protection_radar_up.png new file mode 100644 index 0000000000000000000000000000000000000000..2d51762ae12c7158d04ff33d3e0526ea3d7d6930 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAf3?x51|2hvyaTa()7Bet#3xhBt!>l + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +############################################################################### + +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/mods/basic_materials/electrical-electronic.lua b/mods/basic_materials/electrical-electronic.lua new file mode 100644 index 00000000..91fac4e3 --- /dev/null +++ b/mods/basic_materials/electrical-electronic.lua @@ -0,0 +1,86 @@ +-- Translation support +local S = minetest.get_translator("basic_materials") + +-- items + +minetest.register_craftitem("basic_materials:silicon", { + description = S("Silicon lump"), + inventory_image = "basic_materials_silicon.png", +}) + +minetest.register_craftitem("basic_materials:ic", { + description = S("Simple Integrated Circuit"), + inventory_image = "basic_materials_ic.png", +}) + +minetest.register_craftitem("basic_materials:motor", { + description = S("Simple Motor"), + inventory_image = "basic_materials_motor.png", +}) + +minetest.register_craftitem("basic_materials:heating_element", { + description = S("Heating element"), + inventory_image = "basic_materials_heating_element.png", +}) + +minetest.register_craftitem("basic_materials:energy_crystal_simple", { + description = S("Simple energy crystal"), + inventory_image = "basic_materials_energy_crystal.png", +}) + +-- crafts + +minetest.register_craft( { + output = "mesecons_materials:silicon 4", + recipe = { + { "default:sand", "default:sand" }, + { "default:sand", "default:steel_ingot" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:ic 4", + recipe = { + { "mesecons_materials:silicon", "mesecons_materials:silicon" }, + { "mesecons_materials:silicon", "default:copper_ingot" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:motor 2", + recipe = { + { "default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet" }, + { "default:copper_ingot", "default:steel_ingot", "default:steel_ingot" }, + { "default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet" } + }, + replacements = { + { "basic_materials:copper_wire", "basic_materials:empty_spool" }, + { "basic_materials:copper_wire", "basic_materials:empty_spool" }, + } +}) + +minetest.register_craft( { + output = "basic_materials:heating_element 2", + recipe = { + { "default:copper_ingot", "default:mese_crystal_fragment", "default:copper_ingot" } + }, +}) + +minetest.register_craft({ + --type = "shapeless", + output = "basic_materials:energy_crystal_simple 2", + recipe = { + { "default:mese_crystal_fragment", "default:torch", "default:mese_crystal_fragment" }, + { "default:diamond", "default:gold_ingot", "default:diamond" } + }, +}) + +-- aliases + +minetest.register_alias("homedecor:ic", "basic_materials:ic") +minetest.register_alias("homedecor:motor", "basic_materials:motor") +minetest.register_alias("technic:motor", "basic_materials:motor") +minetest.register_alias("homedecor:heating_element", "basic_materials:heating_element") +minetest.register_alias("homedecor:power_crystal", "basic_materials:energy_crystal_simple") + +minetest.register_alias_force("mesecons_materials:silicon", "basic_materials:silicon") diff --git a/mods/basic_materials/init.lua b/mods/basic_materials/init.lua new file mode 100644 index 00000000..348c0598 --- /dev/null +++ b/mods/basic_materials/init.lua @@ -0,0 +1,15 @@ +-- Basic materials mod +-- by Vanessa Dannenberg + +-- This mod supplies all those little random craft items that everyone always +-- seems to need, such as metal bars (ala rebar), plastic, wire, and so on. + +local modpath = minetest.get_modpath("basic_materials") + +basic_materials = {} +basic_materials.mod = { author = "Vanessa Dannenberg" } + +dofile(modpath.."/metals.lua") +dofile(modpath.."/plastics.lua") +dofile(modpath.."/electrical-electronic.lua") +dofile(modpath.."/misc.lua") diff --git a/mods/basic_materials/locale/basic_materials.de.tr b/mods/basic_materials/locale/basic_materials.de.tr new file mode 100644 index 00000000..8fddd8a7 --- /dev/null +++ b/mods/basic_materials/locale/basic_materials.de.tr @@ -0,0 +1,33 @@ +# textdomain: basic_materials +Silicon lump=Siliziumklumpen +Simple Integrated Circuit=Einfacher Integrierter Schaltkreis +Simple Motor=Einfacher Motor +Heating element=Heizelement +Simple energy crystal=Einfacher Energiekristall + +Spool of steel wire=Spule mit Stahldraht +Spool of copper wire=Spule mit Kupferdraht +Spool of silver wire=Spule mit Silberdraht +Spool of gold wire=Spule mit Golddraht +Steel Strip=Stahlstreifen +Copper Strip=Kupferstreifen +Steel Bar=Stahlstab +Chainlinks (brass)=Messingkettenglieder +Chainlinks (steel)=Stahlkettenglieder +Brass Ingot=Messingbarren +Steel gear=Stahlzahnrad +Padlock=Vorhängeschloss +Chain (steel, hanging)=Hängende Stahlkette +Chain (brass, hanging)=Hängende Messingkette +Brass Block=Messingblock + +Oil extract=Ölextrakt +Unprocessed paraffin=Unverarbeitetes Paraffin +Uncooked Terracotta Base=Ungebranntes Terrakotta +Wet Cement=Nasser Zement +Cement=Zement +Concrete Block=Betonblock + +Plastic sheet=Kunststoffplatte +Plastic strips=Kunststoffstreifen +Empty wire spool=Leere Drahtspule diff --git a/mods/basic_materials/locale/basic_materials.fr.tr b/mods/basic_materials/locale/basic_materials.fr.tr new file mode 100644 index 00000000..0bebf79d --- /dev/null +++ b/mods/basic_materials/locale/basic_materials.fr.tr @@ -0,0 +1,33 @@ +# textdomain: basic_materials +Silicon lump=Morceau de silicium +Simple Integrated Circuit=Circuit intégré simple +Simple Motor=Moteur simple +Heating element=Élément chauffant +Simple energy crystal=Cristal d’énergie simple + +Spool of steel wire=Bobine de fil d’acier +Spool of copper wire=Bobine de fil de cuivre +Spool of silver wire=Bobine de fil d’argent +Spool of gold wire=Bobine de fil d’or +Steel Strip=Bande de acier +Copper Strip=Bande de cuivre +Steel Bar=Barre d’acier +Chainlinks (brass)=Maillon en laiton +Chainlinks (steel)=Maillon en acier +Brass Ingot=Lingot de laiton +Steel gear=Rouage en acier +Padlock=Cadenas +Chain (steel, hanging)=Chaine en acier +Chain (brass, hanging)=Chaine en laiton +Brass Block=Bloc de laiton + +Oil extract=Extrait d’huile +Unprocessed paraffin=Paraffine non transformée +Uncooked Terracotta Base=Argile crue +Wet Cement=Ciment humide +Cement=Ciment +Concrete Block=Bloc de béton + +Plastic sheet=Morceau de plastique +Plastic strips=Bande de plastique +Empty wire spool=Bobine de fil vide diff --git a/mods/basic_materials/locale/basic_materials.it.tr b/mods/basic_materials/locale/basic_materials.it.tr new file mode 100644 index 00000000..aae0b3be --- /dev/null +++ b/mods/basic_materials/locale/basic_materials.it.tr @@ -0,0 +1,34 @@ +# textdomain: basic_materials +# Author: Salvo 'LtWorf' Tomaselli +Silicon lump=Grumo di silicio +Simple Integrated Circuit=Circuito integrato semplice +Simple Motor=Motore semplice +Heating element=Elemento riscaldante +Simple energy crystal=Cristallo di energia semplice + +Spool of steel wire=Bobina di filo d'acciaio +Spool of copper wire=Bobina di filo di rame +Spool of silver wire=Bobina di filo d'argento +Spool of gold wire=Bobina di filo d'oro +Steel Strip=Striscia d'acciaio +Copper Strip=Striscia di rame +Steel Bar=Barra d'acciaio +Chainlinks (brass)=Catena (ottone) +Chainlinks (steel)=Catena (acciaio) +Brass Ingot=Lingotto di ottone +Steel gear=Ingranaggio d'acciaio +Padlock=Catenaccio +Chain (steel, hanging)=Catena (acciaio, pendente) +Chain (brass, hanging)=Catena (ottone, pendente) +Brass Block=Blocco di ottone + +Oil extract=Estratto d'olio +Unprocessed paraffin=Paraffina grezza +Uncooked Terracotta Base=Argilla cruda +Wet Cement=Cemento umido +Cement=Cemento +Concrete Block=Blocco di calcestruzzo + +Plastic sheet=Foglio di plastica +Plastic strips=Striscia di plastica +Empty wire spool=Rocchetto vuoto diff --git a/mods/basic_materials/locale/basic_materials.ru.tr b/mods/basic_materials/locale/basic_materials.ru.tr new file mode 100644 index 00000000..85e9c0cf --- /dev/null +++ b/mods/basic_materials/locale/basic_materials.ru.tr @@ -0,0 +1,33 @@ +# textdomain: basic_materials +Silicon lump=Кусок Кремния +Simple Integrated Circuit=Микросхема +Simple Motor=Мотор +Heating element=Нить Накала +Simple energy crystal=Энергетический Кристалл + +Spool of steel wire=Катушка Стальной Проволоки +Spool of copper wire=Катушка Медной Проволоки +Spool of silver wire=Катушка Серебрянной Проволоки +Spool of gold wire=Катушка Золотой Проволоки +Steel Strip=Стальная Полоса +Copper Strip=Медная Полоса +Steel Bar=Стальной Прут +Chainlinks (brass)=Латунные Звенья +Chainlinks (steel)=Стальные Звенья +Brass Ingot=Латунный Брусок +Steel gear=Стальная Шестерня +Padlock=Навесной Замок +Chain (steel, hanging)=Стальная Цепь +Chain (brass, hanging)=Латунная Цепь +Brass Block=Латунный Блок + +Oil extract=Масляный Экстракт +Unprocessed paraffin=Необработанный Парафин +Uncooked Terracotta Base=Ком Мокрого Терракота +Wet Cement=Ком Мокрого Цемента +Cement=Цемент +Concrete Block=Железобетон + +Plastic sheet=Пластиковый Лист +Plastic strips=Пластиковая Полоса +Empty wire spool=Пустая Катушка diff --git a/mods/basic_materials/metals.lua b/mods/basic_materials/metals.lua new file mode 100644 index 00000000..0a3243b0 --- /dev/null +++ b/mods/basic_materials/metals.lua @@ -0,0 +1,300 @@ +-- Translation support +local S = minetest.get_translator("basic_materials") + +-- items + +minetest.register_craftitem("basic_materials:steel_wire", { + description = S("Spool of steel wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_steel_wire.png" +}) + +minetest.register_craftitem("basic_materials:copper_wire", { + description = S("Spool of copper wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_copper_wire.png" +}) + +minetest.register_craftitem("basic_materials:silver_wire", { + description = S("Spool of silver wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_silver_wire.png" +}) + +minetest.register_craftitem("basic_materials:gold_wire", { + description = S("Spool of gold wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_gold_wire.png" +}) + +minetest.register_craftitem("basic_materials:steel_strip", { + description = S("Steel Strip"), + groups = { strip = 1 }, + inventory_image = "basic_materials_steel_strip.png" +}) + +minetest.register_craftitem("basic_materials:copper_strip", { + description = S("Copper Strip"), + groups = { strip = 1 }, + inventory_image = "basic_materials_copper_strip.png" +}) + +minetest.register_craftitem("basic_materials:steel_bar", { + description = S("Steel Bar"), + inventory_image = "basic_materials_steel_bar.png", +}) + +minetest.register_craftitem("basic_materials:chainlink_brass", { + description = S("Chainlinks (brass)"), + groups = { chainlinks = 1 }, + inventory_image = "basic_materials_chainlink_brass.png" +}) + +minetest.register_craftitem("basic_materials:chainlink_steel", { + description = S("Chainlinks (steel)"), + groups = { chainlinks = 1 }, + inventory_image = "basic_materials_chainlink_steel.png" +}) + +minetest.register_craftitem("basic_materials:brass_ingot", { + description = S("Brass Ingot"), + inventory_image = "basic_materials_brass_ingot.png", +}) + +minetest.register_craftitem("basic_materials:gear_steel", { + description = S("Steel gear"), + inventory_image = "basic_materials_gear_steel.png" +}) + +minetest.register_craftitem("basic_materials:padlock", { + description = S("Padlock"), + inventory_image = "basic_materials_padlock.png" +}) + +-- nodes + +local chains_sbox = { + type = "fixed", + fixed = { -0.1, -0.5, -0.1, 0.1, 0.5, 0.1 } +} + +minetest.register_node("basic_materials:chain_steel", { + description = S("Chain (steel, hanging)"), + drawtype = "mesh", + mesh = "basic_materials_chains.obj", + tiles = {"basic_materials_chain_steel.png"}, + walkable = false, + climbable = true, + sunlight_propagates = true, + paramtype = "light", + inventory_image = "basic_materials_chain_steel_inv.png", + groups = {cracky=3}, + selection_box = chains_sbox, +}) + +minetest.register_node("basic_materials:chain_brass", { + description = S("Chain (brass, hanging)"), + drawtype = "mesh", + mesh = "basic_materials_chains.obj", + tiles = {"basic_materials_chain_brass.png"}, + walkable = false, + climbable = true, + sunlight_propagates = true, + paramtype = "light", + inventory_image = "basic_materials_chain_brass_inv.png", + groups = {cracky=3}, + selection_box = chains_sbox, +}) + +minetest.register_node("basic_materials:brass_block", { + description = S("Brass Block"), + tiles = { "basic_materials_brass_block.png" }, + is_ground_content = false, + groups = {cracky=1, level=2}, + sounds = default.node_sound_metal_defaults() +}) + +-- crafts + +minetest.register_craft( { + output = "basic_materials:copper_wire 2", + type = "shapeless", + recipe = { + "default:copper_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, +}) + +minetest.register_craft( { + output = "basic_materials:silver_wire 2", + type = "shapeless", + recipe = { + "moreores:silver_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, +}) + +minetest.register_craft( { + output = "basic_materials:gold_wire 2", + type = "shapeless", + recipe = { + "default:gold_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, +}) + +minetest.register_craft( { + output = "basic_materials:steel_wire 2", + type = "shapeless", + recipe = { + "default:steel_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, +}) + +minetest.register_craft( { + output = "basic_materials:steel_strip 12", + recipe = { + { "", "default:steel_ingot", "" }, + { "default:steel_ingot", "", "" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:copper_strip 12", + recipe = { + { "", "default:copper_ingot", "" }, + { "default:copper_ingot", "", "" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:steel_bar 6", + recipe = { + { "", "", "default:steel_ingot" }, + { "", "default:steel_ingot", "" }, + { "default:steel_ingot", "", "" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:padlock 2", + recipe = { + { "basic_materials:steel_bar" }, + { "default:steel_ingot" }, + { "default:steel_ingot" }, + }, +}) + +minetest.register_craft({ + output = "basic_materials:chainlink_steel 12", + recipe = { + {"", "default:steel_ingot", "default:steel_ingot"}, + { "default:steel_ingot", "", "default:steel_ingot" }, + { "default:steel_ingot", "default:steel_ingot", "" }, + }, +}) + +minetest.register_craft({ + output = "basic_materials:chainlink_brass 12", + recipe = { + {"", "basic_materials:brass_ingot", "basic_materials:brass_ingot"}, + { "basic_materials:brass_ingot", "", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "" }, + }, +}) + +minetest.register_craft({ + output = 'basic_materials:chain_steel 2', + recipe = { + {"basic_materials:chainlink_steel"}, + {"basic_materials:chainlink_steel"}, + {"basic_materials:chainlink_steel"} + } +}) + +minetest.register_craft({ + output = 'basic_materials:chain_brass 2', + recipe = { + {"basic_materials:chainlink_brass"}, + {"basic_materials:chainlink_brass"}, + {"basic_materials:chainlink_brass"} + } +}) + +minetest.register_craft( { + output = "basic_materials:gear_steel 6", + recipe = { + { "", "default:steel_ingot", "" }, + { "default:steel_ingot","basic_materials:chainlink_steel", "default:steel_ingot" }, + { "", "default:steel_ingot", "" } + }, +}) + +minetest.register_craft( { + type = "shapeless", + output = "basic_materials:brass_ingot 3", + recipe = { + "default:copper_ingot", + "default:copper_ingot", + "moreores:silver_ingot", + }, +}) + +if not minetest.get_modpath("moreores") then + -- Without moreores, there still should be a way to create brass. + minetest.register_craft( { + output = "basic_materials:brass_ingot 9", + recipe = { + {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, + {"default:gold_ingot", "default:copper_ingot", "default:gold_ingot"}, + {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, + }, + }) +end + +minetest.register_craft( { + type = "shapeless", + output = "basic_materials:brass_ingot 9", + recipe = { "basic_materials:brass_block" }, +}) + +minetest.register_craft( { + output = "basic_materials:brass_block", + recipe = { + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + }, +}) + +-- aliases + +minetest.register_alias("homedecor:copper_wire", "basic_materials:copper_wire") +minetest.register_alias("technic:fine_copper_wire", "basic_materials:copper_wire") +minetest.register_alias("technic:fine_silver_wire", "basic_materials:silver_wire") +minetest.register_alias("technic:fine_gold_wire", "basic_materials:gold_wire") + +minetest.register_alias("homedecor:steel_wire", "basic_materials:steel_wire") + +minetest.register_alias("homedecor:brass_ingot", "basic_materials:brass_ingot") +minetest.register_alias("technic:brass_ingot", "basic_materials:brass_ingot") +minetest.register_alias("technic:brass_block", "basic_materials:brass_block") + +minetest.register_alias("homedecor:copper_strip", "basic_materials:copper_strip") +minetest.register_alias("homedecor:steel_strip", "basic_materials:steel_strip") + +minetest.register_alias_force("glooptest:chainlink", "basic_materials:chainlink_steel") +minetest.register_alias_force("homedecor:chainlink_steel", "basic_materials:chainlink_steel") +minetest.register_alias("homedecor:chainlink_brass", "basic_materials:chainlink_brass") +minetest.register_alias("chains:chain", "basic_materials:chain_steel") +minetest.register_alias("chains:chain_brass", "basic_materials:chain_brass") + +minetest.register_alias("pipeworks:gear", "basic_materials:gear_steel") + +minetest.register_alias("technic:rebar", "basic_materials:steel_bar") + diff --git a/mods/basic_materials/misc.lua b/mods/basic_materials/misc.lua new file mode 100644 index 00000000..00128972 --- /dev/null +++ b/mods/basic_materials/misc.lua @@ -0,0 +1,126 @@ +-- Translation support +local S = minetest.get_translator("basic_materials") + +-- items + +minetest.register_craftitem("basic_materials:oil_extract", { + description = S("Oil extract"), + inventory_image = "basic_materials_oil_extract.png", +}) + +minetest.register_craftitem("basic_materials:paraffin", { + description = S("Unprocessed paraffin"), + inventory_image = "basic_materials_paraffin.png", +}) + +minetest.register_craftitem("basic_materials:terracotta_base", { + description = S("Uncooked Terracotta Base"), + inventory_image = "basic_materials_terracotta_base.png", +}) + +minetest.register_craftitem("basic_materials:wet_cement", { + description = S("Wet Cement"), + inventory_image = "basic_materials_wet_cement.png", +}) + +-- nodes + +minetest.register_node("basic_materials:cement_block", { + description = S("Cement"), + tiles = {"basic_materials_cement_block.png"}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("basic_materials:concrete_block", { + description = S("Concrete Block"), + tiles = {"basic_materials_concrete_block.png",}, + groups = {cracky=1, level=2, concrete=1}, + sounds = default.node_sound_stone_defaults(), +}) + +-- crafts + +minetest.register_craft({ + type = "shapeless", + output = "basic_materials:oil_extract 2", + recipe = { + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves" + } +}) + +minetest.register_craft({ + type = "cooking", + output = "basic_materials:paraffin", + recipe = "basic_materials:oil_extract", +}) + +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:oil_extract", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:paraffin", + burntime = 30, +}) + +minetest.register_craft( { + type = "shapeless", + output = "basic_materials:terracotta_base 8", + recipe = { + "bucket:bucket_water", + "default:clay_lump", + "default:gravel", + }, + replacements = { {"bucket:bucket_water", "bucket:bucket_empty"}, }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "basic_materials:wet_cement 3", + recipe = { + "default:dirt", + "dye:dark_grey", + "dye:dark_grey", + "dye:dark_grey", + "bucket:bucket_water" + }, + replacements = {{'bucket:bucket_water', 'bucket:bucket_empty'},}, +}) + +minetest.register_craft({ + type = "cooking", + output = "basic_materials:cement_block", + recipe = "basic_materials:wet_cement", + cooktime = 8 +}) + +minetest.register_craft({ + output = 'basic_materials:concrete_block 6', + recipe = { + {'group:sand', 'basic_materials:wet_cement', 'default:gravel'}, + {'basic_materials:steel_bar', 'basic_materials:wet_cement', 'basic_materials:steel_bar'}, + {'default:gravel', 'basic_materials:wet_cement', 'group:sand'}, + } +}) + +-- aliases + +minetest.register_alias("homedecor:oil_extract", "basic_materials:oil_extract") +minetest.register_alias("homedecor:paraffin", "basic_materials:paraffin") +minetest.register_alias("homedecor:plastic_base", "basic_materials:paraffin") +minetest.register_alias("homedecor:terracotta_base", "basic_materials:terracotta_base") + +minetest.register_alias("gloopblocks:wet_cement", "basic_materials:wet_cement") +minetest.register_alias("gloopblocks:cement", "basic_materials:cement_block") + +minetest.register_alias("technic:concrete", "basic_materials:concrete_block") diff --git a/mods/basic_materials/mod.conf b/mods/basic_materials/mod.conf new file mode 100644 index 00000000..7234bfe9 --- /dev/null +++ b/mods/basic_materials/mod.conf @@ -0,0 +1,4 @@ +name = basic_materials +depends = default +optional_depends = moreores +min_minetest_version = 5.2.0 diff --git a/mods/basic_materials/models/basic_materials_chains.obj b/mods/basic_materials/models/basic_materials_chains.obj new file mode 100644 index 00000000..78724c98 --- /dev/null +++ b/mods/basic_materials/models/basic_materials_chains.obj @@ -0,0 +1,881 @@ +# Blender v2.73 (sub 0) OBJ File: 'chains.blend' +# www.blender.org +o Torus.016_Torus +v 0.000000 -0.429978 0.000002 +v 0.000000 -0.401109 0.055211 +v -0.014044 -0.391975 0.048870 +v -0.014044 -0.423304 0.000002 +v -0.009826 -0.379748 0.040970 +v -0.009826 -0.406012 0.000002 +v 0.009826 -0.379748 0.040970 +v 0.009826 -0.406012 0.000002 +v 0.014044 -0.391975 0.048870 +v 0.014044 -0.423304 0.000002 +v 0.000000 -0.316336 0.080195 +v -0.014044 -0.316336 0.069112 +v -0.009826 -0.316336 0.057941 +v 0.009826 -0.316336 0.057941 +v 0.014044 -0.316336 0.069112 +v 0.000000 -0.231564 0.055211 +v -0.014044 -0.240700 0.048870 +v -0.009826 -0.252925 0.040970 +v 0.009826 -0.252925 0.040970 +v 0.014044 -0.240700 0.048870 +v 0.000000 -0.202695 0.000002 +v -0.014044 -0.209368 0.000002 +v -0.009826 -0.226661 0.000002 +v 0.009826 -0.226661 0.000002 +v 0.014044 -0.209368 0.000002 +v 0.000000 -0.231564 -0.055206 +v -0.014044 -0.240700 -0.048868 +v -0.009826 -0.252925 -0.040967 +v 0.009826 -0.252925 -0.040967 +v 0.014044 -0.240700 -0.048865 +v 0.000000 -0.316336 -0.080190 +v -0.014044 -0.316336 -0.069108 +v -0.009826 -0.316336 -0.057936 +v 0.009826 -0.316336 -0.057936 +v 0.014044 -0.316336 -0.069108 +v 0.000000 -0.400361 -0.055206 +v -0.014044 -0.391975 -0.048868 +v -0.009826 -0.379748 -0.040967 +v 0.009826 -0.379748 -0.040967 +v 0.014044 -0.391975 -0.048868 +v 0.000000 -0.262249 0.000002 +v -0.061672 -0.233381 0.000002 +v -0.054590 -0.224245 -0.012569 +v 0.000000 -0.255577 -0.012569 +v -0.045765 -0.212018 -0.008794 +v 0.000000 -0.238285 -0.008794 +v -0.045765 -0.212018 0.008798 +v 0.000000 -0.238285 0.008798 +v -0.054590 -0.224245 0.012574 +v 0.000000 -0.255577 0.012574 +v -0.089582 -0.148609 0.000002 +v -0.077200 -0.148609 -0.012569 +v -0.064722 -0.148609 -0.008794 +v -0.064722 -0.148609 0.008799 +v -0.077200 -0.148609 0.012574 +v -0.061672 -0.063837 0.000002 +v -0.054590 -0.072971 -0.012569 +v -0.045765 -0.085198 -0.008794 +v -0.045765 -0.085198 0.008799 +v -0.054590 -0.072971 0.012574 +v 0.000000 -0.034967 0.000002 +v 0.000000 -0.041641 -0.012569 +v 0.000000 -0.058933 -0.008794 +v 0.000000 -0.058933 0.008799 +v 0.000000 -0.041641 0.012574 +v 0.061672 -0.063837 0.000002 +v 0.054590 -0.072971 -0.012569 +v 0.045765 -0.085198 -0.008794 +v 0.045765 -0.085198 0.008799 +v 0.054590 -0.072971 0.012574 +v 0.089582 -0.148609 0.000002 +v 0.077200 -0.148609 -0.012569 +v 0.064722 -0.148609 -0.008794 +v 0.064722 -0.148609 0.008799 +v 0.077200 -0.148609 0.012574 +v 0.061672 -0.232631 0.000002 +v 0.054590 -0.224245 -0.012569 +v 0.045765 -0.212018 -0.008794 +v 0.045765 -0.212018 0.008798 +v 0.054590 -0.224245 0.012574 +v 0.000000 0.073316 0.000002 +v 0.061672 0.102183 0.000002 +v 0.054590 0.111319 0.012574 +v 0.000000 0.079988 0.012574 +v 0.045765 0.123546 0.008799 +v 0.000000 0.097280 0.008799 +v 0.045765 0.123546 -0.008794 +v 0.000000 0.097280 -0.008794 +v 0.054590 0.111319 -0.012569 +v 0.000000 0.079988 -0.012569 +v 0.089582 0.186956 0.000002 +v 0.077200 0.186956 0.012574 +v 0.064722 0.186956 0.008799 +v 0.064722 0.186956 -0.008794 +v 0.077200 0.186956 -0.012569 +v 0.061672 0.271728 0.000002 +v 0.054590 0.262594 0.012574 +v 0.045765 0.250367 0.008799 +v 0.045765 0.250367 -0.008794 +v 0.054590 0.262594 -0.012569 +v 0.000000 0.300597 0.000002 +v 0.000000 0.293923 0.012574 +v 0.000000 0.276631 0.008799 +v 0.000000 0.276631 -0.008794 +v 0.000000 0.293923 -0.012569 +v -0.061672 0.271728 0.000002 +v -0.054590 0.262594 0.012574 +v -0.045765 0.250367 0.008799 +v -0.045765 0.250367 -0.008794 +v -0.054590 0.262594 -0.012569 +v -0.089582 0.186956 0.000002 +v -0.077200 0.186956 0.012574 +v -0.064722 0.186956 0.008799 +v -0.064722 0.186956 -0.008794 +v -0.077200 0.186956 -0.012569 +v -0.061672 0.102931 0.000002 +v -0.054590 0.111319 0.012574 +v -0.045765 0.123546 0.008799 +v -0.045765 0.123546 -0.008794 +v -0.054590 0.111319 -0.012569 +v 0.000000 -0.095037 0.000002 +v 0.000000 -0.066168 -0.055206 +v 0.014044 -0.057034 -0.048868 +v 0.014044 -0.088363 0.000002 +v 0.009826 -0.044807 -0.040967 +v 0.009826 -0.071071 0.000002 +v -0.009826 -0.044807 -0.040967 +v -0.009826 -0.071071 0.000002 +v -0.014044 -0.057034 -0.048868 +v -0.014044 -0.088363 0.000002 +v 0.000000 0.018605 -0.080190 +v 0.014044 0.018605 -0.069108 +v 0.009826 0.018605 -0.057936 +v -0.009826 0.018605 -0.057936 +v -0.014044 0.018605 -0.069108 +v 0.000000 0.103377 -0.055206 +v 0.014044 0.094243 -0.048868 +v 0.009826 0.082016 -0.040967 +v -0.009826 0.082016 -0.040967 +v -0.014044 0.094243 -0.048868 +v 0.000000 0.132246 0.000002 +v 0.014044 0.125572 0.000002 +v 0.009826 0.108280 0.000002 +v -0.009826 0.108280 0.000002 +v -0.014044 0.125572 0.000002 +v 0.000000 0.103377 0.055211 +v 0.014044 0.094243 0.048870 +v 0.009826 0.082016 0.040970 +v -0.009826 0.082016 0.040970 +v -0.014044 0.094243 0.048870 +v 0.000000 0.018605 0.080195 +v 0.014044 0.018605 0.069112 +v 0.009826 0.018605 0.057941 +v -0.009826 0.018605 0.057941 +v -0.014044 0.018605 0.069112 +v 0.000000 -0.065420 0.055211 +v 0.014044 -0.057032 0.048870 +v 0.009826 -0.044807 0.040970 +v -0.009826 -0.044807 0.040970 +v -0.014044 -0.057032 0.048870 +v 0.000000 -0.598329 0.000002 +v 0.061672 -0.569460 0.000002 +v 0.054590 -0.560326 0.012574 +v 0.000000 -0.591655 0.012574 +v 0.045765 -0.548099 0.008798 +v 0.000000 -0.574363 0.008798 +v 0.045765 -0.548099 -0.008794 +v 0.000000 -0.574363 -0.008794 +v 0.054590 -0.560326 -0.012569 +v 0.000000 -0.591655 -0.012569 +v 0.089582 -0.484687 0.000002 +v 0.077200 -0.484687 0.012574 +v 0.064722 -0.484687 0.008798 +v 0.064722 -0.484687 -0.008794 +v 0.077200 -0.484687 -0.012569 +v 0.061672 -0.399915 0.000002 +v 0.054590 -0.409051 0.012574 +v 0.045765 -0.421278 0.008798 +v 0.045765 -0.421278 -0.008794 +v 0.054590 -0.409051 -0.012569 +v 0.000000 -0.371048 0.000002 +v 0.000000 -0.377719 0.012574 +v 0.000000 -0.395012 0.008798 +v 0.000000 -0.395012 -0.008794 +v 0.000000 -0.377719 -0.012569 +v -0.061672 -0.399915 0.000002 +v -0.054590 -0.409051 0.012574 +v -0.045765 -0.421278 0.008798 +v -0.045765 -0.421278 -0.008794 +v -0.054590 -0.409051 -0.012569 +v -0.089582 -0.484687 0.000002 +v -0.077200 -0.484687 0.012574 +v -0.064722 -0.484687 0.008798 +v -0.064722 -0.484687 -0.008794 +v -0.077200 -0.484687 -0.012569 +v -0.061672 -0.568712 0.000002 +v -0.054590 -0.560326 0.012574 +v -0.045765 -0.548099 0.008798 +v -0.045765 -0.548099 -0.008794 +v -0.054590 -0.560326 -0.012569 +v 0.000000 0.241043 0.000002 +v 0.000000 0.269910 0.055211 +v -0.014044 0.279047 0.048870 +v -0.014044 0.247717 0.000002 +v -0.009826 0.291274 0.040970 +v -0.009826 0.265007 0.000002 +v 0.009826 0.291274 0.040970 +v 0.009826 0.265007 0.000002 +v 0.014044 0.279047 0.048870 +v 0.014044 0.247717 0.000002 +v 0.000000 0.354683 0.080195 +v -0.014044 0.354683 0.069112 +v -0.009826 0.354683 0.057941 +v 0.009826 0.354683 0.057941 +v 0.014044 0.354683 0.069112 +v 0.000000 0.439455 0.055211 +v -0.014044 0.430321 0.048870 +v -0.009826 0.418094 0.040970 +v 0.009826 0.418094 0.040970 +v 0.014044 0.430321 0.048870 +v 0.000000 0.468325 0.000002 +v -0.014044 0.461651 0.000002 +v -0.009826 0.444361 0.000002 +v 0.009826 0.444361 0.000002 +v 0.014044 0.461651 0.000002 +v 0.000000 0.439455 -0.055206 +v -0.014044 0.430321 -0.048868 +v -0.009826 0.418094 -0.040967 +v 0.009826 0.418094 -0.040967 +v 0.014044 0.430321 -0.048868 +v 0.000000 0.354683 -0.080190 +v -0.014044 0.354683 -0.069108 +v -0.009826 0.354683 -0.057936 +v 0.009826 0.354683 -0.057936 +v 0.014044 0.354683 -0.069108 +v 0.000000 0.270661 -0.055206 +v -0.014044 0.279047 -0.048868 +v -0.009826 0.291274 -0.040967 +v 0.009826 0.291274 -0.040967 +v 0.014044 0.279047 -0.048868 +vt 0.187500 0.125000 +vt 0.250000 0.125000 +vt 0.250000 0.187500 +vt 0.187500 0.187500 +vt 0.250000 0.250000 +vt 0.187500 0.250000 +vt 0.250000 0.312500 +vt 0.187500 0.312500 +vt 0.250000 0.375000 +vt 0.187500 0.375000 +vt 0.187500 0.062500 +vt 0.250000 0.062500 +vt 0.312500 0.125000 +vt 0.312500 0.187500 +vt 0.312500 0.250000 +vt 0.312500 0.312500 +vt 0.312500 0.375000 +vt 0.312500 0.062500 +vt 0.375000 0.125000 +vt 0.375000 0.187500 +vt 0.375000 0.250000 +vt 0.375000 0.312500 +vt 0.375000 0.375000 +vt 0.375000 0.062500 +vt 0.437500 0.125000 +vt 0.437500 0.187500 +vt 0.437500 0.250000 +vt 0.437500 0.312500 +vt 0.437500 0.375000 +vt 0.437500 0.062500 +vt 0.500000 0.125000 +vt 0.500000 0.187500 +vt 0.500000 0.250000 +vt 0.500000 0.312500 +vt 0.500000 0.375000 +vt 0.500000 0.062500 +vt -0.000000 0.125000 +vt 0.062500 0.125000 +vt 0.062500 0.187500 +vt -0.000000 0.187500 +vt 0.062500 0.250000 +vt -0.000000 0.250000 +vt 0.062500 0.312500 +vt -0.000000 0.312500 +vt 0.062500 0.375000 +vt -0.000000 0.375000 +vt -0.000000 0.062500 +vt 0.062500 0.062500 +vt 0.125000 0.125000 +vt 0.125000 0.187500 +vt 0.125000 0.250000 +vt 0.125000 0.312500 +vt 0.125000 0.375000 +vt 0.125000 0.062500 +vt 0.750000 0.625000 +vt 0.812500 0.625000 +vt 0.812500 0.687500 +vt 0.750000 0.687500 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.437500 +vt 0.750000 0.437500 +vt 0.812500 0.500000 +vt 0.750000 0.500000 +vt 0.812500 0.562500 +vt 0.750000 0.562500 +vt 0.875000 0.625000 +vt 0.875000 0.687500 +vt 0.875000 0.375000 +vt 0.875000 0.437500 +vt 0.875000 0.500000 +vt 0.875000 0.562500 +vt 0.937500 0.625000 +vt 0.937500 0.687500 +vt 0.937500 0.375000 +vt 0.937500 0.437500 +vt 0.937500 0.500000 +vt 0.937500 0.562500 +vt 1.000000 0.625000 +vt 1.000000 0.687500 +vt 1.000000 0.375000 +vt 1.000000 0.437500 +vt 1.000000 0.500000 +vt 1.000000 0.562500 +vt 0.500000 0.625000 +vt 0.562500 0.625000 +vt 0.562500 0.687500 +vt 0.500000 0.687500 +vt 0.562500 0.375000 +vt 0.562500 0.437500 +vt 0.500000 0.437500 +vt 0.562500 0.500000 +vt 0.500000 0.500000 +vt 0.562500 0.562500 +vt 0.500000 0.562500 +vt 0.625000 0.625000 +vt 0.625000 0.687500 +vt 0.625000 0.375000 +vt 0.625000 0.437500 +vt 0.625000 0.500000 +vt 0.625000 0.562500 +vt 0.687500 0.625000 +vt 0.687500 0.687500 +vt 0.687500 0.375000 +vt 0.687500 0.437500 +vt 0.687500 0.500000 +vt 0.687500 0.562500 +vt 0.250000 0.625000 +vt 0.312500 0.625000 +vt 0.312500 0.687500 +vt 0.250000 0.687500 +vt 0.312500 0.437500 +vt 0.250000 0.437500 +vt 0.312500 0.500000 +vt 0.250000 0.500000 +vt 0.312500 0.562500 +vt 0.250000 0.562500 +vt 0.375000 0.625000 +vt 0.375000 0.687500 +vt 0.375000 0.437500 +vt 0.375000 0.500000 +vt 0.375000 0.562500 +vt 0.437500 0.625000 +vt 0.437500 0.687500 +vt 0.437500 0.437500 +vt 0.437500 0.500000 +vt 0.437500 0.562500 +vt -0.000000 0.625000 +vt 0.062500 0.625000 +vt 0.062500 0.687500 +vt -0.000000 0.687500 +vt 0.062500 0.437500 +vt -0.000000 0.437500 +vt 0.062500 0.500000 +vt -0.000000 0.500000 +vt 0.062500 0.562500 +vt -0.000000 0.562500 +vt 0.125000 0.625000 +vt 0.125000 0.687500 +vt 0.125000 0.437500 +vt 0.125000 0.500000 +vt 0.125000 0.562500 +vt 0.187500 0.625000 +vt 0.187500 0.687500 +vt 0.187500 0.437500 +vt 0.187500 0.500000 +vt 0.187500 0.562500 +vt 0.687500 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.812500 +vt 0.687500 0.812500 +vt 0.750000 0.875000 +vt 0.687500 0.875000 +vt 0.750000 0.937500 +vt 0.687500 0.937500 +vt 0.750000 1.000000 +vt 0.687500 1.000000 +vt 0.812500 0.750000 +vt 0.812500 0.812500 +vt 0.812500 0.875000 +vt 0.812500 0.937500 +vt 0.812500 1.000000 +vt 0.875000 0.750000 +vt 0.875000 0.812500 +vt 0.875000 0.875000 +vt 0.875000 0.937500 +vt 0.875000 1.000000 +vt 0.937500 0.750000 +vt 0.937500 0.812500 +vt 0.937500 0.875000 +vt 0.937500 0.937500 +vt 0.937500 1.000000 +vt 1.000000 0.750000 +vt 1.000000 0.812500 +vt 1.000000 0.875000 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.500000 0.750000 +vt 0.562500 0.750000 +vt 0.562500 0.812500 +vt 0.500000 0.812500 +vt 0.562500 0.875000 +vt 0.500000 0.875000 +vt 0.562500 0.937500 +vt 0.500000 0.937500 +vt 0.562500 1.000000 +vt 0.500000 1.000000 +vt 0.625000 0.750000 +vt 0.625000 0.812500 +vt 0.625000 0.875000 +vt 0.625000 0.937500 +vt 0.625000 1.000000 +vt 0.750000 0.312500 +vt 0.812500 0.312500 +vt 0.750000 0.062500 +vt 0.812500 0.062500 +vt 0.812500 0.125000 +vt 0.750000 0.125000 +vt 0.812500 0.187500 +vt 0.750000 0.187500 +vt 0.812500 0.250000 +vt 0.750000 0.250000 +vt 0.875000 0.312500 +vt 0.875000 0.062500 +vt 0.875000 0.125000 +vt 0.875000 0.187500 +vt 0.875000 0.250000 +vt 0.937500 0.312500 +vt 0.937500 0.062500 +vt 0.937500 0.125000 +vt 0.937500 0.187500 +vt 0.937500 0.250000 +vt 1.000000 0.312500 +vt 1.000000 0.062500 +vt 1.000000 0.125000 +vt 1.000000 0.187500 +vt 1.000000 0.250000 +vt 0.562500 0.312500 +vt 0.562500 0.062500 +vt 0.562500 0.125000 +vt 0.562500 0.187500 +vt 0.562500 0.250000 +vt 0.625000 0.312500 +vt 0.625000 0.062500 +vt 0.625000 0.125000 +vt 0.625000 0.187500 +vt 0.625000 0.250000 +vt 0.687500 0.312500 +vt 0.687500 0.062500 +vt 0.687500 0.125000 +vt 0.687500 0.187500 +vt 0.687500 0.250000 +vt 0.250000 0.937500 +vt 0.312500 0.937500 +vt 0.312500 1.000000 +vt 0.250000 1.000000 +vt 0.312500 0.750000 +vt 0.250000 0.750000 +vt 0.312500 0.812500 +vt 0.250000 0.812500 +vt 0.312500 0.875000 +vt 0.250000 0.875000 +vt 0.375000 0.937500 +vt 0.375000 1.000000 +vt 0.375000 0.750000 +vt 0.375000 0.812500 +vt 0.375000 0.875000 +vt 0.437500 0.937500 +vt 0.437500 1.000000 +vt 0.437500 0.750000 +vt 0.437500 0.812500 +vt 0.437500 0.875000 +vt 0.000000 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt 0.000000 1.000000 +vt 0.062500 0.750000 +vt 0.000000 0.750000 +vt 0.062500 0.812500 +vt 0.000000 0.812500 +vt 0.062500 0.875000 +vt 0.000000 0.875000 +vt 0.125000 0.937500 +vt 0.125000 1.000000 +vt 0.125000 0.750000 +vt 0.125000 0.812500 +vt 0.125000 0.875000 +vt 0.187500 0.937500 +vt 0.187500 1.000000 +vt 0.187500 0.750000 +vt 0.187500 0.812500 +vt 0.187500 0.875000 +vn 0.000000 -1.000000 -0.004800 +vn 0.000000 -0.657400 0.753500 +vn -0.898300 -0.248500 0.362300 +vn -0.863600 -0.504100 -0.003400 +vn -0.661500 0.421500 -0.620200 +vn -0.746000 0.665900 0.000000 +vn 0.661500 0.421500 -0.620200 +vn 0.746000 0.665900 0.000000 +vn 0.898300 -0.248500 0.362300 +vn 0.863600 -0.504100 -0.003400 +vn 0.000000 0.000000 1.000000 +vn -0.925200 0.000000 0.379500 +vn -0.617100 0.000000 -0.786900 +vn 0.617100 0.000000 -0.786900 +vn 0.925200 0.000000 0.379500 +vn 0.000000 0.657400 0.753500 +vn -0.898300 0.248400 0.362300 +vn -0.661500 -0.421500 -0.620200 +vn 0.661500 -0.421500 -0.620200 +vn 0.898300 0.248400 0.362300 +vn 0.000000 1.000000 0.000000 +vn -0.866100 0.499800 0.000000 +vn -0.746000 -0.665900 0.000000 +vn 0.746000 -0.665900 0.000000 +vn 0.866100 0.499800 0.000000 +vn 0.000000 0.657400 -0.753500 +vn -0.898300 0.248400 -0.362400 +vn -0.661600 -0.421500 0.620200 +vn 0.661500 -0.421500 0.620200 +vn 0.898300 0.248400 -0.362300 +vn 0.000000 -0.000900 -1.000000 +vn -0.924600 -0.000600 -0.380700 +vn -0.617100 0.000000 0.786900 +vn 0.617100 0.000000 0.786900 +vn 0.924700 -0.000600 -0.380700 +vn 0.000000 -0.650300 -0.759600 +vn -0.895600 -0.254600 -0.364800 +vn -0.661600 0.421500 0.620200 +vn 0.661600 0.421500 0.620200 +vn 0.895600 -0.254600 -0.364800 +vn 0.004900 -1.000000 0.000000 +vn -0.729700 -0.683800 0.000000 +vn -0.324500 -0.256300 -0.910500 +vn 0.003300 -0.475500 -0.879700 +vn 0.578700 0.436200 -0.689100 +vn 0.000000 0.666600 -0.745400 +vn 0.578700 0.436200 0.689100 +vn 0.000000 0.666600 0.745400 +vn -0.324500 -0.256300 0.910500 +vn 0.003300 -0.475500 0.879700 +vn -1.000000 0.000000 0.000000 +vn -0.359600 0.000000 -0.933100 +vn 0.756400 0.000000 -0.654100 +vn 0.756400 0.000000 0.654100 +vn -0.359600 0.000000 0.933100 +vn -0.729700 0.683700 0.000000 +vn -0.324500 0.256300 -0.910500 +vn 0.578700 -0.436200 -0.689100 +vn 0.578700 -0.436200 0.689100 +vn -0.324500 0.256300 0.910500 +vn 0.000000 0.470900 -0.882200 +vn 0.000000 -0.666600 -0.745400 +vn 0.000000 -0.666600 0.745400 +vn 0.000000 0.470900 0.882200 +vn 0.729700 0.683700 0.000000 +vn 0.324500 0.256300 -0.910500 +vn -0.578700 -0.436200 -0.689100 +vn -0.578700 -0.436200 0.689100 +vn 0.324500 0.256300 0.910500 +vn 1.000000 -0.001100 0.000000 +vn 0.361000 -0.000700 -0.932600 +vn -0.756400 0.000000 -0.654100 +vn -0.756400 0.000000 0.654100 +vn 0.361000 -0.000700 0.932600 +vn 0.736100 -0.676800 0.000000 +vn 0.327100 -0.263100 -0.907600 +vn -0.578700 0.436200 -0.689100 +vn -0.578700 0.436200 0.689100 +vn 0.327100 -0.263100 0.907600 +vn -0.004900 -1.000000 0.000000 +vn 0.729700 -0.683800 0.000000 +vn 0.324500 -0.256300 0.910500 +vn -0.003300 -0.475400 0.879700 +vn 0.324500 -0.256300 -0.910500 +vn -0.003300 -0.475400 -0.879700 +vn 1.000000 0.000000 0.000000 +vn 0.359600 0.000000 0.933100 +vn 0.359600 0.000000 -0.933100 +vn -1.000000 -0.001100 0.000000 +vn -0.361000 -0.000700 0.932600 +vn -0.361000 -0.000700 -0.932600 +vn -0.736100 -0.676800 0.000000 +vn -0.327100 -0.263100 0.907600 +vn -0.327100 -0.263100 -0.907600 +vn 0.000000 -1.000000 0.004800 +vn 0.000000 -0.657400 -0.753500 +vn 0.898300 -0.248500 -0.362400 +vn 0.863600 -0.504100 0.003400 +vn -0.898300 -0.248500 -0.362400 +vn -0.863600 -0.504100 0.003400 +vn 0.000000 0.000000 -1.000000 +vn 0.925200 0.000000 -0.379500 +vn -0.925200 0.000000 -0.379500 +vn 0.898300 0.248500 -0.362400 +vn 0.661600 -0.421500 0.620200 +vn -0.898300 0.248500 -0.362400 +vn 0.898300 0.248500 0.362300 +vn -0.898300 0.248500 0.362300 +vn 0.000000 -0.000900 1.000000 +vn 0.924700 -0.000600 0.380700 +vn -0.924700 -0.000600 0.380700 +vn 0.000000 -0.650300 0.759600 +vn 0.895600 -0.254600 0.364700 +vn -0.895600 -0.254600 0.364700 +vn 0.729700 -0.683700 0.000000 +vn 0.729700 0.683800 0.000000 +vn -0.729700 0.683800 0.000000 +vn -0.898300 -0.248400 0.362300 +vn -0.863600 -0.504100 -0.003500 +vn 0.898300 -0.248400 0.362300 +vn 0.863600 -0.504100 -0.003500 +vn -0.661500 -0.421500 0.620200 +vn 0.924600 -0.000600 -0.380700 +vn -0.661500 0.421500 0.620200 +vn 0.661500 0.421500 0.620200 +s 1 +f 1/1/1 2/2/2 3/3/3 4/4/4 +f 4/4/4 3/3/3 5/5/5 6/6/6 +f 6/6/6 5/5/5 7/7/7 8/8/8 +f 8/8/8 7/7/7 9/9/9 10/10/10 +f 1/1/1 10/11/10 9/12/9 2/2/2 +f 2/2/2 11/13/11 12/14/12 3/3/3 +f 3/3/3 12/14/12 13/15/13 5/5/5 +f 5/5/5 13/15/13 14/16/14 7/7/7 +f 7/7/7 14/16/14 15/17/15 9/9/9 +f 9/12/9 15/18/15 11/13/11 2/2/2 +f 11/13/11 16/19/16 17/20/17 12/14/12 +f 12/14/12 17/20/17 18/21/18 13/15/13 +f 13/15/13 18/21/18 19/22/19 14/16/14 +f 14/16/14 19/22/19 20/23/20 15/17/15 +f 15/18/15 20/24/20 16/19/16 11/13/11 +f 16/19/16 21/25/21 22/26/22 17/20/17 +f 17/20/17 22/26/22 23/27/23 18/21/18 +f 18/21/18 23/27/23 24/28/24 19/22/19 +f 19/22/19 24/28/24 25/29/25 20/23/20 +f 20/24/20 25/30/25 21/25/21 16/19/16 +f 21/25/21 26/31/26 27/32/27 22/26/22 +f 22/26/22 27/32/27 28/33/28 23/27/23 +f 23/27/23 28/33/28 29/34/29 24/28/24 +f 24/28/24 29/34/29 30/35/30 25/29/25 +f 25/30/25 30/36/30 26/31/26 21/25/21 +f 26/37/26 31/38/31 32/39/32 27/40/27 +f 27/40/27 32/39/32 33/41/33 28/42/28 +f 28/42/28 33/41/33 34/43/34 29/44/29 +f 29/44/29 34/43/34 35/45/35 30/46/30 +f 30/47/30 35/48/35 31/38/31 26/37/26 +f 31/38/31 36/49/36 37/50/37 32/39/32 +f 32/39/32 37/50/37 38/51/38 33/41/33 +f 33/41/33 38/51/38 39/52/39 34/43/34 +f 34/43/34 39/52/39 40/53/40 35/45/35 +f 35/48/35 40/54/40 36/49/36 31/38/31 +f 36/49/36 1/1/1 4/4/4 37/50/37 +f 37/50/37 4/4/4 6/6/6 38/51/38 +f 38/51/38 6/6/6 8/8/8 39/52/39 +f 39/52/39 8/8/8 10/10/10 40/53/40 +f 1/1/1 36/49/36 40/54/40 10/11/10 +f 41/55/41 42/56/42 43/57/43 44/58/44 +f 44/59/44 43/60/43 45/61/45 46/62/46 +f 46/62/46 45/61/45 47/63/47 48/64/48 +f 48/64/48 47/63/47 49/65/49 50/66/50 +f 41/55/41 50/66/50 49/65/49 42/56/42 +f 42/56/42 51/67/51 52/68/52 43/57/43 +f 43/60/43 52/69/52 53/70/53 45/61/45 +f 45/61/45 53/70/53 54/71/54 47/63/47 +f 47/63/47 54/71/54 55/72/55 49/65/49 +f 49/65/49 55/72/55 51/67/51 42/56/42 +f 51/67/51 56/73/56 57/74/57 52/68/52 +f 52/69/52 57/75/57 58/76/58 53/70/53 +f 53/70/53 58/76/58 59/77/59 54/71/54 +f 54/71/54 59/77/59 60/78/60 55/72/55 +f 55/72/55 60/78/60 56/73/56 51/67/51 +f 56/73/56 61/79/21 62/80/61 57/74/57 +f 57/75/57 62/81/61 63/82/62 58/76/58 +f 58/76/58 63/82/62 64/83/63 59/77/59 +f 59/77/59 64/83/63 65/84/64 60/78/60 +f 60/78/60 65/84/64 61/79/21 56/73/56 +f 61/85/21 66/86/65 67/87/66 62/88/61 +f 62/35/61 67/89/66 68/90/67 63/91/62 +f 63/91/62 68/90/67 69/92/68 64/93/63 +f 64/93/63 69/92/68 70/94/69 65/95/64 +f 65/95/64 70/94/69 66/86/65 61/85/21 +f 66/86/65 71/96/70 72/97/71 67/87/66 +f 67/89/66 72/98/71 73/99/72 68/90/67 +f 68/90/67 73/99/72 74/100/73 69/92/68 +f 69/92/68 74/100/73 75/101/74 70/94/69 +f 70/94/69 75/101/74 71/96/70 66/86/65 +f 71/96/70 76/102/75 77/103/76 72/97/71 +f 72/98/71 77/104/76 78/105/77 73/99/72 +f 73/99/72 78/105/77 79/106/78 74/100/73 +f 74/100/73 79/106/78 80/107/79 75/101/74 +f 75/101/74 80/107/79 76/102/75 71/96/70 +f 76/102/75 41/55/41 44/58/44 77/103/76 +f 77/104/76 44/59/44 46/62/46 78/105/77 +f 78/105/77 46/62/46 48/64/48 79/106/78 +f 79/106/78 48/64/48 50/66/50 80/107/79 +f 41/55/41 76/102/75 80/107/79 50/66/50 +f 81/108/80 82/109/81 83/110/82 84/111/83 +f 84/9/83 83/17/82 85/112/78 86/113/48 +f 86/113/48 85/112/78 87/114/77 88/115/46 +f 88/115/46 87/114/77 89/116/84 90/117/85 +f 81/108/80 90/117/85 89/116/84 82/109/81 +f 82/109/81 91/118/86 92/119/87 83/110/82 +f 83/17/82 92/23/87 93/120/73 85/112/78 +f 85/112/78 93/120/73 94/121/72 87/114/77 +f 87/114/77 94/121/72 95/122/88 89/116/84 +f 89/116/84 95/122/88 91/118/86 82/109/81 +f 91/118/86 96/123/65 97/124/69 92/119/87 +f 92/23/87 97/29/69 98/125/68 93/120/73 +f 93/120/73 98/125/68 99/126/67 94/121/72 +f 94/121/72 99/126/67 100/127/66 95/122/88 +f 95/122/88 100/127/66 96/123/65 91/118/86 +f 96/123/65 101/85/21 102/88/64 97/124/69 +f 97/29/69 102/35/64 103/91/63 98/125/68 +f 98/125/68 103/91/63 104/93/62 99/126/67 +f 99/126/67 104/93/62 105/95/61 100/127/66 +f 100/127/66 105/95/61 101/85/21 96/123/65 +f 101/128/21 106/129/56 107/130/60 102/131/64 +f 102/46/64 107/45/60 108/132/59 103/133/63 +f 103/133/63 108/132/59 109/134/58 104/135/62 +f 104/135/62 109/134/58 110/136/57 105/137/61 +f 105/137/61 110/136/57 106/129/56 101/128/21 +f 106/129/56 111/138/89 112/139/90 107/130/60 +f 107/45/60 112/53/90 113/140/54 108/132/59 +f 108/132/59 113/140/54 114/141/53 109/134/58 +f 109/134/58 114/141/53 115/142/91 110/136/57 +f 110/136/57 115/142/91 111/138/89 106/129/56 +f 111/138/89 116/143/92 117/144/93 112/139/90 +f 112/53/90 117/10/93 118/145/47 113/140/54 +f 113/140/54 118/145/47 119/146/45 114/141/53 +f 114/141/53 119/146/45 120/147/94 115/142/91 +f 115/142/91 120/147/94 116/143/92 111/138/89 +f 116/143/92 81/108/80 84/111/83 117/144/93 +f 117/10/93 84/9/83 86/113/48 118/145/47 +f 118/145/47 86/113/48 88/115/46 119/146/45 +f 119/146/45 88/115/46 90/117/85 120/147/94 +f 81/108/80 116/143/92 120/147/94 90/117/85 +f 121/148/95 122/149/96 123/150/97 124/151/98 +f 124/151/98 123/150/97 125/152/39 126/153/8 +f 126/153/8 125/152/39 127/154/38 128/155/6 +f 128/155/6 127/154/38 129/156/99 130/157/100 +f 121/148/95 130/103/100 129/58/99 122/149/96 +f 122/149/96 131/158/101 132/159/102 123/150/97 +f 123/150/97 132/159/102 133/160/34 125/152/39 +f 125/152/39 133/160/34 134/161/33 127/154/38 +f 127/154/38 134/161/33 135/162/103 129/156/99 +f 129/58/99 135/57/103 131/158/101 122/149/96 +f 131/158/101 136/163/26 137/164/104 132/159/102 +f 132/159/102 137/164/104 138/165/105 133/160/34 +f 133/160/34 138/165/105 139/166/28 134/161/33 +f 134/161/33 139/166/28 140/167/106 135/162/103 +f 135/57/103 140/68/106 136/163/26 131/158/101 +f 136/163/26 141/168/21 142/169/25 137/164/104 +f 137/164/104 142/169/25 143/170/24 138/165/105 +f 138/165/105 143/170/24 144/171/23 139/166/28 +f 139/166/28 144/171/23 145/172/22 140/167/106 +f 140/68/106 145/74/22 141/168/21 136/163/26 +f 141/168/21 146/173/16 147/174/107 142/169/25 +f 142/169/25 147/174/107 148/175/19 143/170/24 +f 143/170/24 148/175/19 149/176/18 144/171/23 +f 144/171/23 149/176/18 150/177/108 145/172/22 +f 145/74/22 150/80/108 146/173/16 141/168/21 +f 146/178/16 151/179/109 152/180/110 147/181/107 +f 147/181/107 152/180/110 153/182/14 148/183/19 +f 148/183/19 153/182/14 154/184/13 149/185/18 +f 149/185/18 154/184/13 155/186/111 150/187/108 +f 150/88/108 155/87/111 151/179/109 146/178/16 +f 151/179/109 156/188/112 157/189/113 152/180/110 +f 152/180/110 157/189/113 158/190/7 153/182/14 +f 153/182/14 158/190/7 159/191/5 154/184/13 +f 154/184/13 159/191/5 160/192/114 155/186/111 +f 155/87/111 160/97/114 156/188/112 151/179/109 +f 156/188/112 121/148/95 124/151/98 157/189/113 +f 157/189/113 124/151/98 126/153/8 158/190/7 +f 158/190/7 126/153/8 128/155/6 159/191/5 +f 159/191/5 128/155/6 130/157/100 160/192/114 +f 121/148/95 156/188/112 160/97/114 130/103/100 +f 161/193/80 162/194/115 163/60/82 164/59/83 +f 164/195/83 163/196/82 165/197/78 166/198/48 +f 166/198/48 165/197/78 167/199/77 168/200/46 +f 168/200/46 167/199/77 169/201/84 170/202/85 +f 161/193/80 170/202/85 169/201/84 162/194/115 +f 162/194/115 171/203/86 172/69/87 163/60/82 +f 163/196/82 172/204/87 173/205/73 165/197/78 +f 165/197/78 173/205/73 174/206/72 167/199/77 +f 167/199/77 174/206/72 175/207/88 169/201/84 +f 169/201/84 175/207/88 171/203/86 162/194/115 +f 171/203/86 176/208/116 177/75/69 172/69/87 +f 172/204/87 177/209/69 178/210/68 173/205/73 +f 173/205/73 178/210/68 179/211/67 174/206/72 +f 174/206/72 179/211/67 180/212/66 175/207/88 +f 175/207/88 180/212/66 176/208/116 171/203/86 +f 176/208/116 181/213/21 182/81/64 177/75/69 +f 177/209/69 182/214/64 183/215/63 178/210/68 +f 178/210/68 183/215/63 184/216/62 179/211/67 +f 179/211/67 184/216/62 185/217/61 180/212/66 +f 180/212/66 185/217/61 181/213/21 176/208/116 +f 181/34/21 186/218/117 187/89/60 182/35/64 +f 182/36/64 187/219/60 188/220/59 183/31/63 +f 183/31/63 188/220/59 189/221/58 184/32/62 +f 184/32/62 189/221/58 190/222/57 185/33/61 +f 185/33/61 190/222/57 186/218/117 181/34/21 +f 186/218/117 191/223/89 192/98/90 187/89/60 +f 187/219/60 192/224/90 193/225/54 188/220/59 +f 188/220/59 193/225/54 194/226/53 189/221/58 +f 189/221/58 194/226/53 195/227/91 190/222/57 +f 190/222/57 195/227/91 191/223/89 186/218/117 +f 191/223/89 196/228/92 197/104/93 192/98/90 +f 192/224/90 197/229/93 198/230/47 193/225/54 +f 193/225/54 198/230/47 199/231/45 194/226/53 +f 194/226/53 199/231/45 200/232/94 195/227/91 +f 195/227/91 200/232/94 196/228/92 191/223/89 +f 196/228/92 161/193/80 164/59/83 197/104/93 +f 197/229/93 164/195/83 166/198/48 198/230/47 +f 198/230/47 166/198/48 168/200/46 199/231/45 +f 199/231/45 168/200/46 170/202/85 200/232/94 +f 161/193/80 196/228/92 200/232/94 170/202/85 +f 201/233/1 202/234/2 203/235/118 204/236/119 +f 204/111/119 203/110/118 205/237/5 206/238/6 +f 206/238/6 205/237/5 207/239/7 208/240/8 +f 208/240/8 207/239/7 209/241/120 210/242/121 +f 201/233/1 210/242/121 209/241/120 202/234/2 +f 202/234/2 211/243/11 212/244/12 203/235/118 +f 203/110/118 212/119/12 213/245/13 205/237/5 +f 205/237/5 213/245/13 214/246/14 207/239/7 +f 207/239/7 214/246/14 215/247/15 209/241/120 +f 209/241/120 215/247/15 211/243/11 202/234/2 +f 211/243/11 216/248/16 217/249/108 212/244/12 +f 212/119/12 217/124/108 218/250/18 213/245/13 +f 213/245/13 218/250/18 219/251/19 214/246/14 +f 214/246/14 219/251/19 220/252/107 215/247/15 +f 215/247/15 220/252/107 216/248/16 211/243/11 +f 216/248/16 221/185/21 222/187/22 217/249/108 +f 217/124/108 222/88/22 223/178/23 218/250/18 +f 218/250/18 223/178/23 224/181/24 219/251/19 +f 219/251/19 224/181/24 225/183/25 220/252/107 +f 220/252/107 225/183/25 221/185/21 216/248/16 +f 221/253/21 226/254/26 227/255/106 222/256/22 +f 222/131/22 227/130/106 228/257/122 223/258/23 +f 223/258/23 228/257/122 229/259/29 224/260/24 +f 224/260/24 229/259/29 230/261/104 225/262/25 +f 225/262/25 230/261/104 226/254/26 221/253/21 +f 226/254/26 231/263/31 232/264/32 227/255/106 +f 227/130/106 232/139/32 233/265/33 228/257/122 +f 228/257/122 233/265/33 234/266/34 229/259/29 +f 229/259/29 234/266/34 235/267/123 230/261/104 +f 230/261/104 235/267/123 231/263/31 226/254/26 +f 231/263/31 236/268/36 237/269/37 232/264/32 +f 232/139/32 237/144/37 238/270/124 233/265/33 +f 233/265/33 238/270/124 239/271/125 234/266/34 +f 234/266/34 239/271/125 240/272/40 235/267/123 +f 235/267/123 240/272/40 236/268/36 231/263/31 +f 236/268/36 201/233/1 204/236/119 237/269/37 +f 237/144/37 204/111/119 206/238/6 238/270/124 +f 238/270/124 206/238/6 208/240/8 239/271/125 +f 239/271/125 208/240/8 210/242/121 240/272/40 +f 201/233/1 236/268/36 240/272/40 210/242/121 diff --git a/mods/basic_materials/plastics.lua b/mods/basic_materials/plastics.lua new file mode 100644 index 00000000..e29af53e --- /dev/null +++ b/mods/basic_materials/plastics.lua @@ -0,0 +1,56 @@ +-- Translation support +local S = minetest.get_translator("basic_materials") + +-- items + +minetest.register_craftitem("basic_materials:plastic_sheet", { + description = S("Plastic sheet"), + inventory_image = "basic_materials_plastic_sheet.png", +}) + +minetest.register_craftitem("basic_materials:plastic_strip", { + description = S("Plastic strips"), + groups = { strip = 1 }, + inventory_image = "basic_materials_plastic_strip.png", +}) + +minetest.register_craftitem("basic_materials:empty_spool", { + description = S("Empty wire spool"), + inventory_image = "basic_materials_empty_spool.png" +}) + +-- crafts + +minetest.register_craft({ + type = "cooking", + output = "basic_materials:plastic_sheet", + recipe = "basic_materials:paraffin", +}) + +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:plastic_sheet", + burntime = 30, +}) + +minetest.register_craft( { + output = "basic_materials:plastic_strip 9", + recipe = { + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } + }, +}) + +minetest.register_craft( { + output = "basic_materials:empty_spool 3", + recipe = { + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }, + { "", "basic_materials:plastic_sheet", "" }, + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } + }, +}) + +-- aliases + +minetest.register_alias("homedecor:plastic_sheeting", "basic_materials:plastic_sheet") +minetest.register_alias("homedecor:plastic_strips", "basic_materials:plastic_strip") +minetest.register_alias("homedecor:empty_spool", "basic_materials:empty_spool") diff --git a/mods/basic_materials/textures/basic_materials_brass_block.png b/mods/basic_materials/textures/basic_materials_brass_block.png new file mode 100644 index 0000000000000000000000000000000000000000..c93780002f87ced40ad5cd844688948d20ae8ac9 GIT binary patch literal 272 zcmV+r0q_2aP)QAOHgp5C8x(050AB*_x`W!T=5K?%SEV?y&$p{{H{lo9lo84(;v! z`}%WB5`?cueVTx0*^E2e6CAk@9U$q7a6US*<7tZ^V-h$jBzVo87_Qrt>rjZ zLZCMXtGZFQN6*p}qh=|k;^VD83hTEnGx;DPF!Pi6H|b?HelzCZd%O6-zjXF)S*BSI Tw|Pu}wlH|Q`njxgN@xNA6Yo-v literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_cement_block.png b/mods/basic_materials/textures/basic_materials_cement_block.png new file mode 100644 index 0000000000000000000000000000000000000000..6d30f477f359e93a71112578baace525ce0f0fdc GIT binary patch literal 243 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 Y0yypkc?hzDnE(I)07*qoM6N<$g3I$jPXGV_ literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_chainlink_brass.png b/mods/basic_materials/textures/basic_materials_chainlink_brass.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1ad87e5c4ec6bedb9fa3fcb8bf9c36b2841a57 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^3h)VW1=2k^8k@U}4@@yTw<_e> zl@)7JuCE4)GL{7S1v5B2yO9Ru_<6cGhH%KT9(3etHV|MqurTLclfJ;Oh9$Fh@A{^< z;{X3HV+MwRdBQvTS$DXyzI>(N-KXtxU**TObheBA+nWB{sdS{V1)3_Jdt ZY;yS)^B@^VH=qj`JYD@<);T3K0RX*6Kz#rJ literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_concrete_block.png b/mods/basic_materials/textures/basic_materials_concrete_block.png new file mode 100644 index 0000000000000000000000000000000000000000..5dd0d660a238c6ca7f0274f260f9afb320b77277 GIT binary patch literal 252 zcmVY`8QRl6>1%B6N=CI;5pv6_`|C`xS z|39tB`Tu28&HpzWTK<37J>~!1O;i6r**fk2mBnrUcXww0JJp-=X?d3G`^9mlXICZ} zm%|Mxwv_z;c245|&#Mdn|J>gA|KH&$|NmWB@&EtrtzZmdgTz2`AT^JsME$R_mH7`h zpvhI?-}-FF{}UqZ{$H6s`C!ZX{nYTeq`B4b~ Y0Jhw^anS{dXaE2J07*qoM6N<$f(d7-Z~y=R literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_copper_wire.png b/mods/basic_materials/textures/basic_materials_copper_wire.png new file mode 100644 index 0000000000000000000000000000000000000000..9df9f36635e86c5ea63c1dc3f12887fb3bc22202 GIT binary patch literal 306 zcmV-20nPr2P)U@EwPwOzp8T|3fHAS9c_ zBxqkZTD_-FGjG9BUV9J`Im_gE-a)``b5RszSq4CoB*byt8v?-NdL?ZcV?-$>N+~hM zblx@(>2cC@xsX#zmy3>h&>kk!8SA@iqF_Me4;ckR06t8OwhgAqIuQ`|V zIit{L90puO0RX#7^QkS`Hssqae-gaqFTDiXg`hN+$~Y4IV+R4_(EldzU{`8NZK>RL zu*cL*KY@tI>h|iaD~O2vH1VLyr+RR6|J13n^Jj9_7u?+FHXlP0<^TWy07*qoM6N<$ Ef~uT@yZ`_I literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_empty_spool.png b/mods/basic_materials/textures/basic_materials_empty_spool.png new file mode 100644 index 0000000000000000000000000000000000000000..017a94fd20c34d95fc8342e9df02f0db5e4a64d0 GIT binary patch literal 214 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`b3I)gLo80;o$SbUSV6#bzUdJG zfjgC~{*#=mh1NfC64-Rg>CGzD84+A%SN8|~`8*?WpMgfpa5~kR)YHQlO^dK*b=XraB`4f5$N;C&`1$k|s zef)*gf8GH9tlqubS59wCjXYtw|Ge&-sjcs%u9v!caTa(!^tZpfVcx$fzAL*Q8e9iD Ol)=;0&t;ucLK6VKXII() literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_energy_crystal.png b/mods/basic_materials/textures/basic_materials_energy_crystal.png new file mode 100644 index 0000000000000000000000000000000000000000..f1c28e80547b2ade2e3ad9d04690351752d0eb1a GIT binary patch literal 817 zcmV-11J3-3P) zZ%mYR0KoB|Cm^E@>ok=dXX3-%c?!pc97GUWbD5fNOj^BY=2}L!nffYOptzAsa_j#B z3tw1nDO-Om=4{18?awf)jpm|%Ti6`CIJoD}@Ao|SJil+W)#eLp_4$Z@!mg#o?5=3w zsU-vA|I%H?99o~anYL2cTCDYf^fB>Y(cN6cL!wk2yA@hXwR5^0e}5R-AAOLvl_BwO zvLky#VupV9PNs(&g6w1qxp(hI4Ypu@+z31C*3({BD6S{-+v_1Q!|!{*q$BCsNAAHs zv6<|-J;>fhvO|xN?`c9G+O&YK#yR48cy8S!?bV9TT6D*9^wS1B9)_+O^qz9`juNf+ z#nCUUUg*D=nk}xy!8M=hy_M2EaxdzWB>8s?f}S+&N<&8&_NQ@=S0gVq__`yK5r32Y zYYX#-QrpcZ1?J%x?(izCixI5TYmk@YSeXdckFDfL;e5FSchtZ+HP5rIM!Wq^Q6R>l z$mv|n?-z@(>^T0bx8S}pmrT%xHC%_Bs3rUT7QE*Ttifiolwn%ss4L6Jy%$?7?2jHk zKlP^Yrd1UE$|CISQXD6Vef18^@g!c4f!!a+{;3jqem-(4itSfnUYPHzfyAirx+B=K z3g=2CHZi1*BUK7>Vj13;f%!uPYG5I%?+!x@M9@1I=Xe;l--y4h0JfDdeNy0l9mbO}R3;HP_UdniK3P_64OQZvU4iYD zA$2{HH2Je7aG;*xr6wlFIvM9E>fr6z+=l&g1m!lPf(>hh5@HrD;rrY(2`tM%vI@i?uA%RjjR~Ru{kPcI9By+@s~dU6S@ozea7Ws00000NkvXXu0mjfutA!B literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_gear_steel.png b/mods/basic_materials/textures/basic_materials_gear_steel.png new file mode 100644 index 0000000000000000000000000000000000000000..584f9a51502729fb65198c204230d0100d729b5a GIT binary patch literal 5845 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 literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_gold_wire.png b/mods/basic_materials/textures/basic_materials_gold_wire.png new file mode 100644 index 0000000000000000000000000000000000000000..781de7b1a9439a5d9180f06a1074b6f767a427c2 GIT binary patch literal 286 zcmV+(0pb3MP)}LrYr3NnDttB9Rl=MN-iv2S^8^AZA-TUKwwOhDdf26HCkQMyvnz zH1iicrMiQN$S9Li>LlRUToeU)o&%7kDO&5n5CAsoxpZZ%6=RGTW5in9d)usD&XaC4 zEtj;-bk7`ihj^CowR|KDuTjyIU=je}b`5)1vj47#X9@6pKA`?waQpBCHz7=}P`?2| z-9XiXb(C)ze-cz5uY&}x@gb;N*m)9+-$5Kf9R2SOTw5V+IZPlTQsnoet{@_EXyQqg kFZJLqdGA%(`!jj#2hL93EOD>hK>z>%07*qoM6N<$f|qX6 z@{*qEs#o=@suPJ}+gEYYz8q@%erhbw%@Y%z2L?Xw`&Ix6fCPq+KnNN5pJyi#FX(u) zqTotUTJ%Da!c>y5y#%-vhd2^9(<3Nn#=Cu6LU6yK2>Vm++p!MIf7n(;bPwu#KH7PM zcER9$E=6<#%Bw0KNp081^|D9wIewfOJRRt0i7n}VAOyib1eL79#eB+5&=9>G-_??b z*CWkr9TH}~T~mZx0<{-KyI{Sv;Ndg>+eBAYT}EeSi8IDvdJK0nJ!5R;y6RO>o{4%!RUSCcpnSb?EjDXgu~oqow_# P00000NkvXXu0mjfbef`4 literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_ic.png b/mods/basic_materials/textures/basic_materials_ic.png new file mode 100644 index 0000000000000000000000000000000000000000..4c8889451813f0c8727e0efac36ff761b5f047fc GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl<6e(pbstU!KjfKP~P za74IgfWMQMm#dGDPe`zDXlQU$l(V)`Gl7#ae!VaIKe&p=APB*-uL zKVHCaR!*bvb8f^mY(D}5g$--J~2#QIM$&r{Q^96y+6-Y#45 zTFOgP#I;eyQ>IYH*{d?W;OJ$Oz5EG1j`zR2TsArJ`Od^t$-d<+0!^y=VrSeF)*iL! zQ@Ico&!QeEa#z)ud&4?y&S|NNj@L^yPJdGJxO|24kiinYIS+KwDtcC}+P5p=ASdUy vTK3Jkx0#vV3)XFQd7uBqTIGFkor(M*_EfD+S3VsC`h>yL)z4*}Q$iB}YXn`L literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_oil_extract.png b/mods/basic_materials/textures/basic_materials_oil_extract.png new file mode 100644 index 0000000000000000000000000000000000000000..e34623d0551bbf2334f46393b2a66ade0ca7b8b6 GIT binary patch literal 1966 zcmV;f2T}NmP))Rd!KV>=4LXXt)b124^d+!s8kw|Fe7L~6^YPd(_)Klv4VXQ`XDIycx03ad|5pJ~IZ~(kls0c)4hflp3Y5<-){$j&g zI$(?)H74_wm_W=RqMdB*SB4sZI7+_koVm-nl~8A5IOkxQp{kFcn4SCZPy#SLJ+mK# zuUhLu=I+NbGmNz$qA~CFdqW4nGsjLgiReh+%)avK7g~^IgA79iV*2EX*}2Du3IJow zA#3Sq5I7XE-{)_@#(;=e6i1(*ed)kZ05Cm0vp-G!BgPo?u6}PQ7-L|vt#OQ?-{15A zJag=1lMR2#F!lw3U3K-l!XaY;M6vhy%-nZ3Hv?2Z4d83W7#L&MOniu_%mM~*`1#qF zKC>wSc>3wty#SuDhTxomF(xm321t^!yr2k$@0>b)W@1wTFg-mpN=)}M(=KKP5ko|f zrfJvZz3)G%d`AEPQS439^xK;X0AuKmg8J6-nz7$6MJ};`RrPZxX6KG<3IL8hd+I|4 z^^GAg8*uJS*H1R9YJ!5gSO8#5LHFfj*B5{%pPFHx%Ga4`R}ffO7a|B7utCtdj0<7I z23!~d!~<81s`@b(hL2TUGFJ+KW14b~j|PnfTsVqwWCSh@!N!8f0LU1iqEOL6;-Sm} z25^{(kJJ)?Q>V{Ngrkio!o~=~umNjr*6bM6+47|5Y9LRfa-k03>O;&l$7R zI+u$WRWC6rh@)tmPyB6l41s+`%rZ0R8jl=^Y4zkNXMj%<5Of?wmE{GMoeL23CUmy2 z!P{NL1oa9+c2ChMR`F0#hzfj?bXw;CwiD4!wF3aaM_0fYboB+|72ao#l6ZLUb7wP$ zeJW+=p`bujchnJp-93V}Ce?i+`AQ3*inNm%YO(dLHq1orG=PZql%3CdeJhu$0-B}6 zK1q;75yYomPOjWfcrP$jwK+XKGg=!4oH~7GLcBLcH5Y~sLEzx5fwNg5#B5-#0W(0v zD7OMc01<)rf;9CINf1RTk|ajE9bg z7EQ@CK!gBD=UyU0v)QB|4C}KCT)w>63sf04@lS6Y0Pq6>8HJ7j2%!l3$GH~u{<5eps>oYj z%b#?=d2jqj!8&_)Np#DCIZEtZ#|2NcXsgUkuica&sQ6&Y;WyD`Vl!5H8GELkH9r;- zDwm`^F_M`^6HOTt>+v}?E2bUlpfofs2Lw>Lj!JUVxM$yxq-m!y!xnH@W}@S5GO zT{_Le*I&i$%fZzRigya$&8pWftaSLuYWe2D+=jogy#2KYR?2=1-pklN)ivBPrXm37 OQU*^~KbLh*2~7a=@>Ny< literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_paraffin.png b/mods/basic_materials/textures/basic_materials_paraffin.png new file mode 100644 index 0000000000000000000000000000000000000000..77d2bbd12e37d724d87822457fa22b927a48c18f GIT binary patch literal 345 zcmV-f0jBjm@zqOr9pf#>1mvib%4#NfwJP zPZ)e+%=#VRlNOX9PL7g<0q_A)q;_`)qPX!U# zSv{nT;*Bx|Y8aR_c*mke6>T6Q2U`i>#6!_T=Ykt5RCo;UgIhoODtluh+q2gXSvwWv rlxFN&(J)=jtZ0kTh2#0x-pREfDC$N*K|~Z4L`Bdur1ORjbfHC|ln#V!@?U;3x!wNy#c})~ zE(_bXeKbvD7eygNnx@ui;WSOQ%F=b6kgKYavMfJCuxW(DFvvKLI`@6AApr6`--jrR zcM2#(Fwe8B>nh8#Xb4Vl@dE5aRDor>Biy!4LvRA1u4}UkiK1v9qKYjXAOeCDfMyRk zNRmX+q>j00000NkvXXu0mjfHCcNh literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_plastic_strip.png b/mods/basic_materials/textures/basic_materials_plastic_strip.png new file mode 100644 index 0000000000000000000000000000000000000000..1318dfc04dfb0e80a85e934877e1b3eae6ad43f9 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`>7Fi*Ar`0iURLBgpuppB@qR4B z>A(KrvCVIeOlocA)$m^7yhq-Jd-w6Xd+WSKW=k??s&cYs#dt9)JlFZe?*Df|dwZkc zJGQhB=?P-{*_3v0x_ngL(DeR*7Mlfw%evOCM`V@kMmH`p`ycT4I@X3iVE9{Sc9lH zdl3~uKiP|*7ZC(Oy^UT~e?l*M6@!SN}?zQjdx~p5WjW$kSxQ5;+H8 zFR@7+<03nvu|ztZtD;=4B1G}XSv5$i30XBDDh5(&5d#O@@cP4;Tj*|OG_yl&^=jQo zwy~_3%VZ0P(n$oP4044AV(}#6yn>XPhp6cAjYklep!!q1{G+|JjC9&q2QXNxHk?Ed z)DsCwgI;JNNC~*IvIeg|f^5D9YAONWSO7!rQ4D)VG3*(GQKX6EG2pgJvZRd&Y2Z*n=Ur7b9Ljy#6qfirx=|rjX5=j|mlHpHOrX zv&}YynIhKLpJ6;mBRa`J(TX@4jAHM=AodTrA5)-vAf@II ziiw~(sUL~4Tl)qNY!)iV`tzMGtWx8poUyDKwRq%Y`{HO=Yz`2cZdRNmDWyN9(gmD4 zbq0YDjbL~Z3@iQ27`2UhtNr}KvbdK{j???YT{yUD%d)e>>@0i< zb6cpYzBOcwIS||rkK;&HRRF|sOcX_@Bo7JJb;Vi>faiI*uDkcPZNqUKbC4z?`U)bV z4?QT$Qj4O%_kDsOAPhqQhGAe?7Up>-O;eI2F{kE;h&D~5ec!9KcHcTpleTTEbzT2Z zLDzMEui$#)cdl?7xAItEbtpxx8002ovPDHLkV1ne^ BX2t*j literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_steel_bar.png b/mods/basic_materials/textures/basic_materials_steel_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..0673b6eefcb9a4f1a89fbdb0752f267f30476427 GIT binary patch literal 311 zcmV-70m%M|P)S7)4Je$=eAk(uKaDh$2Nq5G>W!ke^1f3?^34G)+y2)SsozxJoGvY0^#aZWzvY z=iZNjUCVQA*}J`wGM_4kz&h%Xnm#rhNbW);d=P zl!ZMx7Jd+->v|)+>|nL+rp)US0IP6Y=ZZQ9d-C{bU+(;O{sVdPs6OnL;>-X5002ov JPDHLkV1h3Ykc|KU literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_steel_strip.png b/mods/basic_materials/textures/basic_materials_steel_strip.png new file mode 100644 index 0000000000000000000000000000000000000000..6384dc8302080b28df9b484c8113e9809e76f64e GIT binary patch literal 326 zcmV-M0lEH(P)p{RH*@l&{j;V`-Lh=Kg3jd&7x*oiH8#cBX9Fr~jQwym-8a!Fq9kHYM%KS0fYf%w~K@}m*} Y0ADb?S;9pEJpcdz07*qoM6N<$g5}4dO8@`> literal 0 HcmV?d00001 diff --git a/mods/basic_materials/textures/basic_materials_steel_wire.png b/mods/basic_materials/textures/basic_materials_steel_wire.png new file mode 100644 index 0000000000000000000000000000000000000000..0c96c8f34b2857f76ef34a0e68d560d7712dc543 GIT binary patch literal 284 zcmV+%0ptFOP)JC@R=W}rb3>?xXFYS=9VU6sdR1afOp+Lku>gpC5<(z^1Cu=GY{0&*xw)NUt;HBinx+7> zZHxCF@4xtXe`AoK-t9<|7-NnEiirFWgsTu-{{~%xfg7l*F3Y=%2vk*%O+2acdQ}b* iZ0;X=RUZ9JqxB7_@8$Uni6R#O0000 zOGs2v90%av|J-x$%(>T@QD@YdDKgEVA}FjD(ZhlsSVAqL*P;j)xd_?`R*(d>XjKse zErN(z1wB_4H9;5^Q6^UQFk`X_$I+S5dEM9PE?S5X)c4_Eyghk<@IM~zZRPL`oat(P zcdBz8Jg8D=1OZg;eh&o7krn*;XC?%f+)v-Ct2hN%T>G}kgw z$!3uLnZ&CPU$^%5XCGh&2G7p>U!=>pyw<+3KJ(+-73nyVshZ}Li*T$8q?C|m#o`J( ziCGvtiT$mc$u<*ZN2cBk4L7Bd--$#3t|m~(=P{NV#rsr-jZRK4Inv@^49}jZ!r-Be zK8RhbVtu)ixxC`o;KZb^aBY#nFf^s<+)!bJ!;`b+K%6mz zbuME;KTTCEESnpG<`W1A9|HApxKoqh3`mWQi)Ha@YkazN8Ne0}j{&sWj)bl;iiUJF za*jEXT8R2M$aPW9O~4n9z;z|GOa@KSi1Pi@&lmtd+hizufYXwIMo3PYayXrrmMbAu z6?P#9eUcpWrv=91PUCU=7@6VRnnK7o|dVR9?jjdJ;fAxt=bLArhCDo^$7GP!M4W zcoVy!+^XWgbeD?TTm_