From 6e69fe2fcde1f4b50fa355e6dfd88bdad9cfe63d Mon Sep 17 00:00:00 2001 From: josua Date: Wed, 5 Aug 2020 12:45:00 +1000 Subject: [PATCH] Created a working crafting GUI --- src/projectzombie/init/Models.java | 1 + .../inventory/recipe/Recipe.java | 11 +- .../inventory/recipe/RecipeBasic.java | 7 +- .../menu/MenuInventoryBasic.java | 7 +- src/projectzombie/menu/gui/GUIItemHolder.java | 49 ++++++- src/projectzombie/menu/gui/GUIItemSlot.java | 6 +- .../menu/gui/GUIItemSlotGetter.java | 4 + src/projectzombie/menu/gui/GUIRecipeCard.java | 128 ++++++++++++------ src/projectzombie/model/ModelGui.java | 17 ++- src/resources/texture/gui/label_recipe.png | Bin 11517 -> 11549 bytes 10 files changed, 171 insertions(+), 59 deletions(-) diff --git a/src/projectzombie/init/Models.java b/src/projectzombie/init/Models.java index b6df280..2096cf6 100755 --- a/src/projectzombie/init/Models.java +++ b/src/projectzombie/init/Models.java @@ -116,6 +116,7 @@ public class Models public static final ModelGui UI_TEMPERATURE = new ModelGui(Resources.ATLAS.get("/gui/temperature.png"), new Vec2d(0.75, 0.75)); public static final ModelGui UI_WATER = new ModelGui(Resources.ATLAS.get("/gui/water.png"), new Vec2d(0.75, 0.75)); public static final ModelGui UI_ITEM_HOVER = new ModelGui(Resources.ATLAS.get("/gui/pixel_black.png")).setOpacity(0.25); + public static final ModelGui UI_TEXT_BG = new ModelGui(Resources.ATLAS.get("/gui/pixel_white.png")).setColor(0.5f, 0.5f, 0.5f); public static final ModelItem UI_SLOT_ARMOR_HELMET = new ModelItem(Resources.ATLAS.get("/gui/slot_armor_helmet.png")); public static final ModelItem UI_SLOT_ARMOR_CHEST = new ModelItem(Resources.ATLAS.get("/gui/slot_armor_chest.png")); diff --git a/src/projectzombie/inventory/recipe/Recipe.java b/src/projectzombie/inventory/recipe/Recipe.java index 4c6ce78..e1d2e10 100644 --- a/src/projectzombie/inventory/recipe/Recipe.java +++ b/src/projectzombie/inventory/recipe/Recipe.java @@ -4,10 +4,11 @@ import projectzombie.inventory.Inventory; import projectzombie.inventory.Crafting; import projectzombie.util.math.ItemStack; -public abstract class Recipe +public interface Recipe { - public abstract ItemStack getResult(); - public abstract boolean canCraft(Crafting tool); - public abstract boolean hasResourcesToCraft(Inventory inventory); - public abstract ItemStack craftResult(Inventory inventory); + public ItemStack getResult(); + public boolean canCraft(Crafting tool); + public boolean hasResourcesToCraft(Inventory inventory); + public ItemStack craftResult(Inventory inventory); + public ItemStack[] getIngredients(); } diff --git a/src/projectzombie/inventory/recipe/RecipeBasic.java b/src/projectzombie/inventory/recipe/RecipeBasic.java index e34c030..193011e 100644 --- a/src/projectzombie/inventory/recipe/RecipeBasic.java +++ b/src/projectzombie/inventory/recipe/RecipeBasic.java @@ -4,7 +4,7 @@ import projectzombie.inventory.Crafting; import projectzombie.inventory.Inventory; import projectzombie.util.math.ItemStack; -public class RecipeBasic extends Recipe +public class RecipeBasic implements Recipe { protected ItemStack[] stacks_required; protected Crafting[] tools_required; @@ -55,4 +55,9 @@ public class RecipeBasic extends Recipe return result.copy(); } + + @Override + public ItemStack[] getIngredients() { + return stacks_required; + } } diff --git a/src/projectzombie/menu/MenuInventoryBasic.java b/src/projectzombie/menu/MenuInventoryBasic.java index 3f27e4e..183ea91 100644 --- a/src/projectzombie/menu/MenuInventoryBasic.java +++ b/src/projectzombie/menu/MenuInventoryBasic.java @@ -19,13 +19,10 @@ public class MenuInventoryBasic extends MenuInventory { private GUIContainerSlider slider; private Inventory inventory; - private Crafting tool; public MenuInventoryBasic(Menu parent, Crafting tool) { super(parent); - this.tool = tool; - Recipe[] recipies = Recipies.getCraftableRecipies(tool); inventory = Main.player.getInventory(); @@ -39,7 +36,9 @@ public class MenuInventoryBasic extends MenuInventory { Recipe recipe = recipies[i]; - GUIRecipeCard slot = new GUIRecipeCard(inventory, slider, recipe, tool, new Vec2d(0, i*1.5)); + GUIRecipeCard slot = new GUIRecipeCard(inventory, slider, recipe, tool, new Vec2d(0, + Models.UI_SELECTION_BOX_BIG.getHeight() / 2 - + (i + 1) * Models.UI_LABEL_RECIPE.getHeight() * 36 / 34.0)); slider.add(slot); diff --git a/src/projectzombie/menu/gui/GUIItemHolder.java b/src/projectzombie/menu/gui/GUIItemHolder.java index 1a7bda0..813fa1e 100644 --- a/src/projectzombie/menu/gui/GUIItemHolder.java +++ b/src/projectzombie/menu/gui/GUIItemHolder.java @@ -5,6 +5,7 @@ import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; import projectzombie.Main; import projectzombie.entity.EntityItem; +import projectzombie.init.Models; import projectzombie.model.Model; import projectzombie.text.Text; import projectzombie.util.math.ItemStack; @@ -23,22 +24,58 @@ public class GUIItemHolder implements GUIComponent @Override public void render(Matrix4 matrix, Vec2d mousePos, boolean canHover) { + matrix = Matrix4.translate(mousePos.x, mousePos.y, 0); + if(!holding.isEmpty()) { - Model model = holding.item.getModel(holding.meta).getGuiModel(); - matrix = Matrix4.multiply(Matrix4.translate(mousePos.x - 0.425, mousePos.y - 0.425, 0), matrix); + Matrix4 holding_matrix = Matrix4.multiply(matrix, Matrix4.translate(-0.425, -0.425, 0)); - model.setModel(matrix); + Model model = holding.item.getModel(holding.meta).getGuiModel(); + + model.setModel(holding_matrix); model.render(); if(holding.count > 1) { - Matrix4 text_matrix = Matrix4.multiply(matrix, Matrix4.translate(-0.75 / 4, -0.75 / 4, 0)); + Matrix4 text_matrix = Matrix4.multiply(holding_matrix, Matrix4.translate(-0.75 / 4, -0.75 / 4, 0)); text_matrix = Matrix4.multiply(Matrix4.scale(new Vec3d(0.4, 0.4, 0.4)), text_matrix); Text.render("" + holding.count, text_matrix); } } + + if(hover != null || !holding.isEmpty()) + { + ItemStack stack; + + if(!holding.isEmpty()) { + stack = holding; + } else { + stack = hover.getItemStack(); + } + + if(!stack.isEmpty()) + { + String name = stack.item.getName(stack.meta); + + Matrix4 container_matrix = matrix; + + container_matrix = Matrix4.multiply(container_matrix, Matrix4.translate( + -0.4 * name.length() / 2, -1, 0)); + + Matrix4 text_matrix = container_matrix; + + text_matrix = Matrix4.multiply(Matrix4.scale(new Vec3d(0.4, 0.4, 0.4)), text_matrix); + container_matrix = Matrix4.multiply(container_matrix, Matrix4.translate(-0.2, -0.2, 0)); + container_matrix = Matrix4.multiply(Matrix4.scale(new Vec3d( + (0.4 * (name.length() + 1)), 0.8, 0)), container_matrix); + + Models.UI_TEXT_BG.setModel(container_matrix); + Models.UI_TEXT_BG.render(); + + Text.render(name, text_matrix); + } + } } @Override @@ -73,7 +110,7 @@ public class GUIItemHolder implements GUIComponent public void onRightClick(Vec2d pos) { // Drop part of the holding item if the hover item doesn't exist - if(hover == null) + if(hover == null || this.hover.getter.isReadOnly()) { if(!holding.isEmpty()) { @@ -141,7 +178,7 @@ public class GUIItemHolder implements GUIComponent public void onMouseClick(Vec2d pos) { // Drop the holding item if the hover item doesn't exist - if(hover == null) + if(hover == null || this.hover.getter.isReadOnly()) { if(!holding.isEmpty()) { diff --git a/src/projectzombie/menu/gui/GUIItemSlot.java b/src/projectzombie/menu/gui/GUIItemSlot.java index b8f6cbb..4dff3f1 100644 --- a/src/projectzombie/menu/gui/GUIItemSlot.java +++ b/src/projectzombie/menu/gui/GUIItemSlot.java @@ -27,6 +27,10 @@ public class GUIItemSlot implements GUIComponent this.pos = pos; } + public Vec2d getPos() { + return pos; + } + public boolean isItemAllowed(ItemStack stack) { return getter.isAllowed(stack); } @@ -61,7 +65,7 @@ public class GUIItemSlot implements GUIComponent model.render(); } - if(checkMouseHover(mousePos) && canHover) + if(!getter.isReadOnly() && checkMouseHover(mousePos) && canHover) { double offset = (0.85 - hitboxSize) / 2; Matrix4 hover_matrix = Matrix4.multiply(matrix, Matrix4.translate(offset, offset, 0)); diff --git a/src/projectzombie/menu/gui/GUIItemSlotGetter.java b/src/projectzombie/menu/gui/GUIItemSlotGetter.java index bd3fa95..76ac25f 100644 --- a/src/projectzombie/menu/gui/GUIItemSlotGetter.java +++ b/src/projectzombie/menu/gui/GUIItemSlotGetter.java @@ -14,4 +14,8 @@ public interface GUIItemSlotGetter { public default boolean mustTakeAll() { return false; } + + public default boolean isReadOnly() { + return false; + } } diff --git a/src/projectzombie/menu/gui/GUIRecipeCard.java b/src/projectzombie/menu/gui/GUIRecipeCard.java index e48814e..ae6735e 100644 --- a/src/projectzombie/menu/gui/GUIRecipeCard.java +++ b/src/projectzombie/menu/gui/GUIRecipeCard.java @@ -9,7 +9,7 @@ import projectzombie.inventory.recipe.Recipe; import projectzombie.model.ModelGui; import projectzombie.util.math.ItemStack; -public class GUIRecipeCard implements GUIContainer, GUIItemSlotGetter +public class GUIRecipeCard implements GUIContainer { private static final ModelGui LABEL = Models.UI_LABEL_RECIPE; @@ -17,6 +17,7 @@ public class GUIRecipeCard implements GUIContainer, GUIItemSlotGetter private Recipe recipe; private GUIContainer gui; private GUIItemSlot result_slot; + private GUIItemSlot[] ingredients; private Inventory inventory; private Crafting tool; @@ -28,10 +29,77 @@ public class GUIRecipeCard implements GUIContainer, GUIItemSlotGetter this.inventory = inventory; this.tool = tool; - result_slot = new GUIItemSlot(1.5, true, this); + result_slot = new GUIItemSlot(1.5, true, new GUIItemSlotGetter() + { + @Override + public void setItemStack(ItemStack stack) { + } + + @Override + public boolean isAllowed(ItemStack stack) { + return false; + } + + @Override + public ItemStack getItemStack() { + return (recipe.canCraft(tool) && + recipe.hasResourcesToCraft(inventory)) ? + recipe.getResult().copy() : + ItemStack.getEmpty(); + } + + @Override + public boolean mustTakeAll() { + return true; + } + + @Override + public void onRemoveItemStack() { + if(recipe.canCraft(tool) && recipe.hasResourcesToCraft(inventory)) { + recipe.craftResult(inventory); + } + } + }); + result_slot.setPos(pos.add(new Vec2d( - Models.UI_LABEL_RECIPE.getWidth() * 102 / 128.0, - Models.UI_LABEL_RECIPE.getHeight() * 8 / 32.0))); + Models.UI_LABEL_RECIPE.getWidth() * 103 / 128.0 + 0.25, + Models.UI_LABEL_RECIPE.getHeight() * 9 / 32.0 + 0.25))); + + ItemStack[] ingredients = recipe.getIngredients(); + this.ingredients = new GUIItemSlot[ingredients.length]; + + for(int i=0;i8f};Gi%$!t(lFEWqh1817GzNx>TT5p|PI|M0*Y*ES zF8xMfjv`AL@L_3xh>AH8pXEcTC&OPkR5FL@g8f27TEeHdFG@mzbkvEF@_t$+P` z<_rH76?wh-f$V<`uZMvTu4}K@-xO41`uzF(k6C(aUwv0zbDr~+bpv%_R_&XczjyzN#BCpBc2rFg zSy#W8*~rJCsJeFd-|6P{Kc3YW|DW9d+xmEw;eW>O*DrfBf1i1x-l=)hebJZZFQ%^l zEnB{SF2|?i1@S)nBbWTF?K=Ns`hwy!!T0UHUjIHP^!&~9FRS!qcJ68aC1be5{e+ZT z)9$qen(+@K-(TIK_0XuX>gP-L>pZ$H3U-R^qE!}pZ+;sbK5|T^Jmj6>xf$;wSi9@R z(v2=`j(zCjtE>A$;Bt#r=f#S?>Rit7{N2COR%FCAE;Urp+3>VJ?%jKxU#nlsbT1W{ zCr~NV7JD(HU$Sk^-%V%K&c6=X$@eeDp7STu>T-D?&0ad28JiOkA3=vE;UCX4u6=t3qdg zo0YXL$opzk_UgSyr=2)lPkc@v69dx;}^D83&zb43Dxn9A0G1_$gJ?*ET2dS+t6lO41SuGwmO8 zUT5^4$}XDoq4lo*lYfGF>z?dCqWdrQ$sEV;^-AT1#nJm7eq*m+p{srSv(h)0g+H&T zFY5mpTfOG)s*LjQiDw_1$Mp#$slJI`d{X7Qj;wd<9xK1gw~ldg+uU4G%dNPXRr|!; z&YF;8Go`+=_hHnDU3EpR?spGQ$q15sn{g!g%FQb|_xbj|S&;hVszJ_@@Qn+y&usHn zWZCf2VsiUd?dvoAPvut4$ey--v%e%!qVgH9m zB9fQeCbHju@=~Xy`^>KEo$H%l+y3v2e_r1w&yyNpbiyd)#g;~{t$gh}?V2=XkLCLA zj@h+h4rJ$IeudTc6xBei`U=calu?{`1G_9n~<%bB#(R?eK)Ad#=t z=(*x6Iqhqr{_IAxKVMHvcdLHDqy2ljdTUdCiSE&lU-(!!pLASv6+E-?u_vq5i*2)a z=E*!#wb(HA#_6xB6D}TE7EpKek#N`FAIV||drpVGtjcL(6l+zOd{iuIOG2_@wqw`# z-Z`E3Pb_CByZR%ztZ?lQEy4b)5`i0wBXeRi4I-LcURI@@mCmW(KK-<2_APD(v59Uy zJ>5%{Tb)+2T1vYz<==g{GH1@xd?&e?GJFrxq_0eMK6dD{K!v*Sl;Y2?eYQuhkSXC= zs-J#a?WMZc;lmkSR~jm%-@VH^! z|CUI5N7A{|*PoX0AD+?PP%rf=G%;lbpH|Owu7*EGis`DFqRfT@0f}7ZlXx^0o-}Q~ z8p2Xj`l9IYouwc39`y=~^wuy6mM8@6HQa|dN;9LJ9>+~t6QX#($Z~A2A-V5w8^=M;UeWzrW zjweHlZS`u=D~459({^@T+A90=y3?6M6_*8<@V~jZY30;y89y&A~;G zpZ&D2g!WDe*kONl&8Y`QlP@wVeBY3?%cK6c3U5?I5;xb|jk}+G-EgbpkzVjMdBdmb z%155en`vbmd^7XV-&q+lCML>3*R6c+CvPtqBojqq&d@43Ac+KQ3B`L=8 z*m7e;rMAw>P_|=+^0m2Jc~~ZAEE1TXebhYmcJ`iD?W_Hs`pP*Q8=}oUXPax>>^*Q& zNv3jw#tkjNnw)=0=?5;g#Ib5k8@$*8cmeby+XD)u! z4PC4}DTaan_tBGmDV9&B9rB20v-hgIbi!Bevi+=;{XR<+?B6UDZfJg5l$-EbV{iGr zpG_wlCa7F}cVf=9hnM$!)a#nD{K1S{X*TC<;``4sMKSW#A8x#EY@)Si@r2v9tmn>t zernLI^3H)pF6y!EidWa&JojGeHd}M|t%O(qY%M?eKCj~&BEC1I-sQ^B{hfUMD2Fp^ zvuO{1+4ue2x4l+f$aj=~nvq#I_p-Rjgmtf6Ro}!PU-L|2PDuyXDc@}Ke~)D1*A&IM z)|fAwnDW(h`gWaHpA_ruCqx{*p;6WBnDVQ3pU!Hp7-q49%$xUH@0cX#wzPGgX`fN% zm&*z#P9AgeU0T2GJ5P4<*RQwrzC7Hcmv+5orpn90H@S^xaxJHXPO07TF`m8Pd9n6t z)lLQmh7_#rn#_WdWKg@tw$qTW!GMR^`}>|Ib(M{cALeMiJ#g&6f7cfQ(c5(9-#I^f zlkdc)1)r0`r%jL1y;^vU$Kp$Wxl8Nhl!=Uo8^dxlnqh(uYb4$m^zQ=O+e&3tE`#rvz7@J z8cvQCt#4k>q1cc&tJ!FCkEN&Aq2ijmhmU{XEph(Sy5GfLR#|p4+D)vOCYd(1qPe1K zb5_AU^}Y>@)(FiP?w?uW_{e>ow%-0iJqw)=XF6v3ofUTPIO@c%EqkVGnVXHPOsMJH zPpv(twVvyqi`scC>iZLYp66etrmnjz<;K(<(ZnLim8DU?utzIt%j+c(9v3U`9JYV* zL$yfriB{vpWJb}939|M-8Rx4(Vgm}~CO@ZY## z>Gr=<*$h5=R_$Hu+TXA*_rarGYc;D6JmoX^kaA+#8;`muCp-Q<^DmmGHvWrVkbd@U z^lO>r{0_6KrtV?n<7*7M$dtOidXM#$o7?NNqyGM8d{SAI*S6|#Is*d(TavfC3&Veg zmkbP3MW)|jU|`@Z@Q5sCVBi)8VMc~ob0ioT7}!fZeO=j~aImm(8!y}S`t0OgGV1mG ze?46sLn>}B;I|9|G3A9>OrY7VSRJn(qtyH!(8 z*mf*gG3TajDZjyscU37`o>~$-K`r9Hz8~hd&v-ApRK&n|hU8jP17jDK-}@fd?LYo} zrX+)c(#P!`4KoX6*!8A!yQst^r+vBiIDM_?+IrJ3_X>B$JgVDU{^g#d%ZjZ|E+0O8 z5P1L7s)J+i_XuZA*0rWF>#s*7uNAHT^O1euuUFbK#|6KKhu(Q#ZewHP5PC7{@V@s6 zX?OC>b8ffYvknnG)02B!K`CQx;%&1PT6x>0v(~QIdhBoC;{)4rcihcWSQN4P{^xG} zeFyH>|CfFJwf;Hdh8v5vioL%cRk;8D#~(jBo6|Mx?gkzs!b!wRi^|Nm7B z1nO8=KdRgB?6P2$#?ltYnuY%?&9|&_3Z4G?r|J9e)*+${hdku%Y8V6^T?%%_6zq%% z@H+UnuK$4c(g$U`9YYUy?3H@vTfqG?amit z`0;FZ{)XJ!JfEg>F(@6<-~Xp6fB#>xfTM5g+%;KUSVE76nQysg;Im9YK!mHBaqBgX zmPQHbzQqf@-5(apGATT>5pAt!T2U%-vAntCz{C@ROQvzP9*g=k%eG=Ovn%W4yp9ED zS3J!=v%mj+slilLfj_(I-ha0JEB8)?iLu2&`hSfk>#DBh%a`By`nXz}fmfwy_VHsZ z4qOe#qVDgjl|J!(5l4VmXGgHYqBSCIOcu8c^E_BI&a5b2xahFQrP)gx)8;=f*ig@u zaC__T)ZlJLJ3wAEfTB}f;5oc29_}Zx4y}s+(J?mYLGo4Gk-}Aqi`XfhEbq-^P zWU18|-ba3~_WD1bDp`>nE8|x7Snjys?lbe7I|{aly*w4{wN^A*_GkRrl}o2}YVBEO zwdwx$wQaSUg=+jV{L>sH8A?~D%}%Rvnda~{drt;K1>dJRywL{IH&1oTTKnD2-pKrT z;eu_CMPs__V>dT=Gv;jn{ae+s+?wwP+xKj%hs7=$sqan&WxdI8pXkGIes}AJMIG_s zQOrxH9CF!q?qNdv_iMK&RYkq#zCZCvh}rLzQM-IJ58FRp*)VhAG`1@jnr1pmY|}p@ zsNz=^uga=Zc~$Ac+*PYKo)8p>C<-idVDWsfFu^gw+1%NBW;TW$6NLlYoWW+wQ6M_?i^$UVN!iT)5$`77IU{nUJ^7 z#(f)>hARDAbF1{Lqd*{&>XFr3-4ym_Fz9R$GKkDsK9w=vH;r?0$0YlRY~DqaOLA|^ zO_aXw=}}Z>G9%~vG>1h&^;}E1e_ixbO^-jd%XlUCi{&RZ6S8lAuNAlY5}}UyvMKk&S1jdrNj03edBOK-T0%$d|NqoyU}^~Ly4%cg)H~yGKy!?L?&Ib2 z>$onS^gf)JUbR=rt zcII0Y%BlE0Du3>@^_Owhnw9eI1)AIavy}z7eKYpQtq%~5SsxywH$AZT#=H8dS_iz1 z&u7kCo?dB|6_w`3cQ0Y1TfiMbISwt^z1>UuJ4`k_{at^sOmMfEwR`BnXC?a5b01C* z3f#uDG2yh8(>keLUkbL^`-`<-X_A~)-2ZsP*8aKMLbT4k)0Lg(a_&me*8lERYWx@0 z@LL$3Ii(fuw*7tCZG*k#d+Pto`SfHp{?H0_(0i(Md@1|u*l9A?qoj9VkQdSxoUP<- z=zcSL}_; z`8zX%&CAqq_lG7m;lT7=6Gi4MK6Pos~QlbOa3|jGZ)!^a7(&mifW+N{cG>fIuu%#ym=EkmpNImeti+w$=#<* z8y7y%OxP*&>Vr*SK&aTE+0EDHPoH@(+EMdMy~wGQ^(AY2*7$9iy(RLiiqpK{T-~pW zwHo3lvG6fAGX^+RSlIr5SJRkw`EYi)U+R4OBMIw-gf>}klHM8en9uTrQIB=ttf)VC zdRrw`Q$nr_3!He`E5_ec$;(w|Jf;5JPUXcW%(X5hnxVWtEqWYFB7X|3b(~xgeC5m1 zhP$nsraiV~I3(v&QCAoD_uD0z1LZ62KZpdDWVTIlX)F4g@TVs5yU~&LR?UvfUrgFO zw|P$DU}^EN5dvj@8Zc*ssySu??gp6y$!WEU~=Ki>YbTFF6yS*PJbQ< z9XZ8(>ay4S+>;mo$xiIcz5RF}U-7CgCv8m;&s&XrE(=8>es1>L#5B{vd-=tO&p=x%jO62N#^S$R8eqCJq?s`Vn&+`Y5Kl{9w zi?f8!pvcbW#=?wMJBp1>b~~7O-p%PRN^I6We{=N}AJ2vPZ#@_l8E?Vw@pvne%shBaRJ-!)R(dDt32KY zdgGxOhy@vw3)9xS0eY-Z-(BwqR=X%%Kj&YNA$UIk# zSu6T`U$aNBc7@bE@5zkeQnoE~wkxmVwCJ<$IDYQgmpT{oo7Lw8MV3kT*!}m3G?sn( za^9MU*+x%pR_yh5`2IpiiAA1Yt-W47k^7d!9v*827bUM126nH7eqS+K^hzr=#7t>L zOncGKiwC+JI_z>SMBzP_A8nS;hO_lM^i~zV==FHEHss1B?8u^ z1ifzga8D|M<^1ilb~+bb3%9fdc{fG(PF(Bn`|H3j=Ey%MR|IV54LDl3pWkJ3(6!Q* zo2xz63yN)#daZcn6!)Xb#m9eMnaR@s`VdoyU6A@-F6+L-Ifh^R*RWihzK-cmfo;8{ zVoBjQSCbXz=Iwr7@40k(lxN49SBB0}&W1ahjl87(J=pU5&%J$WN{9Bn<&LVD@RK2H zo^{MKhDA~ujEnuW?mk#&B9^w{yk*;Ajj~*|4eQQU%d2o(**VX2Wjqx1Y}d7k%%R0Xl}luypib$2OOdXniBAGw`K|sotKK|5 zndPuT=39w+>pCB%)o-JIYUn>QiF;aHrN~)*VM*d8!$n(pUzo8!OZZfpy6!=j9)2wcFw!I9!iJK+yBpLUc|A^cy-Ig$UEO@QbP^lGfG-C{L_xNI7%wYT^%< zADaYi9u#?&&Xcp7o)N=Um3><0!A-H?&l0QVfB$>lnA5I*Li2C={Ch4Np1iIvQhDpr z!(zGivz%7{Di8Z~Zs)D1uTC=B z$z2MGjb3UwL1wO)#Chr5Gi!P~HPWsG1xH#+JFj2G;$?Rsu%fc#&Wp}JZIN0(bL!9C zUR(Z{-FC^@--iASbDwh;z51v*`^|)T?f(9b8{)sEnmMGF$^O2?bgi|we_l&VeaxN} z6>5Lysm5&;5}bB_Z{|16MxFkHsfT9no)cJiyN1EoH}!YA|G0MJ;@_Lj)pRKPo3j2% zI;Ze#)1_)A$zQP{p9=K^9DlueYyI-``Cnh^H?*7zx4&r-WxeprMbD+zr0(slZf|dI zzdn=m%;ZfB8?GwymY>m#s&`QLt_=AT{PyynsV$H>QZ46-GlfN|rk)S1 zv?E_h)SRs^JLNd5-TP0?!_`X|?6bvJ&GV}i4_oxpX1{et=(S&qNA!2h(nRm@i&e8#7nc83;q|<5NzbikV_}wP^{J%aFEvWk8c$!;_7~Q=u}wbD@*GXs`6qN)ll}ic#WjDwUa$Z0cKiJ#_Fw1Dv1m?j z{JrmZrqcfyyQ{C37?}IG9Gf$H{*teApRNC?ImhPKT>dprD);2xPLg|QbMBdHyxoRP z@2%&}o3|lX`riKf{?}injz9bpv&jDYw%o!5)AQ21*7iN_h-7vWe0XG;bTKM|-@#8y=ZOir6zQuf$_wbpDy1HYRF9-9~ z?JzdJSrqy0a6A9C%L*~;!?TO-CcV`Ys_grEKFxFY_dbxn<+Qy6-aF1I<(l7r#`v@7 z^wX->-e&KK(Gx7F`*X+N?dQ4rnwlf;_y6DbFVdQ&MBb@ E034L6I{*Lx delta 7226 zcmbOm^*3^Yay@5KRY*ihP-3}4K~a8MW=^U?No7H*LTW{38UsVct)Qw;ybF`|LM({oR%R*(ZW)s)`tA(+L-*r{C)T)!x}(;X3inrVQP+BImWY z-${Dz{`LIo``I6U#=U=C-2LDFSnQuW9XzW0F7IBj=ke@9wbt_bq`B+op4(AleC1np z@}E5ysM&5tXv+^73f7bjzdHV0%z2dxJ^X7OT z8Mmh0Yd(b89m?PP{@CtGdcrHF&#(J1Z(%D(iu#icPW;DPYwOP#d^9{RJN3Opx=;C< z`X<+IW7`Fv`P8$rGM92Os)cy=94o%_+Iz?EZM*ODOr0B^ki{dxt@Cq!{`YdVzgK_D zoL(w0Po$EmE&gIgzjWK2*qLeO=cPk-GXC3BFZ7AkEYUY_hBo_~IvcgNmiRkf;xCTa zJp8Q~cj4!R1&g} zOYxTHP5IHYc#?wR$_Xn(TdWeE>U?l7Zgq~Glp?6PC}^pt{>l{hwyBGbKG~LiY0V16?>8*GbT0aiUUd20-0#fS{j7eT&~*2=efvfKN?b_& z_kZjwTE(|kOx#rYt5s_8s`J}-*BtCfWJ@w+7YKJ|aB@F<=K6$UlP5gJ_mv_Q1=Wvk zh&=c`AgN6Ay};8J{Wo=r-}?)SRsXBzeSELmdI<_cFj|_XX7Qa``=%!KB}v7T}^HGdRNyAm%ZMsZC(8M$G$^d zTRpB9`|w^=et-1aowX-C(%(qFnRbu!?~`?vIlj@RbNBZ5o|1b}nxUD!{MZzm@R^52 zJ8nc-S#_37HfH;`uEL^7Cq1jaQhd7#>)N$H?w(`Qhz#4;ed|eFzxUyo2b+&~RdoqW z3(5Itvi;Y@zIAPGGh@3l+P4Y&@y%)996v9-!X)h^OWDh{qH~JY1oam&sPfq@jf|SD zdiL+xnl#3zo9|}iOxsmf+o(2k()q9>zc%N7nSIrIubkXD_hP56fLZ%xtDf9hcD!EM zcU#f2JsMoAw@fTpWAmHu+tq2$V#MeEl{#|sUdD&A%q`M8r*thmQmB0G!^Fw&e{#M% zbZo_Sam#+m9_}3LuoH$CIlpY%JexJ#GxbQJ(0hI5sq>daSUmRWJEvy;;?jx|)g*(n z+%w`k-tu04dQrW`VcNwdwruXdoqCcV%!oU%>1%zynpW|a4acTQ-!JHYU-s|rPyKVM zk|`@rEZQ}R<0X^qwQlW27e#jDeEfPul6%Q7bbBXI(D?@%_pKCz8gb~-KDZD$}f5~kQj=g!! z>fP=cA~Rp=?5lrXs$Rmh%68@ee2^R*93fm=uLYs2Ml4ed6&wJar`CQTbW$X*@w$E!#kiKhnX@~z~xoD2K z(r>#yo|s!(@;1&pf9iyJXFl$>n3Np7US`?yn`b%voF|@DUB#%~QSW}M`+vatO)FA$ z?>ZfQ;`&-fdcmYnKK1PF>Kw|v?4B96E4E~7b-!)U5@d~EBk0q8*V(#N@o9nFj2x}D z5~iY!xu0vLZdsnWb$LP3jTr}Q*8GU@czF7~AAi~PWu{T`i=8*_yZhqCeVJgZs8H8y zT>R!d+TCfJuhn{PxN-7a#LKJoWnZ=CCI$Stxm>@!N$9j_`vEoWzzp4=UP~7_+geNS zjXp5b;C5SU_mtZc1s0mDao>4ij?pCR73`){e|Z|ssheE*JME)sgMN_69-jsBUljG# zCe(Z1Ec2+1=)4klDrLfI50SVpMJID7IWFkh4D#SW+tB5v$KAh zp*&47_FmJZh)F`(<>lUVEdY}1tZQG1GGxxN09)XIJt{wAPSga!J5zZ9qBYL^k zW!plQRV5ascC$Zo-^%@?#v9Z6Zt9hUvNzS+>l^G=&$%tYELG{S+Ii8J(oVr-$qN%j z=3Q-gX?iAg>!HFGdC%wX675u+oN)bs(6xnMw2p~Z&NL0^%U`l!QUco)&G2!*xl~+3p2ClzFWR>LTZ@7$}4}*JY9FW#KWUrU$TE@XM0$c#X?)(+gw^#FD-wz z{F?ex2E)6v<(ijQUh!RK?P2SCZ>uu1by)rP#cgVnMN~e?UsxT<;Pj}l!q1xJNvTuM z2EI)bJ-y3+ZmsY?A!xQ%rYTbD?A6GYj?Gb>OO6#C=HJ!$ucV%tZNg?R{_qnDKYBb| zvzcFtpU6)su3x*|uIog_4JyeL_)x8T|c&e9%7CHG&>;$Wo+-f*h)C+#Tc`M4|@_qFzm9%*&x=-&uI&4%r>Es7bvr{|Oa&IW# zy{0}hq~XNJu;k_UpT{2a%>1O7uxz*S6pqQJi;v&GrFOgJQk6)JkleDBCtiO%5wMHn zYvXF`m#*i}Wo~Wso4c(|L&cR%V0v8sffuLi9AkTxFHX}OcF&&r&MtJ3t)TKIHr_>>Hy;1_S;FaP>$bfC z@)p*z6XSj6S4aLo)EQp~8zaz`)p&>FgZf>Ff+^*fB6v%&DDd>v7mY=4gEIQYBGV>yD0; z6@Fq%x-7ElMY{qNuW+rkni2C$(InF&C`N|$dQ-D}cPP7fdaP^=tK$deBPTCP z6Cacz`1oL<{k^-@clI*3RL#r`J8rSy<+hoAYDaSNTzU2?wIp(MEcQ>EW~l9{`J-=r zHOr4G@yC(>p8u1v&AON5;Gi-uu`N@0y|91oEw<;ik2thX)@yyV{5Zo?T&3>Gu16oG zpD#MibiQZC%r7#9EfG4~HeNcmCME00h**qBDz`csIRf|KEK7Zd7aM zj_D$P40HASJ{vN%lr_4goh{tgFT1>uiDiDH_TH!KuQa~&zm%=3TgCDvk6HY>uJ27| zz4C@eb!W5GaIQ-tT&xfN_UzMS|8k${?&`Swv$b>V7$je5l`_l7FfDdH75BNaJiI#p z|Gdm^-c6fN8Ir{E$3gTRx`F`Va_RMOH+(vp*mQgoAz&C_&Ek`0Y?EfOs(byH2# z%#+QM&67-wEGGN&^s5K*E_RSy{1_lPUByV>YhII@K3=C!=vpOd4mXYUVmt&FOQd77lJo&MV zdc6Rfr;B4q#jUN;zWFMyLbVfThTb(Zu+I2)i2nhD`;xnV|GTr)GfbFazd@PhaL?V? znS#|PY9>z1eSg+1s&d=ib*H-e#r5M{IOAUIm#_PAFe>|mrSj62DMDFmJv1FdH@>%C zcYSre{ZbZ&fYAT{S9MJh>U(_PWl7VjU+J2vTdw`7PuFDK8n)$Hfz{kUb!$zxTvJfe zSn3d3SYG~o|6@xRmbIq#&gUezhRr#jZlA2lDsNYF;P&?XLYema_sX|{l_0aRu1wK5d8DyvOg2U%cV>Q z&V2a${l2ryp92>KufG;u#bxY#?k4Y{=1PEjd5m-q~fr zDvP;(7IXbhSU#@WTlL`SoWh+k32AvQ^HOh{l^-jVS+UhA^y9O$()+{f&q*FHtZ+DX zKAGY38k28@GCOwfK79A?T=o|~YuwJ=WY&#SU)oZ8-?lMhd3$^N(_P=ce_ye6*I6&k ze>E51`G_(6cs4tKL+)*!Pt&;=1P|)(|I?Je|F4+A;ipxu=OmSwj1PyIT?xDBnubb(5ig8_@H;YS+0TUmBqUz2YGosw!XNd z#%-GFj33VhRewzWZqReyt)P=5O4d)ZZ_(kd^k^-0XmftNP&M^R{W4=~r!CvAU0|CcxG4KaZF}6; z_s{0sm2BW!?ALx#p(H3fS4#iJnWKtQXtmV0V<)C{BXGq**SLO!O4pZsJ2QnwDt++9- z&~1Gs+b`#XZpZ4SgHAr4C8?R7kYZgwpSk4vV+P?l*Hs=WD?PE*ss8E^Tp4+oXfYo`1rc9v;TBC-!0FG;Z&DQsB8Tkkyi#s(V$2G&g* zen-SdTB-31%y=2J{D1s$$3t0<=WM)eVEiP=YS#f7(Wtc13wA;}R}#qi|e8kw8>BoAyWOvzBMiFmcD<f9*qB+ni51f~g8kHy%aYYxca6tGNC;>ydk9RwV}KE?g@~e*I{P=PIk@KAu?` z7jOQ1z{yn4ap}!!Ro+dJcMZ;*ifiUoo!)2QXR&+Y`Q?-6Yp?2zn`L0>dS;LM5}v(N zl`XwBOFy3Gsk~if>B%YdgN=FJWQ*FU`P}m_{_%NhF~|F&-PUh?>fYb@R^ARRw3}aO zHMh##Xw(1DT@4k z*QzY=aQLZ>*6gui4;(l+B&Qm*eBt3Ki=jfZYthUzmP-!@2}0mE8SboqBmKeW4m!p=$-A3%OxxurkPH%mY)B- z@Slf??9x?LH@h>80@J2R^B%mpTc_CiqS#u~Cl|Vo9m#6Wxwq&{_bZ0r62tXNC#7UD zZ?tQ>H?{4OfqlpS(xdB*-`-^Fou;uR|MmT|4hv;&8CQospKz^8&fDXR-lm`R>mEop z2sXG?%+ttN#{IC@@$_?FO~qVE%hQ{=Qth*!2!DR$Y2 z^@Ia@2_=_YIm(wGub-@cLZ)g%xv!;tm2@7x7@iN3**~{_Ke|I~}3SHCL zGEc@Qa%3SlC<=D__rl?Hl`E_MndZ-iRwvwvK8! z>tz(`TOUp-DP-DeIzvLl;oc{W;@1mKw?`$X2{gYAwK!mMVa@8o45#J@iLf(fs@5Bm z95$}m5;k4xtx~^P&h2;KRnN?n+_Yv%fN2K%H9=RWgrn~#rC1v6RJwVmabNv{$&stS zooiase|XNj_{cVwK9(uxoL_sn&yvhqUFSF1@D*>ybcXsZi+LmOicNc;zWHa(dMBon zj8$ik3zQvc*DA?tN#k;ve8o3Z|LMX%KV5Y1yL=0Ik!|bbu)=v;qS05r>zR!%*9x-O z?+QL%wXHA2FkyaE5ZB>_oIe)}Cj@vq2}ysAKFqVAYG=oy3Cc%(&4Y>@_m(YBJ(*#C zO11u4SmODfiT=+o*IO*Mc^Iz0OW+aL%(HQ`b8kHT)NxPZM#JAdXV&cvY5BOKMKC94 zdXQJfVz<{PPDD4hFX^4U$26m0@>j-Hxk@f6&+guQG{Gy-E3`Jw@nPzt4UR$cCfmiP zzTa`fX-VSoNlbyp#vWq%6D$9^u2;xn)ttTUS;p*5#VT|3t$32WnH2BTr{+6AVRk@^KwXrsAZd6-&tmXG}ZlbE9OAJD0 z9|=;NG;eOfz8yj*a(s(airCoC6E@tjmM>sghR)s*P>7CH_U zt3@SP`X8t9^~{p$i<;=oSCGAL)7Lx8_>a{nY&VR}DIW0n-os7o z5AHhfUEb}d^-@Bs*HTsGo#n2>M>d-YMPz-xn;BgGfG@cuM1I-Y+;#pAkG4%>%Hmb> zH*E~R%ia-eyDGzE8Doan$&)Rba%;BQeO7<+{&)R8y>6a77meN(hpLaZ@=sE_uHMvD zaog|Ev!paH&dQke*LGdW?U{Dgd|qnn=OC_ij^-QEO*%Vxlupilyp5}S19zg_;s>|Q zzKAtW+!17UGL^G#e`W7@uY3z4?e1QT|tXZ#24rroNI*(vl= zWv$%Ra*khn>i@r#_)*s0xH#(mTV+A%tW=%&+uKT+`Pq*pJld%g{ve6_*t7|)WfPC+ zPj9laVvqZO?PQ?TzxtXi`)zCge|+W}FQT|B zhF_xL`0?XQP4?TcH|$)NZ`E$NH}!IWeW~BkqOxmsvag?T7-?n4-aoy5U&^VfnZf05 zZ{8<=J96~W2~8!ToZD?xAyd}Y|Bwvw^Dz4MsXfB^=k<_gw}~%YIdE39d**LK8JOn$Od!*KU1fUe%*{_*mPe)h`(Kd5OlqIFWgBfyIlD zzuInU6>hh`_V(7T2kd8;o_%e2pJCTs{SLNg(|p&=*43Ne_J5_;x6Aw9u+2EPGI{sK z`Wwp9?~OT2cUqiN*-;>5|M>H{&XvC|ys>Q5(YxYyNOJj{dv*PP8>XbZ(n@v^7d;am z%#^(PO4R4j4?m0!zx5W{{=1?ux2u|=<#62U=MpCSScE#S)Yz`ob=xDm`<&_5pTEMy zvu+ig+fnUdW_$hq5qA5U>WrIGX0Z$AFB1CxQ-P^Iw|JZXrQ`35s%LDfJohwh;j!pWc*(fYg^DSQ2;Ujo-8+&pZ& zS-p1Cud0$|UBBO4Vtrj7Z_~RvA>y9li~1zH+1D@L{jtKd#CG}RlhKxJ?sC?ZI_ZU< zBev=?idy=;SyQjZ9#O7ZeDcDw?zu@5jy)CH7ym;`wc-7(ovYG=?;Xv!xZ}J(``S}c z(Nory7_(>GlF?djV9XJ5K~zO2I>