From 5954863a538d84e9edfa825e4fac2567bedb24f1 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Sat, 26 Jan 2019 00:34:05 +0100 Subject: [PATCH] added the rf converter --- .../de/ellpeck/naturesaura/ModConfig.java | 5 + .../naturesaura/blocks/BlockRFConverter.java | 14 +++ .../ellpeck/naturesaura/blocks/ModBlocks.java | 2 + .../naturesaura/blocks/multi/Multiblock.java | 8 +- .../naturesaura/blocks/multi/Multiblocks.java | 14 +++ .../blocks/tiles/TileEntityRFConverter.java | 110 ++++++++++++++++++ .../de/ellpeck/naturesaura/compat/Compat.java | 5 + .../naturesaura/events/ClientEvents.java | 23 +++- .../naturesaura/packet/PacketParticles.java | 16 +++ .../naturesaura/blockstates/rf_converter.json | 14 +++ .../assets/naturesaura/lang/en_US.lang | 1 + .../en_us/entries/using/rf_converter.json | 27 +++++ .../naturesaura/recipes/rf_converter.json | 42 +++++++ .../textures/blocks/rf_converter.png | Bin 0 -> 703 bytes 14 files changed, 271 insertions(+), 10 deletions(-) create mode 100644 src/main/java/de/ellpeck/naturesaura/blocks/BlockRFConverter.java create mode 100644 src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityRFConverter.java create mode 100644 src/main/resources/assets/naturesaura/blockstates/rf_converter.json create mode 100644 src/main/resources/assets/naturesaura/patchouli_books/book/en_us/entries/using/rf_converter.json create mode 100644 src/main/resources/assets/naturesaura/recipes/rf_converter.json create mode 100644 src/main/resources/assets/naturesaura/textures/blocks/rf_converter.png diff --git a/src/main/java/de/ellpeck/naturesaura/ModConfig.java b/src/main/java/de/ellpeck/naturesaura/ModConfig.java index 49074e37..d0ac637f 100644 --- a/src/main/java/de/ellpeck/naturesaura/ModConfig.java +++ b/src/main/java/de/ellpeck/naturesaura/ModConfig.java @@ -29,12 +29,17 @@ public final class ModConfig { @Comment("The amount of blocks that can be between two Aura Field Creators for them to be connectable and work together") public int fieldCreatorRange = 10; + + @Comment("The Aura to RF ratio used by the RF converter, read as aura*ratio = rf") + public float auraToRFRatio = 5; } public static class Features { @Comment("If using Dragon's Breath in a Brewing Stand should not cause a glass bottle to appear") public boolean removeDragonBreathContainerItem = true; + @Comment("If the RF converter block should be enabled") + public boolean rfConverter = true; @Comment("If the Aura Imbalance effect of grass and trees dying in the area if the Aura levels are too low should occur") public boolean grassDieEffect = true; diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockRFConverter.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockRFConverter.java new file mode 100644 index 00000000..8d126d87 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockRFConverter.java @@ -0,0 +1,14 @@ +package de.ellpeck.naturesaura.blocks; + +import de.ellpeck.naturesaura.blocks.tiles.TileEntityRFConverter; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; + +public class BlockRFConverter extends BlockContainerImpl { + + public BlockRFConverter() { + super(Material.ROCK, "rf_converter", TileEntityRFConverter.class, "rf_converter"); + this.setSoundType(SoundType.STONE); + this.setHardness(3F); + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java index dff63dd9..532ce774 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java @@ -1,5 +1,6 @@ package de.ellpeck.naturesaura.blocks; +import de.ellpeck.naturesaura.ModConfig; import net.minecraft.block.Block; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; @@ -43,4 +44,5 @@ public final class ModBlocks { public static final Block ANIMAL_SPAWNER = new BlockAnimalSpawner(); public static final Block AUTO_CRAFTER = new BlockAutoCrafter(); public static final Block GOLD_BRICK = new BlockImpl("gold_brick", Material.ROCK).setSoundType(SoundType.STONE).setHardness(2F); + public static final Block RF_CONVERTER = ModConfig.enabledFeatures.rfConverter ? new BlockRFConverter() : null; } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblock.java b/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblock.java index 6fc30dd3..ef21c038 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblock.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblock.java @@ -18,7 +18,7 @@ import java.util.function.BiFunction; public class Multiblock implements IMultiblock { private final ResourceLocation name; - private final Map matchers = new HashMap<>(); + private final Map matchers = new HashMap<>(); private final int width; private final int height; private final int depth; @@ -129,9 +129,9 @@ public class Multiblock implements IMultiblock { } @Override - public boolean forEach(BlockPos center, char c, BiFunction function) { + public boolean forEach(BlockPos center, char c, BiFunction function) { BlockPos start = this.getStart(center); - for (Map.Entry entry : this.matchers.entrySet()) { + for (Map.Entry entry : this.matchers.entrySet()) { BlockPos offset = entry.getKey(); if (c == 0 || this.getChar(offset) == c) if (!function.apply(start.add(offset), entry.getValue())) @@ -156,7 +156,7 @@ public class Multiblock implements IMultiblock { } @Override - public Map getMatchers() { + public Map getMatchers() { return this.matchers; } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblocks.java b/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblocks.java index f052cde6..0bd5082a 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblocks.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblocks.java @@ -1,5 +1,6 @@ package de.ellpeck.naturesaura.blocks.multi; +import de.ellpeck.naturesaura.ModConfig; import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.api.NaturesAuraAPI; import de.ellpeck.naturesaura.api.multiblock.IMultiblock; @@ -81,4 +82,17 @@ public final class Multiblocks { 'L', ModBlocks.ANCIENT_LOG, '0', ModBlocks.AUTO_CRAFTER, ' ', Matcher.wildcard()); + public static final IMultiblock RF_CONVERTER = ModConfig.enabledFeatures.rfConverter ? NaturesAuraAPI.instance().createMultiblock( + new ResourceLocation(NaturesAura.MOD_ID, "rf_converter"), + new String[][]{ + {" ", " ", " ", " R ", " ", " ", " "}, + {" ", " R ", " ", " R R ", " ", " R ", " "}, + {" ", " ", " ", " ", " ", " ", " "}, + {" R ", " R R ", " ", "R 0 R", " ", " R R ", " R "}, + {" ", " ", " ", " ", " ", " ", " "}, + {" ", " R ", " ", " R R ", " ", " R ", " "}, + {" ", " ", " ", " R ", " ", " ", " "}}, + 'R', Blocks.REDSTONE_BLOCK, + '0', ModBlocks.RF_CONVERTER, + ' ', Matcher.wildcard()) : null; } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityRFConverter.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityRFConverter.java new file mode 100644 index 00000000..f28fa2d8 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityRFConverter.java @@ -0,0 +1,110 @@ +package de.ellpeck.naturesaura.blocks.tiles; + +import de.ellpeck.naturesaura.ModConfig; +import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; +import de.ellpeck.naturesaura.blocks.multi.Multiblocks; +import de.ellpeck.naturesaura.packet.PacketHandler; +import de.ellpeck.naturesaura.packet.PacketParticles; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ITickable; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.energy.CapabilityEnergy; +import net.minecraftforge.energy.EnergyStorage; +import net.minecraftforge.energy.IEnergyStorage; + +import javax.annotation.Nullable; + +public class TileEntityRFConverter extends TileEntityImpl implements ITickable { + + public final RFStorage storage = new RFStorage(); + private int lastEnergy; + + @Override + public void writeNBT(NBTTagCompound compound, SaveType type) { + super.writeNBT(compound, type); + compound.setInteger("energy", this.storage.getEnergyStored()); + } + + @Override + public void readNBT(NBTTagCompound compound, SaveType type) { + super.readNBT(compound, type); + this.storage.setEnergy(compound.getInteger("energy")); + } + + @Override + public void update() { + if (!this.world.isRemote) { + if (this.lastEnergy != this.storage.getEnergyStored() && this.world.getTotalWorldTime() % 10 == 0) { + this.sendToClients(); + this.lastEnergy = this.storage.getEnergyStored(); + } + + for (EnumFacing facing : EnumFacing.VALUES) { + TileEntity tile = this.world.getTileEntity(this.pos.offset(facing)); + if (tile == null || !tile.hasCapability(CapabilityEnergy.ENERGY, facing.getOpposite())) + continue; + IEnergyStorage storage = tile.getCapability(CapabilityEnergy.ENERGY, facing.getOpposite()); + if (storage == null) + continue; + int canStore = storage.receiveEnergy(Integer.MAX_VALUE, true); + if (canStore <= 0) + continue; + int extracted = this.storage.extractEnergy(canStore, false); + if (extracted <= 0) + continue; + storage.receiveEnergy(extracted, false); + break; + } + + int emptyPart = this.storage.getMaxEnergyStored() - this.storage.getEnergyStored(); + if (emptyPart <= 0) + return; + if (this.world.getTotalWorldTime() % 20 != 0) + return; + if (!Multiblocks.RF_CONVERTER.isComplete(this.world, this.pos)) + return; + + int aura = IAuraChunk.getAuraInArea(this.world, this.pos, 45); + if (aura <= IAuraChunk.DEFAULT_AURA) + return; + int amountToGen = Math.min(Math.min(10000, aura / 10), emptyPart); + int amountToUse = MathHelper.ceil(amountToGen / ModConfig.general.auraToRFRatio); + + this.storage.setEnergy(this.storage.getEnergyStored() + amountToGen); + BlockPos pos = IAuraChunk.getHighestSpot(this.world, this.pos, 45, this.pos); + IAuraChunk.getAuraChunk(this.world, pos).drainAura(pos, amountToUse); + + PacketHandler.sendToAllAround(this.world, this.pos, 32, + new PacketParticles(this.pos.getX(), this.pos.getY(), this.pos.getZ(), 20)); + } + } + + @Override + public boolean hasCapability(Capability capability, @Nullable EnumFacing facing) { + return capability == CapabilityEnergy.ENERGY || super.hasCapability(capability, facing); + } + + @Nullable + @Override + public T getCapability(Capability capability, @Nullable EnumFacing facing) { + if (capability == CapabilityEnergy.ENERGY) + return (T) this.storage; + else + return super.getCapability(capability, facing); + } + + public static class RFStorage extends EnergyStorage { + + public RFStorage() { + super(50000, 0, 2000); + } + + public void setEnergy(int energy) { + this.energy = energy; + } + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/compat/Compat.java b/src/main/java/de/ellpeck/naturesaura/compat/Compat.java index 6ed546a4..7e5ad0d9 100644 --- a/src/main/java/de/ellpeck/naturesaura/compat/Compat.java +++ b/src/main/java/de/ellpeck/naturesaura/compat/Compat.java @@ -1,8 +1,11 @@ package de.ellpeck.naturesaura.compat; +import de.ellpeck.naturesaura.ModConfig; +import de.ellpeck.naturesaura.NaturesAura; import de.ellpeck.naturesaura.compat.crafttweaker.CraftTweakerCompat; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.Loader; +import vazkii.patchouli.api.PatchouliAPI; public final class Compat { @@ -17,6 +20,8 @@ public final class Compat { if (baubles) MinecraftForge.EVENT_BUS.register(new BaublesCompat()); + + PatchouliAPI.instance.setConfigFlag(NaturesAura.MOD_ID + ":rf_converter", ModConfig.enabledFeatures.rfConverter); } public static void postInit() { diff --git a/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java b/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java index 4db59e70..411c9941 100644 --- a/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java +++ b/src/main/java/de/ellpeck/naturesaura/events/ClientEvents.java @@ -8,6 +8,7 @@ import de.ellpeck.naturesaura.api.aura.chunk.IAuraChunk; import de.ellpeck.naturesaura.api.aura.container.IAuraContainer; import de.ellpeck.naturesaura.api.aura.type.IAuraType; import de.ellpeck.naturesaura.blocks.tiles.TileEntityNatureAltar; +import de.ellpeck.naturesaura.blocks.tiles.TileEntityRFConverter; import de.ellpeck.naturesaura.compat.Compat; import de.ellpeck.naturesaura.items.ModItems; import de.ellpeck.naturesaura.particles.ParticleHandler; @@ -28,6 +29,7 @@ import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.energy.EnergyStorage; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent; import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; @@ -291,15 +293,22 @@ public class ClientEvents { IBlockState state = mc.world.getBlockState(pos); ItemStack blockStack = state.getBlock().getPickBlock(state, mc.objectMouseOver, mc.world, pos, mc.player); - this.drawContainerInfo(container, mc, res, 35, blockStack.getDisplayName()); + this.drawContainerInfo(container.getStoredAura(), container.getMaxAura(), container.getAuraColor(), + mc, res, 35, blockStack.getDisplayName(), null); if (tile instanceof TileEntityNatureAltar) { ItemStack tileStack = ((TileEntityNatureAltar) tile).getItemHandler(null).getStackInSlot(0); if (!tileStack.isEmpty() && tileStack.hasCapability(NaturesAuraAPI.capAuraContainer, null)) { - IAuraContainer stackContainer = tileStack.getCapability(NaturesAuraAPI.capAuraContainer, null); - this.drawContainerInfo(stackContainer, mc, res, 55, tileStack.getDisplayName()); + IAuraContainer stackCont = tileStack.getCapability(NaturesAuraAPI.capAuraContainer, null); + this.drawContainerInfo(stackCont.getStoredAura(), stackCont.getMaxAura(), stackCont.getAuraColor(), + mc, res, 55, tileStack.getDisplayName(), null); } } + } else if (tile instanceof TileEntityRFConverter) { + EnergyStorage storage = ((TileEntityRFConverter) tile).storage; + this.drawContainerInfo(storage.getEnergyStored(), storage.getMaxEnergyStored(), 0xcc4916, + mc, res, 35, I18n.format("tile.naturesaura.rf_converter.name"), + storage.getEnergyStored() + " / " + storage.getMaxEnergyStored() + " RF"); } } } @@ -312,13 +321,12 @@ public class ClientEvents { mc.profiler.endSection(); } - private void drawContainerInfo(IAuraContainer container, Minecraft mc, ScaledResolution res, int yOffset, String name) { - int color = container.getAuraColor(); + private void drawContainerInfo(int stored, int max, int color, Minecraft mc, ScaledResolution res, int yOffset, String name, String textBelow) { GlStateManager.color((color >> 16 & 255) / 255F, (color >> 8 & 255) / 255F, (color & 255) / 255F); int x = res.getScaledWidth() / 2 - 40; int y = res.getScaledHeight() / 2 + yOffset; - int width = MathHelper.ceil(container.getStoredAura() / (float) container.getMaxAura() * 80); + int width = MathHelper.ceil(stored / (float) max * 80); mc.getTextureManager().bindTexture(OVERLAYS); if (width < 80) @@ -327,5 +335,8 @@ public class ClientEvents { Gui.drawModalRectWithCustomSizedTexture(x, y, 0, 6, width, 6, 256, 256); mc.fontRenderer.drawString(name, x + 40 - mc.fontRenderer.getStringWidth(name) / 2F, y - 9, color, true); + + if (textBelow != null) + mc.fontRenderer.drawString(textBelow, x + 40 - mc.fontRenderer.getStringWidth(textBelow) / 2F, y + 7, color, true); } } diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java index 6aadbe6a..62efedba 100644 --- a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java @@ -321,6 +321,22 @@ public class PacketParticles implements IMessage { world.rand.nextGaussian() * 0.02F, 0x16b7b2, 1.5F, 40, 0F, false, true); break; + case 20: // RF converter + for (int i = world.rand.nextInt(5) + 2; i >= 0; i--) + Multiblocks.RF_CONVERTER.forEach(new BlockPos(message.posX, message.posY, message.posZ), 'R', (blockPos, matcher) -> { + if (world.rand.nextFloat() < 0.35F) { + NaturesAuraAPI.instance().spawnParticleStream( + blockPos.getX() + world.rand.nextFloat(), + blockPos.getY() + world.rand.nextFloat(), + blockPos.getZ() + world.rand.nextFloat(), + message.posX + world.rand.nextFloat(), + message.posY + world.rand.nextFloat(), + message.posZ + world.rand.nextFloat(), + 0.05F, 0xff1a05, 1.5F); + } + return true; + }); + break; } } }); diff --git a/src/main/resources/assets/naturesaura/blockstates/rf_converter.json b/src/main/resources/assets/naturesaura/blockstates/rf_converter.json new file mode 100644 index 00000000..9dec64c6 --- /dev/null +++ b/src/main/resources/assets/naturesaura/blockstates/rf_converter.json @@ -0,0 +1,14 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube_all", + "textures": { + "all": "naturesaura:blocks/rf_converter" + }, + "transform": "forge:default-block" + }, + "variants": { + "normal": [{}], + "inventory": [{}] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/naturesaura/lang/en_US.lang b/src/main/resources/assets/naturesaura/lang/en_US.lang index 9b90b057..092c7faa 100644 --- a/src/main/resources/assets/naturesaura/lang/en_US.lang +++ b/src/main/resources/assets/naturesaura/lang/en_US.lang @@ -40,6 +40,7 @@ tile.naturesaura.grated_chute.name=Adept Hopper tile.naturesaura.animal_spawner.name=Altar of Birthing tile.naturesaura.auto_crafter.name=Automatic Constructor tile.naturesaura.gold_brick.name=Golden Stone Bricks +tile.naturesaura.rf_converter.name=Energetic Aura Forge item.naturesaura.eye.name=Environmental Eye item.naturesaura.eye_improved.name=Environmental Ocular diff --git a/src/main/resources/assets/naturesaura/patchouli_books/book/en_us/entries/using/rf_converter.json b/src/main/resources/assets/naturesaura/patchouli_books/book/en_us/entries/using/rf_converter.json new file mode 100644 index 00000000..effa6150 --- /dev/null +++ b/src/main/resources/assets/naturesaura/patchouli_books/book/en_us/entries/using/rf_converter.json @@ -0,0 +1,27 @@ +{ + "name": "Energetic Aura Forge", + "icon": "naturesaura:rf_converter", + "category": "using", + "advancement": "naturesaura:sky_ingot", + "flag": "naturesaura:rf_converter", + "pages": [ + { + "type": "text", + "text": "While $(aura) is quite versatile and useful, it's most definitely not the only $(thing)energy source$() around. In recent history, new sources of energy that aren't considered natural have been $(italic)forged$() by the people. Sometimes, it might prove useful to have such a power source at one's disposal instead. The $(item)Energetic Aura Forge$() directly converts $(aura) into what is known to most people as $(thing)Redstone Flux$()," + }, + { + "type": "text", + "text": "to some as $(thing)Forge Energy$() and to even others as $(thing)Crystal Flux$().$(br)To achieve this, simply place the $(item)Energetic Aura Forge$() with the accompanied structure as shown on the next page. Then, any excess amount of $(aura) in the area will automatically be turned into electrical energy. The more $(aura) there is present, the faster the conversion process will go.$(br)Additionally, having the $(l:items/eye)Environmental Eye$() equipped will display the amount of energy in the device." + }, + { + "type": "multiblock", + "multiblock_id": "naturesaura:rf_converter", + "text": "Creating the structure around the $(item)Energetic Aura Forge$()" + }, + { + "type": "crafting", + "text": "Creating the $(item)Energetic Aura Forge$()", + "recipe": "naturesaura:rf_converter" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/naturesaura/recipes/rf_converter.json b/src/main/resources/assets/naturesaura/recipes/rf_converter.json new file mode 100644 index 00000000..086d30e0 --- /dev/null +++ b/src/main/resources/assets/naturesaura/recipes/rf_converter.json @@ -0,0 +1,42 @@ +{ + "type": "forge:ore_shaped", + "pattern": [ + "RWR", + "ITI", + "ROR" + ], + "key": { + "T": { + "item": "naturesaura:conversion_catalyst" + }, + "R": { + "item": "minecraft:redstone_block" + }, + "I": { + "item": "naturesaura:sky_ingot" + }, + "W": { + "type": "minecraft:item_nbt", + "item": "naturesaura:aura_bottle", + "nbt": { + "stored_type": "naturesaura:nether" + } + }, + "O": { + "type": "minecraft:item_nbt", + "item": "naturesaura:aura_bottle", + "nbt": { + "stored_type": "naturesaura:overworld" + } + } + }, + "result": { + "item": "naturesaura:rf_converter" + }, + "conditions": [ + { + "type": "minecraft:item_exists", + "item": "naturesaura:rf_converter" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/naturesaura/textures/blocks/rf_converter.png b/src/main/resources/assets/naturesaura/textures/blocks/rf_converter.png new file mode 100644 index 0000000000000000000000000000000000000000..f4ab05e9972a5bd3e37c5aecf9361d8222ec2ff8 GIT binary patch literal 703 zcmV;w0zmzVP)N2bZe?^J zG%hhNG!sB*!~g&SJxN4CR5(v%Q%!3VQ54N;Iv+8UX7bUbF^yF#w4%!jZn_b4=fbU! zEV__vTm&JCv?5lph=NkvLKP`WsiGpbQq97;vLL9aKf&K|Jm;n_23(wE-n?_qz4zQZ zsaC0o#)05J%;qu%_iXPo;Xm-K*i>tzguTNNK8=U?&i^;{0K4@NPe*;j z3GHJ=w2$Tuoyjs5rYG#*&d00RWGi3lktJ$m(@4pTEefdDIb|gI(b;L-n>lI!?)lE? zNfY^44e^4Ns%0fl$zdmOCH5?%$ZLNt^>P1a(?lfRrNGO50VTIF?owc#j^Ci$$|CY$ z@Z#5tSh;YP@kat3_HWo1Fq}JOemFx_-6F@iUiEDXR)LIo$T_QjUC2ZcJ5v>0JyEl= z?M&hJL;))twRjqR-^86-Zxf$!%XHc0`8}6KhN-OwTr6dF!8a4n1o|y}<6f%`T}Vjf zy{6M54?=wl;%Jqv1qmp?iTpki;TIv2AW^*+#M279kI5=%#A*Ag)Q^Ld1rfAuhJ2R1 lG@7{>%_Iwb#jR2ie*rc&&pqmubXoua002ovPDHLkV1k2WKdJx# literal 0 HcmV?d00001