From 2fffd841689919deb6e14d1789b76f82cffd30bf Mon Sep 17 00:00:00 2001 From: crabman77 Date: Sat, 4 Jun 2016 22:55:24 +0200 Subject: [PATCH] add background in formspec fix can't buy/sell coins fix bug item selled by float 1.2 items fix if item stack by 1, buy only 1 item money value equal coin craft (1 silver = 9 copper) --- change.lua | 2 +- init.lua | 127 +++++++++++++++++++-------------- textures/minercantile_shop.png | Bin 3052 -> 9411 bytes 3 files changed, 73 insertions(+), 56 deletions(-) diff --git a/change.lua b/change.lua index 06278d1..fcd89f6 100644 --- a/change.lua +++ b/change.lua @@ -7,7 +7,7 @@ 100 pc = 1pa, 100pa = 1po --]] -local convertion = { ["maptools:copper_coin"] = 1, ["maptools:silver_coin"]=100, ["maptools:gold_coin"]=1000} +local convertion = { ["maptools:copper_coin"]=1, ["maptools:silver_coin"]=9, ["maptools:gold_coin"]=81} local function get_bancomatic_formspec(pos, name) local spos = pos.x .. "," .. pos.y .. "," .. pos.z diff --git a/init.lua b/init.lua index aab857e..fbb1ae5 100644 --- a/init.lua +++ b/init.lua @@ -13,18 +13,22 @@ minercantile.stock = {} -- table saved money, items list minercantile.shop = {} minercantile.shop.items_inventory = {} minercantile.stock.items = {} -minercantile.stock.money = 10000 +minercantile.stock.money = 100000 --functions specific to wallet minercantile.wallet = {} -- table players wallets minercantile.wallets = {} + --load money dofile(minetest.get_modpath("minercantile") .. "/wallets.lua") dofile(minetest.get_modpath("minercantile") .. "/change.lua") + local shop = {} --formspec temporary variables local shop_buy = {} local shop_items_nb + + --function save items_base function minercantile.save_stock_base() local input, err = io.open(minercantile.file_stock_base, "w") @@ -113,6 +117,9 @@ end -- sell fonction function minercantile.calcul_prices(item, object) + if item == "maptools:copper_coin" or item == "maptools:silver_coin" or item == "maptools:gold_coin" then -- dont's buy/sell coins + return nil + end local price = nil local money = minercantile.shop.get_money() if not minercantile.stock.items[item] then @@ -124,10 +131,14 @@ function minercantile.calcul_prices(item, object) price = math.ceil(minercantile.stock.items[item].price) elseif object == "sell" then local nb = minercantile.stock.items[item].nb - price = math.ceil((((money/2)/nb) - 0.49)) + --price = math.ceil((((money/2)/nb) - 0.49)) + --price = math.ceil(money/10/((math.log(nb+2000-99)*10)*(1000000/((nb+2000-99)^(2.01))))) + price = math.ceil((money/10)/(math.log(nb+2000-99)*10)*1000000/(math.pow((nb+2000-99),(2.01)))) elseif object == "buy" then local nb = minercantile.stock.items[item].nb - price = math.ceil((((money/2)/nb) + 0.49)) + --price = math.ceil((((money/2)/nb) + 0.49)) + --price = math.ceil(money/10/((math.log(nb+2000+99)*10)*(1000000/((nb+2000+99)^(2.01))))) + price = math.ceil((money/10)/(math.log(nb+2000+99)*10)*1000000/(math.pow((nb+2000+99),(2.01)))) end if price < 1 then price = 1 end return price @@ -141,11 +152,11 @@ function minercantile.get_formspec_shop_admin_shop(pos, node_name, name) shop[name].pos = pos shop[name].node_name = node_name - local formspec = {"size[6,6]label[2.2,0;Shop Admin]button[4.5,0;1.5,1;shop;Shop]"} + local formspec = {"size[6,6]bgcolor[#2A2A2A;]label[2.2,0;Shop Admin]button[4.5,0;1.5,1;shop;Shop]"} local isnode = minetest.get_node_or_nil(pos) if not isnode or isnode.name ~= node_name then return end local meta = minetest.get_meta(pos) - + local isopen = meta:get_int("open") or 0 if isopen == 1 then table.insert(formspec, "label[1,1;Is Open: Yes]button[3.5,0.8;1.5,1;open_close;No]") @@ -212,15 +223,19 @@ local function get_shop_inventory_by_page(name) nb_pages = math.ceil(nb_items/32) if page > nb_pages then page = nb_pages end local index = 0 - if nb_pages >1 then + if nb_pages > 1 then index = (page*32)-32 end for i=1, 32 do local item = shop_buy[name].items_list[index+i] if not item then break end local nb = minercantile.stock.items[item].nb - local price = minercantile.calcul_prices(item, "buy") - table.insert(inv_list, {name=item,nb=nb,price=price}) + if nb > 0 then + local price = minercantile.calcul_prices(item, "buy") + if price and price > 0 then + table.insert(inv_list, {name=item,nb=nb,price=price}) + end + end end else nb_items = shop_items_nb @@ -235,12 +250,13 @@ local function get_shop_inventory_by_page(name) if item then local nb = minercantile.stock.items[item].nb local price = minercantile.calcul_prices(item, "buy") - table.insert(inv_list, {name=item,nb=nb,price=price}) + if price and price > 0 then + table.insert(inv_list, {name=item,nb=nb,price=price}) + end else break end - end - + end end shop_buy[name].nb_pages = nb_pages return inv_list @@ -255,25 +271,25 @@ function minercantile.buy(name, item, nb, price) local shop_money = minercantile.shop.get_money() local player_money = minercantile.wallet.get_money(name) if player_money < 1 then - minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1,1;Sorry, you have not enough money]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]bgcolor[#2A2A2A;]label[2.6,0;Shop]label[1,1;Sorry, you have not enough money]button[1.3,2.1;1.5,1;return_buy;Return]button_exit[3.3,2.1;1.5,1;close;Close]") return false end local items_nb = minercantile.stock.items[item].nb -4 if items_nb < 1 then - minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1.7,1;Sorry, shop have 0 item ..".. item.."]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]bgcolor[#2A2A2A;]label[2.6,0;Shop]label[1.7,1;Sorry, shop have 0 item ..".. item.."]button[1.3,2.1;1.5,1;return_buy;Return]button_exit[3.3,2.1;1.5,1;close;Close]") return false end local item_can_sell = nb if items_nb/4 < nb then - item_can_sell = items_nb/4 + item_can_sell = math.floor(items_nb/4) end local price_total = math.floor(item_can_sell * price) local player_can_buy = item_can_sell if player_money < price_total then - player_can_buy = math.floor(player_money/price) + player_can_buy = math.floor(player_money/price) end print("player_can_buy:"..dump(player_can_buy)) local sell_price = player_can_buy * price @@ -292,7 +308,7 @@ function minercantile.buy(name, item, nb, price) minercantile.shop.give_money(sell_price, true) minercantile.wallet.take_money(name, sell_price, " Buy "..player_can_buy .." "..item..", price "..sell_price) - minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1,1;You buy "..player_can_buy .." "..item..", price "..sell_price.."]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]bgcolor[#2A2A2A;]label[2.6,0;Shop]label[1,1;You buy "..player_can_buy .." "..item..", price "..sell_price.."$]button[1.3,2.1;1.5,1;return_buy;Return]button_exit[3.3,2.1;1.5,1;close;Close]") return true end @@ -343,17 +359,22 @@ local function get_formspec_buy_items(name) local max = shop_buy[name].max local nb = shop_buy[name].nb local price = shop_buy[name].price - local formspec = {"size[8,6]label[3.5,0;Buy Items]"} - table.insert(formspec, "button[0.6,2;1,1;amount;-1]") - table.insert(formspec, "button[1.6,2;1,1;amount;-10]") - table.insert(formspec, "button[2.6,2;1,1;amount;-20]") - table.insert(formspec, "item_image_button[3.6,2;1,1;"..item..";buttonchoice_"..item..";"..nb.."]") - table.insert(formspec, "button[4.6,2;1,1;amount;+20]") - table.insert(formspec, "button[5.6,2;1,1;amount;+10]") - table.insert(formspec, "button[6.6,2;1,1;amount;+1]") - - table.insert(formspec, "size[8,6]label[3,3;Buy ".. nb.."x"..price.."="..nb * price.."]") - table.insert(formspec, "button[3.3,4;1.5,1;confirm;Confirm]") + local formspec = {"size[8,6]bgcolor[#2A2A2A;]label[3.5,0;Buy Items]"} + if minetest.registered_items[item] and minetest.registered_items[item].stack_max and minetest.registered_items[item].stack_max == 1 then + table.insert(formspec, "label[2.1,1.5;This item is being sold by 1 max]") + else + table.insert(formspec, "button[0.6,1.5;1,1;amount;-1]") + table.insert(formspec, "button[1.6,1.5;1,1;amount;-10]") + table.insert(formspec, "button[2.6,1.5;1,1;amount;-20]") + table.insert(formspec, "item_image_button[3.6,1.5;1,1;"..item..";buttonchoice_"..item..";"..nb.."]") + table.insert(formspec, "button[4.6,1.5;1,1;amount;+20]") + table.insert(formspec, "button[5.6,1.5;1,1;amount;+10]") + table.insert(formspec, "button[6.6,1.5;1,1;amount;+1]") + end + table.insert(formspec, "label[3.5,2.7;Price:"..price.."$]") + table.insert(formspec, "label[3.5,3.1;Amount:".. nb.." items]") + table.insert(formspec, "label[3.5,3.5;Total:"..nb * price.."$]") + table.insert(formspec, "button[3.3,5;1.5,1;confirm;Confirm]") table.insert(formspec, "button[0,0;1.5,1;abort;Return]") return table.concat(formspec) end @@ -370,7 +391,7 @@ function minercantile.sell(name, item, nb, price) local shop_money = minercantile.shop.get_money() if shop_money < 1 then - minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1,1;Sorry, shop have not enough money]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]bgcolor[#2A2A2A;]label[2.6,0;Shop]label[1,1;Sorry, shop have not enough money]button[1.3,2.1;1.5,1;return_sell;Return]button_exit[3.3,2.1;1.5,1;close;Close]") return false end @@ -382,7 +403,7 @@ function minercantile.sell(name, item, nb, price) end if items_nb == 0 then - minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1.7,1;Sorry, You have 0 item ..".. item.."]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]bgcolor[#2A2A2A;]label[2.6,0;Shop]label[1.7,1;Sorry, You have 0 item ..".. item.."]button[1.3,2.1;1.5,1;return_sell;Return]button_exit[3.3,2.1;1.5,1;close;Close]") return false end @@ -396,16 +417,16 @@ function minercantile.sell(name, item, nb, price) if (shop_money/4) < price_total then shop_can_buy = math.floor((shop_money/4)/price) elseif shop_money < price_total then - shop_can_buy = math.floor(shop_money/price) + shop_can_buy = math.floor(shop_money/price) end - print("shop_can_buy:"..dump(shop_can_buy)) + local sell_price = shop_can_buy * price for i=1,player_inv:get_size("main") do if player_inv:get_stack("main", i):get_name() == item then items_nb = items_nb + player_inv:get_stack("main", i):get_count() end - end + end local stack = ItemStack(item.." "..shop_can_buy) player_inv:remove_item("main", stack) @@ -414,7 +435,7 @@ function minercantile.sell(name, item, nb, price) minercantile.shop.take_money(sell_price, true) minercantile.wallet.give_money(name, sell_price, " Sell "..shop_can_buy .." "..item..", price "..sell_price) - minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]label[2.6,0;Shop]label[1,1;You sell "..shop_can_buy .." "..item..", price "..sell_price.."]button[1.3,2.1;1.5,1;return;Return]button_exit[3.3,2.1;1.5,1;close;Close]") + minetest.show_formspec(name, "minercantile:confirmed", "size[6,3]bgcolor[#2A2A2A;]label[2.6,0;Shop]label[1,1;You sell "..shop_can_buy .." "..item..", price "..sell_price.."$]button[1.3,2.1;1.5,1;return_sell;Return]button_exit[3.3,2.1;1.5,1;close;Close]") return true end @@ -431,12 +452,13 @@ local function show_formspec_to_sell(name) for i=1, player_inv:get_size("main") do if not player_inv:get_stack("main", i):is_empty() and minetest.registered_items[player_inv:get_stack("main", i):get_name()] then local item = player_inv:get_stack("main", i):get_name() - if not inv_items[item] then - inv_items[item] = {nb=0} - end - inv_items[item].nb = inv_items[item].nb + player_inv:get_stack("main", i):get_count() - if not inv_items[item].price then - inv_items[item].price = minercantile.calcul_prices(item, "sell") + local price = minercantile.calcul_prices(item, "sell") + if price and price > 0 then + if not inv_items[item] then + inv_items[item] = {nb=0} + end + inv_items[item].nb = inv_items[item].nb + player_inv:get_stack("main", i):get_count() + inv_items[item].price = price end end end @@ -463,7 +485,7 @@ local function get_formspec_sell_items(name) local max = shop[name].max local nb = shop[name].nb local price = shop[name].price - local formspec = {"size[8,6]label[3.5,0;Sell Items]"} + local formspec = {"size[8,6]bgcolor[#2A2A2A;]label[3.5,0;Sell Items]"} table.insert(formspec, "button[0.6,2;1,1;amount;-1]") table.insert(formspec, "button[1.6,2;1,1;amount;-10]") @@ -474,7 +496,7 @@ local function get_formspec_sell_items(name) table.insert(formspec, "button[5.6,2;1,1;amount;+10]") table.insert(formspec, "button[6.6,2;1,1;amount;+1]") - table.insert(formspec, "size[8,6]label[3,3;sell ".. nb.."x"..price.."="..nb * price.."]") + table.insert(formspec, "label[3,3;sell ".. nb.."x"..price.."="..nb * price.."]") table.insert(formspec, "button[3.3,4;1.5,1;confirm;Confirm]") table.insert(formspec, "button[0,0;1.5,1;abort;Return]") return table.concat(formspec) @@ -482,7 +504,7 @@ end local function get_formspec_welcome(name) - local formspec = {"size[6,5]label[2.6,0;Shop]"} + local formspec = {"size[6,5]bgcolor[#2A2A2A;]label[2.6,0;Shop]"} table.insert(formspec, "image[1,1;5,1.25;minercantile_shop_welcome.png]") table.insert(formspec, "button[1.3,3.3;1.5,1;choice;Buy]") table.insert(formspec, "button[3.5,3.3;1.5,1;choice;Sell]") @@ -502,8 +524,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end return end - - elseif formname == "minercantile:shop_buy" then for b, n in pairs(fields) do if string.find(b, "buttonchoice_") then @@ -612,14 +632,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end minetest.show_formspec(name, "minercantile:shop_sell_items", get_formspec_sell_items(name)) elseif formname == "minercantile:confirmed" then - if fields["return"] then + if fields["return_sell"] then show_formspec_to_sell(name) + elseif fields["return_buy"] then + show_formspec_to_buy(name) end - return - - - - elseif formname == "minercantile:shop_admin_shop" then if fields["quit"] then shop[name] = nil @@ -639,7 +656,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields["open_close"] == "Yes" then open = 1 end - meta:set_int("open", open) + meta:set_int("open", open) elseif fields["always_open"] then local always_open = 0 if fields["always_open"] == "Yes" then @@ -690,10 +707,10 @@ minetest.register_node("minercantile:shop", { if always_open == 1 or (tod > 4500 and tod < 19500) then --FIXME check tod 8h-21h minetest.show_formspec(name, "minercantile:shop_welcome", get_formspec_welcome(name)) else - minetest.show_formspec(name, "minercantile:closed", "size[6,3]label[2.6,0;Shop]label[1.2,1;Sorry shop is only open 7h-21h]button_exit[2.3,2.1;1.5,1;close;Close]") + minetest.show_formspec(name, "minercantile:closed", "size[6,3]bgcolor[#2A2A2A;]label[2.6,0;Shop]label[1.2,1;Sorry shop is only open 7h-21h]button_exit[2.3,2.1;1.5,1;close;Close]") end else - minetest.show_formspec(name, "minercantile:closed", "size[6,3]label[2.6,0;Shop]label[1.7,1;Sorry shop is closed]button_exit[2.3,2.1;1.5,1;close;Close]") + minetest.show_formspec(name, "minercantile:closed", "size[6,3]bgcolor[#2A2A2A;]label[2.6,0;Shop]label[1.7,1;Sorry shop is closed]button_exit[2.3,2.1;1.5,1;close;Close]") end end end, @@ -704,7 +721,7 @@ minetest.register_node("minercantile:shop", { minetest.register_craft({ output = "minercantile:shop", recipe = { - {"default:wood", "default:wood", "default:wood"}, + {"default:wood", "default:wood", "default:wood"}, --FIXME find a free/better craft {"default:wood", "default:mese", "default:wood"}, {"default:wood", "default:wood", "default:wood"}, }, @@ -757,7 +774,7 @@ minetest.register_chatcommand("shop_delmoney",{ params = "money", description = "del money to the shop", privs = {server = true}, - func = function(name, param) + func = function(name, param) local amount = tonumber(param) if (amount == nil ) then minetest.chat_send_player(name, "invalid, you must add amount at param") diff --git a/textures/minercantile_shop.png b/textures/minercantile_shop.png index f0ea80e6e77dfe158088ca28de631f77699a62e7..12fe5973ddbdc450fbb4fca03feaff84792733b1 100644 GIT binary patch literal 9411 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 WHSHfz2+Rf~Kwefwrb5a%;C}#u%3Zwx delta 3051 zcmVh+Hs^FK1p=eb=3}q^U zQ$Voes94epq5-FjmS`c0VlfjKL`0C3fc(&+_=AB#fjHG^{e^@kXiP#vOyZIN``$VI z<879hY(icj`?AYDeS&m(ZXs;EWiCU#WPzt(aNg_~!>eOiXNi{H1nVB_}6q zz1slL5aS*-ZAN=nMI_|;k-yIZux!g#yB4tWtsN&)Q^(zZzXlMHci!8ze__>1TiORO zX4H)nXFv3_Yp$^i!0q;I-n_Y~sYwF}Nbb^Q{ava(0PQi@f3SGWn9*g2kJ!QnVC<;T zwY9Y~XU@Dp08lU!?phR7QBe_d?3k@q#g&zrnemQ9L91793cre{PoLPSF!Vx@jEhHv zxyPdw`#SA{5)RSW0m1LOeFv*5dZ`cP%w;%iSbldSNHGF0DQir*w`3rL^%`ce-J5Qz$B2sP2v(V ztVwp)A$!H@R_j}v-zeK6~k`nG-YpOELh-oz6pNC?jjOc;B2CsWIF0`TAyIgO1c%F4>x$%Fxf*5=0NSNtM9<8K>6 zkTXrQgC1+DYbFjKzM`O@ha{?V%0}tOh{`U4t5pi)>hP6!GrA zD#D)$cU+3lQ<6O<6Rz@jDk>^G9?x0Zh=@|k;Z6~v^F(0wewvL8#b(=;Y$GJ zMBjeHv^l7t~WMplcpEHFdCje^Y6z)t5eBS{egLb)`#vy^WTM ziFHyQWdP1;47lvF;XnNFgWXoAnhOv1v=6|3Ur`PqHa5;MY{wPnlD1rU01^^z$eLg# zhW1XTX?nc_LSA}y-P$KtullUM&h9_-(Kn?9Z|%72FWDLZ0Kn(F>WV=|`?+g->w@M? zx#x;2f3Hjk72b553Ez-D@bk~V7%^gm1`v>v!-vb-Pqm0B`%0GFMuOQ_PX6}t;7o=6HZRP zxW2w3`T(4{fBW?tdf>o;ws$lUwTj${=;XD*Q-~r z&a9U%EiKE;%ruOndJsM%y@w2`s;cr-RoQCwNlnebfiZdzJ`ZDn%jMEeyxRek)_s54 z8)qvCDEFP9#6$qK%r$Moq*j5`(T49!>+1ll+Vz3EZ{KyhcWVG=WX;a415;A7X5JU_ zf2v^^ZBORDvbO)_myer#H-Ha{i`TZ9&~Irs?$o5bg8c958wx)<`1afHJoxDRufP8K z`J$pJ^X4HX<=Mi*hn{{qCL`m)+}ySAzaNzV&Jsjces>H&Tss!P%%*9!sy5Wt)}ClO zoRE-EK`JFB1%Q#5=x$NS{ILa4@7{eze`I7d4jz=0n%vk>KjHf8Z=W@5^5n^zcJBP@ ztFKgcVWw8qF$9Aatzq< z>8DLiO>JjOS|wscWCcG;shbiS0Bry8Gh1Db9z7bU1n|bkA6t9DIup(^v)Ajr@y0>A z6rrWZxF9VWfCivN1JD4pXaE|3e-;fu1JI%YXaHI?01ZHk2A~0G(Ev06EgFCZpe4!y ztXmh^E9N3~d&QbH?+}5YK+pifCo5OINr5%NiU>q9ZQ9Kd4Ina>rM#5CO@V}<2n0f4 zRW>OCk(xf^77d`gWW_(WzO6ESB1EM5AVe^{Dl5(t|n5kX)Lts+8X0${@2?5WY635ONHk|pb{*KR$c+Y z;2m}#f;RQL)zo}>A#=S}@r4%W(^^M~3cU&960G?k~$Pl(PFCxNhvIw()DByua zSb&8KoWJD*H@>j2GQ@Dh!-^x)0+zp6BrI$xm&G*AprRp==C@sm$bufD_n@!{!2}Vr z33A}c3tg`T<*#_de+=lH*<=Qrep84cU;#6eFbh~X=kXamIS$#dVUJP-f!pI&iY81L z-lHv`px{kmW-(a;_r2lw17Kkgi4fQdcH~j#LK>T1$P{*U_*%N21Yp*z+wx!9Dh!jE zO+y4k6bLVc!8~`~J&_fOi--_|$nW=iVmy)If?iy{*|fZme`N;DEb_=BQzA4QTL0Q^ ztLWr*dz7L(vu^0=gRp=}goVMJoqboNr=tvZi4r0f4)Z*D7XdJ1_Uzw9O+7$ZSP20p z3x#)*S?`n&$ZP99AeSPD%k5U=nm92`UP!MC3W#Z??g9}A!k3Y000FsY>L_p^76nUD z(T5s<17!&Sf2Lt@;7|hy|6mNOSZLKyG=T8R)TyJb+O26CB2rZJkp|#^8v+0#L73_i z8bBxlVpUc&04KZ10vu+N}vIRS*&D$1lC$q4Zw+vOkmBCF|fI4 zzXlL~BM{370=A$5gjoXhP@*urbxs2aAycN@6yPA3f7s2FGrAn@u>8mZUS0eCnpbvN z#{~u3wRXZFt!Bi81Uq)@udF;Sk-q&f5-q^ed38+#!aXsk0R(eENMJV{^h;;M4uAk_ zXO?ISaK;5$6og3M{tgYouy!Xl+k%#GTY%+w#0rSCcEWA}){ZS{nU8A;dmdoTOKSoS z0BBabe<fTK!H$L8M4P zASlu6B^(JuL5ko4LFqx*5ep!)p3A9pAnHsQK}rgi6(HoAEx+HWulH%Kbz2xp&95w1 tO0}^7zu#zR=#`hZ?ujSzwc^f~{2w8oVF$+gU|j$J002ovPDHLkV1iuethoRH