From a78e0e885c56759609bc91212f35fcb463db4f16 Mon Sep 17 00:00:00 2001 From: way2muchnoise Date: Thu, 15 Sep 2016 17:29:52 +0200 Subject: [PATCH] add basis for the Disk Manipulator, #39 --- .../refinedstorage/RefinedStorageBlocks.java | 1 + .../refinedstorage/RefinedStorageGui.java | 1 + .../block/BlockDiskManipulator.java | 36 +++ .../container/ContainerDiskManipulator.java | 55 +++++ .../gui/GuiDiskManipulator.java | 42 ++++ .../java/refinedstorage/gui/GuiHandler.java | 4 + .../refinedstorage/proxy/ClientProxy.java | 1 + .../refinedstorage/proxy/CommonProxy.java | 2 + .../tile/TileDiskManipulator.java | 212 ++++++++++++++++++ .../blockstates/disk_manipulator.json | 39 ++++ .../assets/refinedstorage/lang/en_US.lang | 1 + .../textures/blocks/disk_manipulator.png | Bin 0 -> 605 bytes .../textures/gui/disk_manipulator.png | Bin 0 -> 3425 bytes 13 files changed, 394 insertions(+) create mode 100644 src/main/java/refinedstorage/block/BlockDiskManipulator.java create mode 100644 src/main/java/refinedstorage/container/ContainerDiskManipulator.java create mode 100644 src/main/java/refinedstorage/gui/GuiDiskManipulator.java create mode 100644 src/main/java/refinedstorage/tile/TileDiskManipulator.java create mode 100644 src/main/resources/assets/refinedstorage/blockstates/disk_manipulator.json create mode 100644 src/main/resources/assets/refinedstorage/textures/blocks/disk_manipulator.png create mode 100644 src/main/resources/assets/refinedstorage/textures/gui/disk_manipulator.png diff --git a/src/main/java/refinedstorage/RefinedStorageBlocks.java b/src/main/java/refinedstorage/RefinedStorageBlocks.java index b28804898..8c48c3a92 100755 --- a/src/main/java/refinedstorage/RefinedStorageBlocks.java +++ b/src/main/java/refinedstorage/RefinedStorageBlocks.java @@ -26,4 +26,5 @@ public final class RefinedStorageBlocks { public static final BlockNetworkReceiver NETWORK_RECEIVER = new BlockNetworkReceiver(); public static final BlockFluidInterface FLUID_INTERFACE = new BlockFluidInterface(); public static final BlockFluidStorage FLUID_STORAGE = new BlockFluidStorage(); + public static final BlockDiskManipulator DISK_MANIPULATOR = new BlockDiskManipulator(); } \ No newline at end of file diff --git a/src/main/java/refinedstorage/RefinedStorageGui.java b/src/main/java/refinedstorage/RefinedStorageGui.java index 0bf90311d..b88a76736 100755 --- a/src/main/java/refinedstorage/RefinedStorageGui.java +++ b/src/main/java/refinedstorage/RefinedStorageGui.java @@ -23,4 +23,5 @@ public final class RefinedStorageGui { public static final int FLUID_INTERFACE = 19; public static final int EXTERNAL_STORAGE = 20; public static final int FLUID_STORAGE = 21; + public static final int DISK_MANIPULATOR = 22; } diff --git a/src/main/java/refinedstorage/block/BlockDiskManipulator.java b/src/main/java/refinedstorage/block/BlockDiskManipulator.java new file mode 100644 index 000000000..547375d22 --- /dev/null +++ b/src/main/java/refinedstorage/block/BlockDiskManipulator.java @@ -0,0 +1,36 @@ +package refinedstorage.block; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import refinedstorage.RefinedStorage; +import refinedstorage.RefinedStorageGui; +import refinedstorage.tile.TileDiskManipulator; + +import javax.annotation.Nullable; + +public class BlockDiskManipulator extends BlockNode { + + + public BlockDiskManipulator() { + super("disk_manipulator"); + } + + @Override + public TileEntity createTileEntity(World world, IBlockState state) { + return new TileDiskManipulator(); + } + + @Override + public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { + if (!world.isRemote) { + player.openGui(RefinedStorage.INSTANCE, RefinedStorageGui.DISK_MANIPULATOR, world, pos.getX(), pos.getY(), pos.getZ()); + } + return true; + } +} diff --git a/src/main/java/refinedstorage/container/ContainerDiskManipulator.java b/src/main/java/refinedstorage/container/ContainerDiskManipulator.java new file mode 100644 index 000000000..0bb549016 --- /dev/null +++ b/src/main/java/refinedstorage/container/ContainerDiskManipulator.java @@ -0,0 +1,55 @@ +package refinedstorage.container; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.SlotItemHandler; +import refinedstorage.container.slot.SlotSpecimenType; +import refinedstorage.tile.TileDiskManipulator; + +public class ContainerDiskManipulator extends ContainerBase { + public ContainerDiskManipulator(TileDiskManipulator manipulator, EntityPlayer player) { + super(manipulator, player); + + for (int i = 0; i < 6; ++i) { + addSlotToContainer(new SlotItemHandler(manipulator.getDisks(), i, 26 + (i % 2 * 18), ((i / 2) * 18) + 57)); + } + + for (int i = 0; i < 6; ++i) { + addSlotToContainer(new SlotItemHandler(manipulator.getDisks(), 6 + i, 116 + (i%2 * 18), ((i / 2) * 18) + 57)); + } + + for (int i = 0; i < 9; ++i) { + addSlotToContainer(new SlotSpecimenType(manipulator, i, 8 + (18 * i), 20)); + } + + addPlayerInventory(8, 129); + } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int index) { + ItemStack stack = null; + + Slot slot = getSlot(index); + + if (slot != null && slot.getHasStack()) { + stack = slot.getStack(); + + if (index < 12) { + if (!mergeItemStack(stack, 12 + 9, inventorySlots.size(), false)) { + return null; + } + } else if (!mergeItemStack(stack, 0, 12, false)) { + return mergeItemStackToSpecimen(stack, 12, 12 + 9); + } + + if (stack.stackSize == 0) { + slot.putStack(null); + } else { + slot.onSlotChanged(); + } + } + + return stack; + } +} diff --git a/src/main/java/refinedstorage/gui/GuiDiskManipulator.java b/src/main/java/refinedstorage/gui/GuiDiskManipulator.java new file mode 100644 index 000000000..91713cac1 --- /dev/null +++ b/src/main/java/refinedstorage/gui/GuiDiskManipulator.java @@ -0,0 +1,42 @@ +package refinedstorage.gui; + +import refinedstorage.api.storage.CompareUtils; +import refinedstorage.container.ContainerDiskManipulator; +import refinedstorage.gui.sidebutton.SideButtonCompare; +import refinedstorage.gui.sidebutton.SideButtonMode; +import refinedstorage.gui.sidebutton.SideButtonRedstoneMode; +import refinedstorage.gui.sidebutton.SideButtonType; +import refinedstorage.tile.TileDiskManipulator; + +public class GuiDiskManipulator extends GuiBase { + public GuiDiskManipulator(ContainerDiskManipulator container) { + super(container, 176, 211); + } + + @Override + public void init(int x, int y) { + addSideButton(new SideButtonRedstoneMode(TileDiskManipulator.REDSTONE_MODE)); + addSideButton(new SideButtonType(TileDiskManipulator.TYPE)); + addSideButton(new SideButtonMode(TileDiskManipulator.MODE)); + addSideButton(new SideButtonCompare(TileDiskManipulator.COMPARE, CompareUtils.COMPARE_DAMAGE)); + addSideButton(new SideButtonCompare(TileDiskManipulator.COMPARE, CompareUtils.COMPARE_NBT)); + } + + @Override + public void update(int x, int y) { + + } + + @Override + public void drawBackground(int x, int y, int mouseX, int mouseY) { + bindTexture("gui/disk_manipulator.png"); + + drawTexture(x, y, 0, 0, width, height); + } + + @Override + public void drawForeground(int mouseX, int mouseY) { + drawString(7, 7, t("block.refinedstorage:disk_manipulator.name")); + drawString(7, 117, t("container.inventory")); + } +} diff --git a/src/main/java/refinedstorage/gui/GuiHandler.java b/src/main/java/refinedstorage/gui/GuiHandler.java index 119e7991d..4bafad742 100755 --- a/src/main/java/refinedstorage/gui/GuiHandler.java +++ b/src/main/java/refinedstorage/gui/GuiHandler.java @@ -58,6 +58,8 @@ public class GuiHandler implements IGuiHandler { return new ContainerFluidInterface((TileFluidInterface) tile, player); case RefinedStorageGui.FLUID_STORAGE: return new ContainerFluidStorage((TileFluidStorage) tile, player); + case RefinedStorageGui.DISK_MANIPULATOR: + return new ContainerDiskManipulator((TileDiskManipulator) tile, player); default: return null; } @@ -135,6 +137,8 @@ public class GuiHandler implements IGuiHandler { return new GuiFluidInterface((ContainerFluidInterface) getContainer(ID, player, tile)); case RefinedStorageGui.FLUID_STORAGE: return new GuiStorage((ContainerFluidStorage) getContainer(ID, player, tile), (TileFluidStorage) tile); + case RefinedStorageGui.DISK_MANIPULATOR: + return new GuiDiskManipulator((ContainerDiskManipulator) getContainer(ID, player, tile)); default: return null; } diff --git a/src/main/java/refinedstorage/proxy/ClientProxy.java b/src/main/java/refinedstorage/proxy/ClientProxy.java index 2a0c191cf..ebefa6563 100755 --- a/src/main/java/refinedstorage/proxy/ClientProxy.java +++ b/src/main/java/refinedstorage/proxy/ClientProxy.java @@ -280,5 +280,6 @@ public class ClientProxy extends CommonProxy { ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RefinedStorageBlocks.FLUID_STORAGE), EnumFluidStorageType.TYPE_256K.getId(), new ModelResourceLocation("refinedstorage:fluid_storage", "type=256k")); ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RefinedStorageBlocks.FLUID_STORAGE), EnumFluidStorageType.TYPE_512K.getId(), new ModelResourceLocation("refinedstorage:fluid_storage", "type=512k")); ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RefinedStorageBlocks.FLUID_STORAGE), EnumFluidStorageType.TYPE_CREATIVE.getId(), new ModelResourceLocation("refinedstorage:fluid_storage", "type=creative")); + ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(RefinedStorageBlocks.DISK_MANIPULATOR), 0, new ModelResourceLocation("refinedstorage:disk_manipulator", "inventory")); } } diff --git a/src/main/java/refinedstorage/proxy/CommonProxy.java b/src/main/java/refinedstorage/proxy/CommonProxy.java index 4f9322a51..329f46cd9 100755 --- a/src/main/java/refinedstorage/proxy/CommonProxy.java +++ b/src/main/java/refinedstorage/proxy/CommonProxy.java @@ -95,6 +95,7 @@ public class CommonProxy { registerTile(TileNetworkTransmitter.class, "network_transmitter"); registerTile(TileFluidInterface.class, "fluid_interface"); registerTile(TileFluidStorage.class, "fluid_storage"); + registerTile(TileDiskManipulator.class, "disk_manipulator"); registerBlock(RefinedStorageBlocks.CONTROLLER); registerBlock(RefinedStorageBlocks.GRID); @@ -119,6 +120,7 @@ public class CommonProxy { registerBlock(RefinedStorageBlocks.MACHINE_CASING); registerBlock(RefinedStorageBlocks.NETWORK_TRANSMITTER); registerBlock(RefinedStorageBlocks.NETWORK_RECEIVER); + registerBlock(RefinedStorageBlocks.DISK_MANIPULATOR); registerItem(RefinedStorageItems.QUARTZ_ENRICHED_IRON); registerItem(RefinedStorageItems.STORAGE_DISK); diff --git a/src/main/java/refinedstorage/tile/TileDiskManipulator.java b/src/main/java/refinedstorage/tile/TileDiskManipulator.java new file mode 100644 index 000000000..14f737abb --- /dev/null +++ b/src/main/java/refinedstorage/tile/TileDiskManipulator.java @@ -0,0 +1,212 @@ +package refinedstorage.tile; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemHandlerHelper; +import refinedstorage.RefinedStorageItems; +import refinedstorage.apiimpl.storage.fluid.FluidStorageNBT; +import refinedstorage.apiimpl.storage.fluid.FluidUtils; +import refinedstorage.apiimpl.storage.item.ItemStorageNBT; +import refinedstorage.block.EnumFluidStorageType; +import refinedstorage.block.EnumItemStorageType; +import refinedstorage.inventory.ItemHandlerBasic; +import refinedstorage.inventory.ItemHandlerFluid; +import refinedstorage.inventory.ItemValidatorBasic; +import refinedstorage.tile.config.IComparable; +import refinedstorage.tile.config.IFilterable; +import refinedstorage.tile.config.IType; +import refinedstorage.tile.data.TileDataParameter; + +public class TileDiskManipulator extends TileNode implements IComparable, IFilterable, IType { + public static final TileDataParameter COMPARE = IComparable.createParameter(); + public static final TileDataParameter MODE = IFilterable.createParameter(); + public static final TileDataParameter TYPE = IType.createParameter(); + + private static final String NBT_COMPARE = "Compare"; + private static final String NBT_MODE = "Mode"; + private static final String NBT_TYPE = "Type"; + + private int compare = 0; + private int mode = IFilterable.WHITELIST; + private int type = IType.ITEMS; + + public TileDiskManipulator() { + dataManager.addWatchedParameter(COMPARE); + dataManager.addWatchedParameter(MODE); + dataManager.addWatchedParameter(TYPE); + } + + private ItemHandlerBasic disks = new ItemHandlerBasic(12, this, new ItemValidatorBasic(RefinedStorageItems.STORAGE_DISK) { + @Override + public boolean isValid(ItemStack disk) { + return super.isValid(disk) && ItemStorageNBT.isValid(disk); + } + }, new ItemValidatorBasic(RefinedStorageItems.FLUID_STORAGE_DISK) { + @Override + public boolean isValid(ItemStack disk) { + return super.isValid(disk) && FluidStorageNBT.isValid(disk); + } + }); + + public class ItemStorage extends ItemStorageNBT { + public ItemStorage(ItemStack disk) { + super(disk.getTagCompound(), EnumItemStorageType.getById(disk.getItemDamage()).getCapacity(), TileDiskManipulator.this); + } + + @Override + public int getPriority() { + return 0; + } + + @Override + public ItemStack insertItem(ItemStack stack, int size, boolean simulate) { + if (!IFilterable.canTake(itemFilters, mode, getCompare(), stack)) { + return ItemHandlerHelper.copyStackWithSize(stack, size); + } + + return super.insertItem(stack, size, simulate); + } + } + + public class FluidStorage extends FluidStorageNBT { + public FluidStorage(ItemStack disk) { + super(disk.getTagCompound(), EnumFluidStorageType.getById(disk.getItemDamage()).getCapacity(), TileDiskManipulator.this); + } + + @Override + public int getPriority() { + return 0; + } + + @Override + public FluidStack insertFluid(FluidStack stack, int size, boolean simulate) { + if (!IFilterable.canTakeFluids(fluidFilters, mode, getCompare(), stack)) { + return FluidUtils.copyStackWithSize(stack, size); + } + + return super.insertFluid(stack, size, simulate); + } + } + + private ItemHandlerBasic itemFilters = new ItemHandlerBasic(9, this); + private ItemHandlerFluid fluidFilters = new ItemHandlerFluid(9, this); + + @Override + public int getEnergyUsage() { + return 0; + } + + @Override + public void updateNode() { + int i = 0; + ItemStack disk = disks.getStackInSlot(i); + while (disk == null && i < 6) i++; + if (disk == null) return; + + if (disk.getItem() == RefinedStorageItems.STORAGE_DISK) { + ItemStorage storage = new ItemStorage(disk); + } else if (disk.getItem() == RefinedStorageItems.FLUID_STORAGE_DISK) { + FluidStorage storage = new FluidStorage(disk); + } + + } + + @Override + public int getCompare() { + return compare; + } + + @Override + public void setCompare(int compare) { + this.compare = compare; + } + + @Override + public int getType() { + return this.type; + } + + @Override + public void setType(int type) { + this.type = type; + } + + @Override + public IItemHandler getFilterInventory() { + return getType() == IType.ITEMS ? itemFilters : fluidFilters; + } + + @Override + public void setMode(int mode) { + this.mode = mode; + } + + @Override + public int getMode() { + return this.mode; + } + + public IItemHandler getDisks() { + return disks; + } + + @Override + public void read(NBTTagCompound tag) { + super.read(tag); + + readItems(disks, 0, tag); + readItems(itemFilters, 1, tag); + readItems(fluidFilters, 2, tag); + + if (tag.hasKey(NBT_COMPARE)) { + compare = tag.getInteger(NBT_COMPARE); + } + + if (tag.hasKey(NBT_MODE)) { + mode = tag.getInteger(NBT_MODE); + } + + if (tag.hasKey(NBT_TYPE)) { + type = tag.getInteger(NBT_TYPE); + } + } + + @Override + public NBTTagCompound write(NBTTagCompound tag) { + super.write(tag); + + writeItems(disks, 0, tag); + writeItems(itemFilters, 1, tag); + writeItems(fluidFilters, 2, tag); + + tag.setInteger(NBT_COMPARE, compare); + tag.setInteger(NBT_MODE, mode); + tag.setInteger(NBT_TYPE, type); + + return tag; + } + + @Override + public IItemHandler getDrops() { + return disks; + } + + @Override + public T getCapability(Capability capability, EnumFacing facing) { + if (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { + return (T) disks; + } + + return super.getCapability(capability, facing); + } + + @Override + public boolean hasCapability(Capability capability, EnumFacing facing) { + return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY || super.hasCapability(capability, facing); + } +} diff --git a/src/main/resources/assets/refinedstorage/blockstates/disk_manipulator.json b/src/main/resources/assets/refinedstorage/blockstates/disk_manipulator.json new file mode 100644 index 000000000..0f6ae13a7 --- /dev/null +++ b/src/main/resources/assets/refinedstorage/blockstates/disk_manipulator.json @@ -0,0 +1,39 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "orientable", + "textures": { + "side": "refinedstorage:blocks/side", + "top": "refinedstorage:blocks/side", + "front": "refinedstorage:blocks/disk_manipulator" + } + }, + "variants": { + "inventory": [ + { + "transform": "forge:default-block", + "y": 0 + } + ], + "direction": { + "north": { + "y": 0 + }, + "east": { + "y": 90 + }, + "south": { + "y": 180 + }, + "west": { + "y": 270 + }, + "up": { + "x": 270 + }, + "down": { + "x": 90 + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/refinedstorage/lang/en_US.lang b/src/main/resources/assets/refinedstorage/lang/en_US.lang index f400594a6..250525ac4 100755 --- a/src/main/resources/assets/refinedstorage/lang/en_US.lang +++ b/src/main/resources/assets/refinedstorage/lang/en_US.lang @@ -114,6 +114,7 @@ block.refinedstorage:grid.1.name=Crafting Grid block.refinedstorage:grid.2.name=Pattern Grid block.refinedstorage:grid.3.name=Fluid Grid block.refinedstorage:disk_drive.name=Disk Drive +block.refinedstorage:disk_manipulator.name=Disk Manipulator block.refinedstorage:external_storage.name=External Storage block.refinedstorage:importer.name=Importer block.refinedstorage:exporter.name=Exporter diff --git a/src/main/resources/assets/refinedstorage/textures/blocks/disk_manipulator.png b/src/main/resources/assets/refinedstorage/textures/blocks/disk_manipulator.png new file mode 100644 index 0000000000000000000000000000000000000000..a4016ce34ffdcb3d44988c199e6ff1ede9821bcf GIT binary patch literal 605 zcmV-j0;2tiP)N2bZe?^J zG%heMF)~90YwQ330oqAKK~y+TjZ$lC+F%%ce^2f)R}CuSye(D}veYF-tP*4}ajxxX zt8tB3P3E+}$Q$#I?X=Lbk3O6{Je<7GIp>9!n5I)HHLF#-R0PkHh3=w2q>e$s`FU$^DP#F#I(h#}5yS(I~vV zefmC{7E309a1eac^&FsS+5e%chNfaLRK-w~%y4*LESjWHsP_9es%9*g%gtt!B+2jh zdU-35>-8E3y4^u8S0bfSy%!94UYX5i$K!E6pC1l~)9JL|@6o|*x7#R+I8GW2$JuO= z)j7wZ*Bj*W9|*oP9lG7GvYaMxIo}~|N zD2mZ;e?gDq81m4A_F}QXCOlWG6-fLNMcwnRB}pfOptf4qf}r5UZnr~+HikcMg&74h zg@vnt<7C3~G9C=Wh+!B`r_+BOF%WX{UNp@&n=O`25ybNSAeGW3Nt2{B23}O4!m={U zq-a{eA)b?Q2V7MUwAVQgQ!trg(vuw|@e8*`6NDH`b8+@bDf&`%`fueXsVp)k{ r1Q-HPg(Ltgh667$lt?i=O>=(%>;N>gl{x&p00000NkvXXu0mjfT9^l5 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/refinedstorage/textures/gui/disk_manipulator.png b/src/main/resources/assets/refinedstorage/textures/gui/disk_manipulator.png new file mode 100644 index 0000000000000000000000000000000000000000..77cf93f689334e108b6154a784635de22eb03d20 GIT binary patch literal 3425 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$6&2?&#~tz_78O`%fY(kk47* z5n0T@z_%NO8IS+CVg?kHEOCt}3C>R|DNig)Whh9@%q!8$OD$0_(KFC9G;(Iie#5}P zbI;SoF{C2y?VQ^a@3`@}PMvBLpvmaEbkCGF=ZVq`%hw!Ql*nIs_v({*!KHO>(KimN zR{Z^OVY>Z~-U?y+55K>^Pqmx4QT%}IhU(tUf7yRmO!ZHG!%`q$_xIP=g)GO8pRSQg zUS7YUK(PGV@qYPrck|{Luokp#3=U}R-7#CFVcOtgO=$l2>+9>(`hR~S>;A1f^Ro8S zoSNxiS59cIvu)6pIy3Y1oH*tCs;moA--tX}V0mWenU|sGPL_KzW=LAIT4wMS>lIf` zE&dc6#1M7N&yjD|;W>S;3QCNEcD@7=L@ z&_yWm$!zU~e?=!&-@30KUi)vI+45g~{2$h5-7nwkd=BcVwI50a!c9VoSH1tiu$N)g z-1`@A*rszioW7yC;!v0eqs~O8h$ojNtXV^EaA`KE1~GJlQvL$2XhqfyZd?hyz-%EB zlBm6e;hG2Inva=1bDOksT15^>X*QVJ^@4K2+6hb%%B&lXEjKLVTD3tmh#?!O_J;{D z6^U+h0vZ5RJO3EevNb@<9>Xm&1*)Z@Wrwai#<-dSL%{#T<|jVjgbno5+xZ&dTNkgf zs}G+YTzgzS;_dHsb|2rPuC^?{ud?A8`}hBfd76F_E)~S^@U?YF{W75U z5KjJZ{(a!zpP|T}=lEQ{vhG^qd;cq+WiUfj-}V3hbs4NXw53*AUM;U_ny(5>cHL0dA(;wHR}+~Uj9~!)Og;~I z{%z=iCNqSGXsBg>?eDO6fBM*1KkS4B`?Vi`e}6A}UT&h%aK06*qd$UE*++0R)yN(R z1!pl9dv8$2dt7My{pf*oVDV}hSI@=pUXgXd(~7^E413x^l3$lIe2@c{w0+m-Gaab* z7*Iv_Vhw-q7KCrzAGhk)pV*m~e?PGVmyE|>$BQ?hRvky3&5AC_Jd1huMeF&K-Afp@ zRGe@_sVT(xZ=P^0o>4sW^6EL0-%nz?@JLY_wQjLVQD#4zcrMj%eUaZjZ(wq0&q1w? zK2GSBF=@A)Zn^gq#2s>*CN?8iJ_F_m)QZFX%-8*lF<1K*pat6bdZsIbahO^X4GUCOYpFv;haY_2d7sJ>KsuZ*XAq PLy#Swu6{1-oD!M