From 43d3050b40042318f2cd66e48d1f51c126d7c7d3 Mon Sep 17 00:00:00 2001 From: Aidan Brady Date: Thu, 12 Dec 2013 18:33:56 -0500 Subject: [PATCH] Work on Chemical Infuser --- common/mekanism/api/gas/GasTank.java | 10 +- common/mekanism/common/ChemicalInput.java | 20 +- common/mekanism/common/RecipeHandler.java | 11 +- .../TileEntityChemicalFormulator.java | 2 +- .../tileentity/TileEntityChemicalInfuser.java | 383 ++++++++---------- .../common/tileentity/TileEntityGasTank.java | 4 +- .../TileEntityRotaryCondensentrator.java | 6 +- .../mekanism/gui/GuiChemicalInfuser.png | Bin 4545 -> 4522 bytes 8 files changed, 209 insertions(+), 227 deletions(-) diff --git a/common/mekanism/api/gas/GasTank.java b/common/mekanism/api/gas/GasTank.java index 5067340ff..1b716ce06 100644 --- a/common/mekanism/api/gas/GasTank.java +++ b/common/mekanism/api/gas/GasTank.java @@ -20,7 +20,7 @@ public class GasTank stored = stack; } - public GasStack draw(int amount, boolean doDrain) + public GasStack draw(int amount, boolean doDraw) { if(stored == null || amount <= 0) { @@ -31,7 +31,7 @@ public class GasTank if(ret.amount > 0) { - if(doDrain) + if(doDraw) { stored.amount -= ret.amount; @@ -39,8 +39,6 @@ public class GasTank { stored = null; } - - } return ret; @@ -49,7 +47,7 @@ public class GasTank return null; } - public int fill(GasStack amount, boolean doFill) + public int receive(GasStack amount, boolean doReceive) { if(amount == null || (stored != null && stored.amount == maxGas)) { @@ -58,7 +56,7 @@ public class GasTank int toFill = Math.min(maxGas-getStored(), amount.amount); - if(doFill) + if(doReceive) { if(stored == null) { diff --git a/common/mekanism/common/ChemicalInput.java b/common/mekanism/common/ChemicalInput.java index fa2ed8bd8..16c09d1d0 100644 --- a/common/mekanism/common/ChemicalInput.java +++ b/common/mekanism/common/ChemicalInput.java @@ -22,9 +22,23 @@ public class ChemicalInput @Override public boolean equals(Object obj) { - return obj instanceof ChemicalInput && - ((ChemicalInput)obj).leftGas == leftGas && - ((ChemicalInput)obj).rightGas == rightGas; + if(!(obj instanceof ChemicalInput)) + { + return false; + } + + ChemicalInput compare = (ChemicalInput)obj; + + if(leftGas == compare.leftGas && rightGas == compare.rightGas) + { + return true; + } + else if(leftGas == compare.rightGas && rightGas == compare.leftGas) + { + return true; + } + + return false; } @Override diff --git a/common/mekanism/common/RecipeHandler.java b/common/mekanism/common/RecipeHandler.java index e3dc2dd24..ed9f4f81f 100644 --- a/common/mekanism/common/RecipeHandler.java +++ b/common/mekanism/common/RecipeHandler.java @@ -145,7 +145,16 @@ public final class RecipeHandler if(input != null && input.isValid()) { HashMap recipes = Recipe.CHEMICAL_INFUSER.get(); - return recipes.get(input); + + for(Map.Entry entry : recipes.entrySet()) + { + ChemicalInput key = (ChemicalInput)entry.getKey(); + + if(key.equals(input)) + { + return entry.getValue().copy(); + } + } } return null; diff --git a/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java b/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java index b063e4491..be8b0379e 100644 --- a/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java +++ b/common/mekanism/common/tileentity/TileEntityChemicalFormulator.java @@ -104,7 +104,7 @@ public class TileEntityChemicalFormulator extends TileEntityElectricBlock implem else { GasStack stack = RecipeHandler.getChemicalFormulatorOutput(inventory[0], true); - gasTank.fill(stack, true); + gasTank.receive(stack, true); operatingTicks = 0; } } diff --git a/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java b/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java index 7726b965d..7d30f4ab8 100644 --- a/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java +++ b/common/mekanism/common/tileentity/TileEntityChemicalInfuser.java @@ -1,16 +1,39 @@ package mekanism.common.tileentity; -import mekanism.api.gas.GasStack; -import mekanism.common.IRedstoneControl.RedstoneControl; -import mekanism.common.Mekanism; -import net.minecraft.item.ItemStack; +import java.util.ArrayList; -public class TileEntityChemicalInfuser extends TileEntityElectricBlock //implements IActiveState, IGasStorage, IGasAcceptor, ITubeConnection, IRedstoneControl +import mekanism.api.Object3D; +import mekanism.api.gas.Gas; +import mekanism.api.gas.GasRegistry; +import mekanism.api.gas.GasStack; +import mekanism.api.gas.GasTank; +import mekanism.api.gas.GasTransmission; +import mekanism.api.gas.IGasHandler; +import mekanism.api.gas.ITubeConnection; +import mekanism.common.ChemicalInput; +import mekanism.common.IActiveState; +import mekanism.common.IRedstoneControl; +import mekanism.common.Mekanism; +import mekanism.common.PacketHandler; +import mekanism.common.PacketHandler.Transmission; +import mekanism.common.RecipeHandler; +import mekanism.common.network.PacketTileEntity; +import mekanism.common.util.ChargeUtils; +import mekanism.common.util.MekanismUtils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraftforge.common.ForgeDirection; +import net.minecraftforge.fluids.FluidStack; + +import com.google.common.io.ByteArrayDataInput; + +public class TileEntityChemicalInfuser extends TileEntityElectricBlock implements IActiveState, IGasHandler, ITubeConnection, IRedstoneControl { - public GasStack leftStack; - public GasStack rightStack; - - public GasStack centerStack; + public GasTank leftTank = new GasTank(MAX_GAS); + public GasTank rightTank = new GasTank(MAX_GAS); + public GasTank centerTank = new GasTank(MAX_GAS); public static final int MAX_GAS = 10000; @@ -35,7 +58,7 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme inventory = new ItemStack[4]; } - /*@Override + @Override public void onUpdate() { if(worldObj.isRemote) @@ -66,123 +89,51 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme ChargeUtils.discharge(4, this); - if(mode == 0) + if(inventory[0] != null && (leftTank.getGas() == null || leftTank.getStored() < leftTank.getMaxGas())) { - if(inventory[1] != null && (getGas() == null || getGas().amount < getMaxGas())) - { - if(getGas() == null) - { - setGas(GasTransmission.removeGas(inventory[1], null, getMaxGas())); - } - else { - GasStack removed = GasTransmission.removeGas(inventory[1], getGas().getGas(), getMaxGas()-getGas().amount); - setGas(new GasStack(getGas().getGas(), getGas().amount + (removed != null ? removed.amount : 0))); - } - } + leftTank.receive(GasTransmission.removeGas(inventory[0], null, leftTank.getNeeded()), true); + } + + if(inventory[2] != null && (rightTank.getGas() == null || rightTank.getStored() < rightTank.getMaxGas())) + { + rightTank.receive(GasTransmission.removeGas(inventory[2], null, rightTank.getNeeded()), true); + } + + if(inventory[1] != null && centerTank.getGas() != null) + { + centerTank.draw(GasTransmission.addGas(inventory[1], centerTank.getGas()), true); + } + + if(canOperate() && getEnergy() >= ENERGY_USAGE && MekanismUtils.canFunction(this)) + { + setActive(true); + GasStack stack = RecipeHandler.getChemicalInfuserOutput(new ChemicalInput(leftTank.getGas().getGas(), rightTank.getGas().getGas())); - if(getEnergy() >= ENERGY_USAGE && MekanismUtils.canFunction(this) && isValidGas(gasTank) && (fluidTank.getFluid() == null || (fluidTank.getFluid().amount < 10000 && gasEquals(gasTank, fluidTank.getFluid())))) + leftTank.draw(1, true); + rightTank.draw(1, true); + centerTank.receive(stack, true); + + setEnergy(getEnergy() - ENERGY_USAGE); + } + else { + if(prevEnergy >= getEnergy()) { - setActive(true); - fluidTank.fill(new FluidStack(getGas().getGas().getFluid(), 1), true); - setGas(new GasStack(getGas().getGas(), getGas().amount-1)); - setEnergy(getEnergy() - ENERGY_USAGE); - } - else { - if(prevEnergy >= getEnergy()) - { - setActive(false); - } + setActive(false); } } - else if(mode == 1) + + if(centerTank.getGas() != null) { - if(getGas() != null) - { - if(inventory[0] != null) - { - setGas(new GasStack(getGas().getGas(), getGas().amount - GasTransmission.addGas(inventory[0], getGas()))); - } - } + GasStack toSend = new GasStack(centerTank.getGas().getGas(), Math.min(centerTank.getStored(), gasOutput)); + centerTank.draw(GasTransmission.emitGasToNetwork(toSend, this, ForgeDirection.getOrientation(facing)), true); - if(getGas() != null) - { - GasStack toSend = new GasStack(getGas().getGas(), Math.min(getGas().amount, gasOutput)); - setGas(new GasStack(getGas().getGas(), getGas().amount - GasTransmission.emitGasToNetwork(toSend, this, MekanismUtils.getLeft(facing)))); - - TileEntity tileEntity = Object3D.get(this).getFromSide(MekanismUtils.getLeft(facing)).getTileEntity(worldObj); - - if(tileEntity instanceof IGasHandler) - { - if(((IGasHandler)tileEntity).canReceiveGas(MekanismUtils.getLeft(facing).getOpposite(), getGas().getGas())) - { - int added = ((IGasHandler)tileEntity).receiveGas(new GasStack(getGas().getGas(), Math.min(getGas().amount, gasOutput))); - - setGas(new GasStack(getGas().getGas(), getGas().amount - added)); - } - } - } + TileEntity tileEntity = Object3D.get(this).getFromSide(ForgeDirection.getOrientation(facing)).getTileEntity(worldObj); - if(FluidContainerRegistry.isFilledContainer(inventory[2])) + if(tileEntity instanceof IGasHandler) { - FluidStack itemFluid = FluidContainerRegistry.getFluidForFilledItem(inventory[2]); - - if((fluidTank.getFluid() == null && itemFluid.amount <= 10000) || fluidTank.getFluid().amount+itemFluid.amount <= 10000) + if(((IGasHandler)tileEntity).canReceiveGas(ForgeDirection.getOrientation(facing).getOpposite(), centerTank.getGas().getGas())) { - if(fluidTank.getFluid() != null && !fluidTank.getFluid().isFluidEqual(itemFluid)) - { - return; - } - - ItemStack containerItem = inventory[2].getItem().getContainerItemStack(inventory[2]); - - boolean filled = false; - - if(containerItem != null) - { - if(inventory[3] == null || (inventory[3].isItemEqual(containerItem) && inventory[3].stackSize+1 <= containerItem.getMaxStackSize())) - { - inventory[2] = null; - - if(inventory[3] == null) - { - inventory[3] = containerItem; - } - else { - inventory[3].stackSize++; - } - - filled = true; - } - } - else { - inventory[2].stackSize--; - - if(inventory[2].stackSize == 0) - { - inventory[2] = null; - } - - filled = true; - } - - if(filled) - { - fluidTank.fill(itemFluid, true); - } - } - } - - if(getEnergy() >= ENERGY_USAGE && MekanismUtils.canFunction(this) && isValidFluid(fluidTank.getFluid()) && (gasTank == null || (gasTank.amount < MAX_GAS && gasEquals(gasTank, fluidTank.getFluid())))) - { - setActive(true); - setGas(new GasStack(GasRegistry.getGas(fluidTank.getFluid().getFluid()), getGas() != null ? getGas().amount+1 : 1)); - fluidTank.draw(1, true); - setEnergy(getEnergy() - ENERGY_USAGE); - } - else { - if(prevEnergy >= getEnergy()) - { - setActive(false); + centerTank.draw(((IGasHandler)tileEntity).receiveGas(ForgeDirection.getOrientation(facing).getOpposite(), toSend), true); } } } @@ -191,34 +142,26 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme } } - public boolean isValidGas(GasStack g) + public boolean canOperate() { - if(g == null) + if(leftTank.getGas() == null || rightTank.getGas() == null || centerTank.getNeeded() == 0) { return false; } - return g.getGas().hasFluid(); - } - - public boolean gasEquals(GasStack gas, FluidStack fluid) - { - if(fluid == null || gas == null || !gas.getGas().hasFluid()) + GasStack out = RecipeHandler.getChemicalInfuserOutput(new ChemicalInput(leftTank.getGas().getGas(), rightTank.getGas().getGas())); + + if(out == null) { return false; } - return gas.getGas().getFluid() == fluid.getFluid(); - } - - public boolean isValidFluid(FluidStack f) - { - if(f == null) + if(centerTank.getNeeded() < out.amount) { return false; } - return GasRegistry.getGas(f.getFluid()) != null; + return true; } @Override @@ -230,7 +173,11 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme if(type == 0) { - mode = mode == 0 ? 1 : 0; + leftTank.setGas(null); + } + else if(type == 1) + { + rightTank.setGas(null); } for(EntityPlayer player : playersUsing) @@ -243,24 +190,31 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme super.handlePacketData(dataStream); - mode = dataStream.readInt(); isActive = dataStream.readBoolean(); controlType = RedstoneControl.values()[dataStream.readInt()]; if(dataStream.readBoolean()) { - fluidTank.setFluid(new FluidStack(dataStream.readInt(), dataStream.readInt())); + leftTank.setGas(new GasStack(GasRegistry.getGas(dataStream.readInt()), dataStream.readInt())); } else { - fluidTank.setFluid(null); + leftTank.setGas(null); } if(dataStream.readBoolean()) { - gasTank = new GasStack(GasRegistry.getGas(dataStream.readInt()), dataStream.readInt()); + rightTank.setGas(new GasStack(GasRegistry.getGas(dataStream.readInt()), dataStream.readInt())); } else { - gasTank = null; + rightTank.setGas(null); + } + + if(dataStream.readBoolean()) + { + centerTank.setGas(new GasStack(GasRegistry.getGas(dataStream.readInt()), dataStream.readInt())); + } + else { + centerTank.setGas(null); } @@ -272,25 +226,34 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme { super.getNetworkedData(data); - data.add(mode); data.add(isActive); data.add(controlType.ordinal()); - if(fluidTank.getFluid() != null) + if(leftTank != null) { data.add(true); - data.add(fluidTank.getFluid().fluidID); - data.add(fluidTank.getFluid().amount); + data.add(leftTank.getGas().getGas().getID()); + data.add(leftTank.getStored()); } else { data.add(false); } - if(gasTank != null) + if(rightTank != null) { data.add(true); - data.add(gasTank.getGas().getID()); - data.add(gasTank.amount); + data.add(rightTank.getGas().getGas().getID()); + data.add(rightTank.getStored()); + } + else { + data.add(false); + } + + if(centerTank != null) + { + data.add(true); + data.add(centerTank.getGas().getGas().getID()); + data.add(centerTank.getStored()); } else { data.add(false); @@ -304,16 +267,12 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme { super.readFromNBT(nbtTags); - mode = nbtTags.getInteger("mode"); isActive = nbtTags.getBoolean("isActive"); controlType = RedstoneControl.values()[nbtTags.getInteger("controlType")]; - gasTank = GasStack.readFromNBT(nbtTags.getCompoundTag("gasTank")); - - if(nbtTags.hasKey("fluidTank")) - { - fluidTank.readFromNBT(nbtTags.getCompoundTag("fluidTank")); - } + leftTank = GasTank.readFromNBT(nbtTags.getCompoundTag("leftTank")); + rightTank = GasTank.readFromNBT(nbtTags.getCompoundTag("rightTank")); + centerTank = GasTank.readFromNBT(nbtTags.getCompoundTag("centerTank")); } @Override @@ -321,19 +280,12 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme { super.writeToNBT(nbtTags); - nbtTags.setInteger("mode", mode); nbtTags.setBoolean("isActive", isActive); nbtTags.setInteger("controlType", controlType.ordinal()); - if(gasTank != null) - { - nbtTags.setCompoundTag("gasTank", gasTank.write(new NBTTagCompound())); - } - - if(fluidTank.getFluid() != null) - { - nbtTags.setTag("fluidTank", fluidTank.writeToNBT(new NBTTagCompound())); - } + nbtTags.setCompoundTag("leftTank", leftTank.write(new NBTTagCompound())); + nbtTags.setCompoundTag("rightTank", rightTank.write(new NBTTagCompound())); + nbtTags.setCompoundTag("centerTank", centerTank.write(new NBTTagCompound())); } @Override @@ -342,14 +294,37 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme return i != 0 && i != 1; } - public int getScaledFluidLevel(int i) + public GasTank getTank(ForgeDirection side) { - return fluidTank.getFluid() != null ? fluidTank.getFluid().amount*i / 10000 : 0; + if(side == MekanismUtils.getLeft(facing)) + { + return leftTank; + } + else if(side == MekanismUtils.getRight(facing)) + { + return rightTank; + } + else if(side == ForgeDirection.getOrientation(facing)) + { + return centerTank; + } + + return null; } - public int getScaledGasLevel(int i) + public int getScaledLeftGasLevel(int i) { - return gasTank != null ? gasTank.amount*i / MAX_GAS : 0; + return leftTank != null ? leftTank.getStored()*i / MAX_GAS : 0; + } + + public int getScaledRightGasLevel(int i) + { + return leftTank != null ? rightTank.getStored()*i / MAX_GAS : 0; + } + + public int getScaledCenterGasLevel(int i) + { + return leftTank != null ? centerTank.getStored()*i / MAX_GAS : 0; } @Override @@ -387,55 +362,13 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme @Override public boolean canTubeConnect(ForgeDirection side) { - return side == MekanismUtils.getLeft(facing); - } - - @Override - public int receiveGas(GasStack stack) - { - if(gasTank == null || (gasTank != null && gasTank.getGas() == stack.getGas())) - { - int stored = getGas() != null ? getGas().amount : 0; - int toUse = Math.min(getMaxGas()-stored, stack.amount); - - setGas(new GasStack(stack.getGas(), stored + toUse)); - - return toUse; - } - - return 0; + return side == MekanismUtils.getLeft(facing) || side == MekanismUtils.getRight(facing) || side == ForgeDirection.getOrientation(facing); } @Override public boolean canReceiveGas(ForgeDirection side, Gas type) { - return mode == 0 && (getGas() == null || getGas().getGas() == type) && side == MekanismUtils.getLeft(facing); - } - - @Override - public GasStack getGas(Object... data) - { - return gasTank; - } - - @Override - public void setGas(GasStack stack, Object... data) - { - if(stack == null || stack.amount == 0) - { - gasTank = null; - } - else { - gasTank = new GasStack(stack.getGas(), Math.max(Math.min(stack.amount, getMaxGas()), 0)); - } - - MekanismUtils.saveChunk(this); - } - - @Override - public int getMaxGas(Object... data) - { - return MAX_GAS; + return getTank(side) != null && getTank(side) != centerTank ? getTank(side).canReceive(type) : false; } @Override @@ -449,5 +382,33 @@ public class TileEntityChemicalInfuser extends TileEntityElectricBlock //impleme { controlType = type; MekanismUtils.saveChunk(this); - }*/ + } + + @Override + public int receiveGas(ForgeDirection side, GasStack stack) + { + if(canReceiveGas(side, stack != null ? stack.getGas() : null)) + { + return getTank(side).receive(stack, true); + } + + return 0; + } + + @Override + public GasStack drawGas(ForgeDirection side, int amount) + { + if(canDrawGas(side, null)) + { + return getTank(side).draw(amount, true); + } + + return null; + } + + @Override + public boolean canDrawGas(ForgeDirection side, Gas type) + { + return getTank(side) != null && getTank(side) == centerTank ? getTank(side).canDraw(type) : false; + } } diff --git a/common/mekanism/common/tileentity/TileEntityGasTank.java b/common/mekanism/common/tileentity/TileEntityGasTank.java index 2ab470b87..4af7a703f 100644 --- a/common/mekanism/common/tileentity/TileEntityGasTank.java +++ b/common/mekanism/common/tileentity/TileEntityGasTank.java @@ -50,7 +50,7 @@ public class TileEntityGasTank extends TileEntityContainerBlock implements IGasH if(inventory[1] != null && (gasTank.getGas() == null || gasTank.getGas().amount < gasTank.getMaxGas())) { - gasTank.fill(GasTransmission.removeGas(inventory[1], null, gasTank.getNeeded()), true); + gasTank.receive(GasTransmission.removeGas(inventory[1], null, gasTank.getNeeded()), true); } if(!worldObj.isRemote && gasTank.getGas() != null && MekanismUtils.canFunction(this)) @@ -110,7 +110,7 @@ public class TileEntityGasTank extends TileEntityContainerBlock implements IGasH @Override public int receiveGas(ForgeDirection side, GasStack stack) { - return gasTank.fill(stack, true); + return gasTank.receive(stack, true); } @Override diff --git a/common/mekanism/common/tileentity/TileEntityRotaryCondensentrator.java b/common/mekanism/common/tileentity/TileEntityRotaryCondensentrator.java index 4ffc585a3..29b2a852b 100644 --- a/common/mekanism/common/tileentity/TileEntityRotaryCondensentrator.java +++ b/common/mekanism/common/tileentity/TileEntityRotaryCondensentrator.java @@ -102,7 +102,7 @@ public class TileEntityRotaryCondensentrator extends TileEntityElectricBlock imp { if(inventory[1] != null && (gasTank.getGas() == null || gasTank.getStored() < gasTank.getMaxGas())) { - gasTank.fill(GasTransmission.removeGas(inventory[1], null, gasTank.getNeeded()), true); + gasTank.receive(GasTransmission.removeGas(inventory[1], null, gasTank.getNeeded()), true); } if(inventory[2] != null) @@ -229,7 +229,7 @@ public class TileEntityRotaryCondensentrator extends TileEntityElectricBlock imp if(getEnergy() >= ENERGY_USAGE && MekanismUtils.canFunction(this) && isValidFluid(fluidTank.getFluid()) && (gasTank == null || (gasTank.getStored() < MAX_GAS && gasEquals(gasTank.getGas(), fluidTank.getFluid())))) { setActive(true); - gasTank.fill(new GasStack(GasRegistry.getGas(fluidTank.getFluid().getFluid()), 1), true); + gasTank.receive(new GasStack(GasRegistry.getGas(fluidTank.getFluid().getFluid()), 1), true); fluidTank.drain(1, true); setEnergy(getEnergy() - ENERGY_USAGE); } @@ -443,7 +443,7 @@ public class TileEntityRotaryCondensentrator extends TileEntityElectricBlock imp @Override public int receiveGas(ForgeDirection side, GasStack stack) { - return gasTank.fill(stack, true); + return gasTank.receive(stack, true); } @Override diff --git a/resources/assets/mekanism/gui/GuiChemicalInfuser.png b/resources/assets/mekanism/gui/GuiChemicalInfuser.png index 0a2fc0627217d0986c6610ceb5bfae5b9725c2e1..4d851e5472775bc1cb6ce5820f6e094a21e4fbfe 100644 GIT binary patch delta 3054 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 delta 3076 zcmb`JXH-*L7RPU{K?n@eML{5ggc3th6i|@FN3UU|N`QcEK&;z zT{Mn9r7p+4eAPzAsH`q>eKtfVA=CBD({!yzraMZc&>?xCG&^hO$ORc|P?~auFm_ug zdS}S{*Q1^Jf~g+)l$zDe2BlrlR@b+bTt)6=WmYS-!MK}m9`g($L5`q^<@6}oM7fGT z8@s(VgBZeZd#SLRA-Z}r#GAS-s2opmSQ$6)->?S!(+@R0nAn>w^(xt68{(U-?0YS5 zY7UCX1U|`#sY&OYobn zy4TKZ7Bu01bi5gIk9J3#mI^$Exa7yEjFj`e?S1L|q+NI##Cf|I7%s<1d$9Rp2B|ld zZYQy(4fzO7`wXWME7OU)_@l4S+iZR^0Ik3wMuVdInp=3c7eL|GW_eh%NcruyB)xrxaxLMtV&ceiGq||HTHn8!iczc z-a_#RTi{?r95YnXY1viCOUUCsc^ug*_eV+}!wzSXd~yEi%gSVJga@|r2;ptv^BW%* zE|(+qD&tzDKAIf|i((ubxpTAmc(mL$$tmcL4iYl{J`8Z{9}A?^Ed zl*D4}7?xe|LqVgYhyaz#5rXpPUBiY?=yliJ5YL}qtPVu6)q*cB#k-T19}W%%qI`pd z`*52Z3xkbTD#QGo0=Y`xD*0 z2rnO>TkYTfI(zU1O{|s_BLhg#+PRE9Qe+@ey}YYF6F3QVA(Jl^bGE;fN5T9d%N(XSx{|U9Lje*ruR4~0TzKKPQOK>5x<>|az8)ATzU2IxWaxI?H=ZM zlQqzE*>XXv)J3_cBu)f}hQnZd0lK4rP%cMdhLX(8YdaG_)k!Dwp#y(o;6IO{%9d78$nJIItnYi#sqhzhBrfyJ&QxQ>jwEZOfSVU*G=^VVw zxVmNHF&D5WN2@a&(ga@Z$3sWp?dtkBDb)4JjDxm~O}HaPof87it3{5YR+dQTaaH{G z_i^v%dX^Z7@?|L^gUto`&Gg7F%+2+vUQ3Ar3_!C@d)mkD&{MCXqDwm*^dxa~YW9k1i0>VuiJ4{+kj)$p9I6x)o| zAw!})`t>at0@2aBl});$GtEB_6_ys}nSa5GWzZ>n2QzZcey+L9$_{9aEb<(5C&xhL zfjp*yU?PoZ>l(AMZVMPIg5=n($)dLDMhU!0wk?2h2l$Kf^9wzAaaj~&EUa`*H=gI; z!^CF~@;1f1cH;1sHb+YbH`mPjW4TZo8Ou8TnomzE+q! zlLtR%k~(Q;S*Ci5M&iVrQVN8W6p78(twh#5)uh^h1IUu@(W^-#1_yHf6LZxD9O5v_wpycO>uFis&*jDe0BBWe|V02;bLJE-S`)F|i7SmVgA zp!ENk<@Y3In>(xpxA6R^`RTmeS~R^jrEU_b!zqaUz8Xjrs56W~B^oiUS1ED!yGh;t zj^FR(K#owLFTVC+D%mjNxG5_pw_b13uHV>#9RN7L+-K(-0AK!X z;B1(Py;LfYcm8MwyA7#E$r0+Fk$j+vM%aG}#Zhxm)_}3tv#x*YSrEVnk0(7qW0_Ro z`fewdnQtNmsb|qzioC9lM$F?Fjx@F`0_B?sW%#4!?FnH2DMHRJsuo;CR=Y{MKZ}Aa zc|kd*1Ukb-v^TFV?uJqom`(1;P z(4n&GaR;B2_6sWE$QDJ54emeCk6AeCd)VgpJD%~7s<6%G#8coMn9&_b*l81G4i|~f zEki2ErveHR4312^h&3Q}{4DA)Ozp5TVOT>F7OfiDB7NQq=4nEyA);Z;=4c>e0%?X17|jgk``bx`B%Kf2p~T!B!WFR2^6fogV=`aRK@2;753HKK^1)L*X>g2sn}_3J$L{ z{Nx<)$($>>^fl;J44=D>;GB9pWFvh;a$0bTIY`9w*ZgS0$O_z8`%P_`oLJEM$cT>f xb59Xj`5VWsCmB9_;U}qwNJC4W-s9vmCJ1Y2pUb-B_%i@68w*GCqMv+k{s#aCwTS=#